列表的使用及搜索框、图片切换实现
列表的使用及搜索框、图片切换实现
一、整体结构框架
-
总体设计
![]()
-
实现思路

二、具体步骤
(PS:登录注册页面的具体实现参考博客之登录注册实现)
1、在实验一基础上创建Recycle活动,设置recycl.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=".Recycle">
<SearchView
android:id="@+id/search"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/shape_round"
android:backgroundTint="@color/pink3"
android:iconifiedByDefault="true"
android:queryHint="请输入搜索内容" >
</SearchView>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/babyAlbumlist"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
效果图如下:

2、准备数据
(可以使用 HashMap 构成的 List,也可以使用 JavaBean 构成的 List。List 的每一个元素对应 RecycleView 的每一行。)
(1)新建AlbumInfo.java,作为一个包装类(JavaBean)
package com.example.myapplication2;
public class AlbumInfo {
private String title;
private String info;
private int imageId;
public AlbumInfo(String title, String info, int imageId) {
this.title = title;
this.info = info;
this.imageId = imageId;
}
public String getTitle() {return title;}
public String getInfo() {return info;}
public int getImageId() {return imageId;}
}
(2)在Recycle.java中设置getData()方法,用于准备列表数据:
private List<AlbumInfo> mData = new ArrayList<>();//存放数据,把数据打包到mDada
private void getData ()
{
AlbumInfo albumInfo1 = new AlbumInfo("兔兔1", "兔兔吃西瓜,西瓜又大又甜真好吃。", R.drawable.t1);
mData.add(albumInfo1);
AlbumInfo albumInfo2 = new AlbumInfo("兔兔2", "两只兔兔一起玩,蹦蹦跳跳真可爱。", R.drawable.t22);
mData.add(albumInfo2);
AlbumInfo albumInfo3 = new AlbumInfo("兔兔3", "小白兔,爱吃胡萝卜,吃了一根又一根。", R.drawable.t3);
mData.add(albumInfo3);
AlbumInfo albumInfo4 = new AlbumInfo("兔兔4", "灰色的兔兔看着毛绒绒。", R.drawable.t4);
mData.add(albumInfo4);
AlbumInfo albumInfo5 = new AlbumInfo("兔兔5", "兔兔在地上,爬啊爬啊爬啊。", R.drawable.t5);
mData.add(albumInfo5);
AlbumInfo albumInfo6 = new AlbumInfo("兔兔6", "一只像小猪的兔兔。", R.drawable.t6);
mData.add(albumInfo6);
AlbumInfo albumInfo7 = new AlbumInfo("兔兔7", "兔兔吃西瓜,西瓜又大又甜真好吃。", R.drawable.t1);
mData.add(albumInfo7);
AlbumInfo albumInfo8 = new AlbumInfo("兔兔8", "两只兔兔一起玩,蹦蹦跳跳真可爱。", R.drawable.t22);
mData.add(albumInfo8);
AlbumInfo albumInfo9 = new AlbumInfo("兔兔9", "小白兔,爱吃胡萝卜,吃了一根又一根。", R.drawable.t3);
mData.add(albumInfo9);
AlbumInfo albumInfo10 = new AlbumInfo("兔兔10", "灰色的兔兔看着毛绒绒。", R.drawable.t4);
mData.add(albumInfo10);
AlbumInfo albumInfo11 = new AlbumInfo("兔兔11", "兔兔在地上,爬啊爬啊爬啊。", R.drawable.t5);
mData.add(albumInfo11);
AlbumInfo albumInfo12 = new AlbumInfo("兔兔12", "一只像小猪的兔兔。", R.drawable.t6);
mData.add(albumInfo12);
}
(3) 定义子项布局 cardview_btn.xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
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"
app:cardCornerRadius="5dp"
app:cardElevation="2dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:background="@drawable/shape3"
android:padding="5dp">
<ImageView
android:id="@+id/thumb2"
android:layout_width="0dp"
android:layout_height="110dp"
android:layout_margin="5dp"
android:layout_weight="1" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@drawable/shape3"
android:layout_weight="3">
<TextView
android:id="@+id/title2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="30dp"
android:textSize="16sp"
/>
<TextView
android:id="@+id/info2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="14sp"/>
<ImageButton
android:id="@+id/btn2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src = "@drawable/btn"
android:layout_gravity="end"
android:layout_marginEnd="10dp"
android:layout_marginBottom="5dp"
android:background="@android:color/transparent"/>
</LinearLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
效果图如下:

(4) 创建自定义适配器 AlbumAdapter,继承自 RecyclerView.Adapter。
① 新建 AlbumAdapter.Java,继承 RecyclerView.Adapter 。
②重写:onCreateViewHolder(),onBindViewHolder(), getItemCount()以及构造函数。
③ 自定义内部类 ViewHolder,继承 RecyclerView.ViewHolder,用于保 存 View(子项布局)实例。
public class AlbumAdapter extends RecyclerView.Adapter<AlbumAdapter.ViewHolder>
{
private int index[]=new int[10];//定义下标的位置计数器
private List<AlbumInfo> albumInfoList;
//java数组不可分开两部分定义
//为了方便,用数组先保存图片数据
private int[] picture =new int[]{R.drawable.btn,R.drawable.btn1,R.drawable.btn2,R.drawable.btn3,R.drawable.btn4,R.drawable.btn5,R.drawable.btn6};
//缓存子项布局中的子控件,内部类保存子项item布局实例,子项第一次出现时调用
static class ViewHolder extends RecyclerView.ViewHolder
{
ImageView thumb;
TextView title;
TextView info;
ImageButton btn;
public ViewHolder(@NonNull View itemView)
{
super(itemView);
this.thumb = (ImageView)itemView.findViewById(R.id.thumb2);
this.title = (TextView)itemView.findViewById(R.id.title2);
this.info = (TextView)itemView.findViewById(R.id.info2);
this.btn = (ImageButton) itemView.findViewById(R.id.btn2);;
}
}
//默认构造函数,接收数据
public AlbumAdapter(List<AlbumInfo> albumInfoList) {
this.albumInfoList = albumInfoList;
}
@Override
// 绑定数据到 ItemView ,显示
// 对子项数据赋值,在每个子项滚动到屏幕内时执行,positon表明要显示哪个子项
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
AlbumInfo album = albumInfoList.get(position);
holder.thumb.setImageResource(album.getImageId());
holder.title.setText(album.getTitle());
holder.info.setText(album.getInfo());
}
@Override
//获取一共有多少项子项
public int getItemCount() {
return albumInfoList.size();
}
//加载子项布局并实例化,然后用其创建一个ViewHolder的实例并返回该实例
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
{
//在 onCreateViewHolder()方法中增加单击事件处理:为每一个子项和按钮都增加单击事件处理。
//⚫当单击的是按钮时,利用子项中的标题(title)和内容(info)弹出对话框,对话框 title 在原标题基础上增加显示“详情”二字
//⚫ 当单击的是子项的其它地方时例如相册图片时,利用 Toast 提示单击的是哪种控件。
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.cardview_bt,parent,false);
final ViewHolder holder = new ViewHolder(view);
Log.e("AlbumAdapter","onCreateViewHolder");
holder.thumb.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
int position = holder.getAdapterPosition();
AlbumInfo data = albumInfoList.get(position);
Toast.makeText(v.getContext(),data.getTitle()+"image",Toast.LENGTH_SHORT).show();
}
});
//监听按钮
holder.btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v)
{
int position = holder.getAdapterPosition();
index[position]++;
//为了方便,用数组先保存图片数据,对应上面picture数组,实现点击按钮切换图片
holder.btn.setImageResource(picture[index[position]%7]);//六张图片,所以对六取模
showInfo(position,v.getContext());
}
});
return holder;
}
//设置弹出对话框
private void showInfo(int position, Context context)
{
AlbumInfo data = albumInfoList.get(position);
new AlertDialog.Builder(context)
.setTitle(data.getTitle())
.setMessage(data.getInfo())
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
}).show();
}
}
(5)在 RecycleActivity.Java的 onCreate()方法中,为 RecycleView 设置 Adapter。
①调用 setLayoutManager 方法设 置 RecycleView 的布局
②调用 setAdapter 将数据和自定义的 AlbumAdapter 进行适配。
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recycle);//调出
getData();//获取数据
searchView = findViewById(R.id.search);//绑定id
//在 onCreate()方法中,为 RecycleView 设置 Adapter。
// 首先调用 setLayoutManager 方法设置 RecycleView 的布局
// 最后调用 setAdapter 将数据和自定义的 AlbumAdapter 进行适配。
//视图
RecyclerView recycleView = (RecyclerView) findViewById(R.id.babyAlbumlist);
//设置线性布局
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
recycleView.setLayoutManager(layoutManager);
//准备Adapter,把mData传进去
AlbumAdapter adapter = new AlbumAdapter(mData);
//桥接
recycleView.setAdapter(adapter);
}
(6)搜索并更新列表显示,在Recycler.java中添加搜索框组件和事件监听
(完整的Recycler.java)
public class Recycle extends AppCompatActivity {
private List<AlbumInfo> mData = new ArrayList<>();//存放数据,把数据打包到mDada
private List<AlbumInfo> search_mData = new ArrayList<>();//搜索
private SearchView searchView;//搜索框组件
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recycle);//调出
getData();//获取数据
searchView = findViewById(R.id.search);//绑定id
//在 onCreate()方法中,为 RecycleView 设置 Adapter。
// 首先调用 setLayoutManager 方法设置 RecycleView 的布局
// 最后调用 setAdapter 将数据和自定义的 AlbumAdapter 进行适配。
//视图
RecyclerView recycleView = (RecyclerView) findViewById(R.id.babyAlbumlist);
//设置线性布局
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
recycleView.setLayoutManager(layoutManager);
//准备Adapter,把mData传进去
AlbumAdapter adapter = new AlbumAdapter(mData);
//桥接
recycleView.setAdapter(adapter);
//为搜索框设置监听事件
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String inputText) {
search_mData.clear();//每次搜索前清空原来的
find(inputText);//根据输入的字符去寻找列表
//创建一个新的adapter存放搜索到的列表
AlbumAdapter adapter = new AlbumAdapter(search_mData);
//显示出列表
recycleView.setAdapter(adapter);
return false;
}
});
}
//检查输入的字符
//方法中的两个参数分别是搜索框输入字符串和原列表项
private boolean check(String a,String b)
{
int sign[] = new int[1000];//标记
int l = a.length();
for (int i=0;i<l;++i)
{
//str.charAt(i)函数的意思获取字符串str中第i个字符
char x = a.charAt(i);
//标记位,标记是否匹配过
boolean flag = false;
for (int j=0;j<b.length();++j)
{
char y = b.charAt(j);
//如果没有标记过且完全匹配
if(sign[j]==0 && x==y)
{
//标记置1,退出循环
sign[j]=1;
flag = true;
break;
}
}
// 如果循环完成都没有匹配到,就证明匹配失败
if (!flag) return false;
}
return true;
}
//匹配搜索框输入的字符
private void find(String x)
{
for (int i=0;i<mData.size();++i)
{
if (check(x,mData.get(i).getTitle()))
{
//如果搜索到,就添加到search_mData中
search_mData.add(mData.get(i));
}
}
}
private void getData ()
{
AlbumInfo albumInfo1 = new AlbumInfo("兔兔1", "兔兔吃西瓜,西瓜又大又甜真好吃。", R.drawable.t1);
mData.add(albumInfo1);
AlbumInfo albumInfo2 = new AlbumInfo("兔兔2", "两只兔兔一起玩,蹦蹦跳跳真可爱。", R.drawable.t22);
mData.add(albumInfo2);
AlbumInfo albumInfo3 = new AlbumInfo("兔兔3", "小白兔,爱吃胡萝卜,吃了一根又一根。", R.drawable.t3);
mData.add(albumInfo3);
AlbumInfo albumInfo4 = new AlbumInfo("兔兔4", "灰色的兔兔看着毛绒绒。", R.drawable.t4);
mData.add(albumInfo4);
AlbumInfo albumInfo5 = new AlbumInfo("兔兔5", "兔兔在地上,爬啊爬啊爬啊。", R.drawable.t5);
mData.add(albumInfo5);
AlbumInfo albumInfo6 = new AlbumInfo("兔兔6", "一只像小猪的兔兔。", R.drawable.t6);
mData.add(albumInfo6);
AlbumInfo albumInfo7 = new AlbumInfo("兔兔7", "兔兔吃西瓜,西瓜又大又甜真好吃。", R.drawable.t1);
mData.add(albumInfo7);
AlbumInfo albumInfo8 = new AlbumInfo("兔兔8", "两只兔兔一起玩,蹦蹦跳跳真可爱。", R.drawable.t22);
mData.add(albumInfo8);
AlbumInfo albumInfo9 = new AlbumInfo("兔兔9", "小白兔,爱吃胡萝卜,吃了一根又一根。", R.drawable.t3);
mData.add(albumInfo9);
AlbumInfo albumInfo10 = new AlbumInfo("兔兔10", "灰色的兔兔看着毛绒绒。", R.drawable.t4);
mData.add(albumInfo10);
AlbumInfo albumInfo11 = new AlbumInfo("兔兔11", "兔兔在地上,爬啊爬啊爬啊。", R.drawable.t5);
mData.add(albumInfo11);
AlbumInfo albumInfo12 = new AlbumInfo("兔兔12", "一只像小猪的兔兔。", R.drawable.t6);
mData.add(albumInfo12);
}
}
三、 运行结果


浙公网安备 33010602011771号