View绘制过程
继承自View类的控件在绘制中分为三个主要过程
Measure
在这一阶段确定控件的大小,应对不同specModel采取不用策略
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
一般直接调用super.onMeasure(widthMeasureSpec,heightMeasureSpec)
就可以了。如果不能达到预期效果,就需要先了解一下class#MeasureSpec
在onMeasure函数传入的两个int并不单纯是view的width和height,只有30位用于记录数值,高二位记录specModel 大概,反正不全是用来计数的 。specModel有如下三种,以height属性为例:
- EXACTLY
在layout_height为 具体数值 or match_parent时生效 - AT_MOST
在layout_height为wrap_content时生效。表示view尺寸为不超过父视图最大尺寸的任意大小 - UNSPECIFIED
不指定大小,父视图不限制子视图的大小
在确定view的height和width之后,调用setMeasuredDimension(width,height);
为view设定大小,否则不会生效。
onLayout
确定view左上位置 具体作用不明,用到再更
onDraw
这一过程负责绘制你的CustomView,也是实现动画效果的关键部分。根据计时器数指计算参数,调用invalidate()
不断刷新控件实现动画。
示例:仿华为天气:日出日落动画效果
三者调用关系如下图
自定义属性
声明属性
如果需要额外的信息来配置自定义控件,可以在res/value资源文件下新建Resource File
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="自定义控件类名">
<attr name="自定义属性名称" format="属性格式">
</declare-styleable>
</resources>
构造函数
现在仅定义属性我们还无法在控件加载时获取,获取还需要写构造函数。
关于构造函数有如下三种重载函数
- public CustomView(Context context)
在代码中动态为页面动态添加时调用构造器,需要配合setter配置属性 - public CustomView(Context context, @Nullable AttributeSet attrs)
从xml文件中构造控件时调用的构造器,获取属性方法如下
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.yourCustomViewClassName);
if (typedArray!=null){
int color = typedArray.getInt(R.styleable.declare_attr , defValue);
// 注意String类型没有默认值,如果xml文件中没有配置获取为null
String text = typedArray.getString(R.styleable.declare_attr);
// 获取dimension类型时,默认值单位为px
float width = typedArray.getDimension(R.styleable.declare_attr, defValue);
typedArray.recycle();
}
- public CustomView(Context context, @Nullable AttributeSet attrs, int defStyleAttr)
从xml中构造控件且使用theme attr style时调用。大概用不到,用到再更
动画效果
这里仅对Android Anime效果做简单概述
帧动画
实现较为简单但是由于不会画图所以从来没有试过
- 在res/drawable资源文件下新建xml,root为 animation-list
- 将帧动画的每一帧按序添加,设置持续时间duration
- 更改需要动画效果的activity/fragment的background
- AnimationDrawable drawable =activity/fragment id.getBackground();drawable.start()开始动画;drawable.stop()停止动画
补间动画
补间动画有四种动画效果:alpha 透明度 / rotate 旋转 / scale 缩放 / translate 平移
配置补间动画需要在res/anim资源文件夹下新建Animation Resource File。配置属性见开发文档,下面以alpha示例
<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:fromAlpha="0.8"
android:toAlpha="1"
android:duration="3000"
android:interpolator="@android:anim/accelerate_decelerate_interpolator">
</alpha>
页面布局
<ImageView
android:id="@+id/background"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="bg pic"/>
bg = findViewById(R.id.background);
Animation animation = AnimationUtils.loadAnimation(SplashActivity.this,R.anim.yourResoucreFileName);
animation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
//动画开始时回调函数
}
@Override
public void onAnimationEnd(Animation animation) {
//动画结束后回调函数
}
@Override
public void onAnimationRepeat(Animation animation) {
//动画重复时回调函数
}
});
bg.startAnimation(animation);