今天没事的时候,感觉Win8的扁平化的button还是挺好看的,就研究了下怎样在安卓界面实现Win8的扁平化button点击效果。

发现了一个自己定义的View能够实现扁平化button效果,话不多说,我们直接上代码。

1、首先要自己定义自己的View。创建一个自己定义的MyImageView类继承ImageView,并实现点击效果的设定。

public class MyImageView extends ImageView {

   private boolean onAnimation = true;// 是否处于动画状态
private int rotateDegree = 10;// 运行动画的时间
private boolean isFirst = true;// 标识是否为第一次绘制视图
private float minScale = 0.95f;// 最小缩放限度
private int vWidth;// 视图宽度
private int vHeight;// 视图高度
private boolean isFinish = true;// 标识是否为结束
private boolean isActionMove = false;// 标识是否在移动状态
private boolean isScale = false;// 标识是否为缩放状态
private Camera camera; boolean XbigY = false;// 是否放大
float RolateX = 0;// 旋转的X轴点
float RolateY = 0;// 旋转的Y轴点

OnViewClick onclick = null; public MyImageView(Context context) {
super(context);
// TODO Auto-generated constructor stub
camera = new Camera();
} public MyImageView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
camera = new Camera();
} public void SetAnimationOnOff(boolean oo) {
onAnimation = oo;
} /**
* 设置点击事件
*
* @param onclick
*/
public void setOnClickIntent(OnViewClick onclick) {
this.onclick = onclick;
} /**
* 绘制View
*/
@SuppressLint("DrawAllocation")
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (isFirst) {// 推断是否为第一次进入
isFirst = false;
init();
}
canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG
| Paint.FILTER_BITMAP_FLAG));// 抗锯齿
} /**
* 初始化视图---初始化配置
*/
public void init() {
vWidth = getWidth() - getPaddingLeft() - getPaddingRight();
vHeight = getHeight() - getPaddingTop() - getPaddingBottom();
Drawable drawable = getDrawable();
BitmapDrawable bd = (BitmapDrawable) drawable;
bd.setAntiAlias(true);
} /**
* 触摸监听
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);
if (!onAnimation)// 推断是否为动画状态
return true; switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:// 按下
float X = event.getX();
float Y = event.getY();
RolateX = vWidth / 2 - X;
RolateY = vHeight / 2 - Y;
XbigY = Math.abs(RolateX) > Math.abs(RolateY) ? true : false; isScale = X > vWidth / 3 && X < vWidth * 2 / 3 && Y > vHeight / 3
&& Y < vHeight * 2 / 3;
isActionMove = false; if (isScale) {// 推断是否同意缩放
scaleHandler.sendEmptyMessage(1);
} else {
rolateHandler.sendEmptyMessage(1);
}
break;
case MotionEvent.ACTION_MOVE:// 移动
float x = event.getX();
float y = event.getY();
if (x > vWidth || y > vHeight || x < 0 || y < 0) {
isActionMove = true;
} else {
isActionMove = false;
} break;
case MotionEvent.ACTION_UP:// 松开
if (isScale) {// 推断是否同意缩放
scaleHandler.sendEmptyMessage(6);
} else {
rolateHandler.sendEmptyMessage(6);
}
break;
}
return true;
} /**
* 自己定义View点击事件接口
*/
public interface OnViewClick {
public void onClick();
} /**
* 旋转动画的Handler,依据状态运行动画
*/
@SuppressLint("HandlerLeak")
private Handler rolateHandler = new Handler() {
private Matrix matrix = new Matrix();
private float count = 0; @Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
matrix.set(getImageMatrix());
switch (msg.what) {
case 1:
count = 0;
BeginRolate(matrix, (XbigY ? count : 0), (XbigY ? 0 : count));
rolateHandler.sendEmptyMessage(2);
break;
case 2:
BeginRolate(matrix, (XbigY ? count : 0), (XbigY ? 0 : count));
if (count < getDegree()) {
rolateHandler.sendEmptyMessage(2);
} else {
isFinish = true;
}
count++;
count++;
break;
case 3:
BeginRolate(matrix, (XbigY ? count : 0), (XbigY ? 0 : count));
if (count > 0) {
rolateHandler.sendEmptyMessage(3);
} else {
isFinish = true;
if (!isActionMove && onclick != null) {
onclick.onClick();
}
}
count--;
count--;
break;
case 6:
count = getDegree();
BeginRolate(matrix, (XbigY ? count : 0), (XbigY ? 0 : count));
rolateHandler.sendEmptyMessage(3);
break;
}
}
}; /**
* 開始旋转--使用线程锁控制,确保每次仅仅运行一个动作
*
* @param matrix
* @param rolateX
* @param rolateY
*/
private synchronized void BeginRolate(Matrix matrix, float rolateX,
float rolateY) {
int scaleX = (int) (vWidth * 0.5f);
int scaleY = (int) (vHeight * 0.5f);
camera.save();
camera.rotateX(RolateY > 0 ? rolateY : -rolateY);
camera.rotateY(RolateX < 0 ? rolateX : -rolateX);
camera.getMatrix(matrix);
camera.restore();
// 控制中心点
if (RolateX > 0 && rolateX != 0) {
matrix.preTranslate(-vWidth, -scaleY);
matrix.postTranslate(vWidth, scaleY);
} else if (RolateY > 0 && rolateY != 0) {
matrix.preTranslate(-scaleX, -vHeight);
matrix.postTranslate(scaleX, vHeight);
} else if (RolateX < 0 && rolateX != 0) {
matrix.preTranslate(-0, -scaleY);
matrix.postTranslate(0, scaleY);
} else if (RolateY < 0 && rolateY != 0) {
matrix.preTranslate(-scaleX, -0);
matrix.postTranslate(scaleX, 0);
}
setImageMatrix(matrix);
} /**
* 缩放动画Handler
*/
@SuppressLint("HandlerLeak")
private Handler scaleHandler = new Handler() {
private Matrix matrix = new Matrix();
private float s;
int count = 0; @Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
matrix.set(getImageMatrix());
switch (msg.what) {
case 1:
if (!isFinish) {
return;
} else {
isFinish = false;
count = 0;
s = (float) Math.sqrt(Math.sqrt(minScale));
BeginScale(matrix, s);
scaleHandler.sendEmptyMessage(2);
}
break;
case 2:
BeginScale(matrix, s);
if (count < 4) {
scaleHandler.sendEmptyMessage(2);
} else {
isFinish = true;
if (!isActionMove && onclick != null) {
onclick.onClick();
}
}
count++;
break;
case 6:
if (!isFinish) {
scaleHandler.sendEmptyMessage(6);
} else {
isFinish = false;
count = 0;
s = (float) Math.sqrt(Math.sqrt(1.0f / minScale));
BeginScale(matrix, s);
scaleHandler.sendEmptyMessage(2);
}
break;
}
}
}; /**
* 開始缩放动画
*
* @param matrix
* @param scale
*/
private synchronized void BeginScale(Matrix matrix, float scale) {
int scaleX = (int) (vWidth * 0.5f);
int scaleY = (int) (vHeight * 0.5f);
matrix.postScale(scale, scale, scaleX, scaleY);
setImageMatrix(matrix);
} /**
* 获取运行的时间--旋转
*
* @return
*/
public int getDegree() {
return rotateDegree;
} /**
* 设置动画时间--旋转
*
* @param degree
*/
public void setDegree(int degree) {
rotateDegree = degree;
} /**
* 获取缩放程度
*
* @return
*/
public float getScale() {
return minScale;
} /**
* 设置视图缩放度
*
* @param scale
*/
public void setScale(float scale) {
minScale = scale;
}
}

当中Record类的主要内容例如以下:
public class Record{

   public int getDegrees(float a, float b) {
float dx = a;
float x = b / 4;
float x2 = 3 * b / 4;
if (dx < x / 10)
return 10;
else if (dx < x / 5)
return 9;
else if (dx < x * 3 / 10)
return 8;
else if (dx < x * 2 / 5)
return 7;
else if (dx < x * 5 / 10)
return 6;
else if (dx < x * 3 / 5)
return 5;
else if (dx < x * 7 / 10)
return 4;
else if (dx < x * 4 / 5)
return 3;
else if (dx < x * 9 / 10)
return 2;
else if (dx < x)
return 2;
else if (dx - x2 > x * 9 / 10)
return 10;
else if (dx - x2 > x * 4 / 5)
return 9;
else if (dx - x2 > x * 7 / 10)
return 8;
else if (dx - x2 > x * 3 / 5)
return 7;
else if (dx - x2 > x * 5 / 10)
return 6;
else if (dx - x2 > x * 2 / 5)
return 5;
else if (dx - x2 > x * 3 / 10)
return 4;
else if (dx - x2 > x / 5)
return 3;
else if (dx - x2 > x / 10)
return 2;
return 10;
}

}

2、定义好了自己的ImageView后,在给界面加入button的时候,引用自己定义的ImageView就可以。



Android仿Win8界面的button点击的更多相关文章

  1. Android 仿Win8的metro的UI界面(上)

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/23441455 昨晚没事手机下载了一些APP,发现现在仿win8的主界面越来越多, ...

  2. 实现 在子界面的button按下,在主界面的label显示。

    不知道理解的对不对,反正功能是实现了. 这是子界面,COM口配置界面的 .H文件的定义.下面的Private:定义了Ui:MainWindow  *main_ui;的指针变量      要   注  ...

  3. Android开发-之监听button点击事件

    一.实现button点击事件的方法 实现button点击事件的监听方法有很多种,这里总结了常用的四种方法: 1.匿名内部类 2.外部类(独立类) 3.实现OnClickListener接口 4.添加X ...

  4. Android仿WIN8系统磁贴点击下沉倾斜效果

    ※效果 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGluZ2xvbmd4aW4yNA==/font/5a6L5L2T/fontsize/400/fil ...

  5. android仿win8

    在 eoe上偶然发现已经有人实现了这个功能的源码(地址:http://www.eoeandroid.com /forum.php?mod=viewthread&tid=327557),马上下载 ...

  6. android仿win8 metro磁贴布局

    代码下载     //更新代码,   这里是更新后的代码 //////////////////////// 1,含一个图片无限滚动的控件,自己实现的 2.可新增删除每个磁贴 3.来个图片吧 ////* ...

  7. 仿it快播顶部button点击背景滑动切换的效果

    最近在it快播中看见它顶部的几个button可以点击后 背景会滑动到相应的button后面 就得很好看 就想办法实现了那效果 思路 大概就是通过view的叠加 把3个button通过RelativeL ...

  8. VC/Wince 实现仿Win8 Metro风格界面1——设计概述和自绘Button(附效果图)

    去年用VC做了一个仿Win8 Metro风格的界面,感觉挺有意思,最近打算把实现过程和一些技术原理记录下来. 主要是风格上类似Win8,其实功能上很多借鉴了Android的操作方式.界面只支持两种大小 ...

  9. Android笔记——Button点击事件几种写法

    Button点击事件:大概可以分为以下几种: 匿名内部类 定义内部类,实现OnClickListener接口 定义的构造方法 用Activity实现OnClickListener接口 指定Button ...

随机推荐

  1. svn 学习

    svn命令在linux下的使用 svn命令在linux下的使用SVN软件版本管理 1.将文件checkout到本地目录svn checkout path(path是服务器上的目录)例如:svn che ...

  2. 去除windows编辑文本中的回车符

    情景描述: 最近,huskiesir的朋友遇到了一个很奇葩的问题.那就是他在windows上搭建了一个http服务,把A脚本放在了上面并用linux去下载和执行,但是在执行的时候出现了问题,在linu ...

  3. mysql去掉密码规则的两种方式

    环境介绍:centeros 7 + mysqld5.7 当我们装完数据库以后,使用临时密码登录到数据库去更改一个简单的密码,如 set password='; 结果出现以下提示: ERROR (HY0 ...

  4. docker容器存放目录磁盘空间满了,转移数据修改Docker默认存储位置

    原文:docker容器存放目录磁盘空间满了,转移数据修改Docker默认存储位置 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/qq_3767485 ...

  5. Spring Cloud学习笔记【六】Hystrix 监控数据聚合 Turbine

    上一篇我们介绍了使用 Hystrix Dashboard 来展示 Hystrix 用于熔断的各项度量指标.通过 Hystrix Dashboard,我们可以方便的查看服务实例的综合情况,比如:服务调用 ...

  6. MYSQL 更新时间自己主动同步与创建时间默认值共存问题

    本文作者:苏生米沿 本文地址:http://blog.csdn.net/sushengmiyan/article/details/50326259 在使用SQL的时候,希望在更新数据的时候自己主动填充 ...

  7. STL 源代码剖析 算法 stl_algo.h -- search

    本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie search --------------------------------------- ...

  8. 分布式架构中shiro

    分布式架构中shiro 前言:前段时间在搭建公司游戏框架安全验证的时候,就想到之前web最火的shiro框架,虽然后面实践发现在netty中不太适用,最后自己模仿shiro写了一个缩减版的,但是中间花 ...

  9. Redis封装之String

    RedisBase类 /// <summary> /// RedisBase类,是redis操作的基类,继承自IDisposable接口,主要用于释放内存 /// </summary ...

  10. quartz-misfire 错失、补偿执行

    调度(scheduleJob)或恢复调度(resumeTrigger,resumeJob)后不同的misfire对应的处理规则 misfire产生的条件是:到了该触发执行时上一个执行还未完成,且线程池 ...