RecyclerView是一个Android 5.0推出的,是support-v7包中的新组件,它被用来代替ListView和GridView,并且能够实现瀑布流的布局,是个更加高级和灵活的控件,并且提供了更加高效的回收复用机制。
有RecyclerView还要什么listView,还要什么GridView??
官方使用说明:https://developer.android.google.cn/guide/topics/ui/layout/recyclerview?hl=zh_cn
官方文档:https://developer.android.google.cn/reference/androidx/recyclerview/widget/RecyclerView?hl=zh_cn
添加RecyclerView依赖问题
使用该控件第一个问题就是引入RecyclerView依赖,这时候网上大部分资料提供的方式是:
在app/build.gradle中的dependencies中添加以下内容:
implementation 'com.android.support:recyclerview-v7:28.0.0'
这时候大部分人都会发现:
这个地方踩了很多坑,最好还是建议使用AndroidX包,人家提示最后一行也说了,建议迁移至AndroidX,按照提示:
然后依赖问题就彻底解决了(顺便一起加上cardview的依赖):
最后奉劝大家现在能用AndroidX的尽量不要用Support包
RecyclerView 使用第一步:结局布局问题
首先是activity_main.xml文件:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/my_text_view"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"
android:id="@+id/my_Rec"
tools:ignore="MissingConstraints"/>
</androidx.constraintlayout.widget.ConstraintLayout>
主要布局中添加RecyclerView控件,具体属性可以参考文档。
然后是RecyclerView的item内容的布局文件item.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_height="130dp">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:id="@+id/card_view"
android:layout_gravity="center"
app:cardCornerRadius="18dp"
app:cardElevation="12dp"
android:onClick="ItemClick"
android:layout_marginBottom="5dp"
android:layout_marginLeft="12dp"
android:layout_marginRight="12dp"
android:clickable="true"
android:foreground="?android:attr/selectableItemBackground"
android:layout_height="100dp">
</androidx.cardview.widget.CardView>
</LinearLayout>
item布局使用了一个线性布局,然后使用了一个cardview控件,设置了阴影,圆角等属性,更多属性参考文档
核心代码部分:
MainActivity.java中代码:
以下代码获取了RecyclerView对象,添加了适配器,逐行解释非常详细:
package com.example.recyclerviewdemo;
import android.app.ActionBar;
import android.content.res.ColorStateList;
import android.view.View;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import androidx.cardview.widget.CardView;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private MyAdapter myAdapter;
public String[] myDataset;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
}
public void init(){
/**
* 初始化RecyclerView
*/
//RecyclerView对象
recyclerView = (RecyclerView)findViewById(R.id.my_Rec);
//sethasFixedSize这个方法在知道item内容不会影响到RecyclerView的宽高的时候,设置为true可以不再重复计算宽高从而提升性能,
recyclerView.setHasFixedSize(true);
//创建布局管理器
LinearLayoutManager llm = new LinearLayoutManager(this);
recyclerView.setLayoutManager(llm);
//myDataset设置了item的条数,在这里我没有设置任何数据,创建的空条目
myDataset = new String[100];
//用自定义的构造方法创建一个Adapter对象
myAdapter = new MyAdapter(myDataset);
//给RecyclerView添加一个适配器
recyclerView.setAdapter(myAdapter);
}
}
MyAdapter.java适配器中的代码
这里主要内容就是实现RecyclerView.Adapter的三个方法onCreateViewHolder(),onBindViewHolder(),getItemCount()。在加一个内部类继承RecyclerView.ViewHolder。
不过之后设置点击事件还需要设置一个用于回调的点击事件监听接口
package com.example.recyclerviewdemo;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.cardview.widget.CardView;
import androidx.recyclerview.widget.RecyclerView;
import org.w3c.dom.Text;
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
private String[] mDataset;
private String TAG = "Adapter";
/**
* 构造方法,传入item需要的数据
* @param myDataset
*/
public MyAdapter(String[] myDataset){
Log.d(TAG, "MyAdapter: 成功创建");
mDataset = myDataset;
}
/**
* 该类继承ViewHolder
* 这个内部类是外部类泛型的类型(观察上面)
* 这个类对于下面的onCreateViewHolder方法和onBindViewHolder方法都很关键
*/
public static class MyViewHolder extends RecyclerView.ViewHolder{
public CardView cardView;
public MyViewHolder(@NonNull View view) {
super(view);
cardView = (CardView) view.findViewById(R.id.card_view);
}
}
/**
* 该方法返回一个MyViewHolder对象,这个对象是以上内部类的对象,也就是一个viewHolder
* @param parent
* @param viewType
* @return
*/
@NonNull
@Override
public MyAdapter.MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
Log.d(TAG, "onCreateViewHolder: CreateViewHolder");
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false);
return new MyViewHolder(view);
}
/**
* 这个方法用于每个子ViewHolder的数据的绑定
* @param holder 这个参数是以上内部类的类型,同样也是ViewHolder
* @param position item的position
*/
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, final int position) {
try {
//我对于每个item进行的操作就是设置成随机颜色,这里有点要讲下
//setCardbackgroundColor方法可以设置背景颜色,但是传入的是int类型,这就需要Color.parseColor()方法将rgb颜色参数转换为int
//Utils.RandomColor方法用于生成随机颜色,这是我自己写的工具类的方法
holder.cardView.setCardBackgroundColor(Color.parseColor(Utils.RandomColor()));
Log.d(TAG, "onBindViewHolder: Is onBindViewHolder");
}catch (Exception e){
e.printStackTrace();
}
}
/**
* 该方法返回数据的长度,也就是有多少个items
* @return
*/
@Override
public int getItemCount() {
Log.d(TAG, "getItemCount: Is GetItemCount");
return mDataset.length;
}
}
Utils.java 工具类的内容
package com.example.recyclerviewdemo;
import java.io.RandomAccessFile;
import java.util.Random;
public class Utils {
public static String RandomColor(){
/**
* 此方法提供随机RGB颜色字符串;
*/
String R,G,B;
Random random = new Random();
String r = Integer.toHexString(random.nextInt(256)).toUpperCase();
String g = Integer.toHexString(random.nextInt(256)).toUpperCase();
String b = Integer.toHexString(random.nextInt(256)).toUpperCase();
//加上判断可以解决部分随机颜色错误的异常
if (r.length()<2){
r = "0"+r;
}
if (g.length()<2){
g = "0"+g;
}
if (b.length()<2){
b = "0"+b;
}
String color = "#"+r+g+b;
System.out.println(color);
return "#"+r+g+b;
}
}
然后项目就基本能跑起来了,cardView和RecyclerView的结合使用基本就是这样,下期增加item点击事件,非常重要,建议收藏。