RecyclerView控件可以实现和ListView相同的效果,但是效果更好,能实现的效果更多,且性能更高
能够实现
1. 竖向(横向)单列条目滚动,类似ListView
2. 竖向(横向)多列滚动
3. 瀑布流
下面开始介绍实现RecyclerView的流程
在Adapter里实现数据与adapter绑定,adapter与要显示的xml条目样式绑定
下面是具体实现
1.首先添加RecyclerView控件
在activity_main.xml中添加RecyclerView控件,并设置id,注意是widget下的RecyclerView,如果不自动提示,请手动在build.gradle中的dependencies 中添加依赖
implementation 'androidx.recyclerview:recyclerview:1.1.0 '
并点击右上角的sync now
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#D3D3D3"/>
</LinearLayout>
2.设置RecyclerView里每一个条目的样式
在res/layout里创建item_list_view.xml 这里存放的是类似ListView的每一个条目的样式
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="90dp">
<ImageView
android:id="@+id/icon"
android:layout_width="150dp"
android:src="@mipmap/sample_0"
android:layout_height="150dp"
android:layout_margin="10dp"
android:scaleType="fitXY"/>
<TextView
android:layout_toRightOf="@id/icon"
android:layout_marginLeft="20dp"
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="我是标题"
android:layout_centerVertical="true"
android:textSize="30sp"/>
</RelativeLayout>
</RelativeLayout>
当样式都已经创建好之后,则进行数据的准备
3.准备数据
数据通常在网络中获取,为方便演示,我们使用本地数据
将图片放入mipmap中
因为每一条目都有一张图片和一段文字,我们创建实体对象来保存图片和文字
创建包entity,并在包里创建ItemBean类
package entity;
public class ItemBean {
public int icon;
public String title;
}
接下来在MainActivity中初始化数据
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private List<ItemBean> mdata;
public static int [] icons = {
R.mipmap.sample_0,
R.mipmap.sample_1,
R.mipmap.sample_2,
R.mipmap.sample_3,
R.mipmap.sample_4,
R.mipmap.sample_5,
R.mipmap.sample_6,
R.mipmap.sample_7,
}; //存放图片资源的id
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//找到控件
recyclerView = findViewById(R.id.recycler_view);
//准备数据
initData();
}
private void initData() {
//创建集合
mdata = new ArrayList<>();
//创建数据
for (int i = 0; i < Datas.icons.length; i++) {
//创建数据对象
ItemBean data = new ItemBean();
data.icon = MainActivity.icons[i];
data.title = "第" + i + "条目";
mdata.add(data);
}
}
}
4.创建Adapter
因为list的数据无法直接加载到RecyclerView中,需要使用Adapter作为一个中间人
即 List---->Adapter—>setAdapter---->显示
创建包adapter,在包里创建ListViewAdapter类并继承自 RecyclerView.Adapter<>
<>里的泛型我们创建一个,并按住alt+enter根据提示自动创建方法
可以看到创建了三个方法和一个内部类
public class ListViewAdapter extends RecyclerView.Adapter<ListViewAdapter.InnerHolder> {
@NonNull
@Override
public InnerHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return null;
}
@Override
public void onBindViewHolder(@NonNull InnerHolder holder, int position) {
}
@Override
public int getItemCount() {
return 0;
}
public class InnerHolder extends RecyclerView.ViewHolder {
public InnerHolder(@NonNull View itemView) {
super(itemView);
}
}
}
接下来对其进行改造
public class ListViewAdapter extends RecyclerView.Adapter<ListViewAdapter.InnerHolder> {
private List<ItemBean> mData;
//创建时就传入数据
public ListViewAdapter(List<ItemBean> mData) {
this.mData = mData;
}
@NonNull
@Override
public ListViewAdapter.InnerHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
//绑定每一条目样式的xml文件item_list_view
View view = View.inflate(parent.getContext(),R.layout.item_list_view,null);
return new InnerHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ListViewAdapter.InnerHolder holder, int position) {
//为绑定的视图样式设置数据
holder.setData(mData.get(position));
}
@Override
public int getItemCount() {
//获取条目数量
if(mData != null){
return mData.size();
}
return 0;
}
public class InnerHolder extends RecyclerView.ViewHolder {
private ImageView icon;
private TextView title;
public InnerHolder(@NonNull View itemView) {
super(itemView);
imageView = itemView.findViewById(R.id.icon);
title = itemView.findViewById(R.id.title);
}
//设置每一条目里的数据
public void setData(ItemBean itemBean) {
title.setText(itemBean.title);
imageView.setImageResource(itemBean.icon);
}
}
}
然后在MainActivity中创建适配器
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//找到控件
recyclerView = findViewById(R.id.recycler_view);
//准备数据
initData();
ListViewAdapter listViewAdapter = new ListViewAdapter(mdata);
recyclerView.setAdapter(listViewAdapter);
}
当适配器创建好之后,大部分工作就已经完成了,完成了数据到适配器,适配器到视图的转换
5.创建LayoutManager
LayoutManager可以完成布局的管理,可以设置顺序还是逆序,横向还是竖向
还是在MainActivity中
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//找到控件
recyclerView = findViewById(R.id.recycler_view);
//准备数据
initData();
ListViewAdapter listViewAdapter = new ListViewAdapter(mdata);
//第一个参数是上下文环境,写this就可以,第二个参数是选择横向还是竖向布局,可以通过ctrl点进LinearLayoutManager进行查看
//LinearLayoutManager.VERTICAL是竖向,可以选成LinearLayoutManager.HORIZONTAL横向
//第三个参数是设置是否逆序显示
LinearLayoutManager layoutManager = new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(listViewAdapter);
}
至此,一个简单的类似ListView的已经实现
发现没有边界,不好看,可以通过CarView进行优化
首先在build.gradle中导入依赖
implementation 'androidx.cardview:cardview:1.0.0-beta01'
然后修改item_list_view.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardUseCompatPadding="true"
android:background="#fff">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/icon"
android:layout_width="150dp"
android:layout_height="150dp"
android:src="@mipmap/sample_0"/>
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="我是文本"
android:layout_toRightOf="@+id/icon"
android:textSize="25dp"
android:layout_centerVertical="true"
android:layout_marginLeft="20dp"/>
</RelativeLayout>
</androidx.cardview.widget.CardView>
</RelativeLayout>
其中的app:cardUseCompatPadding="true"是让其设置自动的间距
而backgroud设置颜色则是设置了间隔的颜色
到此,通过RecyclerView实现ListView完成
多行或多列(含瀑布流)
如果想实现多条竖向显示,只需更改布局管理器即可
参数1为上下文环境,选this
参数2为要设置的行数或列数
参数3为设置横行还是竖向GridLayoutManager.VERTICAL竖向GridLayoutManager.HORIZATAL为横向
参数4为是否逆序显示
GridLayoutManager gridLayoutManager = new GridLayoutManager(this,2,GridLayoutManager.VERTICAL,false);
recyclerView.setLayoutManager(gridLayoutManager);
效果如图,如不满意请自行修改item_list_view.xml
如果要设置瀑布流布局,也是需要修改布局管理器
参数一为行数或是列数,参数二为横向或是竖向
StaggeredGridLayoutManager manager = new StaggeredGridLayoutManager(3,GridLayoutManager.VERTICAL);
recyclerView.setLayoutManager(manager);
如果需要逆序,请设置 manager.setReverseLayout(true);
运行APP,此时可能没有效果,那是因为图片设置了固定高度150dp
将item_list_view.xml里的ImageView的android:layout_height="wrap_content"即可
效果如图
如果想要图片填满空白,请在ImageView里设置android:scaleType=“fitXY”
本文参考自Bilibili UP主程序员拉大锯 他的视频讲解的更加全面,如需了解,请跳转至 【安卓常用控件】RecyclerView-程序员拉大锯
如果up主看我不爽,请联系我删除。。。。