Android仿Win8界面的button点击
今天没事的时候,感觉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点击的更多相关文章
- Android 仿Win8的metro的UI界面(上)
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/23441455 昨晚没事手机下载了一些APP,发现现在仿win8的主界面越来越多, ...
- 实现 在子界面的button按下,在主界面的label显示。
不知道理解的对不对,反正功能是实现了. 这是子界面,COM口配置界面的 .H文件的定义.下面的Private:定义了Ui:MainWindow *main_ui;的指针变量 要 注 ...
- Android开发-之监听button点击事件
一.实现button点击事件的方法 实现button点击事件的监听方法有很多种,这里总结了常用的四种方法: 1.匿名内部类 2.外部类(独立类) 3.实现OnClickListener接口 4.添加X ...
- Android仿WIN8系统磁贴点击下沉倾斜效果
※效果 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGluZ2xvbmd4aW4yNA==/font/5a6L5L2T/fontsize/400/fil ...
- android仿win8
在 eoe上偶然发现已经有人实现了这个功能的源码(地址:http://www.eoeandroid.com /forum.php?mod=viewthread&tid=327557),马上下载 ...
- android仿win8 metro磁贴布局
代码下载 //更新代码, 这里是更新后的代码 //////////////////////// 1,含一个图片无限滚动的控件,自己实现的 2.可新增删除每个磁贴 3.来个图片吧 ////* ...
- 仿it快播顶部button点击背景滑动切换的效果
最近在it快播中看见它顶部的几个button可以点击后 背景会滑动到相应的button后面 就得很好看 就想办法实现了那效果 思路 大概就是通过view的叠加 把3个button通过RelativeL ...
- VC/Wince 实现仿Win8 Metro风格界面1——设计概述和自绘Button(附效果图)
去年用VC做了一个仿Win8 Metro风格的界面,感觉挺有意思,最近打算把实现过程和一些技术原理记录下来. 主要是风格上类似Win8,其实功能上很多借鉴了Android的操作方式.界面只支持两种大小 ...
- Android笔记——Button点击事件几种写法
Button点击事件:大概可以分为以下几种: 匿名内部类 定义内部类,实现OnClickListener接口 定义的构造方法 用Activity实现OnClickListener接口 指定Button ...
随机推荐
- 20180929 北京大学 人工智能实践:Tensorflow笔记03
更改的程序部分如下: 另: 难?????????????见链接: https://www.bilibili.com/video/av22530538/?p=17 + (完)
- windows server 打开 FTP 服务器上的文件夹时发生错误。请检查是否有权限访问该文件夹。
解决方案1: 打开高级安全windows防火墙,设置出入站规则. 然后,再打开windows防火墙界面,点击左上角“允许程序或功能通过windows防火墙”,勾选上设置的出入站名称和FTP服务器. 如 ...
- Android 6.0 执行时权限处理全然解析
转载请标明出处: http://blog.csdn.net/lmj623565791/article/details/50709663: 本文出自:[张鸿洋的博客] 一.概述 随着Android 6. ...
- PHP经常使用功能
1)字符串 主要方法有:strops().substr().str_split().explode()等.很多其它方法查看PHP官方手冊. <?php /** * 字符串的方法:strpos() ...
- vue.2.0-自定义全局组件
App.vue <template> <div id="app"> <h3>welcome vue-loading</h3> < ...
- centos7 nginx搭建及其反向代理
摘要:nginx反向代理的原理:外部通过ip加端口访问nginx,nginx接收到外部请求,通过ip解析访问内部服务器,内部服务器再将数据传回Nginx服务器,而Nginx再把数据传回给外部客户机. ...
- C#解决System.Security.Cryptography.MD5.Create()调用的目标发生了异常)的问题
今天搭建微信扫码支付环境的时候,一样的配置参数,调用连接提示错误 错误:调用的目标发生了异常 然后跟踪到执行 MD5 md5 = System.Security.Cryptography.MD5.Cr ...
- OpenSUSE42.3 leap 软件源设置
一.OpenSUSE软件源介绍: 1.默认已经加入了官方的软件源,不过我们自己也可以根据需要添加很多非官方软件源,添加软件源时要注意: 非官方源可能包含一些试验中的不稳定的软件包 不同的软件源之 ...
- 安装完Python之后,如何设置Python环境变量
人生苦短,我用Python.最近有许多加群的萌新在咨询Python安装的事宜,Python安装问题不大,可以戳这篇文章:.本以为安装Python之后就可以万事大吉,高枕无忧了,往命令行中输入pytho ...
- WebAssembly学习(六):AssemblyScript - 限制与类型
一.限制 将无类型的JavaScript编译为WebAssembly没有意义,因为它最终会导致运行其中较慢的一个JavaScript. 相反,AssemblyScript专注于WebAssembly擅 ...