每天都被不同的需求纠缠的生活是幸福而又不幸的,这不我们家亲爱的设计师们又让我们在低版本的 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 来开发项目,可以通过使用以下代码将本库进行集成:

[ruby] view plain copy
  1. dependencies{
  2. compile'com.kifile:MaterialView:1.0'
  3. }

通过在 gradle.build 文件中引入 maven 项目,我们现在就可以正式使用这个点击效果了。

a.继承你希望实现的控件,代码如下:

[html] view plain copy
  1. publicclassMaterialImageViewextendsImageView{
  2. publicMaterialImageView(Contextcontext){
  3. super(context);
  4. init(null,0);
  5. }
  6. publicMaterialImageView(Contextcontext,AttributeSetattrs){
  7. super(context,attrs);
  8. init(attrs,0);
  9. }
  10. publicMaterialImageView(Contextcontext,AttributeSetattrs,intdefStyle){
  11. super(context,attrs,defStyle);
  12. init(attrs,defStyle);
  13. }
  14. }


b.在 init 方法中创建一个 MaterialBackgroundDetector 对象,用于事件委托:

[html] view plain copy
  1. privateMaterialBackgroundDetectormDetector;
  2. privatevoidinit(AttributeSetattrs,intdefStyle){
  3. finalTypedArraya=getContext().obtainStyledAttributes(
  4. attrs,com.kifile.materialwidget.R.styleable.MaterialTextView,defStyle,0);
  5. intcolor=a.getColor(com.kifile.materialwidget.R.styleable.MaterialTextView_maskColor,MaterialBackgroundDetector.DEFAULT_COLOR);
  6. a.recycle();
  7. mDetector=newMaterialBackgroundDetector(getContext(),this,null,color);
  8. }


c.重写父类方法,将相应事件委托给 mDetector 对象处理

[html] view plain copy
  1. @Override
  2. protectedvoidonSizeChanged(intw,inth,intoldw,intoldh){
  3. super.onSizeChanged(w,h,oldw,oldh);
  4. mDetector.onSizeChanged(w,h);
  5. }
  6. @Override
  7. publicbooleanonTouchEvent(MotionEventevent){
  8. booleansuperResult=super.onTouchEvent(event);
  9. returnmDetector.onTouchEvent(event,superResult);
  10. }
  11. @Override
  12. protectedvoidonDraw(Canvascanvas){
  13. super.onDraw(canvas);
  14. if(isInEditMode()){
  15. return;
  16. }
  17. mDetector.draw(canvas);
  18. }


d.(可选)将点击事件的处理也交给 mDetector

当我们对控件进行点击的时候,android 自身的点击事件处理机制会起作用,如果你的点击回调函数中存在页面跳转,那么你可能会发现,当你进行点击之后,按键中深色遮罩尚未扩散到整个控件,整个界面就已经跳转。这样会导致Material 动画看起来会在跳转的一刹那停止。

为了解决这种问题,我们需要在继承的空间中对点击事件做处理,我们先让 mDetector 接收到点击请求,当动画执行完毕之后,再进行分发给控件做点击处理。

因此,你需要实现以下代码:

1)在 init 方法里,将 null,改为 this,令控件实现Callback接口

[html] view plain copy
  1. mDetector=newMaterialBackgroundDetector(getContext(),this,this,color);


2)重写以下方法:

[html] view plain copy
  1. @Override
  2. publicbooleanperformClick(){
  3. returnmDetector.handlePerformClick();
  4. }
  5. @Override
  6. publicbooleanperformLongClick(){
  7. returnmDetector.handlePerformLongClick();
  8. }
  9. @Override
  10. publicvoidperformClickAfterAnimation(){
  11. super.performClick();
  12. }
  13. @Override
  14. publicvoidperformLongClickAfterAnimation(){
  15. super.performLongClick();
  16. }

到目前为止,你已经成功的完成了整个界面效果的实现,恭喜你!

3.关于混淆

其实很多时候,我们都可能涉及到对代码进行混淆,为了避免在混淆过程中,混淆工具对代码的处理导致程序应用失败,我们需要在混淆配置文件中加入以下代码:

[html] view plain copy
  1. -keepclasscom.kifile.materialwidget.MaterialBackgroundDetector{
  2. publicvoidsetRadius(...);
  3. publicvoidsetAlpha(...);
  4. }

基本上整个代码的使用流程就到这里了,感谢大家的阅览,如果觉得对自己有帮助,还请顶一下。

其他精彩文章文章

jQuery教程(10)-DOM树操作之内容setter和getter方法

android学习笔记(37)使用 DatePickerDialog、TimePickerDialog

android学习笔记(36)使用AlertDialog创建自定义对话框

jQuery教程(1)-操作DOM之操作属性

Spring mvc新手入门(11)-返回json 字符串的其他方式

更多关于android开发文章

更多相关文章

  1. Android实现Splash界面全屏效果
  2. android 横向滑动多屏(开源项目)
  3. 兼容性(一) - 使代码向前兼容SDK版本
  4. 第一章 开始启程,你的第一行Android代码
  5. android图片轮播效果,RollViewPager的简单使用
  6. Android(安卓)Databinding数据绑定框架
  7. Android(安卓)7.1 APP 启动流程分析
  8. 声波通信、声波传输原理及源代码
  9. Android特色开发之语音识别

随机推荐

  1. Android Menu(Context Menu,Options Menu
  2. Android(安卓)如何全局获取Context
  3. Android(安卓)HAL的STUB的具体处理
  4. Android GL_OUT_OF_MEMORY
  5. 2013.12.04 (6)——— android SlidingMenu
  6. Android使用URLConnection显示网络图片
  7. 【PPT】The new (or the first?) build s
  8. (安卓初步)TextView
  9. 调用所有的 android activity 的实现
  10. 从 App 启动过程看 Android(安卓)10.0 Fr