使用RecyclerView实现列表展开动画

  昨天想起了公司前一段时间需要实现的一个动效,用listView实现列表item的展开动画。最后由于时间关系,只是实现了展开效果,但是展开的过程中是没有添加动画效果的,整个展开列表是由一种十分生硬的方式直接弹出来的,体验非常不好。本周的工作量不大,就想看一下有没有更好的实现方式,就在网上找了一下,看到了Google提供的RecyclerView,就查了一下相关的资料,看到了一位国外大牛写的用RecyclerView实现的这种效果,就下载源码看了一下,非常简单的实现,但效果很好,就来这里记录一下,防止以后需要的时候找不到。这也是我的第一篇博客,算是翻译+转载了。在这里感谢一下那位大牛。

  好了,不说废话了。使用Google最新的列表控件需要添加一个jar包,我使用的时studio 的开发环境,所以只需要在build.gradle中添加一句代码compile ‘com.android.support:recyclerview-v7:21.+’就可以了。使用eclipse的童鞋可以在网上搜一下相关的jar包,有很多,就不提供下载地址了。

  下面开始上代码。

  首先是列表的item布局,这里只是两个textview,第一个tv是一个标题,也就是运行后界面上始终显示的一个文字;另外的一个textview就是默认隐藏的控件了,点击列表的item的时候隐藏的部分慢慢展开。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:clickable="true"
    android:orientation="vertical"
    android:paddingBottom="10dp"
    android:paddingEnd="10dp"
    android:paddingLeft="30dp"
    android:paddingRight="10dp"
    android:paddingStart="30dp"
    android:paddingTop="20dp">

    <TextView
        android:id="@+id/contactName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="10dp"
        android:text="Contact name"
        android:textAppearance="?android:attr/textAppearanceLarge"
        tools:ignore="HardcodedText"/>

    <TextView
        android:id="@+id/infos"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/lipsum"
        android:textAppearance="?android:attr/textAppearanceMedium"/>
</LinearLayout>

  activity的界面布局就更简单了,只有一个列表控件。

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/rv"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollbars="vertical" />
</FrameLayout>

  activity里的代码很少,只有几行,具体内容就看代码里的注释了。

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);

        // 设置启动列表的修改动画效果(默认为关闭状态)
        rv.getItemAnimator().setSupportsChangeAnimations(true);
        // 设置动画时长
        rv.getItemAnimator().setChangeDuration(300);
        rv.getItemAnimator().setMoveDuration(300);

        // 实现RecyclerView实现竖向列表展示模式
        final LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        rv.setLayoutManager(layoutManager);

        // 实例化数据适配器并绑定在控件上
        final MainAdapter adapter = new MainAdapter();
        rv.setAdapter(adapter);
    }
}

  接下来就是最最重要的Adapter类了,之前的操作都和使用ListView差不多,google对RecyclerView的Adapter做了很多优化,让开发者使用起来更加的方便。

public class MainAdapter extends RecyclerView.Adapter<MainAdapter.MainViewHolder> {

    // 为列表提供数据的数据集合
    final String[] contacts = new String[]{
            "Amanda M. Ormond",
            "Anquises Mejia Bustos",
            "Bellisima Goodchild",
            "Bodo Greenhand",
            "Brogan Allan",
            "Claudia Bosch",
            "Elisa Asmara",
            "Emile Barrientos",
            "Ermes Toscano",
            "Guarino Romani",
            "Heike Dresner",
            "Isobel Chamberlain",
            "Ja'rod Kahnrah",
            "Jessica L. Carrillo",
            "Joseph M. Parks",
            "Kabarann D'Ghor",
            "Karol Perea Paredes",
            "Kotkhe Varrin",
            "Kiera Pritchard",
            "Lavinia Sackville-Baggins",
            "Manville Dubois",
            "Marion Deslauriers",
            "Mewael Semere",
            "Negassi Girmay",
            "Numilen Sarabia Solano",
            "Ovidio Colombo",
            "Simone Hahn",
            "Stanley Ross",
            "Spencer Porter",
            "Tekle Ambessa",
            "Yasmin Alexander"
    };

    // 列表展开标识
    int opened = -1;

    /**
     * 绑定item布局
     * @param parent
     * @param pos
     * @return
     */
    @Override
    public MainViewHolder onCreateViewHolder(ViewGroup parent, int pos) {
        return new MainViewHolder((ViewGroup) LayoutInflater.from(parent.getContext()).inflate(R.layout.main_item, parent, false));
    }

    /**
     * 绑定数据到控件
     * @param holder
     * @param pos
     */
    @Override
    public void onBindViewHolder(MainViewHolder holder, int pos) {
        final String contact = contacts[pos];
        holder.bind(pos, contact);
    }

    /**
     * 返回列表条数
     * @return
     */
    @Override
    public int getItemCount() {
        return contacts.length;
    }

    /**
     * 实例化控件等操作
     */
    public class MainViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

        // 标题
        public final TextView contactNameTV;
        // 隐藏的内容
        public final TextView infos;

        // 实例化
        public MainViewHolder(ViewGroup itemView) {
            super(itemView);
            contactNameTV = ((TextView) itemView.findViewById(R.id.contactName));
            infos = ((TextView) itemView.findViewById(R.id.infos));

            itemView.setOnClickListener(this);
        }

        // 此方法实现列表的展开和关闭
        public void bind(int pos, String name) {
            contactNameTV.setText(name);

            if (pos == opened)
                infos.setVisibility(View.VISIBLE);
            else
                infos.setVisibility(View.GONE);

        }

        /**
         * 为item添加点击效果
         * (recyclerView是不提供onItemClickListener的。所以列表的点击事件需要我们自己来实现)
         * @param v
         */
        @Override
        public void onClick(View v) {
            if (opened == getPosition()) {
                opened = -1;
                notifyItemChanged(getPosition());
            }
            else {
                int oldOpened = opened;
                opened = getPosition();
                notifyItemChanged(oldOpened);
                notifyItemChanged(opened);
            }
        }
    }
}

  所有的代码到这里就结束了,再次感谢各位前辈的贡献,让我们的开发之路走得更加顺畅,但路还是要自己来走。

RecyclerView体验简介 http://blog.iderzheng.com/first-date-with-recyclerview/

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值