创建自定义控件3-可交互性

2024-03-31 08:48

本文主要是介绍创建自定义控件3-可交互性,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

绘制UI仅仅是创建自定义视图的一部分。除此之外,你还需要以一种非常接近现实世界行为的方式来响应用户的输入。所有的对象都应该表现得像现实世界的对象那样。例如,图片不应该突然消失后又出现在别的地方,因为现实中的物体是不会那样的。合乎情理的做法是它应该从一个位置移动到另一个位置。 用户要么体验到UI中精细的操作,要么仅仅感觉到只是界面,相比较而言前者模拟的现实世界会获得最好的用户体验。例如,当用户在操作UI的时候,他们一旦感到界面的滑动响应延迟,将会感到烦躁而疯狂的滑动屏幕。

这篇文章展示了如何结合Android框架的特点来增添现实世界的行为到你所定制的视图中。

处理输入手势-Handle Input Gestures


跟许多其它的UI框架一样,Android也支持输入事件模型。用户的操作会转变成触发回调函数的事件,你可以重写这个回调函数来定制你的应用如何响应用户。在Android系统中最常用的输入事件是触摸事件,它会触发onTouchEvent(android.view.MotionEvent),重写该方法可以处理该事件:

1
2
3
4
@Override   
public boolean onTouchEvent(MotionEvent event) {    
return super.onTouchEvent(event);  
}

触摸事件本身并不是特别的有用。现在的可触摸UI可以接受许多种手势动作的交互,如 轻拍、拉、推、摇动和缩放。Android系统提供了GestureDetector类,将基本的触摸事件转变成各种不同的手势动作。 通过实现GestureDetector.OnGestureListener接口来构造一个GestureDetector的一个实例。如果你仅仅只是想处理少部分的手势动作,你可以选择继承GestureDetector.SimpleOnGestureListener而不用去实现GestureDetector.OnGestureListener接口。例如,下面的代码就是创建了一个继承GestureDetector.SimpleOnGestureListener的类并重写了onDown(MotionEvent)方法。

1
2
3
4
5
6
7
class mListener extends GestureDetector.SimpleOnGestureListener {   
@Override   
public boolean onDown(MotionEvent e) {       return true;   
}
}
mDetector = new GestureDetector(PieChart.this.getContext(),new mListener());

不管你是否使用了GestureDetector.SimpleOnGestureListener类,你都必须要实现onDown()方法并返回true。这一步是必须的因为所有的触摸操作都从onDown() 方法中的事件开始。如果你在onDown()方法中返回false,就像GestureDetector.SimpleOnGestureListener所设计的那样,系统会认为你不需要其它的手势操作,那么GestureDetector.OnGestureListener接口的其余方法都不会被调用。唯一能够将onDown()方法返回false的情况就是你真的想忽略所有的手势操作。一旦你实现了GestureDetector.OnGestureListener接口并且创造了GestureDetector类的一个实例,你就可以用GestureDetector类来完成你在 onTouchEvent()方法中接收的触屏事件。

 123456789
10
11
@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。你可以执行你自定义的检测手势操作的代码。

创建让人感觉合理的操作-Create Physically Plausible Motion

手势动作是控制触摸屏设备的一种很强有力的方式,但是它会违背人的直觉而让人难以记住,除非它让人得到合理的结果。滑动手指就是一个很好的例子,用户用一根手指快速的在屏幕上滑动然后抬起。只有在UI的响应速度跟得上用户快速的滑动屏幕的频率的时候,这个手势操作才是有意义的,就像用户在推动一个飞轮并想让它旋转起来。

然而,模拟一种飞轮的感觉也是不平凡的。要想得到一个正确的飞轮运转模型是需要大量的物理和数学验证的。庆幸的是,Android提供了帮助类来模拟它以及别的操作行为。Scroller 类是处理具有飞轮风格手势操作的基类。 开始实现滑动操作时,要调用fling()并传入初始的速率和在X轴和Y轴上滑动的最小值和最大值。根据这个速率的值,你就可以用该值并通过GestureDetector类来为你计算。

1
2
3
4
5
@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.computeScrollOffset() 方法来更新Scroller类的数据。computeScrollOffset() 方法通过读取当前的时间并用物理模型计算当前的X坐标和Y坐标来更新Scroller对象的内部状态调用getCurrX() 和getCurrY()方法可以获取最新的X坐标和Y坐标。 大部分的视图通过直接调用scrollTo()方法改变Scroller对象的X坐标和Y坐标的值。但是图表是有一点不一样的,它用当前Y轴的坐标来设定图表的张开角度。

1
2
3
4
if (mScroller.isFinished()) {mScroller.computeScrollOffset();setPieRotation(mScroller.getCurrY());
}

Scroller类能为你计算出滚动轴的位置,但是它不能自动的为你的视图提供它们的坐标位置。你必须确保你获得并应用的坐标在正常情况下足以能让滚动动画看起来流畅。这里有两种方法可以实现:

    • 为了能重绘视图,在调用fling()之后要调用postInvalidate()。这种技术需要你每次在补偿滚动轴的变化时要在onDraw()方法中计算滚动轴的变化并调用postInvalidate()方法。
    • 建立一个ValueAnimator来动态模拟滑动动作持续的状态,然后调用addUpdateListener()来添加一个监听者进行动画的更新。

图表用的就是第二种方法。这种方法在创建的时候略微会显得更加复杂,但是它工作起来会跟动画系统配合得更密切而且不需要可能不必要的无效视图。它的缺憾就是在低于API11的版本上ValueAnimator是不可用的,所以这种方法是不能用在低于Android3.0系统的设备上的。

提示:ValueAnimator虽然在低于API11的版本不可用,但是你仍然可以在你的应用程序中使用这个类并标上API版本过低。在程序运行的时候你必须确保检查了当前的API版本,如果当前的API版本低于11,在视图动画系统中就要忽略这些调用。

 123456789
10
11
12
13
14
mScroller = new Scroller(getContext(), null, true);
mScrollAnimator = ValueAnimator.ofFloat(0,1);
mScrollAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {           
@Override           
public void onAnimationUpdate(ValueAnimator valueAnimator) {               
if(mScroller.isFinished()){                   
mScroller.computeScrollOffset();
setPieRotation(mScroller.getCurrY());               
} else {                   
mScrollAnimator.cancel();                   
onScrollFinished();               
}           
}       
});

让你的界面流畅地转换

用户期望现代的UI能流畅的在状态之间转换。UI元素的淡入淡出会取代直接的出现和消失。各种操作都会按照自然的方式开始和结束而不是突然的启动和停止。在Android3.0系统中引入的property animation framework框架,会让流畅的转换变得简单。 在使用动画系统时,每一个视图属性的改变都将会影响到视图的外观,所以不要直接去改变视图的属性。取而代之的是,你可以用ValueAnimator来实现你对视图属性的改变。在下面的例子中,修改当前在图表中选定的饼图饼片会导致整个图表旋转,以便让你选择的点集中在选定的切片上。ValueAnimator 会在一个短暂的时间内实现旋转的改变,而不是突然地改变旋转的状态。

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

如果你想改变基本的View 中的一个属性值,不如去改变视图动画,因为视图中有一个嵌入的ViewPropertyAnimator类,它对同步的多属性的动画做了优化。例如:

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

这篇关于创建自定义控件3-可交互性的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/863925

相关文章

Window Server创建2台服务器的故障转移群集的图文教程

《WindowServer创建2台服务器的故障转移群集的图文教程》本文主要介绍了在WindowsServer系统上创建一个包含两台成员服务器的故障转移群集,文中通过图文示例介绍的非常详细,对大家的... 目录一、 准备条件二、在ServerB安装故障转移群集三、在ServerC安装故障转移群集,操作与Ser

Window Server2016 AD域的创建的方法步骤

《WindowServer2016AD域的创建的方法步骤》本文主要介绍了WindowServer2016AD域的创建的方法步骤,文中通过图文介绍的非常详细,对大家的学习或者工作具有一定的参考学习价... 目录一、准备条件二、在ServerA服务器中常见AD域管理器:三、创建AD域,域地址为“test.ly”

C#实现WinForm控件焦点的获取与失去

《C#实现WinForm控件焦点的获取与失去》在一个数据输入表单中,当用户从一个文本框切换到另一个文本框时,需要准确地判断焦点的转移,以便进行数据验证、提示信息显示等操作,本文将探讨Winform控件... 目录前言获取焦点改变TabIndex属性值调用Focus方法失去焦点总结最后前言在一个数据输入表单

Python在固定文件夹批量创建固定后缀的文件(方法详解)

《Python在固定文件夹批量创建固定后缀的文件(方法详解)》文章讲述了如何使用Python批量创建后缀为.md的文件夹,生成100个,代码中需要修改的路径、前缀和后缀名,并提供了注意事项和代码示例,... 目录1. python需求的任务2. Python代码的实现3. 代码修改的位置4. 运行结果5.

使用IntelliJ IDEA创建简单的Java Web项目完整步骤

《使用IntelliJIDEA创建简单的JavaWeb项目完整步骤》:本文主要介绍如何使用IntelliJIDEA创建一个简单的JavaWeb项目,实现登录、注册和查看用户列表功能,使用Se... 目录前置准备项目功能实现步骤1. 创建项目2. 配置 Tomcat3. 项目文件结构4. 创建数据库和表5.

使用SpringBoot创建一个RESTful API的详细步骤

《使用SpringBoot创建一个RESTfulAPI的详细步骤》使用Java的SpringBoot创建RESTfulAPI可以满足多种开发场景,它提供了快速开发、易于配置、可扩展、可维护的优点,尤... 目录一、创建 Spring Boot 项目二、创建控制器类(Controller Class)三、运行

JAVA中整型数组、字符串数组、整型数和字符串 的创建与转换的方法

《JAVA中整型数组、字符串数组、整型数和字符串的创建与转换的方法》本文介绍了Java中字符串、字符数组和整型数组的创建方法,以及它们之间的转换方法,还详细讲解了字符串中的一些常用方法,如index... 目录一、字符串、字符数组和整型数组的创建1、字符串的创建方法1.1 通过引用字符数组来创建字符串1.2

手把手教你idea中创建一个javaweb(webapp)项目详细图文教程

《手把手教你idea中创建一个javaweb(webapp)项目详细图文教程》:本文主要介绍如何使用IntelliJIDEA创建一个Maven项目,并配置Tomcat服务器进行运行,过程包括创建... 1.启动idea2.创建项目模板点击项目-新建项目-选择maven,显示如下页面输入项目名称,选择

SpringBoot 自定义消息转换器使用详解

《SpringBoot自定义消息转换器使用详解》本文详细介绍了SpringBoot消息转换器的知识,并通过案例操作演示了如何进行自定义消息转换器的定制开发和使用,感兴趣的朋友一起看看吧... 目录一、前言二、SpringBoot 内容协商介绍2.1 什么是内容协商2.2 内容协商机制深入理解2.2.1 内容

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06