一、屬性動畫
1.Animator
3.0之後的api,如果要在3.0之前使用需要導入NineOldAndroids。
2.ObjectAnimator
改變對象(Object)的屬性,需要目標對象中對屬性有get/set的方法。
如:
//可以幫助視圖修改顯示寬度,以及顯示高度的類型
class ViewTool {
View v;
ViewTool(View v) {
this.v = v;
}
public void setWidth(int width) {
v.getLayoutParams().width = width;
//刷新視圖
v.requestLayout();
}
public int getWidth() {
return v.getLayoutParams().width;
}
}
要對ViewTool這個對象改變width
ViewToolvt = new ViewTool(view);
ObjectAnimator.ofInt(vt,"width",vt.getWidth(),500).setDuration(3000).start();
3.ValueAnimator
改變數值的對象,需要設置改變範圍、設置改變監聽
privatevoid playAnimatorByValue(final int oldWidth) {
//創建ValueAnimator
ValueAnimator anim = ValueAnimator.ofInt(1, 100);
//添加變化監聽
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
private IntEvaluator mEvaluator = new IntEvaluator();
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
int current = (Integer)valueAnimator.getAnimatedValue();
Log.e("m_tag","==>" + current);
//取當前的寬度
// //基於當前變化的值算出要加的量
// int wantAdd = 380 * current/ 100;
// int w = oldWidth+ wantAdd;
// //改變顯示的寬度
// mBtn.getLayoutParams().width = w;
float fraction = current /100f;
int w =mEvaluator.evaluate(fraction, oldWidth, 500);
mBtn.getLayoutParams().width =w;
mBtn.requestLayout();
}
});
anim.setDuration(3000).start();
}
二、自定義View
(一) View的顯示流程
1、onMeasure,計算實際寬高
2、onLayout,容器佈置顯示位置和大小
3、onDraw,顯示效果
(二)自定義屬性
可以再values下創建屬性資源文件,如attrs.xml,然後在resource標籤中添加屬性的定義。
<!--聲明一系列屬性集(屬性數組)的標籤 -->
<declare-styleable name="MyTextView">
<attr name="bigText" format="string"/>
<attr name="bigTextSize" format="dimension"/>
<attr name="bigTextColor"format="color"/>
<attr name="smallText" format="string"/>
<attr name="smallTextSize"format="dimension"/>
<attr name="smallTextColor" format="color"/>
</declare-styleable>
format表示屬性的類型string是字符串 dimension表示尺寸 color表示顏色。
(三)應用自定義屬性
需要在使用自定屬性的佈局中添加屬性的命名空間(前綴)
如:
<LinearLayout
...
xmlns:abc="http://schemas.android.com/apk/res-auto"
...>
<com.xyy.viewdemo.MyTextView
...
abc:bigText="@string/app_name"
abc:bigTextSize="30sp"
abc:bigTextColor="@color/colorAccent"
abc:smallText="你好"
abc:smallTextColor="#ff0000ff"
abc:smallTextSize="20sp"/>
</LinearLayout>
(四)解析自定義屬性
需要在自定義View的構造中獲取屬性值
/**一般在xml佈局中使用自定義標籤(包名.類名)申明,會調用的構造方法
*@param context 視圖依賴的環境(如Activity)
*@param attrs 屬性域
*/
public MyTextView(Context context, AttributeSet attrs) {
super(context, attrs); //該父類構造的調用均可以解析基本屬性:寬高背景邊距
//將AttributeSet轉爲TypeArray
TypedArray ta = context.obtainStyledAttributes(attrs,R.styleable.MyTextView);
//按照屬性下標解析屬性值
bigTitle = ta.getString(R.styleable.MyTextView_bigText);
bigTitleSize = ta.getDimensionPixelSize(R.styleable.MyTextView_bigTextSize,20);
bigTitleColor = ta.getColor(R.styleable.MyTextView_bigTextColor,Color.BLACK);
smallTitle = ta.getString(R.styleable.MyTextView_smallText);
smallTitleSize =ta.getDimensionPixelSize(R.styleable.MyTextView_smallTextSize, 16);
smallTitleColor = ta.getColor(R.styleable.MyTextView_smallTextColor,Color.RED);
//這裏解析完畢一定要回收掉TypedArray
ta.recycle();
init();
}
(五)自定義寬高
需要重寫onMeasure方法通過setMeasuredDimension設置實際寬高。
//視圖需要測量寬高時觸發(計算自身的寬高告訴父容器)
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//獲取高方向的模式
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
//獲取參考的高度
int height = MeasureSpec.getSize(heightMeasureSpec);
//如果模式爲wrap_content方式,則計算精確的高度設置到MeasuredDimension
if (heightMode == MeasureSpec.AT_MOST) {
computeHeight();
height = bigHeight + smallHeight + 15;
}
setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(),widthMeasureSpec), height);
}
(六)畫出效果
//該視圖顯示的效果
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setTextSize(bigTitleSize);
mPaint.setColor(bigTitleColor);
//畫文本
Paint.FontMetrics fm = mPaint.getFontMetrics();
int bigHeight = (int) (fm.bottom - fm.top);
canvas.drawText(bigTitle,5,bigHeight,mPaint);
mPaint.setTextSize(smallTitleSize);
mPaint.setColor(smallTitleColor);
fm = mPaint.getFontMetrics();
int smallHeight = (int) (fm.bottom - fm.top);
canvas.drawText(smallTitle,15,smallHeight+bigHeight+5,mPaint);
}