以前都是用的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的适配器大同小异,就不做太多说明,