上一次我们讲解了ListView和GridView两种控件的用法,这一次我们讲解新的控件RecyclerView,这个控件可以说是前两个控件的集成版本,并且拥有更多的功能。下面我们进行详细的讲解。

RecyclerView能够灵活的实现大数据集的展现,视图的复用管理比ListView好,能够展示列表、网格、瀑布流等形式,且不同的ViewHolder能够实现item多元化的功能。

接下来我们主要讲解RecyclerView的几种用法,包括:①列表视图;②水平滚动;③网格视图;④瀑布流。

我们新建recyclerview包,里面新建的类如下图所示:

其中RecyclerViewActivity相当于一个总的类,里面的代码主要用于按钮的跳转,我们先展示与其对应的布局文件activity_recycler_view.xml的代码,如下:

<?xml version="1.0" encoding="utf-8"?>    

RecyclerViewActivity的代码如下:

package com.autumn.recyclerview;import android.content.Intent;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;import android.widget.Button;import com.autumn.R;public class RecyclerViewActivity extends AppCompatActivity {    @Override    protected void onCreate(final Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_recycler_view);        //用于列表视图按钮的页面跳转        Button btnLinear = findViewById(R.id.btn_linear);        btnLinear.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                Intent intent = new Intent(RecyclerViewActivity.this,LinearRecyclerViewActivity.class);                startActivity(intent);            }        });        //用于水平滚动按钮的页面跳转        Button btnHor = findViewById(R.id.btn_hor);        btnHor.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                Intent intent = new Intent(RecyclerViewActivity.this,HorRecyclerViewActivity.class);                startActivity(intent);            }        });        //用于网格视图按钮的页面跳转        Button btnGrid = findViewById(R.id.btn_grid);        btnGrid.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                Intent intent = new Intent(RecyclerViewActivity.this,GridRecyclerViewActivity.class);                startActivity(intent);            }        });        //用于瀑布流按钮的页面跳转        Button btnPu = findViewById(R.id.btn_pu);        btnPu.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                Intent intent = new Intent(RecyclerViewActivity.this,PuRecyclerViewActivity.class);                startActivity(intent);            }        });    }}

主界面截图如下:

接下来我们就要处理各个按钮的点击事件了,我们先处理列表视图按钮,我们新建LinearRecyclerViewActivity活动类,附带的activity_linear_recycler_view.xml文件如下:

<?xml version="1.0" encoding="utf-8"?>    

这里我们只引入一个RecyclerView的控件,具体样式我们会另外新建xml文件的。我们在layout下新建两个xml文件,分别是layout_linear_item.xml和layout_linear_item2.xml文件,代码分别如下所示:

<?xml version="1.0" encoding="utf-8"?>        
<?xml version="1.0" encoding="utf-8"?>        

经过对比我们可以发现,第一个仅仅包含文本,第二个则包含文本和图片,与之前类似,我们需要创建适配器LinearAdapter,代码如下:

package com.autumn.recyclerview;import android.content.Context;import android.support.annotation.NonNull;import android.support.v7.widget.RecyclerView;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.ImageView;import android.widget.TextView;import android.widget.Toast;import com.autumn.R;public class LinearAdapter extends RecyclerView.Adapter {    private Context context;    private OnItemClickListener listener;    public LinearAdapter(Context context,OnItemClickListener listener){        this.context = context;        this.listener = listener;    }    @NonNull    @Override    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {        //返回的是RecyclerView单项item的布局        if(i == 0)            return new LinearViewHolder(LayoutInflater.from(context).inflate(R.layout.layout_linear_item,viewGroup,false));        else            return new LinearViewHolder2(LayoutInflater.from(context).inflate(R.layout.layout_linear_item2,viewGroup,false));    }    //给viewHolder中控件进行赋值    @Override    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, final int position) {        //不同的viewHolder呈现出来的效果        if(getItemViewType(position) == 0){            ((LinearViewHolder)viewHolder).textView.setText("以梦为马,不负韶华");        }else{            ((LinearViewHolder2)viewHolder).imageView.setImageResource(R.drawable.beauty_girl);            ((LinearViewHolder2)viewHolder).textView.setText("面朝大海,春暖花开");        }        //设置点击监听事件        viewHolder.itemView.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                listener.onClick(position);                //Toast.makeText(context,"click..."+position,Toast.LENGTH_SHORT).show();            }        });    }    @Override    public int getItemCount() {        return 20;    }    public int getItemViewType(int pos) {        if(pos %2 == 0)            return 0;        else            return 1;    }    //自定义内部类LinearViewHolder    class LinearViewHolder extends RecyclerView.ViewHolder {        private TextView textView;        public LinearViewHolder(@NonNull View itemView) {            super(itemView);            textView = itemView.findViewById(R.id.tv_title);        }    }    class LinearViewHolder2 extends RecyclerView.ViewHolder {        private TextView textView;        private ImageView imageView;        public LinearViewHolder2(@NonNull View itemView) {            super(itemView);            textView = itemView.findViewById(R.id.tv_title);            imageView = itemView.findViewById(R.id.iv);        }    }    public interface OnItemClickListener {        void onClick(int pos);    }}

RecyclerView中没有item监听事件,所以我们需要自定义接口,然后我们也定义了两个内部类ViewHolder,分别用于加载两个布局文件,这里我们用item的下标进行判断加载了哪一种布局,pos为偶数,则加载第一种布局;pos为奇数,则加载第二种布局。其中onBindViewHolder方法主要用于给控件进行赋值,getItemCount方法用于返回Item的数量,这里我们设置为常量20。

LinearRecyclerViewActivity则主要用于设置布局样式,设置适配器以及添加分隔线。代码如下:

package com.autumn.recyclerview;import android.graphics.Rect;import android.support.annotation.NonNull;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.support.v7.widget.LinearLayoutManager;import android.support.v7.widget.RecyclerView;import android.view.View;import android.widget.Toast;import com.autumn.R;public class LinearRecyclerViewActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_linear_recycler_view);        RecyclerView recyclerView = findViewById(R.id.rv_main);        recyclerView.setLayoutManager(new LinearLayoutManager(LinearRecyclerViewActivity.this));        recyclerView.addItemDecoration(new MyDecoration());        //设置适配器Adapter,其中监听事件方法需要自己定义        recyclerView.setAdapter(new LinearAdapter(LinearRecyclerViewActivity.this, new LinearAdapter.OnItemClickListener() {            @Override            public void onClick(int pos) {                Toast.makeText(LinearRecyclerViewActivity.this,"click..."+pos,Toast.LENGTH_SHORT).show();            }        }));    }    //定义内部类MyDecoration,并设置分隔线    class MyDecoration extends RecyclerView.ItemDecoration {        @Override        public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {            super.getItemOffsets(outRect, view, parent, state);            outRect.set(0,0,0,getResources().getDimensionPixelOffset(R.dimen.dividerHeight));        }    }}

这里我们定义了内部类MyDecoration,主要用于item之间的分隔线,我们在values文件夹下新建dimens.xml文件,代码如下:

<?xml version="1.0" encoding="utf-8"?>    4dp

到这儿一步列表视图就好了,运行截图如下:

我们添加了点击事件,默认下标从0开始。

接下来到了水平滚动了,我们新建HorRecyclerViewActivity活动类,附带的activity_hor_recycler_view.xml布局文件代码如下:

<?xml version="1.0" encoding="utf-8"?>        

这里我们和上面一样,只加入了一个RecyclerView的控件。具体的样式布局在layout_hor_item.xml文件中,代码如下:

<?xml version="1.0" encoding="utf-8"?>        

然后操作和上面差不多,我们新建适配器HorAdapter,代码如下:

package com.autumn.recyclerview;import android.content.Context;import android.support.annotation.NonNull;import android.support.v7.widget.RecyclerView;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.TextView;import android.widget.Toast;import com.autumn.R;public class HorAdapter extends RecyclerView.Adapter {    private Context context;    private OnItemClickListener clickListener;    public HorAdapter(Context context,OnItemClickListener listener){        this.context = context;        this.clickListener = listener;    }    @NonNull    @Override    public HorAdapter.LinearViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {        //返回的是RecyclerView单项item的布局        return new LinearViewHolder(LayoutInflater.from(context).inflate(R.layout.layout_hor_item,viewGroup,false));    }    //给viewHolder中控件textView进行赋值    @Override    public void onBindViewHolder(@NonNull HorAdapter.LinearViewHolder viewHolder, final int position) {        viewHolder.textView.setText("lsq");        viewHolder.itemView.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                clickListener.OnClick(position);                //Toast.makeText(context,"click..."+position,Toast.LENGTH_SHORT).show();            }        });    }    @Override    public int getItemCount() {        return 20;    }    //自定义内部类LinearViewHolder    class LinearViewHolder extends RecyclerView.ViewHolder {        private TextView textView;        public LinearViewHolder(@NonNull View itemView) {            super(itemView);            textView = itemView.findViewById(R.id.tv_title);        }    }    public interface OnItemClickListener {        void OnClick(int pos);    }}

具体解释就不多说了,和前面一个差不多。接下来就是完善HorReyclerViewActivity的代码了,如下所示:

package com.autumn.recyclerview;import android.graphics.Rect;import android.support.annotation.NonNull;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.support.v7.widget.LinearLayoutManager;import android.support.v7.widget.RecyclerView;import android.view.View;import android.widget.Toast;import com.autumn.R;public class HorRecyclerViewActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_hor_recycler_view);        RecyclerView RvHor = findViewById(R.id.rv_hor);        LinearLayoutManager manager = new LinearLayoutManager(HorRecyclerViewActivity.this);        manager.setOrientation(LinearLayoutManager.HORIZONTAL);        RvHor.setLayoutManager(manager);        RvHor.addItemDecoration(new MyDecoration());        RvHor.setAdapter(new HorAdapter(HorRecyclerViewActivity.this, new HorAdapter.OnItemClickListener() {            @Override            public void OnClick(int pos) {                Toast.makeText(HorRecyclerViewActivity.this,"click..."+pos,Toast.LENGTH_SHORT).show();            }        }));    }    //内部装饰类(用于加上分隔线)    class MyDecoration extends RecyclerView.ItemDecoration {        @Override        public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {            super.getItemOffsets(outRect, view, parent, state);            outRect.set(0,0,getResources().getDimensionPixelOffset(R.dimen.dividerHeight),0);        }    }}

这里我们添加了水平的分割线,并添加了点击事件,运行截图如下所示:

接下来就到了网格视图了,同理,新建GridRecyclerViewActivity,同时新建activity_grid_recycler_view.xml,代码如下:

<?xml version="1.0" encoding="utf-8"?>        

具体的布局文件为layout_grid_recycler_view.xml,代码如下:

<?xml version="1.0" encoding="utf-8"?>        

我们仅仅添加了一个TextView控件,用于简单的测试,接下来我们新建GridAdapter适配器,代码如下:

package com.autumn.recyclerview;import android.content.Context;import android.support.annotation.NonNull;import android.support.v7.widget.RecyclerView;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.TextView;import com.autumn.R;public class GridAdapter extends RecyclerView.Adapter {    private Context context;    private OnItemClickListener clickListener;    public GridAdapter(Context context, OnItemClickListener listener){        this.context = context;        this.clickListener = listener;    }    @NonNull    @Override    public GridAdapter.LinearViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {        //返回的是GridRecyclerView单项item的布局        return new LinearViewHolder(LayoutInflater.from(context).inflate(R.layout.layout_grid_recycler_item,viewGroup,false));    }    //给viewHolder中控件textView进行赋值    @Override    public void onBindViewHolder(@NonNull GridAdapter.LinearViewHolder viewHolder, final int position) {        viewHolder.textView.setText("Hello");        viewHolder.itemView.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                clickListener.OnClick(position);                //Toast.makeText(context,"click..."+position,Toast.LENGTH_SHORT).show();            }        });    }    @Override    public int getItemCount() {        return 60;    }    //自定义内部类LinearViewHolder    class LinearViewHolder extends RecyclerView.ViewHolder {        private TextView textView;        public LinearViewHolder(@NonNull View itemView) {            super(itemView);            textView = itemView.findViewById(R.id.tv_title);        }    }    public interface OnItemClickListener {        void OnClick(int pos);    }}

适配器写好之后,接下来就到了GridRecyclerViewActivty了,代码如下:

package com.autumn.recyclerview;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.support.v7.widget.GridLayoutManager;import android.support.v7.widget.RecyclerView;import android.widget.Toast;import com.autumn.R;public class GridRecyclerViewActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_grid_recycler_view);        RecyclerView RvGrid = findViewById(R.id.rv_grid);        //一行展示3个Item        RvGrid.setLayoutManager(new GridLayoutManager(GridRecyclerViewActivity.this,3));        RvGrid.setAdapter(new GridAdapter(GridRecyclerViewActivity.this, new GridAdapter.OnItemClickListener() {            @Override            public void OnClick(int pos) {                Toast.makeText(GridRecyclerViewActivity.this,"click..."+pos,Toast.LENGTH_SHORT).show();            }        }));    }}

运行的效果如下图所示:

同样的,我们在GridLayoutManager中设置一行显示3个Item,并添加了监听事件。

接下来我们介绍最后一个版块,即瀑布流的布局。

我们新建PuRecyclerViewActivity,然后在layout下新建activity_pu_recycler_view.xml文件,代码如下:

<?xml version="1.0" encoding="utf-8"?>        

具体的布局样式我们重新定义,新建layout_staggered_grid_recycler_view.xml文件,代码如下:

<?xml version="1.0" encoding="utf-8"?>        

然后是创建适配器StaggeredGridAdapter,具体代码如下:

package com.autumn.recyclerview;import android.content.Context;import android.support.annotation.NonNull;import android.support.v7.widget.RecyclerView;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.ImageView;import com.autumn.R;public class StaggeredGridAdapter extends RecyclerView.Adapter {    private Context context;    private OnItemClickListener clickListener;    public StaggeredGridAdapter(Context context, OnItemClickListener listener){        this.context = context;        this.clickListener = listener;    }    @NonNull    @Override    public StaggeredGridAdapter.LinearViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {        //返回的是GridRecyclerView单项item的布局        return new LinearViewHolder(LayoutInflater.from(context).inflate(R.layout.layout_staggered_grid_recycler_item,viewGroup,false));    }    //给viewHolder中控件textView进行赋值    @Override    public void onBindViewHolder(@NonNull StaggeredGridAdapter.LinearViewHolder viewHolder, final int position) {        if(position % 2 != 0){            viewHolder.imageView.setImageResource(R.drawable.image1);        }else {            viewHolder.imageView.setImageResource(R.drawable.image2);        }        viewHolder.itemView.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                clickListener.OnClick(position);                //Toast.makeText(context,"click..."+position,Toast.LENGTH_SHORT).show();            }        });    }    @Override    public int getItemCount() {        return 30;    }    //自定义内部类LinearViewHolder    class LinearViewHolder extends RecyclerView.ViewHolder {        private ImageView imageView;        public LinearViewHolder(@NonNull View itemView) {            super(itemView);            imageView = itemView.findViewById(R.id.iv);        }    }    public interface OnItemClickListener {        void OnClick(int pos);    }}

这里的和第一个LinearAdapter差不多,position为奇数加载图片1,为偶数加载图片2,我们这里挑了两张图片的长宽相差很大,以此显示出交错感,然后PuRecyclerViewActivity的代码如下:

package com.autumn.recyclerview;import android.graphics.Rect;import android.support.annotation.NonNull;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.support.v7.widget.RecyclerView;import android.support.v7.widget.StaggeredGridLayoutManager;import android.view.View;import android.widget.Toast;import com.autumn.R;public class PuRecyclerViewActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_pu_recycler_view);        RecyclerView RvPu = findViewById(R.id.rv_pu);        //垂直有两列        RvPu.setLayoutManager(new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL));        RvPu.addItemDecoration(new MyDecoration());        RvPu.setAdapter(new StaggeredGridAdapter(PuRecyclerViewActivity.this, new StaggeredGridAdapter.OnItemClickListener() {            @Override            public void OnClick(int pos) {                Toast.makeText(PuRecyclerViewActivity.this,"click:"+pos,Toast.LENGTH_SHORT).show();            }        }));    }    //内部类,用于创建分割线    class MyDecoration extends RecyclerView.ItemDecoration {        @Override        public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {            super.getItemOffsets(outRect, view, parent, state);            int gap = getResources().getDimensionPixelSize(R.dimen.dividerHeight);            outRect.set(gap,gap,gap,gap);        }    }}

运行截图如下所示:

好了,有关RecyclerView的讲解就到这里了,全部的代码(包括之前的)我已经上传到GitHub上,链接为https://github.com/229394/AndroidBasic,欢迎大家Star!

更多相关文章

  1. 没有一行代码,「2020 新冠肺炎记忆」这个项目却登上了 GitHub 中
  2. RN 与 Android(安卓)代码交互
  3. 一步步实现 仿制Android(安卓)LOL多玩盒子(四) 自定义AlertDialo
  4. Cocos2d-x +Android(安卓)+ Windows 7环境配置
  5. android 内存泄露之jni local reference table overflow (max=51
  6. 说说Android(安卓)两种为自定义组件添加属性的使用方法和区别
  7. Android(安卓)4.4 Graphic系统详解(4)HWUI概述
  8. android 模拟器和PC用sockets通讯
  9. Android应用开发笔记(12):Android应用的自动升级、更新模块的实现

随机推荐

  1. Android全屏与非全屏问题
  2. Android Studio 第六十五期 - Android业
  3. Android开发之Android的原生库
  4. Android(安卓)L为什么不用Android(安卓)5
  5. Android 人脸识别
  6. Android(安卓)ApiDemos示例解析(141):Vie
  7. 告别Dagger2模板代码:DaggerAndroid原理解
  8. Android 应用安装设置
  9. Android培训HandlerThread的使用及源码解
  10. Android(安卓)Handler机制