阅读 11

Android View 体系的简单介绍

View类简介

View类是Android中各种组件的基类

View表现为显示在屏幕上的各种视图

View的视图结构

View基础-颜色

颜色模式

ARGB8888:四通道高精度(32位)
ARGB4444:四通道低精度(16位)
RGB565:屏幕默认模式(16位)
Alpha8:仅有透明通道(8位)

颜色定义

A(Alpha):透明度,透明0(0* 00),不透明255*(0*ff)
RGB:分别是红、绿、蓝

创建颜色的方法

Java

  int color = Color.GRAY;//灰色     
  int color = Color.argb(127,255,0,0)//半透明红色 
  int color = 0xaaff0000;
复制代码

xml

 文件:/res/values/color.xml    
 < color name ="red" >#ff0000< /color>   
 #f00     //低精度-不带透明通道红色  
 #af00    //低精度-带透明通道红色   
 #ff0000  //高精度-不带透明通道红色   
 #aaff0000// 高精度-带透明通道红色
复制代码

引用颜色的方法

java

    int color = getResoures().getColor(R.color.mycolor);   
    int color = getColor(R.color.mycolor);//API 23及以上
复制代码

xml

   < style name="Apptheme" parent="Theme.AppCompat.Light.DarkActionBar">  
   < item name = "colorPrimary">@color/red</item>  
    < /style>
    
    android:background="@color/red"
    android:background="#ff0000" 
复制代码

View基础-位置参数

4个顶点:top、left、right、bottom
width = right-left
height = bottom-top

获取

   left= getLeft()获取View自身左边到其父布局左边的距离  
   right= getRight()获取View自身右边到其父布局右边的距离  
   top=getTop(获取View自身顶边到其父布局顶边的距离   
   bottom=getBottom(获取View自身底边到其父布局顶边的距离 
复制代码

Android 3.0中增加的额外参数
translationX、translationY: Veiw左上角相对于父容器的偏移量
x = left + translationX
y = top + translationY

View基础-坐标系

获取屏幕区域的宽高等尺寸

DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int width=metrics.widthPixels;
int height= metrics.heightPixels;
复制代码

获取应用程序App区域宽高等尺寸

 Rect rect = new Rect();
 getWindow.getDecorView.getWindowVisibleDisplayFrame(rect);
复制代码

获取状态栏高度

 Rect rect = new Rect();
 getWindow.getDecorView.getWindowVisibleDisplayFrame(rect);
 int statusBarHeight = rect.top;
复制代码

获取View布局区域宽高等尺寸

 Rect rect = new Rect();
 getWindow.findViewById(window.ID_ANDROID_CONTENT).getDrawingRect(rect);
复制代码

View的坐标系:相对于父控件

MotionEvent中的get和getRaw的区别:
evet.getX():触控点相对于所在组件坐标系
evet.getRawY():触控点相对于屏幕默认坐标系

View自身的宽高 getHeight()、getWidth()

View滑动

能够实现View滑动的方法有很多,下面我们一一介绍:

使用 scrollTo/scrollBy
使用动画
使用LayoutParams
使用Layout
使用offsetLeftAndRight()与offsetTopAndBottom()

scrollTop、offsetHeight和offsetTop等属性用法详解:

标题中的几个相关相关属性在网页中有这大量的应用,尤其是在运动框架中,但是由于有些属性相互之间的概念比较混杂或者浏览器兼容性问题,导致掌握起来比较有难度,下面就介绍一下相关属性的用法。
看下图:

一.offsetTop属性:
此属性可以获取元素的上外缘距离最近采用定位父元素内壁的距离,如果父元素中没有采用定位的,则是获取上外边缘距离文档内壁的距离。所谓的定位就是position属性值为relative、absolute或者fixed。 返回值是一个整数,单位是像素 。此属性是只读的。

二.offsetLeft属性:
此属性和offsetTop的原理是一样的,只不过方位不同,这里就不多介绍了。

三.offsetWidth属性:
此属性可以获取元素的宽度,宽度值包括:元素内容+内边距+边框。不包括外边距和滚动条部分。 返回值是一个整数,单位是像素。 此属性是只读的。

四.offsetHeight属性:
此属性可以获取元素的高度,宽度值包括:元素内容+内边距+边框。不包括外边距和滚动条部分。 返回值是一个整数,单位是像素。 此属性是只读的。

五.clientWidth属性:
此属性可以返回一个元素的宽度值,值是:元素的内容+内边距。不包括边框、外边距和滚动条部分。 返回值是一个整数,单位是像素。 此属性是只读的。

六.clientHeight属性:
此属性可以返回一个元素的高度值,值是:元素的内容+内边距。不包括边框、外边距和滚动条部分。 返回值是一个整数,单位是像素。 此属性是只读的。

七.scrollLeft属性:
此属性可以获取或者设置对象的最左边到对象在当前窗口显示的范围内的左边的距离,也就是元素被滚动条向左拉动的距离。 返回值是一个整数,单位是像素。 此属性是可读写的

八.scrollTop属性:
此属性可以获取或者设置对象的最顶部到对象在当前窗口显示的范围内的顶边的距离,也就是元素滚动条被向下拉动的距离。 返回值是一个整数,单位是像素。 此属性是可读写的。

九.scrollHeight属性:
此属性获取对象的实际尺寸。

使用动画

使用动画。通过动画我们能够让一个View进行平移,而平移就是一种滑动。使用动画来移动View,主要是操作View的 translationX 和 translationY 属性,既可以采用传统的View动画,也可以采用属性动画,如果采用属性动画的话,为了能够兼容 3.0以下的版本,需要采用开源动画库 nineoldandroids 。

   <?xml version="1.0" encoding="utf-8"?>
  <set xmlns:android="http://schemas.android.com/apk/res/android"
      android:fillAfter="true"
      android:zAdjustment="normal">

<translate
    android:duration="100"
    android:fromXDelta="0"
    android:fromYDelta="0"
    android:interpolator="@android:anim/linear_interpolator"
    android:toXDelta="100"
    android:toYDelta="100"></translate>

  </set>
复制代码

此动画可以在100ms内将一个View从原始位置向右下角移动100个像素。

使用LayoutParams

LayoutParms比较容易理解,比如我们想把一个 Button 向右平移100px,我们只需要将这个 Button 的 LayoutParams 里的 marginLeft 参数的值增加 100px 即可,是不是很简单呢?还有一种情形,为了达到移动 Button 的目的,我们还可以在 Button 的左边放置一个空的 View,这个空 View 的默认宽度为 0,当我们需要向右滑动 Button 时,只需要重新设置空 View 的宽度即可,当空 View 的宽度增大时(假设 Button 的父容器是水平方向的 LinearLayout),Button 就会被自动挤向右边,这样也间接的实现了 View 向右平移的效果。如何重新设置一个 View 的 LayoutParams 呢? 很简单, 如下所示:

    scrollTo.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) scrollTo.getLayoutParams();
            layoutParams.leftMargin +=100;
 //                scrollTo.requestLayout();
            scrollTo.setLayoutParams(layoutParams);
        }
    });
复制代码

使用Layout

我们知道,在 View 进行绘制时,会调用 onLayout() 方法来设置显示的位置。同样我们可以通过修改 View 的 left、top、right、bottom 四个属性来控制 View 的坐标。这里我们就不演示了,这种方式基本不常用,知道就行。

各种滑动方式的对比

先看 scrollTo/scrollBy 这种方式,它是 View 提供的原生方法,其作用是专门用于 View 的滑动,他可以比较方便地实现滑动效果并且不影响内部元素的单击事件,但是它的缺点也是很显然的:它只能滑动View的内容,并不能滑动View本身。

再看动画,通过动画的方式来实现 View 的滑动,这要分为两种情况,如果是 Android 3.0 以上并且采用的是属性动画,那么采用这种方式没有明显缺点;如果是使用 View 动画或者在 Android 3.0之前使用属性动画,均不能改变View本身的属性。在实际使用中,如果动画元素不需要响应用户的交互,那么使用动画来做滑动是比较合适的,否则就不太合适。但是动画有一个很明显的优点,那就是一些复杂的效果必须通过动画才能实现。

最后再看一下改变布局这种方式,它除了使用起来比较麻烦点以外,也没有明显的缺点,它的主要使用对象是一些具有交互性的 View,因为这些 View 需要和用户交互,直接通过动画去实现会有问题。

针对上面的分析下面来做一下总结,如下所示:

scrollTo/scrollBy :操作简单,适合对 View 的内容的滑动;
动画 :操作简单,主要适用于没有交互的 View 和实现复杂的动画效果
改变布局参数 :操作稍微复杂,适用于有交互的 View。

VIew动画

概述

Android的动画可以分为三种:View动画、帧动画和属性动画。
主要对View动画进行简单的概括与介绍,其实帧动画也属于View动画的一种,只不过它和平移、旋转等常见的View动画在表现形式上略有不同而已。
View动画是通过对场景里的对象不断做图像变换(平移、缩放、旋转、透明度)从而产生动画效果,它是一种渐进式动画,并且View动画支持自定义。
View动画的作用对象是View,它支持4种动画效果,分别是平移动画,缩放动画、旋转动画和透明度动画。上面提到过帧动画也属于View动画,为了更好的区分这四种变换和帧动画,在 本文中如果没有特殊说明,那么所提到的View动画均指这四种变换,帧动画在后面会单独介绍。

View动画的分类

View动画的四种变换效果分别对应着Animation的四个子类:TranslateAnimation、ScaleAnimation、RotateAnimation和AlphaAnimation,如下表所示。这四种动画既可以通过XML来定义,也可以通过代码来动态创建,对于View动画来说,建议采用XML来定义动画,这是因为XML格式的动画可读性更好。

要使用View动画,首先要创建动画的XML文件,这个文件的路径为:res/anim/filename.xml。View动画的描述文件是有固定语法的,如下所示:

  <?xml version="1.0" encoding="utf-8"?>
  <set xmlns:android="http://schemas.android.com/apk/res/android"
      android:interpolator="@[package:]anim/interpolator_resource"
      android:shareInterpolator=["true" | "false"]>


<alpha 
    android:fromAlpha="float"
    android:toAlpha="float"/>

<scale 
    android:fromXScale="float"
    android:toXScale="float"
    android:fromYScale="float"
    android:toYScale="float"
    android:pivotX="float"
    android:pivotY="float"/>

<translate 
    android:fromXDelta="float"
    android:toXDelta="float"
    android:fromYDelta="float"
    android:toYDelta="float" />

<rotate 
    android:fromDegrees="float"
    android:toDegrees="float"
    android:pivotX="float"
    android:pivotY="float" />

<set>
    ...
</set>
复制代码
从上面的语法可以看出,View动画既可以是单个动画,也可以由一系列动画组成。

标签表示动画集合,对应AnimationSet类,它可以包含若干个动画,并且它的内部也是可以嵌套其他动画集合的,它的两个属性含义如下:

  android:interpolator    
复制代码

表示动画集合所采用的的插值器,插值器影响动画的速度,比如非均匀动画就需要通过插值器来控制动画的播放过程。这个属性可以不指定,默认为@android:anim/interpolator_resource,即加速插值器。
android:shareInterpolator
表示集合中的动画是否和集合共享同一个插值器。如果集合不指定插值器,那么子动画就需要单独指定插值器或使用默认值。 标签表示平移动画,对应TranslateAnimation类,它可以使一个View在水平和竖直方向完成平移的动画效果,它的一系列属性的含义如下:

  • android:fromXDelta ---- 表示X的起始值,比如0;
  • android:toXDelta ---- 表示X的结束值,比如100;
  • android:fromYDelta ---- 表示Y的起始值;
  • android:toYDelta ---- 表示Y的结束值;

标签表示缩放动画,对应ScaleAnimation,它可以使View具有放大或缩小的动画效果,它的一系列属性的含义如下:

  • android:fromXScale ---- 水平方向缩放的起始值,比如0.5;
  • avandroid:toXScale ---- 水平方向缩放的结束值,比如1.2;
  • android:fromYScale ---- 竖直方向缩放的起始值;
  • android:toYScale ---- 竖直方向缩放的结束值;
  • android:pivotX ---- 缩放的轴点的x坐标,它会影响缩放的效果;
  • android:pivotY ---- 缩放的轴点的Y坐标,它会影响缩放的效果;

上面提到了轴点的概念,举个例子,默认情况下轴点是View的中心,这时在水平方向进行缩放的话会导致View向左右两个方向同时进行缩放,但是如果把轴点设为View的右边界,那么View就只会向左边进行缩放,反之则会向右边进行缩放。

标签表示旋转动画,对应RotateAnimation,它可以使View具有旋转的动画效果,它的属性的含义如下:

  • android:fromDegrees ---- 旋转开始的角度,比如0;
  • android:toDegrees ---- 旋转结束的角度,比如180;
  • android:pivotX ---- 旋转的轴点的x坐标;
  • android:pivotY ---- 旋转的轴点的y坐标;
    在旋转动画中也有轴点的概念,它也会影响旋转的具体效果。在旋转动画中,轴点扮演着旋转轴的角色,即View是围绕着轴点进行旋转的。

标签表示透明度动画,对应AlphaAnimation,它可以改变View的透明度,它的属性的含义如下:

  • android:fromAlpha ---- 表示透明度的起始值,比如0.1;

  • android:toAlpha ---- 表示透明度的结束值,比如1;
    上面介绍了View动画的XML格式。除了上面介绍的属性以外,View动画还有一些常用的属性,如下所示:

  • android:duration ---- 动画持续时间,单位毫秒;

  • android:fillAfter ---- 动画结束以后View是否停留在结束位置,true表示View停留在结束位置,false则不停留。

补件动画

步骤:

1.在res/anim目录创建动画效果xml文件
2.根据不同动画效果的语法,设置不同的动画参数
3.在java类中创建Animation对象,播放动画:或者在Java类中创建动画对象并播放

动画效果的公共属性
  • duration:动画持续时间(ms),必须设置,动画才有效果
  • startOffset:动画之间的时间间隔(ms)
  • fillBefore:设置位true,动画转化开始前被应用,默认为true
  • fillAfter:设置为true,动画转化在动画结束后被应用,默认为false
  • fillEnabled:是否应用fillBefore值,对fillAfter值无影响,默认true
  • repeatMode:选择重复播放动画模式,restart正序重放,reverse倒序回放,默认为restart
  • repeatCount:重复次数(动画的播放次数=重放次数+1),infinite无限重复
  • interpolator:插值器,即影响动画的播放速度
动画的实现方式

1./res/anim设置:alpha、scale、translate、rotate
2.Java代码实现:

  • AlphaAnimation:透明度
  • ScaleAnimation:缩放
  • TranslateAnimation:平移
  • RotateAnimation:旋转
加载方式
1.加载配置文件,并播放动画
Animation translateAnimation = AnimationUtils.loadAnimation(this,R.anim.view_translate_animation);  
tvView.startAnimation(translateAnimation);
复制代码
2.动态创建
Animation translateAnimation = new TranslateAnimation(0,500,0,500);  
translateAnimation.setDuration(3000);  
tvView.startAnimation(translateAnimation);
复制代码

帧动画

帧动画是顺序播放一组预先定义好的图片,类似电影播放,不同于View动画,系统提供了另一个类AnimationDrawable来使用帧动画。帧动画的使用比较简单,首先需要通过XML来定义一个AnimationDrawable,如下所示:

   // res/drawable/frame_animation.xml
          <?xml version="1.0" encoding="utf-8"?>
   <animation-list
       android:oneshot="false"
       xmlns:android="http://schemas.android.com/apk/res/android">

<item
    android:drawable="@drawable/image1"
    android:duration="500"/>

<item
    android:drawable="@drawable/image2"
    android:duration="500"/>

<item
    android:drawable="@drawable/image3"
    android:duration="500"/>
复制代码
然后将上述的Drawable作为View的背景并通过Drawable来播放动画即可:
   TextView textView = findViewById(R.id.mTextView);
   textView.setBackgroundResource(R.drawable.frame_animation);
   AnimationDrawable drawable = (AnimationDrawable) textView.getBackground();
   drawable.start();
复制代码

帧动画的使用比较简单,但是比较容易引起OOM,所以在使用帧动画时应尽量避免使用过多尺寸较大的图片 。

属性动画-0bjectAnimator

直接对对象的属性值进行改变操作(自动给对象属性赋值),实现动画效果
继承于ValueAnimator 编程方法与ValueAnimator-致
与ValueAnimator的区别
1.ValueAnimator类是先改变值,然后手动赋值给对象的属性实现动画,间接对对象属性进行操作
2.objectAnimator类是先改变值,然后自动赋值给对象的属性实现动画,直接对对象属性进行操作

在0bjectAnimator . ofFloat( )的第二个参数String property可以传入alpha、rotation、 trans lationX和scaleY等
0bjectAnimator类根据传入的属性名寻找对象的属性名的get/set方法,进行对象属性值的赋值
objectAnimator类针对的是任意对象的任意属性值,所以可以自定义对象属性

自定义对象属性实现动画的编程步骤
1.设置对象属性的get/set方法
2.在布局文件中加入自定义View控件
3.自定义Evaluator类实现TypeEvaluator接口,重写evaluate( )方法,实现动画过渡的逻辑
4.在Activity类中调用0bjectAnimator的of0bject( )方法,启动动画

设置xml文件
  <objectAnimator
  xmlns: android="http: //schemas. android. com/apk/res/android"
  android : propertyName=" alpha"
  android : valueFrom= "1"
  android:valueTo="o"
  android:valueType="floatType" />
复制代码
在Java中启动
 Animator animator = AnimatorInflater. loadAnimator( context: this, R. animator.set_ object_ animation);
 animator .setTarget( btnValue);
 animator .start();
复制代码
PropertyValuesHolder
 PropertyValuesHolder p1 = PropertyValuesHolder . ofFloat( "translationX", 0, 200f );
 PropertyValuesHolder p2 = PropertyValuesHolder .ofFloat("rotation", 0, 200f);
 PropertyValuesHolder p3 = PropertyValuesHolder. ofFloat("translationY", 0, 200f);
 ObjectAnimator . ofPropertyVa luesHolder(point, p1, p2, p3). setDuration(1000).start();
复制代码
属性动画的一种简写方式
 btnValue . animate( ). alpha(0f).x(500).y(500);
 btnValue . animate( ).alpha(0f) . setDuration( 1000). setInterpolator( new BounceInterpolator( ));
复制代码

组合动画-AnimatorSet

AnimatorSet类:实现组合动画的功能

AnimatorSet . play( Animator anim):播放当前动画
AnimatorSet . after(long delay): 将现有动画延迟x毫秒后执行
AnimatorSet . with(Animator anim):将现有动画和传入的动画同时执行
AnimatorSet .after(Animator anim): 将现有动画插入到传入的动画之后执行
AnimatorSet. before( Animator anim):将现有动画插入到传入的动画之前执行

  AnimatorSet animatorSet = new AnimatorSet( );
  animatorSet . play( translationX) . with( rotation). before( scaleX);
  animatorSet . setDuration( 5000 );animatorSet.start();
复制代码

动画的常见问题

通过动画可以实现一些比较绚丽的效果,但是在使用过程中,也需要注意一些事情,主要分为下面几类:

OOM问题
这个问题主要出现在帧动画中,当图片数量较多且图片较大时就极易出现OOM,这在实际的开发中要尤其注意,尽量避免使用帧动画。
内存泄漏
在属性动画中有一类无限循环的动画,这类动画需要在Activity退出时及时停止,否则将导致Activity无法释放从而造成内存泄漏,通过验证后发现View动画并不存在此问题。
兼容性问题
动画在 3.0 以下的系统上有兼容性问题,在某些特殊场景可能无法正常工作,因此需要做好适配工作。
View动画的问题
View动画是对View的影像做动画,并不是真正的改变View的状态,因此有时候会出现动画完成后View无法隐藏的现象,即setVisibility(View.GONE)失效了,这个时候只要调用view.clearAnimation()清除View动画即可解决此问题。
不要使用 px
在进行动画的过程中,要尽量使用dp,使用px会导致在不同的设备上有不同的效果。
动画元素的交互
将view移动(平移)后,在Android3.0以前的系统上,不管是View动画还是属性动画,新位置均无法触发单击事件,同时,老位置仍然可以触发点击事件。尽管View已经在视觉上已经不存在了,将View移回原位置后,原位置的单击事件继续生效。从 3.0开始,属性动画的单击事件触发位置为移动后的位置,但是View动画仍然在原处。
硬件加速
使用动画的过程中,建议开启硬件加速,这样会提高动画的流畅性。

自定义动画View

除了系统提供的四种View动画外,我们还可以自定义View动画。自定义动画是一件既简单又复杂的事情,说它简单是因为派生一种新动画只需要继承Animation这个抽象类,然后重写它的initialize和applyTransformation方法,在initialize方法中做一些初始化工作,在applyTransformation中进行响应的矩阵变换即可,很多时候需要采用Camera来简化矩阵变换的过程。说它复杂,是因为定义View动画的过程主要是矩阵变换的过程,而矩阵变换是数学上的概念,如果对这方面的知识不熟悉的话,就会觉得这个过程比较复杂了。

一般来说,在实际开发中很少用到自定义View动画。这里提供一个自定义View动画的例子,这个例子来自于Android的ApiDemos中的一个自定义View动画Rotate3dAnimation。Rotate3Animation可以围绕y周旋转并且同时沿着z轴平移从而实现一种类似于3D的效果,它的代码如下: public class Rotate3dAnimation extends Animation {

private final float mFromDegrees;
private final float mToDegrees;
private final float mCenterX;
private final float mCenterY;
private final float mDepthZ;
private final boolean mReverse;
private Camera mCamera;


public Rotate3dAnimation(float fromDegrees, float toDegrees,
                         float centerX, float centerY, float depthZ, boolean reverse) {
    this.mFromDegrees = fromDegrees;
    this.mToDegrees = toDegrees;
    this.mCenterX = centerX;
    this.mCenterY = centerY;
    this.mDepthZ = depthZ;
    this.mReverse = reverse;
}

@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
    super.initialize(width, height, parentWidth, parentHeight);
    mCamera = new Camera();
}

@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
    final float fromDegrees = mFromDegrees;
    float degrees = fromDegrees + ((mToDegrees - fromDegrees) * interpolatedTime);

    final float centerX = mCenterX;
    final float centerY = mCenterY;
    final Camera camera = mCamera;

    final Matrix matrix = t.getMatrix();

    camera.save();
    if (mReverse) {
        camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime);
    } else {
        camera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime));
    }
    camera.rotateY(degrees);
    camera.getMatrix(matrix);
    camera.restore();

    matrix.preTranslate(-centerX, -centerY);
    matrix.postTranslate(centerX, centerY);

}
}
复制代码

插值器和估值器

插值器

定义:一个接口
作用:设置 属性值 从初始值过渡到结束值 的变化规律(如匀速、加速 & 减速 等等 即确定了 动画效果变化的模式,如匀速变化、加速变化 等等)
应用场景:实现非线性运动(动画改变的速率不是一成不变的,如加速 & 减速运动都属于非线性运动)的动画效果
特别提醒:系统默认的插值器是AccelerateDecelerateInterpolator,即先加速后减速

具体应用

1.在Java代码中设置:

 //动画作用对象
     Button button = (Button) findViewById(R.id.button);

    //步骤1:创建动画对象 & 设置动画效果
    Animation alphaAnimation = new AlphaAnimation(1, 0);
    alphaAnimation.setDuration(3000);

    //步骤2:创建对应的插值器类对象
    Interpolator overshootInterpolator = new OvershootInterpolator();

    //步骤3:给动画设置插值器
    alphaAnimation.setInterpolator(overshootInterpolator);

    //步骤4:设置动画作用对象 & 开始动画
    button.startAnimation(alphaAnimation);
复制代码

2.在xml中设置:

 <?xml version="1.0" encoding="utf-8"?>
 <scale xmlns:android="http://schemas.android.com/apk/res/android"
// 通过资源ID设置插值器
android:interpolator="@android:anim/overshoot_interpolator"

android:duration="3000"
android:fromXScale="0.0"
android:fromYScale="0.0"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="2"
android:toYScale="2" />
复制代码

系统内置插值器类型

对应的Java类 资源ID 作用
AccelerateInterpolator @android:anim/accelerate_interpolator 动画加速进行
OvershootInterpolator @android:anim/overshoot_interpolator 快速完成动画,超出再回到结束样式
AccelerateDecelerateInterpolator @android:anim/accelerate_decelerate_interpolator 先加速再减速
AnticipateInterpolator @android:anim/anticipate_interpolator 先退后再加速前进
AnticipateOvershootInterpolator @android:anim/anticipate_overshoot_interpolator 先退后再加速前进,超出终点后再回终点
BounceInterpolator @android:anim/bounce_interpolator 最后阶段弹球效果
CycleInterpolator @android:anim/cycle_interpolator 周期运动
DecelerateInterpolator @android:anim/decelerate_interpolator 减速
LinearInterpolator @android:anim/linear_interpolator LinearInterpolator 匀速

估值器

定义:一个接口
作用:设置 属性值 从初始值过渡到结束值 的变化具体数值
插值器(Interpolator)决定 值 的变化规律(匀速、加速blabla),即决定的是变化趋势;而接下来的具体变化数值则交给估值器
特别注意:估值器属性动画特有的属性
应用场景:协助插值器 实现非线性运动的动画效果

具体使用

在Java中实现

 ObjectAnimator anim = ObjectAnimator.ofObject(myView2, "height", new Evaluator(),1,3);
 // 在第3个参数中传入对应估值器类的对象
 // 系统内置的估值器有3个:
 // IntEvaluator:以整型的形式从初始值 -  结束值 进行过渡
 // FloatEvaluator:以浮点型的形式从初始值 - 结束值 进行过渡
 // ArgbEvaluator:以Argb类型的形式从初始值 结束值 进行过渡
复制代码

系统内置的估值器类型

类型 说明
IntEvaluator 整数属性值。
FloatEvaluator 浮点数属性值。
ArgbEvaluato 十六进制color属性值。
TypeEvaluator 用户自定义属性值接口,譬如对象属性值类型不是int、float、color类型,你必须实现这个接口去定义自己的数据类型。

事件分发机制原理

什么叫事件分发机制 ?
事件分发是:当发生了一个事件时,在屏幕上找到一个合适的控件来处理这个事件的过程。
因为一个界面上控件如此之多,发生一个事件后总要寻找一个合适来处理事件吧。这个过程就叫做事件分发的机制。

事件分发的对象:点击事件Touch、Touch的细节封装在MotionEvent对象

事件传递的对象及传递顺序: Activity -> ViewGroup -> View

完成事件分发的方法 dispatchTouchEvent(): 分发(传递)点击事件,在点击事件传递给当前Vi ew时调用
onTouchEvent(): 处理点击事件,在dispatchTouchEvent( )内部调用

onInterceptTouchEvent(): 判断是否拦截事件,在Vi ewGroup的di spatchTouchEvent( )内部调用
**解决的问题:**点击事件由哪个对象发出、经过哪些对象、最终达到哪个对象,以及最终得到处理
事件分发的顺序: disptachTouchEvent -> setOnTouchListener -> onTouchEventonClick、onLongClick来自 onTouchEvent的处理
事件种类:

事件类型 具体动作
MotionEvent.ACTION_DOWN 按下View(所有事件的开始)
MotionEvent.ACTION_UP 按下View(与DOWN对应)
MotionEvent.ACTION_MOVE 滑动View
MotionEvent.ACTION_CANCEL 结束事件(非人为原因)

Activity的事件分发机制
点击事件总是从Activity的事件分发开始 如下图过程

ViewGroup的事件分发机制 Android的事件总是先传递到ViewGroup、再传递到View,当View把事件处理了,事件就不会再继续往下传递,过程如下图:

View的事件分发机制 如下图:

关注下面的标签,发现更多相似文章
评论