1. 处理手势操作
android提供了创建自定义手势的功能。本章接收检测和相应手势操作的基础知识。在学习过程中,你将了解到所有的视图都有一个onTouchEvent方法,你可以使用这个方法来不活触摸时间;MotionEvent雷士触摸屏输入的底层接口;你应该使用GestureDetector以及它的子类类启用最常见的手势操作;你可以通过使用ScaleGestureDetector来启用那你缩放功能。
1. 监听触摸事件
手势识别的最基础形式是触摸事件。触摸事件是用户与触摸屏交互的最低层次。事件包括把手指放在屏幕上,在屏幕上滑动手指,以及把手指从屏幕上移开。每种操作都代表一个独立的触摸事件。有两种监听这种事件的方法:通过在一个视图上登记一个onTouchListenner并实现onTouchEvent放阿飞。这些方法被一个包含事件信息的MotionEvent对象共同调用。
下面是一个简单的示例类,它重写了View 并实现了onTouchEvent方法
1. 创建一个名为TouchExample的继承View的类:
public class TouchExample extends View{
public TouchExample(){
super(context);
}
}
2. 添加一个位置坐标字段以及一些与计算的颜色和字体值。创建一个新的Paint对象用来存储文字颜色和大小:
public class TouchExample extends View{
private Paint mPaint;
private float mFontSize;
private float dx;
private float dy;
public TouchExample(){
super(context);
mFontSize = 16*getResources().getDisplayMetrics().density;
mPaint = new Paint();
mPaint.setColor(Color.WHITE);
mPaint.setTextSize(mFontSize);
}
}
3. 重写onDraw方法,使用dx和dy值来设置文本的位置
@Override
protected void onDraw(){
super.onDraw(canvas);
String text n= "Hello World";
canvas.drawText(text,dx,dy,mPaint);
}
4. 现在重写onTouchEvent方法,设置基本输入MotionEvent对象的x和y坐标,结束时让视图失效:
@Override
public boolean onTouchEvent(MotionEvent event){
dx = event.getX();
dy = event.getY();
invalidate();
return true;
}
当重写onTouchEvent方法是,你应当返回true来占用时间并防止基类处理它,否者,你只会收到ACTION_DOWN 事件而不会收到其他东西。
5. 最后给视图创建一个Activity
多点触摸
MotionEvent 对象实际上包含对个事件信息。用户放在屏幕上的每根手指都会被记录作为一个出点来引用。默认情况下,getX()和getY()方法会返回默认的触点。但是所有的其他触点都可以通过getX(int)和getY(int)方法访问。输入参数是触点的索引值。主触点第一个,第一个触碰屏幕的索引值为0.通过调用getPointCount()方法可以得到触点的总数。触点的索引值可以改变。所以每个触点也被赋予了一个ID
触点ID在触摸过程中保持不变。
注意:为了提高效率,Android把触摸事件整合精一个单个的对onTouchEvent的调用。 除了包含多个触点事件,MotionEvent对象也包含每一个事件的近期历史。你可以通过使用getHistoricalX()和getHistoricalY调用访问这些时刻。
除了包含触点。MotionEvent对象包含一个描述发生了什么事件的action参数。
2. 响应手势操作
触摸事件为触摸屏提供了一个非常底层的接口,者可能导致他非常难以被解释。通常来说你实际需要的其实是识别用化在触摸屏上的的特定的手势。为了解决这个问题,android提供了检测手势操作非常方便的类。
2.1 GestureDetector
要想检测手势操作,你先创建一个GestureDetector类的实例并把它发送给视图收到的所有触摸事件。你用GestureDetector注册一个onGestureListener,用来接收当手势操作被检测到时的回调函数。这个接口有你所需要的最常用的手势操作:点击、双击、滑动以及速动。
修改例子,当你双击屏幕时缩放文本。
1. 在View上添加一个缩放区域。你可以使用这个缩放区域来缩放文本大小:
public class TouchExample extends View{
private float mScale = 1.0f;
}
2. 创建将会缩放文本的手势监听。在本例中,继承SimpleOnGestureListener,这个类提供了毁掉方法的实现。重写onDoubleTap方法用来监听双击手势:
public class ZoomGesture extends GestureDetector.SimpleOnGestureListener{
private boolean normal = true;
@Override
public boolean onDoubleTap(MotionEvent e){
mScale = normal ? 3f :1f;
mPaint.setTextSize(mScal*mFontSize);
normal = !normal;
invalidate();
return true;
}
}
监听知是基于不二常量更改了缩放银子并更新了文本大小。当动作完成时,踏实的视图无效并强制重绘
3. 添加一个GestureDetector区域并在视图构造函数中实例化它,用你创建的ZoomGesture监听初始化它:
private GestureDetector mGestureDetector;
public TouchExample(Context context){
super(context);
mGestureDetector = new GestureDetector(context,new ZoomGesture());
}
4. 你必须在视图的onTouchEvent方法中调用Gesture Detector的onTouchEvent方法:
@Override
public boolean onTouchEvent(MotionEvent event){
mGestureDetector.onTouchEvent(event);
}
当你再次运行程序,双击屏幕会缩放文本。再次双击则会使他恢复初始大小。这个例子说明,往应用中增加建档的手势识别非常简答。
GestureDetector是的使用手势炒作变得非常简单,但是它缺少一个中药并非常常用的手势:拿捏缩放。出于这个原因,android2.2添加了ScaleGestureDetector
2.2 ScaleGestureDetector
ScaleGestureDetector类的功能与标准的GestureDetector非常相似,但是他提供两根手指动作的识别。毁掉函数可用于得知两根出掉之间的距离,当前先前触点之间的缩放改变,以及两个触点的焦点。这个最常用的是拿捏缩放功能,一个用户用两根手指点击屏幕并通过移动数值缩放视图。GoogleMap提供了一个这种互动模式很好的例子。
实现拿捏缩放手势操作需要是想OnScaleGestureListener,它与GestureListener相似。拿捏缩放实现使用了onScale方法来检测拿捏动作,它使用这些动作来改变显示的视图。
1. 建立一个继承自SimpleOnScaleGestureListener的名为ScaleGesture的新类:
public class ScaleGesture extends ScaleGestrueDetector.SimpleOnScaleGestureListener{
@Override
public boolean onScale(){
mScale *= detector.getScaleFactor();
mPaint.setTextSize(mScale*mFontSize);
invalidate();
return true;
}
}
2. 要想在示例应用中使用这个手势,你需要向视图的onCrete方法中添加ScaleGestureDetector:
privateGestureDetector mGestureDetector;
private ScaleGestureDetector mScaleGestureDetector;
public TouchExample(){
super(context);
mGestureDetector = new GestureDetector(context,new ZoomGesture());
mScaleGestureDetector = new ScaleGestureDetector(context,new ScaleGesture());
}
3. 记住调用OnScaleGestureListener 中的onTouchEvent
@Override
public boolean onTouchEvent(MotionEvent event){
mGestureDetector.onTouchEvent(event);
mScaleGestureDetector.onTouchEvent(event);
}
使用ScaleGestureDetector和GestureDetector,你将可以处理所有常见的触摸屏交互。
参见现有的手势识别的例子实现自己的手势识别,源码在http://source.android.com/
动画
创建自定义视图
Android分两步绘制视图,测量阶段和布局阶段;在创建一个自定的视图时你需要重写onMeasure和onDraw方法;使用自定义视图属性需要你为那些属性定义一个新的XML命名空间;复合视图把多个视图结合成为一个自定义组件。
1. 理解Android如何绘制视图
在学习如何创建自定义视图之前,你需要理解Android如何绘制和系那是。如你在本书之前部分所了解的,Android UI按照层级摆放。这个层级包括系统元素,例如通知栏和导航栏等,还有现在的活动
当你调用setContentView时需要设置活动的根节点。
显示屏被绘制的区域被标记为无效的。任何与无效区域交互的东西都要被重新绘制。当系统绘制一个活动时会调用invalidate(),但是你也可以通过在视图上调用invalidate()强制其发生。当时图被绘制好之后,它就会被标记被有效(valid)
绘制分为两个阶段。在第一个阶段,层级的根节点被要求衡量自身。然后根节点会测量每个子视图(child view).每个子视图随后又会测量的子视图。这样视图层级的每个视图的尺寸都被测量出来了。在每一级别上,父视图(parent view)都会给予子视图一个特定的尺寸或者会要求他们自己设置自己的尺寸。
当测量阶段结束之后,系统会执行视图层级的布局。他会先序遍历布局树,把每个视图绘制道义个位图上。父视图首先绘制,然后再骑上绘制子视图。布局完成之后,绘制系统回想屏幕绘制位图并把他们展示给用户。
2. 创建自定义视图
你可以继承基础视图来获取最大的可配置性,或者你也可以从现有的视图类开始并添加你需要的功能。
者只适用于静态或者低性能的2D图像。如果你想养创建3D图形或者复杂动画,你应当继承SurfaceView或者使用RenderScript或者OpenGL。
public class CrossView extends View{
publicCrossView(Context context,AttributeSet atts){
super(context,attrs);
}
}
该够着函数需要一个Context和一个AttributeSet对象。Context提供了应用资源系统服务接口,系统服务用来正确地扩展视图以及把它加入到你的活动中。AttributeSet要求传递XML参数到活动中。当你学习如何创建自定义XML属性是会学到更多关于这个的知识。通常你需要调用superclass中重写的方法来执行活动的初始设置。完成这个之后,你肯想要重写li8angge基础方法:onMeasure和onDraw。
2.1 OnMeasure
2.2 OnDraw
3. 自定义视图中添加自定义属性
3.1 声明属性
3.2 在XML中使用属性
3.3 在代码中使用属性
4. 创建复合组件
4.1 创建一个符合组件
4.2 优化布局
创建高级图形
Android视图框架对于创建复杂布局非常方便。然而,这种便利是以性能为代价的。当性能至关重要时,Android提供了集中更强大的图形处理能力,其难度也随之上升。
在本章中,你会了解到SurfaceView和TextureView类如何使用标准的Canvas对象并与单独的渲染进程结合,以得到比标准视图更好的的性能;新的RenderScript框架可以被用于创建独立结构的吐信渲染;OpenGL可用于易写 样的图形工作和游戏。
1. 使用Canvas
2. 使用RenderScript
3. 使用OpenGL
本地化和辅助功能