使视图互动

绘制用户界面只是创建自定义视图的一部分。您还需要使您的视图以与您模拟的真实世界动作非常相似的方式响应用户输入。对象应始终以与真实对象相同的方式进行操作。例如,图像不应该立即跳出存在,并在其他地方重新出现,因为现实世界中的物体不会这样做。相反,图像应该从一个地方移动到另一个地方。

用户还会感觉到界面中的微妙行为或感觉,并对模仿真实世界的微妙事物做出最佳反应。例如,当用户投掷UI对象时,他们应该在开始时感觉到摩擦,从而延迟运动,然后在最后感觉到运动超出投掷的动量。

本课程演示如何使用Android框架的功能将这些现实世界的行为添加到自定义视图中。

处理输入手势

和许多其他UI框架一样,Android支持输入事件模型。用户操作转换为触发回调的事件,您可以覆盖回调来自定义应用程序对用户的响应方式。Android系统中最常见的输入事件是触摸,触发onTouchEvent(android.view.MotionEvent)。重写此方法来处理事件:

 @Overridepublic boolean onTouchEvent(MotionEvent event) {return super.onTouchEvent(event);}

触摸事件本身并不是特别有用。现代触摸UI定义了手势方面的交互,例如点击,拉动,推动,抛掷和缩放。为了将原始触摸事件转换为手势,Android提供了GestureDetector。
GestureDetector通过传入一个实现的类的实例来构造一个GestureDetector.OnGestureListener。如果您只想处理几个手势,则可以扩展GestureDetector.SimpleOnGestureListener而不是实现GestureDetector.OnGestureListener 接口。例如,这段代码创建了一个扩展GestureDetector.SimpleOnGestureListener和覆盖的类onDown(MotionEvent)。

class mListener extends GestureDetector.SimpleOnGestureListener {@Overridepublic boolean onDown(MotionEvent e) {return true;}
}
mDetector = new GestureDetector(PieChart.this.getContext(), new mListener());

无论您是否使用GestureDetector.SimpleOnGestureListener,您都必须执行onDown()返回的 方法true。这一步是必要的,因为所有手势都以onDown()消息开头 。如果返回false的onDown(),因为 GestureDetector.SimpleOnGestureListener确实,系统会假设你要忽略手势的其余部分,以及其他方法 GestureDetector.OnGestureListener永远不会被调用。您应该返回唯一的一次false由onDown() 是,如果你真的想忽略的整个姿态。一旦你实现GestureDetector.OnGestureListener 并创建了一个实例GestureDetector,你可以使用你GestureDetector的解释你接收到的触摸事件onTouchEvent()。

@Override
public boolean onTouchEvent(MotionEvent event) {boolean result = mDetector.onTouchEvent(event);if (!result) {if (event.getAction() == MotionEvent.ACTION_UP) {stopScrolling();result = true;}}return result;
}

当您传递onTouchEvent()一个触摸事件时,它不会将其识别为手势的一部分,它会返回false。然后您可以运行自己的自定义手势检测代

创造物理上合理的运动

手势是控制触摸屏设备的强大方式,但除非它们产生物理上合理的结果,否则它们可能是违反直觉的,难以记忆。这方面的一个很好的例子就是挥动手势,用户在屏幕上快速移动手指然后举起手指。如果用户界面通过在投掷方向上快速移动来响应,则该姿势是有意义的,然后放慢,就好像用户已经推动飞轮并将其设置为旋转。但是,模拟飞轮的感觉并不是微不足道的。要使飞轮模型正常工作,需要大量的物理和数学知识。幸运的是,Android提供了辅助类来模拟这个和其他行为。该Scroller班级是处理飞轮式抛动手势的基础。要开始投掷,请fling()用起始速度和投掷的最小和最大x和y值进行调用。对于速度值,您可以使用为您计算的值GestureDetector。

@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {mScroller.fling(currentX, currentY, velocityX / SCALE, velocityY / SCALE, minX, minY, maxX, maxY);postInvalidate();
}

注意:虽然计算的速度 GestureDetector在物理上是准确的,但许多开发人员认为使用此值会使得动画动画速度过快。通常将x和y的速度除以4到8的因子。
这个呼吁fling()建立了手势的物理模型。之后,您需要定期Scroller拨打电话进行更新Scroller.computeScrollOffset()。通过读取当前时间并使用物理模型计算当时的x和y位置来computeScrollOffset()更新Scroller对象的内部状态。调用getCurrX()并getCurrY()检索这些值。
大多数视图直接传递Scroller对象的x和y位置 scrollTo()。PieChart示例稍有不同:它使用当前的滚动y位置来设置图表的旋转角度。

if (!mScroller.isFinished()) {mScroller.computeScrollOffset();setPieRotation(mScroller.getCurrY());
}

该Scroller级计算滚动位置给你,但它不会自动应用这些位置你的看法。确保您经常获得并应用新坐标以使滚动动画看起来平滑是您的责任。有两种方法可以做到这一点:

调用postInvalidate()后调用 fling(),以强制重绘。这种技术要求您计算滚动偏移量onDraw() 并在postInvalidate()每次滚动偏移量更改时调用。
设置一个ValueAnimator动画的持续时间,并添加一个侦听器来处理动画更新通过调用addUpdateListener()。
PieChart示例使用第二种方法。这种技术的设置稍微复杂一些,但它与动画系统的关系更密切,不需要潜在的不必要的视图无效。缺点是ValueAnimator 在API级别11之前不可用,所以此技术不能用于运行Android版本低于3.0的设备。

注意:您可以ValueAnimator在针对较低API级别的应用程序中使用。您只需确保在运行时检查当前API级别,并在当前级别小于11时省略对视图动画系统的调用。

mScroller = new Scroller(getContext(), null, true);mScrollAnimator = ValueAnimator.ofFloat(0,1);mScrollAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator valueAnimator) {if (!mScroller.isFinished()) {mScroller.computeScrollOffset();setPieRotation(mScroller.getCurrY());} else {mScrollAnimator.cancel();onScrollFinished();}}});

让你的转换顺利

用户期望现代用户界面能够在状态之间平滑过渡。UI元素淡入淡出而不是出现和消失。动作顺利开始和结束,而不是突然开始和停止。Android 3.0中引入的Android 属性动画框架使平滑过渡变得简单。

要使用动画系统,只要属性发生变化而影响视图外观,请不要直接更改属性。相反,使用ValueAnimator来进行更改。在以下示例中,修改PieChart中当前选定的饼图切片会导致整个图表旋转,以便选择指针位于所选切片的中心。ValueAnimator改变几百毫秒周期的旋转,而不是立即设置新的旋转值。

mAutoCenterAnimator = ObjectAnimator.ofInt(PieChart.this, "PieRotation", 0);
mAutoCenterAnimator.setIntValues(targetAngle);
mAutoCenterAnimator.setDuration(AUTOCENTER_ANIM_DURATION);
mAutoCenterAnimator.start();

如果要更改的值是基本View属性之一,则动画更容易,因为Views具有内置功能,ViewPropertyAnimator该功能已针对多个属性的同时动画进行了优化。例如:

animate().rotation(targetAngle).setDuration(ANIM_DURATION).start();

Android自定义控件学习(六)-------使视图互动相关推荐

  1. Android自定义控件学习(四)------创建一个视图类

    创建一个视图类 精心设计的自定义视图与其他精心设计的类非常相似.它使用易于使用的界面封装了一组特定的功能,它可以高效地使用CPU和内存,等等.不过,作为一个设计良好的设计,自定义视图应该: 符合And ...

  2. Android JNI学习(六)——Java与Native实战演习

    前言: 前几篇我主要介绍了jni先关的基础知识和常用API,相信看过的童靴对JNI已经有了一定的了解,如果不了解也没关系,下面我给出了链接,可以点进去学习.接下来我将实战一个完整案例,案例很简单,就是 ...

  3. Android自定义控件学习(三)----- 自定义视图组件

    自定义视图组件 说明 Android提供了用于构建UI的基础上,基本布局类一个复杂和强大的组件化模式:View和 ViewGroup.首先,该平台包含各种预构建的View和ViewGroup子类 - ...

  4. Android自定义控件学习(七)-------优化视图

    优化视图 既然您的设计良好,可以响应手势和状态之间的转换,请确保视图运行速度很快.为了避免在播放过程中感觉呆滞或断断续续的用户界面,请确保动画一直以每秒60帧的速度运行. 少,少频繁 为了加速你的视图 ...

  5. Android自定义控件学习(一)-----属性

    Android中XML的命名空间.自定义属性 命名空间(namespace) XML 命名空间提供避免元素命名冲突的方法. 打个比方,A学校有名学生叫做林小明,B学校也有名学生叫林小明,那我们如何识别 ...

  6. Android自定义控件学习(五)-------自定义绘图

    自定义视图中最重要的部分是它的外观.根据您的应用需求,自定义绘图可以很容易或复杂. 本课包含一些最常见的操作 覆盖onDraw() 绘制自定义视图中最重要的步骤是重写该onDraw()方法.参数to ...

  7. Android Framework学习(六)之RefBase,SP,WP

    Android中通过引用计数来实现智能指针,并且实现有强指针与弱指针.由对象本身来提供引用计数器,但是对象不会去维护引用计数器的值,而是由智能指针来管理. 要达到所有对象都可用引用计数器实现智能指针管 ...

  8. Android多媒体学习六:访问网络上的Audio对应的M3U文件,实现网络音频流的播放

    Android中提供了对网络上流媒体的支持,我们可以使用MediaPlayer类来播放一个网络上的音频文件. 但是网络上的站点并不建议我们直接访问流,我们需要获取他提供的M3U文件,根据M3U文件来实 ...

  9. Android自定义控件学习(二)-----自定义attr Style styleable以及其应用

    相信每一位从事Android开发的猿都遇到过需要自己去自定义View的需求,如果想通过xml指定一些我们自己需要的参数,就需要自己声明一个styleable,并在里面自己定义一些attr属性,这个过程 ...

最新文章

  1. java单例模式的实现方法_Java中的五种单例模式实现方法
  2. Spring Security原理之springSecurityFilterChain
  3. iOS架构-静态库.framework之资源文件打包bundle(6)
  4. python 读取excel表格_python 对Excel表格的读取
  5. 深度系统安装移动硬盘启动_深度系统如何安装_电脑知识
  6. [转载]布谷鸟算法的程序(个人注释)
  7. 热传导方程以及Matlab求解
  8. Windows Phone上的相机景深计算器
  9. 笔记44-JQuery高级笔记
  10. java人才市场需求分析_人才招聘需求及分析报告.doc
  11. HASH SEMI JOIN (semi join) 比 hash join 快!
  12. 帝国cms登陆表单的制作与变量说明
  13. java实现缩放图像、切割图像、图像类型转换、彩色转黑白、文字水印、图片水印等
  14. Microsoft office 2016在win10上的安装
  15. android 和风图标字体移植显示墨迹天气图标
  16. android 解锁mac,论一台笔记本三个不同系统的玩法,解锁正确姿势
  17. 如何为Web3.0世界启动完美的DAO
  18. C语言------函数
  19. cf 1A Theatre Square
  20. Spring学习心得体会

热门文章

  1. php array 取值 没有key,PHP array_key_exists不起作用;数组不是多维的
  2. 单机mongodb最大_mongodb单机多实例主从配置
  3. c语音学习-输入一个字母,输出其对应的ASCII码
  4. 清空linux+history_1分钟学会的Linux小技巧,大大提高你的工作效率
  5. PIR 宣布被营利性机构收购,.org 顶级域名注册费用或上涨
  6. WCF同步到异步转换
  7. SQL 使用总结二 ( 不同库的日期总结)
  8. 64位电脑mysql_Windows 64位操作系统下安装和配置MySQL
  9. json入门 PHP,PHP开发基础教程之JSON
  10. 用python画出圣诞树_【闲趣】如何用python画出一棵圣诞树