对RecyclerViewItem做动画
转载地址:ruzhan123.github.io/2016/07/01/2016-07-01-01-
%E5%AF%B9RecyclerViewItem%E5%81%9A%E5%8A%A8%E7%94%BB/#rd
RecyclerView,ListView这些具有Item复⽤性的View,想要对其Item做动画
需要注意以下⼏点:
1,如果要⼀点击,让所有Item做动画的效果。例如,上图的编辑和取消,这样的动态动画。可以对所有ViewHolder中的View直接做动画。但是需要在onBindViewHolder⽅法中对复⽤的item做静态动画,保证动画状态的平滑衔接。
2,每⼀个Item的特有属性,例如,上图checkbox的选中状态,都需要把状态字段放到对应的Java bean中,并在onBindViewHolder⽅法从java bean取出状态值,设置到view⾥。
⾸先,对⼀些细节进⾏分析:
如何设计⼀个⾃定义View,来让他可以⾃⼰移动,做动画起来?
1,⾸先,创建⼀个View,他是RecyclerView Item的根布局:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
public class SlideRelativeLayout extends RelativeLayout {
public static final String TAG = SimpleName();
private CheckBox mCheckBox;
private RelativeLayout mContentSlide;
private int mOffset;
public SlideRelativeLayout(Context context){
super(context);
}
public SlideRelativeLayout(Context context, AttributeSet attrs){
super(context, attrs);
}
public SlideRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr){
super(context, attrs, defStyleAttr);
}
@Override
protected void onFinishInflate(){
mCheckBox = (CheckBox) findViewById(R.id.item_checkbox);
mContentSlide = (RelativeLayout) findViewById(R.id.item_content_rl);
setOffset(35);
}
public void setOffset(int offset){
mOffset = (int) (getContext().getResources().getDisplayMetrics().density * offset + 0.5f);
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public void openAnimation(){
对RecyclerView Item做动画,刚刚开始研究的时候⼀些坑
在这⾥把⼀些设计思路分享出去
添加动态位移,静态位移,缩放等动画,保证了动画状态的平滑衔接
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
public void openAnimation(){
ValueAnimator valueAnimator = new ValueAnimator();
valueAnimator.setIntValues(0, 1);
valueAnimator.setDuration(300);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator){
float fraction = AnimatedFraction();
int endX = (int) (-mOffset * fraction);
doAnimationSet(endX, fraction);
}
});
valueAnimator.start();
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public void closeAnimation(){
ValueAnimator valueAnimator = new ValueAnimator();
valueAnimator.setIntValues(0, 1);
valueAnimator.setDuration(150);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator){
float fraction = AnimatedFraction();
int endX = (int) (-mOffset * (1 - fraction));
doAnimationSet(endX, (1 - fraction));
}
});
valueAnimator.start();
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void doAnimationSet(int dx, float fraction){
mContentSlide.scrollTo(dx, 0);
mCheckBox.setScaleX(fraction);
mCheckBox.setScaleY(fraction);
mCheckBox.setAlpha(fraction * 255);
}
public void open(){
mContentSlide.scrollTo(-mOffset, 0);
}
public void close(){
mContentSlide.scrollTo(0, 0);
}
}
这⾥,在View树创建完毕之后到我们需要做动画的⼦View:1
2 3 4 5 6 7 8@Override
protected void onFinishInflate(){
mCheckBox = (CheckBox) findViewById(R.id.item_checkbox);
mContentSlide = (RelativeLayout) findViewById(R.id.item_content_rl); setOffset(35);
}
然后,设计4个⽅法,分别为:动态的打开动画,动态的关闭动画,静态的打开动画,静态的关闭动画。
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public void openAnimation(){
ValueAnimator valueAnimator = new ValueAnimator();
valueAnimator.setIntValues(0, 1);
valueAnimator.setDuration(300);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator){
float fraction = AnimatedFraction();
int endX = (int) (-mOffset * fraction);
doAnimationSet(endX, fraction);
}
});
valueAnimator.start();
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public void closeAnimation(){
ValueAnimator valueAnimator = new ValueAnimator();
valueAnimator.setIntValues(0, 1);
valueAnimator.setDuration(150);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator){
float fraction = AnimatedFraction();
int endX = (int) (-mOffset * (1 - fraction));
doAnimationSet(endX, (1 - fraction));
}
});
valueAnimator.start();
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void doAnimationSet(int dx, float fraction){
mContentSlide.scrollTo(dx, 0);
mCheckBox.setScaleX(fraction);
javabean是干什么的mCheckBox.setScaleY(fraction);
mCheckBox.setAlpha(fraction * 255);
}
public void open(){
mContentSlide.scrollTo(-mOffset, 0);
}
public void close(){
mContentSlide.scrollTo(0, 0);
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void doAnimationSet(int dx, float fraction){
mContentSlide.scrollTo(dx, 0);
mCheckBox.setScaleX(fraction);
mCheckBox.setScaleY(fraction);
mCheckBox.setAlpha(fraction * 255);
}
对⼦View做动画我采取的策略是:使⽤属性动画,在每⼀贞动画⾥获取到对应的值,对⼦View做相应的动画,例如:动态的打开动画。onAnimationUpdate⽅法,显⽰每⼀贞动画都会回调⼀次
1
2
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public void openAnimation(){
ValueAnimator valueAnimator = new ValueAnimator();
valueAnimator.setIntValues(0, 1);
valueAnimator.setDuration(300);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator){
float fraction = AnimatedFraction();
int endX = (int) (-mOffset * fraction);
doAnimationSet(endX, fraction);
}
});
valueAnimator.start();
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void doAnimationSet(int dx, float fraction){
mContentSlide.scrollTo(dx, 0);
mCheckBox.setScaleX(fraction);
mCheckBox.setScaleY(fraction);
mCheckBox.setAlpha(fraction * 255);
25 26 mCheckBox.setAlpha(fraction * 255); }
这样RecylerView 带有动态动画和静态动画的View就设计好了。2,在bind⽅法中使⽤静态动画,动态动画对外提供⽅法调⽤:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31private class SlideViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { private SlideRelativeLayout mSlideRelativeLayout;
private CheckBox mCheckBox;
private ItemBean mItemBean;
public SlideViewHolder(View itemView){
super(itemView);
mSlideRelativeLayout = (SlideRelativeLayout) itemView.findViewById(R.id.item_root);
mCheckBox = (CheckBox) itemView.findViewById(R.id.item_checkbox);
itemView.setOnClickListener(this);
}
public void bind(ItemBean itemBean){
mItemBean = itemBean;
mCheckBox.setChecked(itemBean.isChecked());
switch (mState) {
case NORMAL:
mSlideRelativeLayout.close();
break;
case SLIDE:
mSlideRelativeLayout.open();
break;
}
}
public void openItemAnimation(){
mSlideRelativeLayout.openAnimation();
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论