Android 仿Win8的metro的UI界面(上)
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/23441455
昨晚没事手机下载了一些APP,发现现在仿win8的主界面越来越多,在大家见惯了类GridView或者类Tab后,给人一种耳目一新的感觉。今天在eoe上偶然发现已经有人实现了这个功能的源码(地址:http://www.eoeandroid.com/forum.php?mod=viewthread&tid=327557),马上下载跑了一下,效果很炫,但是有些bug,比如点击速度特别快时图像会被放大,以及点击时会触发两次点击事件。
本例子基于eoe中这位大神的实现,做了一些简化,和bug的修复。
效果:
首先普及一个小知识点:
我们在项目中有时候需要一个缓慢的梯度数据,例如:控件的宽度以一定的比例增加,然后以相同的比例还原到原来的长度。
- package com.zhy._01;
- public class Test2
- {
- public static void main(String[] args)
- {
- float val = 1;
- float s = 0.85f;
- int i = 0;
- s = (float) Math.sqrt(1 / s);
- System.out.println(val);
- while (i < 5)
- {
- val = val *s ;
- System.out.println(val);
- i++;
- }
- s = 0.85f;
- i = 0;
- s = (float) Math.sqrt(s);
- while (i < 5)
- {
- val = val *s ;
- System.out.println(val);
- i++;
- }
- }
输出结果:
- 1.0
- 1.0846523
- 1.1764706
- 1.2760615
- 1.384083
- 1.5012488
- 1.384083
- 1.2760615
- 1.1764706
- 1.0846523
- 1.0
很完美吧,基本是个对称的梯度数据,梯度的幅度由代码中的s觉得,越接近1幅度越小,反之则反之。
好了下面开始代码:
1、布局文件
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:background="@drawable/bkg_img_default"
- android:gravity="center"
- android:orientation="vertical" >
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="vertical" >
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="horizontal" >
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="vertical" >
- <com.ljp.ani01.MyImageView
- android:id="@+id/c_joke"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_margin="2dp"
- android:scaleType="matrix"
- android:src="@drawable/left_top" />
- <com.ljp.ani01.MyImageView
- android:id="@+id/c_idea"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_margin="2dp"
- android:scaleType="matrix"
- android:src="@drawable/left_bottom" />
- </LinearLayout>
- <com.ljp.ani01.MyImageView
- android:id="@+id/c_constellation"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_margin="2dp"
- android:scaleType="matrix"
- android:src="@drawable/right" />
- </LinearLayout>
- <com.ljp.ani01.MyImageView
- android:id="@+id/c_recommend"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_margin="2dp"
- android:scaleType="matrix"
- android:src="@drawable/bottom" />
- </LinearLayout>
- </LinearLayout>
布局文件,完成了上面效果图的静态效果,如果你不需要添加点击动画,或者只需要很简单的点击效果,那么就已经完成这样的菜单的编写,再添加个backgroud自定义下点击效果就好了。当然,我们这里有个比较柔和的点击动画,有自定义的ImageView完成。
2、MyImageView.java
- package com.ljp.ani01;
- import android.content.Context;
- import android.graphics.Matrix;
- import android.graphics.drawable.BitmapDrawable;
- import android.graphics.drawable.Drawable;
- import android.os.Handler;
- import android.util.AttributeSet;
- import android.util.Log;
- import android.view.MotionEvent;
- import android.widget.ImageView;
- public class MyImageView extends ImageView
- {
- private static final String TAG = "MyImageView";
- private static final int SCALE_REDUCE_INIT = 0;
- private static final int SCALING = 1;
- private static final int SCALE_ADD_INIT = 6;
- /**
- * 控件的宽
- */
- private int mWidth;
- /**
- * 控件的高
- */
- private int mHeight;
- /**
- * 控件的宽1/2
- */
- private int mCenterWidth;
- /**
- * 控件的高 1/2
- */
- private int mCenterHeight;
- /**
- * 设置一个缩放的常量
- */
- private float mMinScale = 0.85f;
- /**
- * 缩放是否结束
- */
- private boolean isFinish = true;
- public MyImageView(Context context)
- {
- this(context, null);
- }
- public MyImageView(Context context, AttributeSet attrs)
- {
- this(context, attrs, 0);
- }
- public MyImageView(Context context, AttributeSet attrs, int defStyle)
- {
- super(context, attrs, defStyle);
- }
- /**
- * 必要的初始化
- */
- @Override
- protected void onLayout(boolean changed, int left, int top, int right, int bottom)
- {
- super.onLayout(changed, left, top, right, bottom);
- if (changed)
- {
- mWidth = getWidth() - getPaddingLeft() - getPaddingRight();
- mHeight = getHeight() - getPaddingTop() - getPaddingBottom();
- mCenterWidth = mWidth / 2;
- mCenterHeight = mHeight / 2;
- Drawable drawable = getDrawable();
- BitmapDrawable bd = (BitmapDrawable) drawable;
- bd.setAntiAlias(true);
- }
- }
- @Override
- public boolean onTouchEvent(MotionEvent event)
- {
- switch (event.getAction())
- {
- case MotionEvent.ACTION_DOWN:
- float X = event.getX();
- float Y = event.getY();
- mScaleHandler.sendEmptyMessage(SCALE_REDUCE_INIT);
- break;
- case MotionEvent.ACTION_UP:
- mScaleHandler.sendEmptyMessage(SCALE_ADD_INIT);
- break;
- }
- return true;
- }
- /**
- * 控制缩放的Handler
- */
- private Handler mScaleHandler = new Handler()
- {
- private Matrix matrix = new Matrix();
- private int count = 0;
- private float s;
- /**
- * 是否已经调用了点击事件
- */
- private boolean isClicked;
- public void handleMessage(android.os.Message msg)
- {
- matrix.set(getImageMatrix());
- switch (msg.what)
- {
- case SCALE_REDUCE_INIT:
- if (!isFinish)
- {
- mScaleHandler.sendEmptyMessage(SCALE_REDUCE_INIT);
- } else
- {
- isFinish = false;
- count = 0;
- s = (float) Math.sqrt(Math.sqrt(mMinScale));
- beginScale(matrix, s);
- mScaleHandler.sendEmptyMessage(SCALING);
- }
- break;
- case SCALING:
- beginScale(matrix, s);
- if (count < 4)
- {
- mScaleHandler.sendEmptyMessage(SCALING);
- } else
- {
- isFinish = true;
- if (MyImageView.this.mOnViewClickListener != null && !isClicked)
- {
- isClicked = true;
- MyImageView.this.mOnViewClickListener.onViewClick(MyImageView.this);
- } else
- {
- isClicked = false;
- }
- }
- count++;
- break;
- case 6:
- if (!isFinish)
- {
- mScaleHandler.sendEmptyMessage(SCALE_ADD_INIT);
- } else
- {
- isFinish = false;
- count = 0;
- s = (float) Math.sqrt(Math.sqrt(1.0f / mMinScale));
- beginScale(matrix, s);
- mScaleHandler.sendEmptyMessage(SCALING);
- }
- break;
- }
- }
- };
- protected void sleep(int i)
- {
- try
- {
- Thread.sleep(i);
- } catch (InterruptedException e)
- {
- e.printStackTrace();
- }
- }
- /**
- * 缩放
- *
- * @param matrix
- * @param scale
- */
- private synchronized void beginScale(Matrix matrix, float scale)
- {
- matrix.postScale(scale, scale, mCenterWidth, mCenterHeight);
- setImageMatrix(matrix);
- }
- /**
- * 回调接口
- */
- private OnViewClickListener mOnViewClickListener;
- public void setOnClickIntent(OnViewClickListener onViewClickListener)
- {
- this.mOnViewClickListener = onViewClickListener;
- }
- public interface OnViewClickListener
- {
- void onViewClick(MyImageView view);
- }
- }
代码不算复杂,主要就是对onTouchEvent的Action_Down和Action_Up的监听,然后通过Handler结合matrix完成缩放的效果。这里简单说一个mScaleHandler里面代码的逻辑,当检测到ACTION_DOWN事件,会判断当前缩放是否完成,如果完成了则添加缩小的效果,如果没有,则一直检测。ACTION_UP也是同样的过程。缩放的梯度就用到了文章开始介绍的小知识点。
有人会觉得使用Handler比较麻烦,这里一直使用Handler.sendMsg的原因是,利用了这个消息队列,队列先进先出,保证动画效果的流畅。因为ACTION_DOWN_与ACTION_UP一瞬点完成的,其实动画还在进行。如果你在onTouchEvent中用while集合sleep完成动画,会出现卡死,监听不到Up事件等问题。
3、主Activity
- package com.ljp.ani01;
- import android.app.Activity;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Toast;
- public class TestRolateAnimActivity extends Activity
- {
- MyImageView joke;
- @Override
- public void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- joke = (MyImageView) findViewById(R.id.c_joke);
- joke.setOnClickIntent(new MyImageView.OnViewClickListener()
- {
- @Override
- public void onViewClick(MyImageView view)
- {
- Toast.makeText(TestRolateAnimActivity.this, "Joke", 1000).show();
- }
- });
- }
- }
利用提供的回调接口注册了点击事件。这里说明一下,现在为ImageView设置OnClickLIstener是没有作用的,因为自定义的ImageView的onTouchEvent直接返回了true,不会往下执行click事件,如果你希望通过OnClickLIstener进行注册,你可以把ontouchevent里面返回值改成super.ontouchevent(event),并且需要将ImageView的clickable设置为true。这些都是Ontouch事件的传播机制,不了解的google下,还是很有必要的。
如果你觉得这篇文章对你有用,可以顶一个~~
源码下载点击此处
Android 仿Win8的metro的UI界面(上)的更多相关文章
- Android 仿PhotoShop调色板应用(三) 主体界面绘制
版权声明:本文为博主原创文章,未经博主允许不得转载. Android 仿PhotoShop调色板应用(三) 主体界面绘制 关于PhotoShop调色板应用的实现我总结了两个最核心的部分: 1 ...
- Unity在UI界面上显示3D模型/物体,控制模型旋转
Unity3D物体在UI界面的显示 本文提供全流程,中文翻译. Chinar 坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) Chinar -- ...
- 在Android中实现service动态更新UI界面
之前曾介绍过Android的UI设计与后台线程交互,据Android API的介绍,service一般是在后台运行的,没有界面的.那么如何实现service动态更新UI界面呢?案例:通过service ...
- Android Handler传递参数动态更新UI界面demo
package com.example.demo_test; import android.app.Activity; import android.os.Bundle; import android ...
- android中实现service动态更新UI界面
案例:通过service向远程服务器发送请求,根据服务器返回的结果动态更新主程序UI界面,主程序可实时关闭或重启服务. 注册BroadcastReceiver 在主程序activity中注册一个Bro ...
- Flash Stage3D 在2D UI 界面上显示3D模型问题完美解决
一直以来很多Stage3D开发者都在为3D模型在2DUI上显示的问题头疼.Stage3D一直是在 Stage2D下面.为了做到3D模型在2DUI上显示通常大家有几种实现方式,下面来说说这几种实现方式吧 ...
- android仿win8 metro磁贴布局
代码下载 //更新代码, 这里是更新后的代码 //////////////////////// 1,含一个图片无限滚动的控件,自己实现的 2.可新增删除每个磁贴 3.来个图片吧 ////* ...
- Android基础总结(3)——UI界面布局
Android的UI设计有好几种界面程序编写方式.大体上可分为两大类:一类是利用可视化工具来进行,允许你进行拖拽控件来进行布局:还有一类是编写xml文档来进行布局.这两种方法可以相互转换. 1.常见的 ...
- Android仿Win8界面的button点击
今天没事的时候,感觉Win8的扁平化的button还是挺好看的,就研究了下怎样在安卓界面实现Win8的扁平化button点击效果. 发现了一个自己定义的View能够实现扁平化button效果,话不多说 ...
随机推荐
- java 安卓开发之文件的读与写
java文件的读与写,代码: String file="user.txt"; private void writeFileData(String str1, String str2 ...
- Linux 寻找安装路径
1.whereis 语法: # whereis [-bmsu] 文件或者目录名称 参数说 明: -b : 只找二进制文件 -m: 只找在说明文件manual路径下的文件 -s : 只找sou ...
- cxf客户端代码设置设置访问用户名、密码、证书域名不匹配认证通过
最近和第三方联调,需要调用对方的wsdl,但是调用必须的设置用户名.密码验证.在soapUI里面设置用户名.密码调用通过.但是怎么转换成JAVA代码呢,搜索了好多解决方案,现将代码截图如下: 1.SO ...
- Java基础--IO
1,流的认识和分类 2,Java种处理流的IO类架构 3,字节流和字符流转换 4,NIO的概述 5,Java IO关闭资源 1,流的认识和分类 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的 ...
- 0.0C语言重点问题回顾
左值和右值得区别:左值是用来表明变量的身份的,右值更加侧重于值本身: void*是个例外,它只有基地址没有类型信息,所以无法解引用. int *p = malloc(100); char *s = m ...
- Android开发-解决 AIDL 中找不到couldn't find import for class错误
最近在使用AIDL做IPC的时候,在处理复杂的数据类型的时候,编译器总是报couldn't find import for class错误,所以在这里总结下AIDL使用的时候的一些注意事项,希望对你能 ...
- underscorejs-reduceRight学习
2.4 reduceRight 2.4.1 语法: _.reduceRight(list, iteratee, memo, [context]) 2.3.2 说明: reduceRight和reduc ...
- 【FLYabroad 】微软内部代码检查工具 (Microsoft Source Analysis for C#)[转]
SourceAnalysis (StyleCop)的终极目标是让所有人都能写出优雅和一致的代码,因此这些代码具有很高的可读性. 早就听说了微软内部的静态代码检查和代码强制格式美化工具 StyleCop ...
- 自定义jdbc框架
获取元数据 元数据- DataBaseMetaData DatabaseMetaData meta = con.getMetaData(); getDatabaseProductName().getD ...
- 腾讯QQ、新浪微博等知名社交网络图标素材
腾讯QQ.新浪微博.QQ空间.淘宝.知乎.支付宝.大众点评等设计网络图标矢量素材. 注意是矢量素材,AI格式.放大缩小不变形. 社交网络图标几乎在网页制作中都会用到.一个好看的图标,完全可以提升整体网 ...