本文将根据《第一行代码》的内容对RecyclerView控件的简单使用进行讲解。
简单的说,RecyclerView是ListView的升级版,ListView只能实现列表的纵向滚动,并且运行效率比较低下,而RecyclerView既能实现纵向滚动也能实现横向滚动,并且RecyclerView还优化了ListView中存在的各种问题。官方也是更推荐我们使用RecyclerView。
本文将使用RecyclerView实现和ListView一样的效果。
由于RecyclerView是属于新增的控件,为了让RecyclerView在所有Android版本上都能使用,android团队将RecyclerView定义在support-v7库当中,所以使用前需要对它进行导包。
在grade.build
中加入并点击Sync Now
更新同步
implementation 'androidx.recyclerview:recyclerview:1.1.0'
由于是实现和ListView相同的效果,我们也需要提前准备好一个Fruit类,一些水果图片以及一个列表展示布局fruit_item,这里就不再写了,上一篇关于ListView的使用的博客
里面有。
和ListView一样,RecyclerView也需要一个适配器
来传递数据,但RecyclerView的适配器和ListView的适配器还是有所差异的。
首先需要新建一个FruitAdapter
类,接着让这个类继承自RecyclerView.Adapter
,并将其泛型
指定为FruitAdapter.ViewHolder
。这里的ViewHolder
是FruitAdapter里面中定义的一个内部类,该内部类需要继承自RecyclerView.ViewHolder,我们在ViewHolder中定义了一个ViewHolder构造器并传入了一个view,这个view是通常就是RecyclerView子项最外层的布局,这样的话我们就可以通过findViewById()方法获取到ImageView以及TextView的实例了。
因为继承了RecyclerView.Adapter,所以需要重写
onBindViewHolder()、getItemCount()、onCreateViewHolder()三个方法。
onBindViewHolder()方法
是用于对RecyclerView子项的数据进行赋值绑定,这个方法会在每个子项滚动到屏幕前时都会被使用,这里通过position参数得到当前项的Fruit实例,然后将其数据再设置到ViewHolder的ImageView和TextView当中即可。
getItemCount()方法
是用来获取当前RecyclerView有多少个子项的个数的,将获取的数据返回。·
onCreateViewHolder()方法
是用于创建ViewHolder实例,并把加载出来的布局传入到该构造函数中去,最后将ViewHolder的实例返回。
方法的最上面还定义了一个mFruitList集合,里面有Fruit的数据,其实上面的方法都是在mListView里面的数据的基础上进行操作的。并且FruitAdapter也有一个构造器,该构造函数中将数据都赋值给mListView。
public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder> {
private List<Fruit> mFruitList;
static class ViewHolder extends RecyclerView.ViewHolder{
View fruitView;
ImageView fruitImage;
TextView fruitText;
public ViewHolder(@NonNull View view) {
super(view);
fruitView = view;
fruitImage = (view).findViewById(R.id.fruit_image_recyclerview);
fruitText = (view).findViewById(R.id.fruit_name_recyclerview);
}
}
public FruitAdapter(List<Fruit> fruitList){
mFruitList = fruitList;
}
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fruit_recyclerview,parent,false);
ViewHolder holder = new ViewHolder(view);
return holder;
}
public void onBindViewHolder(ViewHolder holder, int position) {//每个子项滚动到屏幕前都会调用此方法
Fruit fruit = mFruitList.get(position);//获取fruit实例
holder.fruitText.setText(fruit.getName());
holder.fruitImage.setImageResource(fruit.getImageId());
}
@Override
public int getItemCount() {
return mFruitList.size();
}
}
对MainActivity活动进行修改
首先,我们也是先定义了一个带有Fruit数据的fruitList列表。
其次,和ListView一样,我们也是选择手动添加数据到RecyclerView列表当中,但在布局方面,我们选择了LayoutManager进行对RecyclerView布局的设置。
然后,我们再获取RecyclerView。我们创建了一个LayoutManager对象,并将获取的recycleVie为它设置布局方式——设置为线性布局layoutManager。
最后就是FruitAdapter类的实例化,将实例化的adapter传入到recycleView当中去。这样就实现了RecyclerView与数据之间的关联。
public class MainActivity extends AppCompatActivity {
private List<Fruit> fruitList = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initFruit();//手动添加数据
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);//布局设置
FruitAdapter adapter = new FruitAdapter(fruitList);
recyclerView.setAdapter(adapter);
}
private void initFruit() {//用for循环添加多条数数据以便于RecyclerView能够占满整个屏幕。
for(int i = 0 ; i< 5 ;i++ ){
Fruit apple = new Fruit("apple",R.drawable.img);
fruitList.add(apple);
Fruit banana = new Fruit("banana",R.drawable.img_1);
fruitList.add(banana);
Fruit orange = new Fruit("orange",R.drawable.img_2);
fruitList.add(orange);
Fruit cherry = new Fruit("orange",R.drawable.img_3);
fruitList.add(cherry);
Fruit watermelon = new Fruit("matermelon",R.drawable.img_4);
fruitList.add(watermelon);
Fruit pear = new Fruit("pear",R.drawable.img_5);
fruitList.add(pear);
Fruit prineaplle = new Fruit("prineaplle",R.drawable.img_6);
fruitList.add(prineaplle);
Fruit strawberry = new Fruit("strawberry",R.drawable.img_7);
fruitList.add(strawberry);
}
}
}
前面说过,RecyclerView布局除了能够实现LsitView相同的效果,还可以做到ListView做不到的效果,例如横向布局,瀑布流布局和网格布局等。这里就不一一介绍的,其实本质上大同小异,只需要在布局上为RecyclerView设置布局上做一些微小的修改就行。
在RecyclerView上下滑动触底的时候,会有阴影,下面将是阴影的删除方法。
方法一:在xml布局中的RecyclerView里面添加这一行代码
android:overScrollMode="never"
方法二:在java/kotlin代码中加入
recyclerview.setOverScrollMode(RecyclerView.OVER_SCROLL_NEVER);
这样滑动触底时的阴影就消失了。
这里再顺带提一句,滚动控件删除它的滚动栏也只需要下面这样设置即可
android:scrollbars="none"
这两天把ListView和RecyclerView的布局复习了下,因为自己学了第一遍感觉自己对这些知识掌握的不够透彻,所以就写了这两篇博客来重新温习一下(尽管是看着书来写的哈哈哈 不过我还是觉得又让自己对这两种布局的理解以及记忆更深了些虽然还是没有完全记到 )。
鄙人是大一的小菜鸡,对这些东西的理解还远远不够,文章里面如果有错误的地方或者不足之处以及可以优化的方法欢迎各位前辈提出。