让低版本的 Android 项目显示出 Material 风格的点击效果
每天都被不同的需求纠缠的生活是幸福而又不幸的,这不我们家亲爱的设计师们又让我们在低版本的 Android 平台上实现一下类似于 Material Design 的点击效果。
虽然大家都知道 MaterialDesign 的确好看很多,但是让我们为低版本适配也是一个苦逼的活儿。
不过还好,在使用了 nineoldandroids 这个开源库之后,总算是实现了这个效果。
先放出一个 Github 地址,大家如果可以去那里看看源码: https://github.com/Kifile/MaterialView, 能够 Star 一下就更好了。
再给出两张效果图,分别是基于 TextView 和 ImageView 的点击效果:
图1 TextView、ImageView应用后的点击效果示意图
1.代码实现逻辑
首先我们分析一下这种点击效果的实现逻辑。
点击效果的处理主要分为两个阶段:
a.手指按下:
当用户触摸到控件的时候,首先我们先让控件显示一层浅色遮罩,然后从手指按下位置开始,有一个深色遮罩逐渐扩大至整个控件。
b.手指弹起:
当用户松开手指之后,这里存在两种情况,一种是深色遮罩已经扩大到了整个控件的范围,一种是深色遮罩尚未完全包围整个控件。
对于前一种情况,我们简单做一次透明度变化,让遮罩逐渐消失即可;
对于后一种情况,我们需要让深色遮罩从当前的位置快速扩散到整个控件,同时也要做透明度变化,放置遮罩消失太过突兀。
具体代码实现逻辑请参看这里: https://github.com/Kifile/MaterialView/blob/master/materialwidget/src/main/java/com/kifile/materialwidget/MaterialBackgroundDetector.java,MaterialBackgroundDetector 中 onTouchEvent 的处理。
2.使用库文件实现 Material 点击效果
目前我已经将这个项目部署到了 Maven 中心库中,如果大家对部署的逻辑感兴趣,可以看看这篇文章(一步一步教你分享开源项目到 Maven 中心仓库),因此如果大家是使用 Android Studio 来开发项目,可以通过使用以下代码将本库进行集成:
- dependencies {
- compile 'com.kifile:MaterialView:1.0'
- }
通过在 gradle.build 文件中引入 maven 项目,我们现在就可以正式使用这个点击效果了。
a.继承你希望实现的控件,代码如下:
- public class MaterialImageView extends ImageView {
- public MaterialImageView(Context context) {
- super(context);
- init(null, 0);
- }
- public MaterialImageView(Context context, AttributeSet attrs) {
- super(context, attrs);
- init(attrs, 0);
- }
- public MaterialImageView(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- init(attrs, defStyle);
- }
- }
b.在 init 方法中创建一个 MaterialBackgroundDetector 对象,用于事件委托:
- private MaterialBackgroundDetector mDetector;
- private void init(AttributeSet attrs, int defStyle) {
- final TypedArray a = getContext().obtainStyledAttributes(
- attrs, com.kifile.materialwidget.R.styleable.MaterialTextView, defStyle, 0);
- int color = a.getColor(com.kifile.materialwidget.R.styleable.MaterialTextView_maskColor, MaterialBackgroundDetector.DEFAULT_COLOR);
- a.recycle();
- mDetector = new MaterialBackgroundDetector(getContext(), this, null, color);
- }
c.重写父类方法,将相应事件委托给 mDetector 对象处理
- @Override
- protected void onSizeChanged(int w, int h, int oldw, int oldh) {
- super.onSizeChanged(w, h, oldw, oldh);
- mDetector.onSizeChanged(w, h);
- }
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- boolean superResult = super.onTouchEvent(event);
- return mDetector.onTouchEvent(event, superResult);
- }
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
- if (isInEditMode()) {
- return;
- }
- mDetector.draw(canvas);
- }
d.(可选)将点击事件的处理也交给 mDetector
当我们对控件进行点击的时候,android 自身的点击事件处理机制会起作用,如果你的点击回调函数中存在页面跳转,那么你可能会发现,当你进行点击之后,按键中深色遮罩尚未扩散到整个控件,整个界面就已经跳转。这样会导致Material 动画看起来会在跳转的一刹那停止。
为了解决这种问题,我们需要在继承的空间中对点击事件做处理,我们先让 mDetector 接收到点击请求,当动画执行完毕之后,再进行分发给控件做点击处理。
因此,你需要实现以下代码:
1)在 init 方法里,将 null,改为 this,令控件实现Callback接口
- mDetector = new MaterialBackgroundDetector(getContext(), this, this, color);
2)重写以下方法:
- @Override
- public boolean performClick() {
- return mDetector.handlePerformClick();
- }
- @Override
- public boolean performLongClick() {
- return mDetector.handlePerformLongClick();
- }
- @Override
- public void performClickAfterAnimation() {
- super.performClick();
- }
- @Override
- public void performLongClickAfterAnimation() {
- super.performLongClick();
- }
到目前为止,你已经成功的完成了整个界面效果的实现,恭喜你!
3.关于混淆
其实很多时候,我们都可能涉及到对代码进行混淆,为了避免在混淆过程中,混淆工具对代码的处理导致程序应用失败,我们需要在混淆配置文件中加入以下代码:
- -keep class com.kifile.materialwidget.MaterialBackgroundDetector {
- public void setRadius(...);
- public void setAlpha(...);
- }
基本上整个代码的使用流程就到这里了,感谢大家的阅览,如果觉得对自己有帮助,还请顶一下。
其他精彩文章文章
jQuery教程(10)-DOM树操作之内容setter和getter方法
android学习笔记(37)使用 DatePickerDialog、TimePickerDialog
更多关于android开发文章
让低版本的 Android 项目显示出 Material 风格的点击效果的更多相关文章
- 分享vs低版本开发的项目到VS高版本时遇到的4个小问题解决之记录
分享vs低版本开发的项目到VS高版本时遇到的4个小问题解决之记录 原文首发: http://anforen.com/wp/2017/08/extensionattribute_compilerserv ...
- Android popupwindow在低版本手机上无法显示
popupwindow偶尔的显示失效(在低版本Android系统的手机上,测试机6.0)实在是坑害了不少人,害,而且坑了for a long time.本小白就是其中一个受害者. 百度了N久N多还是没 ...
- 使用VS2017开发APP中使用VUE.js开发遇到打包出来的android文件 在低版本的android(4.3)中无法正常使用
使用VS2017开发VUE的APP应用遇到的问题集合 1, 打包出来的apk文件在Android 6.0版本以上手机可以正常打开,在Android 4.3版本手机上无法打开 原因:一开始猜测是不是V ...
- Fundebug前端JavaScript插件更新至1.8.0,兼容低版本的Android浏览器
摘要: 兼容低版本Android浏览器,请大家及时更新. Fundebug前端BUG监控服务 Fundebug是专业的程序BUG监控平台,我们JavaScript插件可以提供全方位的BUG监控,可以帮 ...
- Web Uploader在低版本IE下无法显示Flash的一种情况
用户反馈在IE 8下无法正常显示Web Uploader控件,并已安装了Flash插件.调试发现在内部抛出了Runtime Error的错误,关键代码如下: Runtime.create = func ...
- (转)android底部弹出iOS7风格对话选项框(QQ对话框)--第三方开源--IOS_Dialog_Library
本文转载于:http://blog.csdn.net/zhangphil/article/details/44940339 完成这个效果的是使用了 IOS_Dialog_Library 下载地址:ht ...
- Maven项目转化出WebContent风格的目录
这篇文章已被废弃. 现在,Deolin已经比较熟悉Maven,完全可以使用Jetty插件调试.热部署项目了. 在 [SpringMVC框架下Web项目的搭建与部署] 中,提到了将tomcat的默认上下 ...
- Android之水波纹点击效果(RippleView)
Android5.0后各种炫的效果纷纷出来,写这篇博客主要是讲的是按钮点击效果带有的水波纹(波浪式). 当然我写的这个是自定义来实现的,在低版本(5.0一下)也可以实现点击效果.看看效果图: 上图可看 ...
- Android较低版本(<5.2) 页面默认Select选择框效果的BUG解决
Bug描述: 使用低版本安卓(<5.2),在微信上打开网页,点击下拉框,会出现如下图所示的用来展示select选项的弹出框: 在选项较少的时候,可以向下滑动,将选项滑到底部 滑动前: 滑动后: ...
随机推荐
- pointer-events 使用场景
最近做一个简单移动web功能,可以左右滑动切换功能.如下图: 但是用户不知道可以滑动切换,所以需要提示用户可以滑动切换,那就添加了一个滑动动画. 滑动动画在最上层,所以当显示滑动提示显示的时候,用户切 ...
- 【ORACLE】字符串操作 B字符串时A的一部分
select * from a where instr(a,b)>0;用于实现B字段是A字段中的某一部分的时候,要论顺序或者要相邻的字符. 如果想要不论顺序或者不相邻的字符时,定义函数可以实现: ...
- 二分图&网络流&最小割等问题的总结
二分图基础: 最大匹配:匈牙利算法 最小点覆盖=最大匹配 最小边覆盖=总节点数-最大匹配 最大独立集=点数-最大匹配 网络流: 技巧: 1.拆点为边,即一个点有限制,可将其转化为边 BZOJ1066, ...
- 原生js封装二级城市下拉列表
闲的蛋疼,封装了个二级城市下拉 先保证html里有 <select id="province" size=1 > </select> <select ...
- golang 裸写一个pool池控制协程的大小
这几天深入的研究了一下golang 的协程,读了一个好文 http://mp.weixin.qq.com/s?__biz=MjM5OTcxMzE0MQ==&mid=2653369770& ...
- web常见错误提示总结
在写web程序的时候,经常会出现一些网页错误的数字提示,如果能够明白这些提示的含义,那对于调试程序是有极大帮助的.网上有很多这方面的总结,但为了适应自己的阅读习惯,以及日后的查找方便,就做了一些修改并 ...
- CentOS 7 防止端口自动关闭
tl;dr firewall-cmd --permanent --zone=public --add-port=2888/tcp firewall-cmd --reload #重新载入服务 永久配置f ...
- bzoj 3821: 玄学
题目大意 有一个长度为 n 数列,有若干个事件,事件分为操作和询问两种, 一次操作是把数列[l...r] 区间中的每个元素x变成 ax + b mod p. 一次询问是询问 执行了 第l 次到第r次操 ...
- 【http代理报文】通过发包实现代理请求网页内容
工作中,我们难免需要通过TCP/IP协议发送报文来直接请求网页内容(比如爬虫工具),有同学问如何通过HTTP代理来请求网页,其实我们只需要把报文稍稍修改下,发送给代理服务器即可实现. 基础不过关的朋友 ...
- STL之关联容器
关联容器包含map.set.multimap.multiset. 关联容器的特点是明显的,相对于顺序容器,有如下特点: 1.其内部是采用非线性的二叉树结构,具体的说是红黑树的结构原理实现的. 2.se ...