我们知道自定义属性要在自定义控件中使用的,我们自定义styleable,并通过obtainStyledAttributes方法解析,这就必须自定义View来解析我们自定义的属性,今天来介绍一种在系统控件上设置自定义属性的方法
首先看布局文件
<com.aruba.animationlibrary.AnimatorScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:discrollve="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.aruba.animationlibrary.AnimatorLinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="match_parent"
android:layout_height="600dp"
android:scaleType="centerCrop"
android:src="@mipmap/tb_bg" />
<TextView
android:layout_width="match_parent"
android:layout_height="200dp"
android:background="#007788"
android:fontFamily="serif"
android:gravity="center"
android:padding="25dp"
android:text="带上您的行李箱,准备shopping!"
android:textColor="@android:color/black"
android:textSize="25sp"
discrollve:discrollve_alpha="true" />
<ImageView
android:layout_width="200dp"
android:layout_height="120dp"
android:layout_gravity="top|right"
android:src="@mipmap/baggage"
discrollve:discrollve_alpha="true"
discrollve:discrollve_translation="fromLeft|fromBottom" />
<TextView
android:layout_width="match_parent"
android:layout_height="200dp"
android:fontFamily="serif"
android:gravity="center"
android:padding="25dp"
android:text="准备好相机,这里有你想象不到的惊喜!"
android:textColor="@android:color/black"
android:textSize="25sp"
discrollve:discrollve_fromBgColor="#ffff00"
discrollve:discrollve_toBgColor="#88EE66" />
<ImageView
android:layout_width="220dp"
android:layout_height="110dp"
android:layout_gravity="right"
android:src="@mipmap/camera"
discrollve:discrollve_translation="fromRight" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#D97C1F"
android:fontFamily="serif"
android:gravity="center"
android:padding="20dp"
android:text="这次淘宝造物节真的来了,我们都在造,你造吗?\n
7月22日-7月24日\n
上海世博展览馆\n
在现场,我们造什么?"
android:textSize="23sp"
discrollve:discrollve_alpha="true"
discrollve:discrollve_translation="fromBottom" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="20dp"
android:src="@mipmap/sweet"
discrollve:discrollve_scaleX="true"
discrollve:discrollve_scaleY="true" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="20dp"
android:src="@mipmap/shoes"
discrollve:discrollve_alpha="true"
discrollve:discrollve_scaleX="true"
discrollve:discrollve_scaleY="true"
discrollve:discrollve_translation="fromLeft|fromBottom" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="20dp"
android:src="@mipmap/shoes"
discrollve:discrollve_alpha="true"
discrollve:discrollve_scaleY="true"
discrollve:discrollve_translation="fromRight|fromTop" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="20dp"
android:src="@mipmap/sweet"
discrollve:discrollve_alpha="true"
discrollve:discrollve_scaleY="true"
discrollve:discrollve_translation="fromLeft" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="20dp"
android:src="@mipmap/camera"
discrollve:discrollve_scaleY="true"
discrollve:discrollve_translation="fromLeft" />
</com.aruba.animationlibrary.AnimatorLinearLayout>
</com.aruba.animationlibrary.AnimatorScrollView>
discrollve属性被设置到了系统控件上,效果如下
animator.gif
其中的核心思想是改写父布局的addView方法,并使用我们自定义的ViewGroup将系统控件包裹,将系统控件隐式的嵌套了一个ViewGroup,动画效果的实现在自定义的ViewGroup上执行
/**
* 自定义动画框架使用的LinearLayout
*/
public class AnimatorLinearLayout extends LinearLayoutCompat {
public AnimatorLinearLayout(Context context) {
this(context, null);
}
public AnimatorLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
setOrientation(VERTICAL);
}
/**
* 解析自定义属性,并记录下来,用于之后addView使用
*
* @param attrs
* @return
*/
@Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
return new MyLayoutParams(getContext(), attrs);
}
/**
* 干预Activity启动过程中xml解析,偷梁换柱使用自定义动画组件包裹
*
* @param child
* @param params
*/
@Override
public void addView(View child, ViewGroup.LayoutParams params) {
MyLayoutParams p = (MyLayoutParams) params;
if (!isDiscrollvable(p)) {
super.addView(child, params);
} else {
//将原始child中的属性给AnimatorFrameLayout用
AnimatorFrameLayout animatorFrameLayout = new AnimatorFrameLayout(getContext());
animatorFrameLayout.setmDiscrollveAlpha(p.mDiscrollveAlpha);
animatorFrameLayout.setmDiscrollveFromBgColor(p.mDiscrollveFromBgColor);
animatorFrameLayout.setmDiscrollveToBgColor(p.mDiscrollveToBgColor);
animatorFrameLayout.setmDiscrollveScaleX(p.mDiscrollveScaleX);
animatorFrameLayout.setmDisCrollveTranslation(p.mDisCrollveTranslation);
animatorFrameLayout.setmDiscrollveScaleY(p.mDiscrollveScaleY);
//使得child成为AnimatorFrameLayout的子View
animatorFrameLayout.addView(child);
//将AnimatorFrameLayout添加到AnimatorLinearLayout中
super.addView(animatorFrameLayout, params);
}
}
private boolean isDiscrollvable(MyLayoutParams p) {
return p.mDiscrollveAlpha ||
p.mDiscrollveScaleX ||
p.mDiscrollveScaleY ||
p.mDisCrollveTranslation != -1 ||
(p.mDiscrollveFromBgColor != -1 &&
p.mDiscrollveToBgColor != -1);
}
public class MyLayoutParams extends LinearLayoutCompat.LayoutParams {
public int mDiscrollveFromBgColor;//背景颜色变化开始值
public int mDiscrollveToBgColor;//背景颜色变化结束值
public boolean mDiscrollveAlpha;//是否需要透明度动画
public int mDisCrollveTranslation;//平移值
public boolean mDiscrollveScaleX;//是否需要x轴方向缩放
public boolean mDiscrollveScaleY;//是否需要y轴方向缩放
public MyLayoutParams(Context c, AttributeSet attrs) {
super(c, attrs);
//解析attrs得到自定义的属性,保存
TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.DiscrollView_LayoutParams);
mDiscrollveAlpha = a.getBoolean(R.styleable.DiscrollView_LayoutParams_discrollve_alpha, false);
mDiscrollveScaleX = a.getBoolean(R.styleable.DiscrollView_LayoutParams_discrollve_scaleX, false);
mDiscrollveScaleY = a.getBoolean(R.styleable.DiscrollView_LayoutParams_discrollve_scaleY, false);
mDisCrollveTranslation = a.getInt(R.styleable.DiscrollView_LayoutParams_discrollve_translation, -1);
mDiscrollveFromBgColor = a.getColor(R.styleable.DiscrollView_LayoutParams_discrollve_fromBgColor, -1);
mDiscrollveToBgColor = a.getColor(R.styleable.DiscrollView_LayoutParams_discrollve_toBgColor, -1);
a.recycle();
}
}
}
网友评论