RecyclerView
简介
- 可以说是一个增强版的ListView
- RecyclerView被定义在了support库中,因此使用时,需要在项目的build.gradle中添加相应的依赖库
- RecyclerView并不是内置在系统SDK中的,所以需要在xml里把完整的包路径写出来
实例(上下滑动显示实现)
- 新建一个FruitAdapter类,让该适配器继承RecyclerView.Adapter,并将泛型指定为FruitAdapter.ViewHolder,其中,ViewHolder为我们定义在该适配器中的一个内部类
- ViewHolder要继承自RecyclerView.ViewHolder,其构造函数中要传入一个View参数,该参数通常是RecyclerView子项最外层布局,因此我们可以通过findViewById获取布局中的控件
- 由于FruitAdapter继承自RecyclerView.Adapter,因此需重写onCreateViewHolder()/onBindViewHolder()/getItemCount()这三个方法
onCreateViewHolder():用于创建ViewHolder实例
onBindViewHolder():用于对RecyclerView子项数据进行赋值
getItemCount():用于告诉RecyclerView()一共有多少个子项
public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder> {
private List<Fruit> mFruitList;
static class ViewHolder extends RecyclerView.ViewHolder {
ImageView mImageView;
TextView mTextView;
public ViewHolder(View view) {
super(view);
mImageView = view.findViewById(R.id.image_fruit);
mTextView = view.findViewById(R.id.text_fruit_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 holder = new ViewHolder(view);
return holder;
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
Fruit fruit = mFruitList.get(position);
holder.mImageView.setImageResource(fruit.getImageId());
holder.mTextView.setText(fruit.getName());
}
@Override
public int getItemCount() {
return mFruitList.size();
}
}
- MainActivity
一个同样的initFruits()初始化水果数据
LayoutManager用于指定RecyclerView的布局方式,这里使用了LinearLayoutManager线性布局,可以实现和ListView类似的效果
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initFruits();
RecyclerView recyclerView = findViewById(R.id.recycler_view);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
FruitAdapter adapter = new FruitAdapter(fruitList);
recyclerView.setAdapter(adapter);
}
实例(横向滚动实现)
- 修改MainActivity
/**
* 横向滚动
* */
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initFruits();
RecyclerView recyclerView = findViewById(R.id.recycler_view);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
recyclerView.setLayoutManager(layoutManager);
FruitAdapterHorizontal adapter = new FruitAdapterHorizontal(fruitList);
recyclerView.setAdapter(adapter);
}
- xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
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="80dp"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/image_fruit_horizontal"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginTop="8dp"
android:foregroundGravity="center_horizontal|bottom"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/text_fruit_name_horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:foregroundGravity="center_horizontal|top"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/image_fruit_horizontal" />
</androidx.constraintlayout.widget.ConstraintLayout>
实例(瀑布流布局)
- MainActivity
为了让排版更加的好看,此处将textView里面的文字随机增多
StaggeredGridLayoutManager有俩参数(用于指定布局的列数 | 指定布局的排列方向)
/**
* 瀑布滚动
* */
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initFruits();
RecyclerView recyclerView = findViewById(R.id.recycler_view);
StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL);
recyclerView.setLayoutManager(layoutManager);
FruitAdapterWaterfall adapter = new FruitAdapterWaterfall(fruitList);
recyclerView.setAdapter(adapter);
}
private void initFruits(){
for (int i = 0; i <5; i++){
Fruit apple = new Fruit(getRandomLengthName("Apple"),R.drawable.apple);
fruitList.add(apple);
.......
}
}
private String getRandomLengthName(String name) {
Random random = new Random();
int length = random.nextInt(30) + 1;
StringBuilder builder = new StringBuilder();
for (int i = 0; i < length; i++) {
builder.append(name);
}
return builder.toString();
}
- xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp">
<ImageView
android:id="@+id/image_fruit_waterfall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:foregroundGravity="center_horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/text_fruit_name_waterfall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:foregroundGravity="left"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/image_fruit_waterfall" />
</androidx.constraintlayout.widget.ConstraintLayout>
点击事件
- RecyclerView没有提供类似于setOnItemClickListener()这样的监听器的方法,其所有的点击事件都有具体的view去注册
- 监听事件写在ViewHolder里
- fruitView变量用来保存子项最外层的布局和实例
- Adapter
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fruit_item_waterfall,parent,false);
final ViewHolder holder = new ViewHolder(view);
holder.fruitView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int position = holder.getAdapterPosition();
Fruit fruit = mFruitList.get(position);
Toast.makeText(view.getContext(),"you clicked view " + fruit.getName(),Toast.LENGTH_SHORT).show();
}
});
holder.mImageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int position = holder.getAdapterPosition();
Fruit fruit = mFruitList.get(position);
Toast.makeText(view.getContext(),"you clicked image " + fruit.getImageId(),Toast.LENGTH_SHORT).show();
}
});
return holder;
}
- 源码地址
DoSomeAndroidTest/RecyclerViewTest at main · qricis/DoSomeAndroidTest · GitHub