博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android 仿Win8的metro的UI界面(上)
阅读量:5088 次
发布时间:2019-06-13

本文共 6394 字,大约阅读时间需要 21 分钟。

转载请标明出处: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、布局文件

布局文件,完成了上面效果图的静态效果,如果你不需要添加点击动画,或者只需要很简单的点击效果,那么就已经完成这样的菜单的编写,再添加个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下,还是很有必要的。

如果你觉得这篇文章对你有用,可以顶一个~~

版权声明:本文为博主原创文章,未经博主允许不得转载。

转载于:https://www.cnblogs.com/dingxiaoyue/p/4924995.html

你可能感兴趣的文章
@Column标记持久化详细说明
查看>>
创建本地yum软件源,为本地Package安装Cloudera Manager、Cloudera Hadoop及Impala做准备...
查看>>
mysql8.0.13下载与安装图文教程
查看>>
站立会议08(冲刺2)
查看>>
url查询参数解析
查看>>
http://coolshell.cn/articles/10910.html
查看>>
[转]jsbsim基础概念
查看>>
DIV和SPAN的区别
查看>>
第一次使用cnblogs
查看>>
C#语法糖之 session操作类 asp.net
查看>>
2015 Multi-University Training Contest 3
查看>>
使用Gitblit 在windows 上部署你的Git Server
查看>>
217. Contains Duplicate
查看>>
vue2.0 关于Vue实例的生命周期
查看>>
jenkins 更换主数据目录
查看>>
Silverlight中恼人的g.i.cs错误
查看>>
SQLite 数据库增删改查
查看>>
<s:iterator>的status
查看>>
C++入门--1.0输入输出
查看>>
让搭建在Github Pages上的Hexo博客可以被Google搜索到
查看>>