ListView
的进阶版,可以实现横向滚动
这次也新建一个项目:day05_RecyclerView
一、基本用法
1、导入依赖库
参考资料:Android布局学习(四)——百分比布局Percent?Layout
新增控件需要引入依赖库,在app/build.gradle
中添加如下内容:
implementation 'androidx.recyclerview:recyclerview:1.0.0'
2、主布局添加控件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" 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"
/>
</LinearLayout>
3、子布局
fruit_item.xml
,和上篇文章一样
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/fruite_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextView
android:id="@+id/fruite_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp"
/>
</LinearLayout>
4、类和适配器
类和上篇文章一样:
public class Fruit {
private String name;
private int imageId;
public Fruit(String name,int imageId){
this.name = name;
this.imageId = imageId;
}
public String getName(){
return name;
}
public int getImageId(){
return imageId;
}
}
新建类FruitAdapter
继承自RecyclerView.Adapter
,指定泛型为FruitAdapter.ViewHolder
:
public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder> {
private List<Fruit> mFruitList;
static class ViewHolder extends RecyclerView.ViewHolder{
ImageView fruitImage;
TextView fruitName;
public ViewHolder(View view){
super(view);
fruitImage = (ImageView) view.findViewById(R.id.fruite_image);
fruitName = (TextView) view.findViewById(R.id.fruite_name);
}
}
public FruitAdapter(List<Fruit> fruitList){
mFruitList = fruitList;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fruit_item, parent, false);
ViewHolder viewholder = new ViewHolder(view);
return viewholder;
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
Fruit fruit = mFruitList.get(position);
holder.fruitImage.setImageResource(fruit.getImageId());
holder.fruitName.setText(fruit.getName());
}
@Override
public int getItemCount() {
return mFruitList.size();
}
}
- 首先定义了内部类
ViewHolder
,继承自RecyclerView.ViewHolder
,其中传入了一个View
参数,这个参数继承通常是RecycleView
子项的最外层布局,通过它就能取到ImageView
和TextView
了 FruitAdapter
的构造函数把要传递的数据源传递进来,并赋给全局变量- 必须重写的三个方法:
onCreateViewHolder()
: 用来创建ViewHolder
实例,在这个方法中,将子布局传入创建的ViewHolder
实例,然后将其返回onBindViewHolder()
:对RecyclerView
子项数据赋值,会在子项布局滚动到屏幕时执行getItemCount()
:返回数据源的长度,用来判断子布局的个数
5、主活动修改
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);
initFruits();
FruitAdapter adapter = new FruitAdapter(fruitList);
RecyclerView recyclerView = findViewById(R.id.recycler_view);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
}
private void initFruits(){
for (int i = 0; i < 2; i++){
Fruit apple = new Fruit("苹果", R.drawable.apple);
fruitList.add(apple);
Fruit banana = new Fruit("香蕉", R.drawable.banana);
fruitList.add(banana);
Fruit orange = new Fruit("橙子", R.drawable.orange);
fruitList.add(orange);
Fruit watermelon = new Fruit("西瓜", R.drawable.watermelon);
fruitList.add(watermelon);
Fruit pear = new Fruit("梨", R.drawable.pear);
fruitList.add(pear);
Fruit grape = new Fruit("葡萄", R.drawable.grape);
fruitList.add(grape);
Fruit pineapple = new Fruit("菠萝", R.drawable.pineapple);
fruitList.add(pineapple);
Fruit strawberry = new Fruit("草莓", R.drawable.strawberry);
fruitList.add(strawberry);
Fruit cherry = new Fruit("樱桃", R.drawable.cherry);
fruitList.add(cherry);
Fruit mango = new Fruit("芒果", R.drawable.mango);
fruitList.add(mango);
}
}
}
先通过initFruit()
初始化水果数据,接着创建RecycleView
实例,然后创建了一个LinearLayoutManger
对象,并将它设置到RecycleView
中,表示使用线性布局,最后创建FruitAdapter
实例建立数据关联
6、运行
二、实现横向滚动
1、子布局
首先修改子布局,排列方向垂直,宽度100dp,图片和文字中心水平居中,上下边距10dp
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="100dp"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/fruite_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
/>
<TextView
android:id="@+id/fruite_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10dp"
/>
</LinearLayout>
2、主活动修改
只修改调用的LineatLayout
属性,修改为水平,加入一行代码即可
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initFruits();
FruitAdapter adapter = new FruitAdapter(fruitList);
RecyclerView recyclerView = findViewById(R.id.recycler_view);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
}
3、运行
支持横向滚动:
三、实现瀑布流布局
1、子布局
这次的宽度根据布局的列数自动适配,设置了边距5dp
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp">
<ImageView
android:id="@+id/fruite_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
/>
<TextView
android:id="@+id/fruite_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="ccenter_horizontal"
android:layout_marginTop="10dp"
/>
</LinearLayout>
2、主活动修改
使用StaggeredGridLayoutManger
布局,仅修改一行代码:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initFruits();
FruitAdapter adapter = new FruitAdapter(fruitList);
RecyclerView recyclerView = findViewById(R.id.recycler_view);
StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
}
StaggeredGridLayoutManger
的构造函数接收两个参数,第一个参数用来指定布局列数;第二个参数指定排列方向
3、运行
四、点击事件
RecyclerView
的点击实现起来比ListView
要复杂,所有的点击事件都由具体的View
去注册,这样每个子项的按钮都能注册不同的事件
1、修改适配器
重写两个方法viewHolder
和onCreateViewHolder
:
static class ViewHolder extends RecyclerView.ViewHolder{
View fruitView;
ImageView fruitImage;
TextView fruitName;
ViewHolder(View view){
super(view);
fruitView = view;
fruitImage = view.findViewById(R.id.fruite_image);
fruitName = view.findViewById(R.id.fruite_name);
}
}
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fruit_item, parent, false);
final ViewHolder holder = new ViewHolder(view);
holder.fruitName.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
int position = holder.getAdapterPosition();
Fruit fruit = mFruitList.get(position);
Toast.makeText(v.getContext(), "你点击了文字 "+fruit.getName(), Toast.LENGTH_SHORT).show();
}
});
holder.fruitImage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int position = holder.getAdapterPosition();
Fruit fruit = mFruitList.get(position);
Toast.makeText(v.getContext(), "你点击了图片 "+fruit.getName(), Toast.LENGTH_SHORT).show();
}
});
return holder;
}
2、运行
点击草莓的图片:
点击草莓的文字:
完成!
来源:CSDN
作者:有意识的呼吸
链接:https://blog.csdn.net/qq_41205771/article/details/103962950