Android(安卓)中 RecyclerView 的基本使用
Android 中 RecyclerView 的基本使用
-
- 1. 垂直布局
-
- 1.1 基本使用
- 1.2 点击事件
- 2. 水平布局
- 3. 网格布局
- 4. 瀑布流
- 5. 样式
RecyclerView 能够灵活实现大数据集的展示, 视图的复用管理比 ListView 更好, 能够显示列表、网格、瀑布流等形式, 且不同的 ViewHolder 能够实现 item 多元化的功能.
但是使用起来会稍微麻烦一点, 并且没有类似 ListView 的 onItemClickListene r监听事件, 需要开发者自己实现.
新版本不用导入下面依赖的
implementation 'com.android.support:cardview-v7:26.1.0'implementation 'com.android.support:recyclerview-v7:26.1.0'
1. 垂直布局
1.1 基本使用
LinearRecyclerViewActivity
package com.example.hello.recyclerView;import androidx.annotation.NonNull;import androidx.appcompat.app.AppCompatActivity;import androidx.core.content.ContextCompat;import androidx.recyclerview.widget.LinearLayoutManager;import androidx.recyclerview.widget.RecyclerView;import android.content.Context;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.Rect;import android.os.Bundle;import android.view.View;import com.example.hello.R;public class LinearRecyclerViewActivity extends AppCompatActivity { // 声明 private RecyclerView rv1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_linear_recycler_view); // 获取 rv1 = findViewById(R.id.rv_1); rv1.setLayoutManager(new LinearLayoutManager(LinearRecyclerViewActivity.this)); // 添加分割线 rv1.addItemDecoration(new Decoration()); rv1.setAdapter(new LinearViewAdapterActivity(LinearRecyclerViewActivity.this)); } /** * 设置分割线 */ class Decoration extends RecyclerView.ItemDecoration { @Override public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) { super.getItemOffsets(outRect, view, parent, state); outRect.set(0, 0, 0, getResources().getDimensionPixelOffset(R.dimen.dividerHeight)); } }}
outRect.set(0, 0, 0, getResources().getDimensionPixelOffset(R.dimen.dividerHeight));
这句中的 dividerHeight 来自文件 dimens.xml
<?xml version="1.0" encoding="utf-8"?><resources> <dimen name="dividerHeight">2dpdimen>resources>
activity_linear_recycler_view
<?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="match_parent" tools:context=".recyclerView.LinearRecyclerViewActivity"> <androidx.recyclerview.widget.RecyclerView android:id="@+id/rv_1" android:layout_width="match_parent" android:layout_height="wrap_content" />RelativeLayout>
LinearViewAdapterActivity
package com.example.hello.recyclerView;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.TextView;import androidx.annotation.NonNull;import androidx.recyclerview.widget.RecyclerView;import com.example.hello.R;public class LinearViewAdapterActivity extends RecyclerView.Adapter<LinearViewAdapterActivity.LinearViewHolder> { private Context context; public LinearViewAdapterActivity(Context context) { this.context = context; } @NonNull @Override public LinearViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { return new LinearViewHolder(LayoutInflater.from(context).inflate(R.layout.layout_linear_item, parent, false)); } @Override public void onBindViewHolder(@NonNull LinearViewHolder holder, int position) { CharSequence charSequence = "Hello World!"; holder.ltv.setText(charSequence); } @Override public int getItemCount() { return 30; } /** * 封装控件 */ static class LinearViewHolder extends RecyclerView.ViewHolder { private TextView ltv; public LinearViewHolder(@NonNull View itemView) { super(itemView); ltv = itemView.findViewById(R.id.linear_tv); } }}
layout_linear_item
<?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" android:background="@color/yellow_blew" android:clickable="true" android:orientation="vertical" android:padding="15dp"> <TextView android:id="@+id/linear_tv" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/bg_btn2" android:gravity="center" android:padding="5dp" android:text="@string/app_name" android:textColor="@color/black" android:textSize="20sp" />LinearLayout>
1.2 点击事件
在这个文件内设置不方便, 想在 LinearRecyclerViewActivity 文件内设置.
LinearViewAdapterActivity 文件改变如下
package com.example.hello.recyclerView;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.TextView;import androidx.annotation.NonNull;import androidx.recyclerview.widget.RecyclerView;import com.example.hello.R;public class LinearViewAdapterActivity extends RecyclerView.Adapter<LinearViewAdapterActivity.LinearViewHolder> { private Context context; private OnItemClickListener listener; public LinearViewAdapterActivity(Context context, OnItemClickListener listener) { this.context = context; this.listener = listener; } @NonNull @Override public LinearViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { return new LinearViewHolder(LayoutInflater.from(context).inflate(R.layout.layout_linear_item, parent, false)); } @Override public void onBindViewHolder(@NonNull LinearViewHolder holder, int position) { CharSequence charSequence = "Hello World!"; holder.ltv.setText(charSequence); // 点击事件 holder.ltv.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { listener.onClick(position); } }); } @Override public int getItemCount() { return 30; } /** * 封装控件 */ static class LinearViewHolder extends RecyclerView.ViewHolder { private TextView ltv; public LinearViewHolder(@NonNull View itemView) { super(itemView); ltv = itemView.findViewById(R.id.linear_tv); } } /** * 设置监听接口 */ public interface OnItemClickListener { void onClick(int position); }}
LinearRecyclerViewActivity 文件改变如下
package com.example.hello.recyclerView;import androidx.annotation.NonNull;import androidx.appcompat.app.AppCompatActivity;import androidx.core.content.ContextCompat;import androidx.recyclerview.widget.LinearLayoutManager;import androidx.recyclerview.widget.RecyclerView;import android.content.Context;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.Rect;import android.os.Bundle;import android.view.View;import android.widget.Toast;import com.example.hello.R;public class LinearRecyclerViewActivity extends AppCompatActivity { // 声明 private RecyclerView rv1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_linear_recycler_view); // 获取 rv1 = findViewById(R.id.rv_1); rv1.setLayoutManager(new LinearLayoutManager(LinearRecyclerViewActivity.this)); // 添加分割线 rv1.addItemDecoration(new Decoration()); rv1.setAdapter(new LinearViewAdapterActivity(LinearRecyclerViewActivity.this, new LinearViewAdapterActivity.OnItemClickListener() { @Override public void onClick(int position) { Toast.makeText(LinearRecyclerViewActivity.this, position + " 进行了点击", Toast.LENGTH_SHORT).show(); } })); } /** * 设置分割线 */ class Decoration extends RecyclerView.ItemDecoration { @Override public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) { super.getItemOffsets(outRect, view, parent, state); outRect.set(0, 0, 0, getResources().getDimensionPixelOffset(R.dimen.dividerHeight)); } }}
2. 水平布局
和垂直的没有什么区别
- 设置成水平布局
- 分割线改成右侧
- item 和其他文件相应改动
package com.example.hello.recyclerView;import androidx.annotation.NonNull;import androidx.appcompat.app.AppCompatActivity;import androidx.recyclerview.widget.LinearLayoutManager;import androidx.recyclerview.widget.RecyclerView;import android.graphics.Rect;import android.os.Bundle;import android.view.View;import android.widget.Toast;import com.example.hello.R;public class HorRecyclerViewActivity extends AppCompatActivity { // 声明 private RecyclerView rv2; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_hor_recycler_view); // 获取 rv2 = findViewById(R.id.rv_2); LinearLayoutManager linearLayoutManager = new LinearLayoutManager(HorRecyclerViewActivity.this); // 设置水平方向 linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL); rv2.setLayoutManager(linearLayoutManager); // 添加分割线 rv2.addItemDecoration(new Decoration()); rv2.setAdapter(new HorViewAdapterActivity(HorRecyclerViewActivity.this, new HorViewAdapterActivity.OnItemClickListener() { @Override public void onClick(int position) { Toast.makeText(HorRecyclerViewActivity.this, position + " 进行了点击", Toast.LENGTH_SHORT).show(); } })); } /** * 设置分割线 */ class Decoration extends RecyclerView.ItemDecoration { @Override public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) { super.getItemOffsets(outRect, view, parent, state); outRect.set(0, 0, getResources().getDimensionPixelOffset(R.dimen.dividerHeight), 0); } }}
3. 网格布局
和垂直, 水平的也没有什么区别
- 设置成网格布局
- 分割线改成全部
- item 和其他文件相应改动
package com.example.hello.recyclerView;import androidx.annotation.NonNull;import androidx.appcompat.app.AppCompatActivity;import androidx.recyclerview.widget.GridLayoutManager;import androidx.recyclerview.widget.RecyclerView;import android.graphics.Rect;import android.os.Bundle;import android.view.View;import android.widget.Toast;import com.example.hello.R;public class GridRecyclerViewActivity extends AppCompatActivity { // 声明 private RecyclerView rv3; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_grid_recycler_view); // 获取 rv3 = findViewById(R.id.rv_3); // 每行显示三个 rv3.setLayoutManager(new GridLayoutManager(GridRecyclerViewActivity.this, 3)); // 添加分割线 rv3.addItemDecoration(new Decoration()); rv3.setAdapter(new GridViewAdapterActivity(GridRecyclerViewActivity.this, new GridViewAdapterActivity.OnItemClickListener() { @Override public void onClick(int position) { Toast.makeText(GridRecyclerViewActivity.this, position + " 进行了点击", Toast.LENGTH_SHORT).show(); } })); } /** * 设置分割线 */ class Decoration extends RecyclerView.ItemDecoration { @Override public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) { super.getItemOffsets(outRect, view, parent, state); int height = getResources().getDimensionPixelOffset(R.dimen.dividerHeight); //noinspection SuspiciousNameCombination outRect.set(height, height, height, height); } }}
4. 瀑布流
和上面的操作也没有什么区别, 为了看出不同, item 中改成了长度不同的照片.
- 设置成瀑布流形式
- item 改成照片
- item 和其他文件相应改动
PuRecyclerViewActivity
package com.example.hello.recyclerView;import androidx.annotation.NonNull;import androidx.appcompat.app.AppCompatActivity;import androidx.recyclerview.widget.RecyclerView;import androidx.recyclerview.widget.StaggeredGridLayoutManager;import android.graphics.Rect;import android.os.Bundle;import android.view.View;import android.widget.Toast;import com.example.hello.R;public class PuRecyclerViewActivity extends AppCompatActivity { // 声明 private RecyclerView rv4; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_pu_recycler_view); // 得到内容 rv4 = findViewById(R.id.rv_4); // StaggeredGridLayoutManager.VERTICAL 代表有多少列, StaggeredGridLayoutManager.HORIZONTAL 代表有多少行 rv4.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL)); // 添加分割线 rv4.addItemDecoration(new Decoration()); rv4.setAdapter(new StaggeredGridViewAdapterActivity(PuRecyclerViewActivity.this, new StaggeredGridViewAdapterActivity.OnItemClickListener() { @Override public void onClick(int position) { Toast.makeText(PuRecyclerViewActivity.this, position + " 进行了点击", Toast.LENGTH_SHORT).show(); } })); } /** * 设置分割线 */ class Decoration extends RecyclerView.ItemDecoration { @Override public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) { super.getItemOffsets(outRect, view, parent, state); int height = getResources().getDimensionPixelOffset(R.dimen.dividerHeight); //noinspection SuspiciousNameCombination outRect.set(height, height, height, height); } }}
StaggeredGridViewAdapterActivity
package com.example.hello.recyclerView;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.ImageView;import android.widget.TextView;import androidx.annotation.NonNull;import androidx.recyclerview.widget.RecyclerView;import com.example.hello.R;public class StaggeredGridViewAdapterActivity extends RecyclerView.Adapter<StaggeredGridViewAdapterActivity.LinearViewHolder> { private Context context; private OnItemClickListener listener; public StaggeredGridViewAdapterActivity(Context context, OnItemClickListener listener) { this.context = context; this.listener = listener; } @NonNull @Override public LinearViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { return new LinearViewHolder(LayoutInflater.from(context).inflate(R.layout.layout_staggered_grid_item, parent, false)); } @Override public void onBindViewHolder(@NonNull LinearViewHolder holder, int position) { // 两列显示不同的内容 int imageResource = position % 2 != 0 ? R.mipmap.beautiful : R.mipmap.long_up; holder.iv.setImageResource(imageResource); // 点击事件 holder.iv.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { listener.onClick(position); } }); } @Override public int getItemCount() { return 30; } /** * 封装控件 */ static class LinearViewHolder extends RecyclerView.ViewHolder { private ImageView iv; public LinearViewHolder(@NonNull View itemView) { super(itemView); iv = itemView.findViewById(R.id.staggered_grid_iv); } } /** * 设置监听接口 */ public interface OnItemClickListener { void onClick(int position); }}
layout_staggered_grid_item
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@color/yellow_blew" android:clickable="true" android:orientation="horizontal" android:padding="15dp"> <ImageView android:id="@+id/staggered_grid_iv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:contentDescription="@string/beautiful" android:scaleType="centerCrop" android:src="@mipmap/beautiful" />LinearLayout>
5. 样式
不同的 ViewHolder.
XRecyclerView: addHeadView, addFootView, 下拉刷新, 上拉加载.
以水平布局布局为例子. 将其改成一个是汉字一个是照片.
新建 layout_linear_item2.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" android:background="@color/yellow_blew" android:clickable="true" android:orientation="vertical" android:padding="15dp"> <TextView android:id="@+id/linear_tv" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/bg_btn3" android:gravity="center" android:padding="5dp" android:text="@string/app_name" android:textColor="@color/black" android:textSize="20sp" /> <ImageView android:id="@+id/linear_iv" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginTop="10dp" android:contentDescription="@string/app_name" android:scaleType="fitCenter" android:src="@mipmap/ic_launcher_round" />LinearLayout>
LinearViewAdapterActivity
package com.example.hello.recyclerView;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.ImageView;import android.widget.TextView;import androidx.annotation.NonNull;import androidx.recyclerview.widget.RecyclerView;import com.example.hello.R;public class LinearViewAdapterActivity extends RecyclerView.Adapter<RecyclerView.ViewHolder> { private Context context; private OnItemClickListener listener; public LinearViewAdapterActivity(Context context, OnItemClickListener listener) { this.context = context; this.listener = listener; } @NonNull @Override public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { if (viewType == 0) { return new LinearViewHolder(LayoutInflater.from(context).inflate(R.layout.layout_linear_item, parent, false)); } else { return new LinearViewHolder2(LayoutInflater.from(context).inflate(R.layout.layout_linear_item2, parent, false)); } } @Override public int getItemViewType(int position) { return position % 2 == 0 ? 0 : 1; } @Override public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { if (getItemViewType(position) == 0) { CharSequence charSequence = "Hello World!"; ((LinearViewHolder) holder).ltv.setText(charSequence); // 点击事件 ((LinearViewHolder) holder).ltv.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { listener.onClick(position); } }); } else { CharSequence charSequence = "Nice to meet you!"; ((LinearViewHolder2) holder).ltv.setText(charSequence); // 点击事件 ((LinearViewHolder2) holder).ltv.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { listener.onClick(position); } }); ((LinearViewHolder2) holder).liv.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { listener.onClick(position); } }); } } @Override public int getItemCount() { return 30; } /** * 封装控件 */ static class LinearViewHolder extends RecyclerView.ViewHolder { private TextView ltv; public LinearViewHolder(@NonNull View itemView) { super(itemView); ltv = itemView.findViewById(R.id.linear_tv); } } /** * 封装控件 */ static class LinearViewHolder2 extends RecyclerView.ViewHolder { private TextView ltv; private ImageView liv; public LinearViewHolder2(@NonNull View itemView) { super(itemView); ltv = itemView.findViewById(R.id.linear_tv); liv = itemView.findViewById(R.id.linear_iv); } } /** * 设置监听接口 */ public interface OnItemClickListener { void onClick(int position); }}
更多相关文章
- 运行时权限解析以及申请的实现(可完美解决java.lang.SecurityExce
- Android(安卓)的res/values/colors自定义颜色列表和注释表及布局
- Android之Adapter用法总结
- android:giavity和layout_gravity的区别
- Android(安卓)文件上传支持拍照录用录视频
- [置顶] TextView属性大全
- Unity导出Android工程生成apk安装包流程
- Android(安卓)在TextView中加入多个点击文本区域
- NPM 和webpack 的基础使用