stackoverflow上看到这个问题,答主给了个demo
http://stackoverflow.com/questions/27446051/recyclerview-animate-item-resize
看懂了之后发个博,记录一下,刚开始看别人代码好难受,就这么3个文件看了一晚上。。

效果如下

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);
} }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

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

public static class KeepOneH<VH extends RecyclerView.ViewHolder & Expandable> {
// 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);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
@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);
}
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

点进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);
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

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

public static interface Expandable {
public View getExpandView();
}
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

在MainAdapter中传入infos这个Textview

@Override
public View getExpandView() {
return infos;
}
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

第三个是一个标记,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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

可以看出 具体展开的动画在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);
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

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);
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

再深入一层看展开的动画

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;
}
}
  • 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
  • 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

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

http://blog.csdn.net/gulumi_mmga/article/details/46683437

Android RecyclerView 动画展开item显示详情的更多相关文章

  1. Android解决RecyclerView中的item显示不全方案

    最近的项目中实现订单确定页面.需要使用ScrollView嵌套RecyclerView,当RecyclerView中的item数量比较多时,就会出现item只显示一部分数据,并没有将用户勾选的商品数量 ...

  2. Android RecyclerView预览item

    参考: Android Tools Attributes listItem 和 Sample Data 的用法 笔记 tools:text TextView可以实现预览,不影响实际的效果 例如: to ...

  3. Android Animation动画实战(一): 从布局动画引入ListView滑动时,每一Item项的显示动画

    前言: 之前,我已经写了两篇博文,给大家介绍了Android的基础动画是如何实现的,如果还不清楚的,可以点击查看:Android Animation动画详解(一): 补间动画 及 Android An ...

  4. 解决ScrollView嵌套RecyclerView出现item显示不全的问题

      问题:ScrollView嵌套RecyclerView时,RecyclerView的item显示不全 出现问题不要慌,耐心解决才是王道,哈哈.首先说下出现这个问题的情景吧,首先声明这个问题在23版 ...

  5. 【Android 界面效果49】RecyclerView高度随Item自适应

    编写RecyclerView.ItemDecoration时,在onDraw方法中,Drawable的高度等于RecyclerView的高度减去RecyclerView的上下padding. @Ove ...

  6. Android 自定义View修炼-自定义可动画展开收缩View的实现

    有时候需要点击一个view可以动画展开和收缩折叠一个View这样的效果,这样就可以直接自定义View来实现. 本例中,采用继承FrameLayout来实现自定义的ExpandView.下面将详细介绍各 ...

  7. Android窗口管理服务WindowManagerService显示窗口动画的原理分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/8611754 在前一文中,我们分析了Activi ...

  8. 基于css3的鼠标经过动画显示详情特效

    之前为大家分享过一款基于jquery的手风琴显示详情,今天给大家分享基于css3的鼠标经过动画显示详情特效.这款实例鼠标经过的时候基于中间动画放大,效果非常不错,效果图如下: 在线预览   源码下载 ...

  9. Android RecyclerView 使用完全解析 体验艺术般的控件

    概述 RecyclerView出现已经有一段时间了,相信大家肯定不陌生了,大家可以通过导入support-v7对其进行使用. 据官方的介绍,该控件用于在有限的窗口中展示大量数据集,其实这样功能的控件我 ...

随机推荐

  1. android tools使用方式

    我们希望在布局中显示测试的属性,而这个属性不会影响到正式代码,因此我们就需要tools这个命名空间. 首先定义:xmlns:tools="http://schemas.android.com ...

  2. Swift开发第八篇——方法嵌套&命名空间

    本篇分为两部分: 一.Swift中的方法嵌套 二.Swift中的命名空间 一.Swift中的方法嵌套 在 swift 中我们可以让方法嵌套方法,如: func appendQuery(var url: ...

  3. Android中应用程序清除data/data,清除cache,超详细

    清除data,清除cache,其实在Android原生Setting里面有这个功能的. 需求是把这个功能做到自己的App里面,并计算出cache和data的size. 所以参考了一下Setting的源 ...

  4. vs合并压缩css,js插件——Bundler & Minifier

    之前做了一个大转盘的抽奖活动,因为比较火,部分用户反馈看不到页面的情况,我怀疑js加载请求过慢导致,所以今天针对之前的一个页面进行调试优化. 首先想到的是对页面的js和css进行压缩优化,百度了下vs ...

  5. openstack security group and rules python api use

    nova和neutron都可以,但是感觉还是用neutron好. import neutronclient.v2_0.client as neclient neutron = neclient.Cli ...

  6. CMPP3.0实现物联网卡通讯

    当下物联网发展迅猛,物联网卡可以接受短信指令,实现千里之外尽可掌控.本人做过一个这类项目,把相关经验记录下来,分享给需要的人. 物联网卡通讯其实跟电话卡一样,可以使用CMPP协议.不过由于物联网卡位数 ...

  7. mapreduce流程中的几个关键点

    MapReduce中数据流动    (1)最简单的过程:  map - reduce    (2)定制了partitioner以将map的结果送往指定reducer的过程: map - partiti ...

  8. Consul 服务发现和配置

    Service discovery and configuration made easy. Distributed, highly available, and datacenter-aware. ...

  9. web会话管理

    http协议是无状态的协议,也就是说服务器不知道这个http连接是那个浏览器发过来的. 要标识会话的唯一,有两种方法:1 Cookie  2 会话级cookie(开关浏览器算一次会话) 和 持久化的c ...

  10. solrconfig.xml介绍

    说明:请务必先了解如下知识,否则阅读本文会晕. Solr术语介绍:SolrCloud,单机Solr,Collection,Shard,Replica,Core之间的关系 Solr通过三个主要文件来作配 ...