sweetyy、

导航

列表的使用及搜索框、图片切换实现

列表的使用及搜索框、图片切换实现

一、整体结构框架

  1. 总体设计

  2. 实现思路

二、具体步骤

(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);
    }
}

三、 运行结果

posted on 2021-11-14 14:14  sweetyy、  阅读(41)  评论(0)    收藏  举报