android动画View展开关闭,Android RecyclerView 动画展开item显示详情

stackoverflow上看到这个问题,答主给了个demo

http://stackoverflow.com/questions/27446051/recyclerview-animate-item-resize

看懂了之后发个博,记录一下,刚开始看别人代码好难受,就这么3个文件看了一晚上。。

效果如下

2245490a2e4bc15c3cfd3a79c8dd3192.png

res文件

main_activity文件就是一个recyclerview

main_item是两个textview 一个标题一个详细信息

MainActivity就是加载了一个RecyclerView

public class MainActivity extends ActionBarActivity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main_activity);

final RecyclerView rv = (RecyclerView) findViewById(R.id.rv);

final LinearLayoutManager layoutManager = new LinearLayoutManager(this);

rv.setLayoutManager(layoutManager);

final MainAdapter adapter = new MainAdapter();

rv.setAdapter(adapter);

}

}

MainAdapter中new了一个keepOne对象,点进去看这个类,有两个方法:bind和toggle,其中的bind是在MainAdapter中的onBindViewHolder()方法中调用,而toggle是响应viewholder的点击事件

public static class KeepOneH {

// opened为-1表示所有item是关闭状态,open为pos值的表示pos位置的item为展开的状态

private int _opened = -1;

public void bind(VH holder, int pos) {

if (pos == _opened)

// 3

// 直接显示expandView 无动画

ExpandableViewHoldersUtil.openH(holder, holder.getExpandView(), false);

else

// 直接关闭expandView 无动画

ExpandableViewHoldersUtil.closeH(holder, holder.getExpandView(), false);

}

@SuppressWarnings("unchecked")

// 响应点击事件的方法

public void toggle(VH holder) {

// 如果点击的就是开着的item,就关闭该item并把opened置-1

// ???TODO

if (_opened == holder.getPosition()) {

_opened = -1;

// 关闭expandView 有动画

ExpandableViewHoldersUtil.closeH(holder, holder.getExpandView(), true);

}

// 如果点击其他本来关闭着的item,则把opened值换成当前pos,把之前开的item给关掉

else {

int previous = _opened;

_opened = holder.getPosition();

// 展开expandView 有动画

ExpandableViewHoldersUtil.openH(holder, holder.getExpandView(), true);

// 用动画关闭之前的item

final VH oldHolder = (VH) ((RecyclerView) holder.itemView.getParent()).findViewHolderForPosition(previous);

if (oldHolder != null)

ExpandableViewHoldersUtil.closeH(oldHolder, oldHolder.getExpandView(), true);

}

}

}

点进openH和closeH方法进去看

// 4

public static void openH(final RecyclerView.ViewHolder holder, final View expandView, final boolean animate) {

// animate参数为true,则有动画效果

if (animate) {

expandView.setVisibility(View.VISIBLE);

// 5

// 改变高度的动画,具体操作点进去看

final Animator animator = ViewHolderAnimator.ofItemViewHeight(holder);

// 扩展的动画结束后透明度动画开始

animator.addListener(new AnimatorListenerAdapter() {

@Override public void onAnimationEnd(Animator animation) {

final ObjectAnimator alphaAnimator = ObjectAnimator.ofFloat(expandView, View.ALPHA, 1);

alphaAnimator.addListener(new ViewHolderAnimator.ViewHolderAnimatorListener(holder));

alphaAnimator.start();

}

});

animator.start();

}

// animate参数为false,则直接设置为可见

else {

expandView.setVisibility(View.VISIBLE);

expandView.setAlpha(1);

}

}

openH方法接收3个参数,

第一个是viewholder.

第二个是展开部分的view,由holder.getExpandView()方法获取。这里定义了一个接口

public static interface Expandable {

public View getExpandView();

}

在MainAdapter中传入infos这个Textview

@Override

public View getExpandView() {

return infos;

}

第三个是一个标记,true时有动画,false时直接设置其展开或者是关闭的状态。所以在bind()方法中调用的openH()都是false,而toggle()中调用的设置为true。

openH方法中 具体动画的操作为ViewHolderAnimator.ofItemViewHeight(holder)

public static Animator ofItemViewHeight(RecyclerView.ViewHolder holder) {

View parent = (View) holder.itemView.getParent();

if (parent == null)

throw new IllegalStateException("Cannot animate the layout of a view that has no parent");

// 测量扩展动画的起始高度和结束高度

int start = holder.itemView.getMeasuredHeight();

holder.itemView.measure(View.MeasureSpec.makeMeasureSpec(parent.getMeasuredWidth(), View.MeasureSpec.AT_MOST), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));

int end = holder.itemView.getMeasuredHeight();

// 6

final Animator animator = LayoutAnimator.ofHeight(holder.itemView, start, end);

// 设定该item在动画开始结束和取消时能否被recycle

animator.addListener(new ViewHolderAnimatorListener(holder));

// 设定结束时这个item的宽高

animator.addListener(new LayoutParamsAnimatorListener(holder.itemView, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));

return animator;

}

可以看出 具体展开的动画在LayoutAnimator.ofHeight(holder.itemView, start, end);中,ViewHolderAnimator只是测量参数,设定监听两个监听事件

1设定在动画开始结束和取消状态下是否可以被回收

public ViewHolderAnimatorListener(RecyclerView.ViewHolder holder) {

_holder = holder;

}

@Override

public void onAnimationStart(Animator animation) {

_holder.setIsRecyclable(false);

}

@Override

public void onAnimationEnd(Animator animation) {

_holder.setIsRecyclable(true);

}

@Override

public void onAnimationCancel(Animator animation) {

_holder.setIsRecyclable(true);

}

}

2.设定在动画结束后view的高和宽分别为warp_content,match_parent.

public static class LayoutParamsAnimatorListener extends AnimatorListenerAdapter {

private final View _view;

private final int _paramsWidth;

private final int _paramsHeight;

public LayoutParamsAnimatorListener(View view, int paramsWidth, int paramsHeight) {

_view = view;

_paramsWidth = paramsWidth;

_paramsHeight = paramsHeight;

}

@Override

public void onAnimationEnd(Animator animation) {

final ViewGroup.LayoutParams params = _view.getLayoutParams();

params.width = _paramsWidth;

params.height = _paramsHeight;

_view.setLayoutParams(params);

}

}

再深入一层看展开的动画

public class LayoutAnimator {

public static class LayoutHeightUpdateListener implements ValueAnimator.AnimatorUpdateListener {

private final View _view;

public LayoutHeightUpdateListener(View view) {

_view = view;

}

@Override

public void onAnimationUpdate(ValueAnimator animation) {

final ViewGroup.LayoutParams lp = _view.getLayoutParams();

lp.height = (int) animation.getAnimatedValue();

_view.setLayoutParams(lp);

}

}

public static Animator ofHeight(View view, int start, int end) {

final ValueAnimator animator = ValueAnimator.ofInt(start, end);

animator.addUpdateListener(new LayoutHeightUpdateListener(view));

return animator;

}

}

是用ValueAnimator.ofInt生成一系列高度值,然后监听动画的变化,不断设定view的高度值

版权声明:本文为博主原创文章,未经博主允许不得转载。

Android动画效果translate、scale、alpha、rotate详解(基础篇)

动画类型Android的animation由四种类型组成XML中alpha渐变透明度动画效果scale渐变尺寸伸缩动画效果translate画面转换位置移动动画效果rotate画面转移旋转动画

android 制作天气预报软件

天气预报软件是android中常见的工具软件最近我也做了一个感觉还是挺有趣的,随便发现很多android基础技术看看效果图:天气预报主要使用的开放接口这

Android 开源框架Universal-Image-Loader完全解析(一)--- 基本介绍及使用

转自:xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/26810303)相信大家平时做Android应用的时候,多少会接触到异步加载图片,或者加载大量图片的

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值