首先在说关于RecyclerView的用法之前,我们先来解决一个问题
什么是RecyclerView?
从Android 5.0开始,谷歌公司推出了一个用于大量数据展示的新控件RecylerView,可以用来代替传统的ListView,更加强大和灵活。有兴趣的同学可以看看官方的RecyclerView Demo。
接下来我们来说说关于其用法:首先在app下的build.gradle
添加依赖库
implementation "androidx.recyclerview:recyclerview:1.1.0"
添加依赖后,记得点击“Sync Now”进行同步。
主界面activity_first.xml的编写
<?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"
android:orientation="vertical"
tools:context=".FirstActivity"
android:background="@color/colorBackground"
>
//标题栏
<TextView
android:layout_width="match_parent"
android:layout_height="40dp"
android:background="@color/colorToolBarBackground"
android:gravity="center"
android:text="@string/first_title"
android:textColor="@color/colorTitleTextColor"
android:textSize="18sp"
android:layout_marginBottom="7dp"
/>
//Button add,点击后列表增加一项
<Button
android:id="@+id/btn_add"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:background="@color/colorAddButton"
/>
//Button remove,点击后列表移除最后一项
<Button
android:id="@+id/btn_remove"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:background="@color/colorRemoveButton"/>
//Button clean,点击后列表清空
<Button
android:id="@+id/btn_clean"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="7dp"
android:gravity="center"
android:background="@color/colorCleanButton" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
>
//RecyclerView列表
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_fixed_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
/>
//当列表为空时显示的text
<TextView
android:id="@+id/tv_empty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textColor="@color/colorBlack"
android:textSize="15sp"
android:gravity="bottom"
/>
</FrameLayout>
</LinearLayout>
列表子项的界面activity_first_list_item.xml编写
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="@color/colorTitleTextColor"
>
//位于左侧的图片
<ImageView
android:id="@+id/iv_pic"
android:layout_width="70dp"
android:layout_height="70dp"
android:scaleType="fitXY"
android:layout_marginTop="15dp"
android:layout_marginStart="15dp"
/>
//位于右侧的文字
<TextView
android:id="@+id/tv_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="15dp"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:textColor="@color/colorBlack"/>
//下划线
<View
android:layout_width="match_parent"
android:layout_height="2dp"
android:layout_alignParentBottom="true"
android:background="@color/colorBackground"/>
</RelativeLayout>
此时,我们已经确定好放在Recycler View中的数据,所以编写一个包含这些数据类型的对象Model
创建FirstModel对象
/**
* model对象
*/
public class FirstModel {
//图片信息,此处使用的是项目本地的图片,故图片信息为int类型,
//若是使用网络加载的图片,则此处用String类型用于放图片网络地址
private int pic;
//文本信息
private String text;
public int getPic() {
return pic;
}
public void setPic(int pic) {
this.pic = pic;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public FirstModel() {
}
}
在配置好以上以后,我们就可以开始
新建RecyclerView适配器FirstAdapter.java
使其继承于RecyclerView.Adapter,把泛型指定为FirstAdapter.FirstViewHolder
**
* FirstActivity列表适配器
*/
public class FirstAdapter extends RecyclerView.Adapter<FirstAdapter.FirstViewHolder> {
private List<FirstModel> mFirstList;
private LayoutInflater mLayoutInflater;
private Context mContext;
//初始化FirstAdapter方法
public FirstAdapter(Context context) {
this.mContext = context;
mLayoutInflater = LayoutInflater.from(mContext);
}
//关于填入数据list的get/set方法
public List<FirstModel> getmFirstList() {
return mFirstList;
}
public void setmFirstList(List<FirstModel> mFirstList) {
this.mFirstList = mFirstList;
}
//将子项的界面activity_first_list_item与FristAdapter绑定
@NonNull
@Override
public FirstViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new FirstViewHolder(mLayoutInflater.inflate(R.layout.activity_first_list_item, parent, false));
}
//将接受到数据在界面上显示出来
@Override
public void onBindViewHolder(@NonNull FirstViewHolder holder, int position) {
FirstModel firstModel = mFirstList.get(position);
holder.mIvPic.setImageResource(firstModel.getPic());
holder.mTvText.setText(firstModel.getText());
}
//获取列表中有多少个待展示的子项
@Override
public int getItemCount() {
return mFirstList == null ? 0 : mFirstList.size();
}
//继承与RecyclerView.ViewHolder,初始化子项中的视图控件
class FirstViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.iv_pic)
ImageView mIvPic;
@BindView(R.id.tv_text)
TextView mTvText;
public FirstViewHolder(@NonNull View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
}
(tip:此处的控件绑定的方法ButterKnife,需提前添加了关于ButterKnife的依赖。)
implementation "com.jakewharton:butterknife:10.1.0"
annotationProcessor "com.jakewharton:butterknife-compiler:10.1.0"
在这些部分都写好之后,就开始咱们的下一步
修改FirstActivity.java
public class FirstActivity extends AppCompatActivity {
@BindView(R.id.btn_add)
Button mBtnAdd;
@BindView(R.id.btn_clean)
Button mBtnClean;
@BindView(R.id.btn_remove)
Button mBtnRemove;
@BindView(R.id.tv_empty)
TextView mTvEmpty;
@BindView(R.id.rv_fixed_list)
RecyclerView mRvFixedList;
//RecyclerView列表适配器
private FirstAdapter mFirstAdapter;
//填入列表的数据
private List<FirstModel> mFirstList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_first);
ButterKnife.bind(this);
initList();
initView();
initData();
}
//初始化视图
private void initView() {
mBtnAdd.setText(getResources().getString(R.string.btn_add));
mBtnAdd.setTextColor(getColor(R.color.colorTitleTextColor));
mBtnClean.setText(getResources().getString(R.string.btn_clean));
mBtnClean.setTextColor(getColor(R.color.colorTitleTextColor));
mBtnRemove.setText(getResources().getString(R.string.btn_remove));
mBtnRemove.setTextColor(getColor(R.color.colorTitleTextColor));
mTvEmpty.setText(getString(R.string.text_empty));
}
//初始化数据
private void initData() {
mRvFixedList.setLayoutManager(new LinearLayoutManager(this));
mFirstAdapter = new FirstAdapter(this);
mRvFixedList.setAdapter(mFirstAdapter);
//若填入列表的数据不为空,则显示列表,隐藏提示文案
if (mFirstList != null && mFirstList.size() > 0) {
mTvEmpty.setVisibility(View.GONE);
mRvFixedList.setVisibility(View.VISIBLE);
mFirstAdapter.setmFirstList(mFirstList);
mFirstAdapter.notifyDataSetChanged();
}
}
//初始化列表数据
private void initList() {
mFirstList = new ArrayList<>();
for (int i = 1; i < 6; i++) {
String text = getString(R.string.text_fixed) + i;
FirstModel firstModel = new FirstModel();
firstModel.setPic(R.drawable.android_item);
firstModel.setText(text);
mFirstList.add(firstModel);
}
}
//增加子项按钮
@OnClick(R.id.btn_add)
public void addList() {
if (mFirstList != null && mFirstList.size() > 0) {
} else {
mFirstList = new ArrayList<>();
mTvEmpty.setVisibility(View.GONE);
mRvFixedList.setVisibility(View.VISIBLE);
}
FirstModel first = new FirstModel();
first.setText(getString(R.string.text_add));
first.setPic(R.drawable.android_item);
mFirstList.add(first);
mFirstAdapter.setmFirstList(mFirstList);
mFirstAdapter.notifyDataSetChanged();
}
//移除最后一项按钮
@OnClick(R.id.btn_remove)
public void removeLastItem() {
if (mFirstList != null && mFirstList.size() > 0) {
int size = mFirstList.size();
mFirstList.remove(size - 1);
mFirstAdapter.setmFirstList(mFirstList);
mFirstAdapter.notifyDataSetChanged();
if (size - 1 == 0) {
mTvEmpty.setVisibility(View.VISIBLE);
mRvFixedList.setVisibility(View.GONE);
}
}else {
Toast.makeText(this, R.string.toast_no_item_to_remove, Toast.LENGTH_SHORT).show();
}
}
//清空按钮
@OnClick(R.id.btn_clean)
public void cleanAllItem() {
if (mFirstList != null && mFirstList.size() > 0) {
mFirstList.clear();
mFirstAdapter.setmFirstList(mFirstList);
mFirstAdapter.notifyDataSetChanged();
mTvEmpty.setVisibility(View.VISIBLE);
mRvFixedList.setVisibility(View.GONE);
}else {
Toast.makeText(this, R.string.toast_no_item_to_remove, Toast.LENGTH_SHORT).show();
}
}
}
接下来让我们来运行一下项目,之后
^这是在程序运行完成后出现的样子
^在点击按钮ADD之后,列表添加一项
^点击按钮REMOVE后,移除列表的最后一项
^在点击按钮CLEAN后,列表被清除,列表下的提示文案显示出来
^在列表被清空时,再点击按钮,弹出toast
^当列表被清空时,点击按钮ADD,建一个新的子项
当然,Recycler View不仅仅可以实现像ListView那样的列表,还可以实现
网格布局(GridLayoutManager)
修改activity_first_list_item.xml中的子项布局
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="150dp"
android:layout_height="200dp"
android:background="@color/colorTitleTextColor"
>
<ImageView
android:id="@+id/iv_pic"
android:layout_width="70dp"
android:layout_height="70dp"
android:scaleType="fitXY"
android:layout_centerInParent="true"
/>
<TextView
android:id="@+id/tv_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="15dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="15dp"
android:textColor="@color/colorBlack"/>
<View
android:layout_width="match_parent"
android:layout_height="2dp"
android:layout_alignParentBottom="true"
android:background="@color/colorBackground"/>
</RelativeLayout>
修改FirstActivity.java中initData()方法里的
(默认为水平方向排列)
// mRvFixedList.setLayoutManager(new LinearLayoutManager(this));
mRvFixedList.setLayoutManager(new GridLayoutManager(this,3));
其效果为:
亦或者可以设置成为
瀑布流布局(StaggeredGridLayoutManager)
//mRvFixedList.setLayoutManager(new GridLayoutManager(this,3));
mRvFixedList.setLayoutManager(new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL)
传入的第一个参数为排列的列数,第二个参数为排列的方向。
如下图所示:
关于RecyclerView的点击事件
在这里提供两种我用过的方法,虽说是两种方法,但其本质是差不多的:
第一种 在FirstAdapter中设置
@Override
public void onBindViewHolder(@NonNull FirstViewHolder holder, int position) {
FirstModel firstModel = mFirstList.get(position);
holder.mIvPic.setImageResource(firstModel.getPic());
holder.mTvText.setText(firstModel.getText());
//设置点击事件
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(v.getContext(), "you click the " + position, Toast.LENGTH_SHORT).show();
}
});
}
第二种 在FirstAdapter中设置好接口,然后在FirstActivity中调用接口实现
/**
* FirstActivity列表适配器
*/
public class FirstAdapter extends RecyclerView.Adapter<FirstAdapter.FirstViewHolder> {
private List<FirstModel> mFirstList;
private LayoutInflater mLayoutInflater;
private Context mContext;
public FirstClick mClick;
//定义好接口
public interface FirstClick {
void firstClick(int position);
}
public FirstAdapter(Context context) {
this.mContext = context;
mLayoutInflater = LayoutInflater.from(mContext);
}
public FirstClick getFirstClick() { return mClick; }
public void setFirstClick(FirstClick click) {
this.mClick = click;
}
public List<FirstModel> getmFirstList() {
return mFirstList;
}
public void setmFirstList(List<FirstModel> mFirstList) {
this.mFirstList = mFirstList;
}
@NonNull
@Override
public FirstViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new FirstViewHolder(mLayoutInflater.inflate(R.layout.activity_first_list_item, parent, false));
}
@Override
public void onBindViewHolder(@NonNull FirstViewHolder holder, int position) {
FirstModel firstModel = mFirstList.get(position);
holder.mIvPic.setImageResource(firstModel.getPic());
holder.mTvText.setText(firstModel.getText());
//设置其在点击item时调用其方法
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mClick.firstClick(position);
}
});
}
@Override
public int getItemCount() {
return mFirstList == null ? 0 : mFirstList.size();
}
class FirstViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.iv_pic)
ImageView mIvPic;
@BindView(R.id.tv_text)
TextView mTvText;
public FirstViewHolder(@NonNull View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
}
在FirstActivity.java中的initData()方法里:
private void initData() {
mRvFixedList.setLayoutManager(new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL));
mFirstAdapter = new FirstAdapter(this);
mRvFixedList.setAdapter(mFirstAdapter);
if (mFirstList != null && mFirstList.size() > 0) {
mTvEmpty.setVisibility(View.GONE);
mRvFixedList.setVisibility(View.VISIBLE);
mFirstAdapter.setmFirstList(mFirstList);
mFirstAdapter.notifyDataSetChanged();
}
//具体实现FirstAdapter接口里的方法
mFirstAdapter.setFirstClick(new FirstAdapter.FirstClick() {
@Override
public void firstClick(int position) {
Toast.makeText(FirstActivity.this, "you click the " + position, Toast.LENGTH_SHORT).show();
}
});
}
以上就是本人对于RecyclerView的一些见解,如有不对,还请大佬指出!