以前都是用的listView,但是v7包提供了一个比listView更好用的,具有listView所有功能的组件,那就是recyclerview,它设置布局的时候,不仅有线性布局(listview的布局),还有表格布局,以及瀑布流布局,而且每种布局都可以设置成横向或者纵向,功能简直强大。它除了布局设置,还有分隔线设置,以及添加,删除的动画设置,不过这些只是提供了一种默认的可以使用,一般情况需要自定义。它的适配器比listView的要简单。但是它没有提供item的点击和长按事件,这里需要自己设置回调事件。虽然他没有点击和长按事件不过它的viewholder加载的view有点击和长按事件,设置回调事件,得从这里入手。
使用RecyclerView要导入v7的依赖包虽然Android studio新建项目就会导入v7的appcompat依赖,不过里面并没有这个组件,这个组件要单独导入依赖。
dependencies { compile fileTree(dir: 'libs',include: ['*.jar']) androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2',{ exclude group: 'com.android.support',module: 'support-annotations' }) compile 'com.android.support:recyclerview-v7:25.3.1' compile 'com.android.support:appcompat-v7:25.3.1' compile 'com.android.support.constraint:constraint-layout:1.0.2' testCompile 'junit:junit:4.12' }
item的布局,就是一个imagview和textview,而Data则是与它对应的一个设置图片的int,与一个设置文字的string代码就不贴了。只贴适配器和主活动代码
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder>{ public LinkedList<Data> datas; public Context context; public MyAdapter(LinkedList<Data> datas,Context context){ this.context=context; this.datas=datas; } public void add(Data data){ if(datas==null) datas=new LinkedList<Data>(); datas.add(data); //如果使用notifyDataSetChanged()则没有添加的动画效果 //notifyDataSetChanged(); notifyItemInserted(datas.size()-1); } public void remove(int position){ if(datas!=null){ datas.remove(position); //如果使用notifyDataSetChanged()则没有移除的动画效果 //notifyDataSetChanged(); notifyItemRemoved(position); } } public void modify(Data data,int position){ datas.set(position,data); notifyDataSetChanged(); } //事件监听的回调接口 public interface OnItemClickListener{ void onItemClick(View view,int postion); void onItemLongClick(View view,int postion); } private OnItemClickListener mlistener; public void setOnItemClickListener(OnItemClickListener mlistener){ this.mlistener=mlistener; } @Override public ViewHolder onCreateViewHolder(ViewGroup parent,int viewType) { //加载布局创建viewholder View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.item_recycle,parent,false); ViewHolder viewHoder=new ViewHolder(view); return viewHoder; } @Override public void onBindViewHolder(final ViewHolder holder,int position) { //为viewholder绑定数据 holder.imageView.setImageResource(datas.get(position).imgid); holder.textView.setText(datas.get(position).text); if(mlistener!=null){ holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { int pos=holder.getLayoutPosition(); mlistener.onItemClick(holder.itemView,pos); } }); holder.itemView.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { int pos=holder.getLayoutPosition(); mlistener.onItemLongClick(holder.itemView,pos); return true; } }); } } @Override public int getItemCount() { return datas==null ? 0:datas.size(); } public static class ViewHolder extends RecyclerView.ViewHolder{ ImageView imageView; TextView textView; public ViewHolder(View itemView) { super(itemView); imageView= (ImageView) itemView.findViewById(R.id.img); textView= (TextView) itemView.findViewById(R.id.text); } } }
public class MainActivity extends AppCompatActivity { private MyAdapter myAdapter; private LinkedList<Data> datas; private RecyclerView recyclerView; private Button button; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); button= (Button) findViewById(R.id.button); initrecycler(); listen(); } public void initrecycler(){ recyclerView= (RecyclerView) findViewById(R.id.recycle); datas=new LinkedList<Data>(); for(int i=0;i<10;i++){ datas.add(new Data(R.mipmap.ic_launcher,"item "+i)); } myAdapter=new MyAdapter(datas,MainActivity.this); //设置布局为线性布局,默认竖直 recyclerView.setLayoutManager(new LinearLayoutManager(this)); // //设置布局为横向的线性布局,false表示方向向右。 // recyclerView.setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.HORIZONTAL,false)); // //设置布局为网格3列布局,默认竖直 // recyclerView.setLayoutManager(new GridLayoutManager(this,3)); // //设置布局为3列的瀑布流布局。 // recyclerView.setLayoutManager(new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL)); recyclerView.setAdapter(myAdapter); //设置添加和删除的动画效果 recyclerView.setItemAnimator(new DefaultItemAnimator()); //设置横向分割线 recyclerView.addItemDecoration(new DividerItemDecoration(MainActivity.this,LinearLayoutManager.VERTICAL)); } public void listen(){ //RecyclerView没有点击和长按事件监听,所以自己设置回调事件 myAdapter.setOnItemClickListener(new MyAdapter.OnItemClickListener() { @Override public void onItemClick(View view,int postion) { Toast.makeText(MainActivity.this,"点击"+postion,Toast.LENGTH_SHORT).show(); myAdapter.add(new Data(R.mipmap.ic_launcher,"新来的")); } @Override public void onItemLongClick(View view,"长按"+postion,Toast.LENGTH_SHORT).show(); myAdapter.remove(postion); } }); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { myAdapter.modify(new Data(R.mipmap.ic_launcher,"修改的"),0); } }); } }
这样的话点击或者长按,每个item没有背景颜色变化,不像listView那样变成灰色。解决办法很简单,给每个item布局里面设置一个selector背景就OK了,不清楚selector背景用法的读者自行百度下。 适配器类里面除了一个事件回调接口,还有继承的类要传一个自己的viewholder进去,其他的跟listView的适配器大同小异,就不做太多说明,