昨天想起了公司前一段时间需要实现的一个动效,用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/