基础知识

Android的绘制系统(ActivityManagerService)
Android的事件系统(InputManagerService)

measure

MeasureSpecs

MeasureSpecs维护一个int型(32bit)数据,其中2bit表示mode,30bit表示size

size = MeasureSpec.getSize(measureSpec)mode = MeasureSpec.getMode(measureSpec)measureSpec = MeasureSpec.makeMeasureSpec(size, mode)getDefaultSize(size,measureSpec)//根据View默认大小size和父类measureSpec来测量当前View的大小

一个View的大小由父容器的MeasureSpec和自身的LayoutParams决定

测量过程

例子:修改ListView的onMeasure使得ListView完全展开

@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {    //int widthMeasureSpec, int heightMeasureSpec是父容器的测量spec,现将父容器的高度测量spec修改成足够大,并且是AT_MOST模式,这样子容器即ListView认为父容器有足够大的空间就会将所有的内容完全展开了。        heightMeasureSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);        super.onMeasure(widthMeasureSpec, heightMeasureSpec);}

layout

view的layout过程:layout(确定自身的位置)->onLayout(空实现)
ViewGroup的layout过程:layout(确定自身的位置)->onLayout(确定子控件的位置,这里实现具体布局,并且会遍历子控件的layout对子控件执行layout)
例子:简单实现一个类似LinearLayout的横向布局

public class CustomViewGroup extends ViewGroup {    private final static String TAG = "CustomViewGroup";    // view 的间隔    private final static int VIEW_MARGIN = 0;    public CustomViewGroup(Context context) {        super(context);    }    // 重写它的onMeasure() 在该方法中进行对子View的大小进行测量    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        for (int index = 0; index < getChildCount(); index++) {            final View child = getChildAt(index);            child.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);        }        super.onMeasure(widthMeasureSpec, heightMeasureSpec);    }    // 重写onLayout方法实现子View的定位    @Override    protected void onLayout(boolean changed, int l, int t, int r, int b) {        final int count = getChildCount();        int row = 0;        //当前宽度        int lengthX = l;        //当前高度        int lengthY = t;        for (int i = 0; i < count; i++) {            final View child = this.getChildAt(i);            int width = child.getMeasuredWidth();            int height = child.getMeasuredHeight();            lengthX += width + VIEW_MARGIN;            lengthY = row * (height + VIEW_MARGIN) + VIEW_MARGIN + height                    + t;            if (lengthX > r) {                lengthX = width + VIEW_MARGIN + l;                row++;                lengthY = row * (height + VIEW_MARGIN) + VIEW_MARGIN + height                        + t;            }            child.layout(lengthX - width, lengthY - height, lengthX, lengthY);        }    }}

draw


PS:invalidate最后也是通过调用rootView的performTraversals()来刷新视图的;而invalidate只会重新执行onDraw;requestLayout才会重新执行整个绘制过程

自定义View的四种构造函数及常见函数

// 如果View是在Java代码里面new的,则调用第一个构造函数 public CarsonView(Context context) {        super(context);    }// 如果View是在.xml里声明的,则调用第二个构造函数// 自定义属性是从AttributeSet参数传进来的    public  CarsonView(Context context, AttributeSet attrs) {        super(context, attrs);    }// 不会自动调用// 一般是在第二个构造函数里主动调用// 如View有style属性时    public  CarsonView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);    }    //API21之后才使用    // 不会自动调用    // 一般是在第二个构造函数里主动调用    // 如View有style属性时    public  CarsonView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {        super(context, attrs, defStyleAttr, defStyleRes);    }
view.getTop() 子View左上角距父View顶部的距离 view.getBottom() 子View右下角距父View顶部的距离 view.getLeft() 子View左上角距父View左侧 view.getRight() 子View右下角距父View左侧 event.getX()/event.getY() 触摸点相对于其所在组件坐标系的坐标 event.getRawX()/event.getRawY() 触摸点相对于屏幕默认坐标系的坐标

view的移动方式

layout
offsetTopAndBottom、offsetLeftAndRight
scrollTo、scrollBy
LayoutParams
Scroller

颜色

自定义属性

在values目录下创建自定义属性的xml文件attrs_circle_view.xml

<?xml version="1.0" encoding="utf-8"?>                

常用单位format:color boolean dimension float integer string fraction(百分比) enum(eg:orientation,单选) flag(eg:adjustResize|adjustPan,多选)

布局中进行设置

<?xml version="1.0" encoding="utf-8"?>    

在代码中解析获取

mColor = a.getColor(R.styleable.CircleView_circle_color,Color.RED);

或者 直接在xml中使用(这种方式属性必须赋值否则会出错)

PS:还可以在lib中设置一个默认的style样式,在View直接取过来用。业务层需要使用时只需写一个同名的style则可覆盖之,达到全局修改样式的效果。

其他小细节

  • post替代handler,View的内部本身提供了post系列的方法,完全可以替代Handler的作用,使用起来更加方便、直接。
  • onAttachedToWindow,调用的时机是当包含View的Activity启动的时刻,适合启动线程/动画/注册各种东东
  • onDetachedFromWindow,调用的时机是当包含View的Activity退出或当前View被remove的时刻,适合结束线程/动画/注销各种东东

帧动画

<?xml version="1.0" encoding="utf-8"?>            

同样的也可用AnimationDrawable实现

补间动画

平移动画TranslateAnimation、缩放动画ScaleAnimation、旋转动画RotateAnimatioin、透明度动画AlphaAnimation
自定义动画:通过矩阵变换来实现,可用来做3D动画!继承Animation,实现initialize(初始化工作)、applyTransFormation(动画实现)即可。

常见属性

  • < translate>
    ■ 表示x的起始值
    ■ 表示x的结束值
    ■ 表示y的起始值
    ■ 表示y的结束值
  • < scale>
    ■ fromX 水平方向缩放起始值
    ■ toX 水平方向缩放结束值
    ■ fromY
    ■ toY
    ■ pivotX 缩放的轴点的x坐标
    ■ pivotY 缩放的轴点的y坐标
    ■ pivotXType x轴的所发模式,即中心点相对于哪个物体Animation.ABSOLUTE/RELATIVE_TO_SELF/RELATIVE_TO_PARENT
    ■ pivotYType y轴的所发模式
  • < rotate>
    ■ fromeDegres旋转开始的角度
    ■ toDegrees
    ■ pivotX旋转的轴点的x坐标
    ■ pivotY
  • < alpha>
    ■ fromAlpha透明度起始值
    ■ toAlpha透明度结束值
  • 共有属性
    ■duration动画持续时间
    ■ fillAfter动画结束后是否停留在结束位置

自定义补间动画

public class MyAnimation extends Animation{    @Override    protected void applyTransformation(float interpolatedTime,Transformation transformation){    //interpolatedTime表示动画的时间进行比,transformation表示补间动画在不同时刻对View的变形程度    }}

布局动画LayoutAnimation

为容器型控件里的子View设置动画 LayoutAnimationController

xml实现

android:delay子类动画时间间隔 android:animationOrder="random"   子类的显示方式 normal默认random随机reverse倒序android:animation="@anim/slide_right" 表示孩子显示时的具体动画是什么

组合动画

AnimationSet

属性动画

ObjectAnimator

ObjectAnimator//           .ofFloat(view, "rotationX", 0.0F, 360.0F)//           .setDuration(500)//           .start(); 

一次性修改多个属性

PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("alpha", 1f,                  0f, 1f);  PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("scaleX", 1f,                  0, 1f);  PropertyValuesHolder pvhZ = PropertyValuesHolder.ofFloat("scaleY", 1f,                  0, 1f);  ObjectAnimator.ofPropertyValuesHolder(view, pvhX, pvhY,pvhZ).setDuration(1000).start();

ValueAnimator

ValueAnimator animator = ValueAnimator.ofFloat(0, mScreenHeight                  - mBlueBall.getHeight());          animator.setTarget(mBlueBall);          animator.setDuration(1000).start();  //      animator.setInterpolator(value)          animator.addUpdateListener(new AnimatorUpdateListener()          {              @Override              public void onAnimationUpdate(ValueAnimator animation)              {                  mBlueBall.setTranslationY((Float) animation.getAnimatedValue());              }          }); 

常见属性

Transtion 过度动画

本质上过渡动画也还是属性动画,只不过做了一层封装,方便实现Activity和View的过渡效果

绘制辅助

Interpplator 插值器

  • AccelerateDecelerateInterpolator:开始与结束时速度快,中间慢
  • AccelerateInterpolator:开始慢然后加速
  • CycleInterpolator:动画循环播放特定的次数,速率改变沿着正弦曲线
  • DecelerateInterpolator:开始速度快然后减速
  • LinearInterpolator:均匀的改变速度

TypeEvaluator 类型估值,主要用于设置动画操作属性的值。设置 属性值 从初始值过渡到结束值 的变化具体数值

  • IntEvaluator Int类型估值器,返回int类型的属性改变
  • FloatEvaluator Float类型估值器,返回Float类型属性改变
  • ArgbEvaluator 颜色类型估值器
// 实现TypeEvaluator接口public class PointEvaluator implements TypeEvaluator {    // 复写evaluate()在里面写入对象动画过渡的逻辑    @Override    public Object evaluate(float fraction, Object startValue, Object endValue) {        //fraction为插值器getInterpolation()的返回值,startValue/endValue为初始值/结束值        // 将动画初始值startValue 和 动画结束值endValue 强制类型转换成Point对象        Point startPoint = (Point) startValue;        Point endPoint = (Point) endValue;        // 根据fraction来计算当前动画的x和y的值        float x = startPoint.getX() + fraction * (endPoint.getX() - startPoint.getX());        float y = startPoint.getY() + fraction * (endPoint.getY() - startPoint.getY());        // 将计算后的坐标封装到一个新的Point对象中并返回        Point point = new Point(x, y);        return point;    }}

Activity转场动画

overridePendingTransition

更多相关文章

  1. Android中调用天气预报
  2. Android下相机的调用
  3. RelativeLayout属性详解
  4. Android学习笔记之mainfest文件中android属性
  5. Delphi xe7 up1 调用android振动功能
  6. android中TextView和EditText控件一些属性
  7. pro.Android(安卓)Media--调用内置的照相机
  8. Android控件之ImageView(显示图片的控件)
  9. RelativeLayout用到的一些重要的属性

随机推荐

  1. Android高效率编码-第三方SDK详解系列(二
  2. Android(安卓)API Guides---Near Field C
  3. android 呼入电话的监听(来电监听)
  4. Android(安卓)11 中的隐私权更新 :存储机
  5. 命令行 android 出 No suitable Java fou
  6. Android实现左滑退出Activity(完美封装)
  7. android 常用intent
  8. 探讨android 导航栏中的recent_app界面
  9. android:configChanges属性总结
  10. 在Android中实现图片缩放和旋转