Android 仿Win8的metro的UI界面(上)
来源:互联网 发布:c语言中%u是什么意思 编辑:程序博客网 时间:2024/05/07 04:01
转载请标明出处: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.01.08465231.17647061.27606151.3840831.50124881.3840831.27606151.17647061.08465231.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);}/** * 必要的初始化 */@Overrideprotected 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);}}@Overridepublic 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;@Overridepublic void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.main);joke = (MyImageView) findViewById(R.id.c_joke);joke.setOnClickIntent(new MyImageView.OnViewClickListener(){@Overridepublic 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下,还是很有必要的。
如果你觉得这篇文章对你有用,可以顶一个~~
源码下载点击此处
95 2
- Android 仿Win8的metro的UI界面(上)
- Android 仿Win8的metro的UI界面(上)
- Android 仿Win8的metro的UI界面(上)
- Android 仿Win8的metro的UI界面(上)
- Android瀑布流 & 仿Win8的metro的UI界面
- Android 仿Win8的metro的UI界面
- Android 仿Win8的metro的UI界面
- Android 仿Win8的metro的UI界面
- Android 仿Win8的metro的UI界面(点击缩放效果)
- Win8的Metro界面
- Android 仿Windows Metro 界面UI
- Android 仿Windows Metro 界面UI
- Android 仿Windows Metro 界面UI
- [Android UI界面] 仿WIN8界面方面的问题求解答
- Android仿Win8界面的按钮点击
- Android仿Metro的界面设计
- android仿QQ的UI界面
- Android ImageView仿win8 Metro效果
- 什么是软件工程
- SQL语句分组获取记录的第一条数据的方法
- gcc 编译器之命令选项 GCC Command Options
- mouseout 事件
- MetaQ技术内幕——源码分析(四)
- Android 仿Win8的metro的UI界面(上)
- PCI配置空间简介
- ANDROID应用如何监听自己是否被卸载及卸载反馈功能的实现
- linux clock
- 交换两个变量的值的两种方法
- MetaQ技术内幕——源码分析(六)
- Windows API——》SendMessage、PostMessage
- IE 浏览器模式和文本模式 解析(一)
- 黑马程序员 java IO ObjectInputStream ObuectOutputStream Serializable 读写对象 序列化