欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

安卓 recycler view

程序员文章站 2022-05-04 19:41:51
...

recycler view

recycler view通常用于展示一组数据。比如音乐播放列表里,这个页面需要展示一组歌曲的信息。每一行展示一首歌,里面可能有一张图片放专辑海报,有歌曲名,有歌手姓名。由于歌曲很多,手机屏幕装不下,就需要使用户能够向下滑动。

通常对于固定长度的信息(比如注册页面用户需要填写很多信息)设计允许滑动的用户界面,我们可以用scrollview. 但是如果信息内容过多且变动频繁,那我们可以选择RecyclerView来展示。

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:fillViewport="false"> 
</ScrollView>

scrollview 解决固定屏幕大小不够展示所有信息的问题,而RecyclerView除了具备这个功能,还可以对需展示的数据内容的变更动态处理,它是有几个组件协作来完成的数据展示。首先,RecyclerView使用一个适配器,从数据源中提取内容,并将其输入到列表中。然后我们需要知道,它通过一个布局管理器(比如LinearLayoutManager或GridLayoutManager)来填充自身试图。这个布局管理器会负责把数据源中的对象们放置在RecyclerView中,并决定RecyclerView中哪些对象的view被显示,哪些不可见。这个布局管理器与你RecyclerView放置于哪个布局文件没有关系(底层布局文件可能是任意的layout),它只管理RecyclerView内部的信息展示。

数据源中集合里的每一个对象,需要被一个ViewHolder对象表示,我们可以把它理解为一个容器。我们需要定义一个类,来继承RecyclerView.ViewHolder. 每一个ViewHolder对象展示数据源集合里的一个view。view holder对象被适配器管理。我们需要编写一个适配器的类,继承RecyclerView.Adapter. 适配器会为数据源中每一个对象,生成一个容器view holder,我们可以想象成一个小卡片。针对列表里的歌曲(数据源list),适配器会给每首歌(数据源中的单个对象object)一张小卡片(view holder)在上面画上一个专辑海报,写出歌曲名和歌手名,然后把小卡片放在可滑动查看的容器内(RecyclerView)。适配器有一个功能(也就是方法)叫onBindViewHolder(RecyclerViewAdapter.ViewHolder viewHolder, int position),会根据卡片(viewHolder)的在排列中的位置来决定是否展示该卡片信息。除夕之外,RecyclerView还有notifyItemChanged,notifyItemInserted等方法对展示内容进行修改。

使用方法

使用RecyclerView,首先我们要添加对应的依赖,然后在布局文件中放置一个RecyclerView对象。

标题添加依赖

implementation 'androidx.recyclerview:recyclerview:1.1.0'

底层布局文件

放置recycler view的xml文件。

<?xml version="1.0" encoding="utf-8"?>
<!-- A RecyclerView with some commonly used attributes -->
<android.support.v7.widget.RecyclerView
    android:id="@+id/my_recycler_view"
    android:scrollbars="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

view

recycler view 里通常是把很多对象的信息以某种共同的形式展现出来,所以我们使用的时候新创建一个view的xml文件,用于定义每个对象相关信息的展现格式。以下是一个简单的例子,每个学生对象有姓名和年龄两个属性,用以下view(这里我的文件命名为card.xml)展示出学生的信息。除了学生的两个属性,最后还有个叉号用来删除其对应的对象。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 		
	android:orientation="horizontal"
	android:layout_width="match_parent" 
	android:layout_height="wrap_content"> 
	<TextView
		android:id="@+id/name" 
		android:layout_width="0dp" 
		android:layout_height="wrap_content" 
		android:layout_weight="1" /> 
	<TextView
		android:id="@+id/singer" 
		android:layout_width="0dp" 
		android:layout_height="wrap_content" 
		android:layout_weight="1" /> 
	<ImageView
		android:id="@+id/iv_item_delete" 
		android:layout_width="wrap_content"
		android:layout_height="wrap_content"
		android:layout_weight="1"
		android:padding="8dp" 
		android:src="@android:drawable/ic_menu_close_clear_cancel" 
		android:tint="@android:color/holo_red_dark" />
</LinearLayout>

自定义适配器

为每一个数据对象创建一个view(根据我们刚刚定义的view模板card.xml)

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
    private List<Song> mDataset;

    // Provide a reference to the views for each data item
    // you provide access to all the views for a data item in a view holder
    public static class MyViewHolder extends RecyclerView.ViewHolder {
        public TextView nameTextView; 
        public TextView singerTextView; 
        public ImageView imageView;
        public MyViewHolder(TextView v) {
            super(v);
            nameTextView = v.findViewById(R.id.name);
            singerTextView = v.findViewById(R.id.singer);
            imageView = v.findViewById(R.id.my_recycler_view);
        }
    }

    // Provide a suitable constructor (depends on the kind of dataset)
    public MyAdapter(List<Song> myDataset) {
        mDataset = myDataset;
    }

    // Create new views (invoked by the layout manager)
    @Override
    public MyAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent,
                                                   int viewType) {
        // create a new view
        Context context = parent.getContext();
        LayoutInflater inflater = LayoutInflater.from(context);
        // Inflate the view from an XML layout file
        View songView = inflater.inflate(R.layout.card, parent, false); // construct the viewholder with the new view
        ViewHolder viewHolder = new ViewHolder(songView);
        return viewHolder;
    }

    // Replace the contents of a view (invoked by the layout manager)
    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
    	final Song song = mDataset.get(position);
    	
        TextView tvName = holder.nameTextView;
        TextView tvSinger = holder.singerTextView;
        ImageView ivDelete = holder.imageView;

        tvName.setText(song.getName());
        tvSinger.setText(song.getSinger());
        ivDelete.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                songs.remove(song);
                notifyDataSetChanged();
            }
        });


    }

    // Return the size of your dataset (invoked by the layout manager)
    @Override
    public int getItemCount() {
        return mDataset.length;
    }
}

activity

public class MyActivity extends Activity {

    private RecyclerView recyclerView;
    private RecyclerView.Adapter mAdapter;
    private RecyclerView.LayoutManager layoutManager;
    private List<Song> myDataset;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.my_activity);
        recyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);

        // use this setting to improve performance if you know that changes
        // in content do not change the layout size of the RecyclerView
        recyclerView.setHasFixedSize(true);

        // use a linear layout manager
        layoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(layoutManager);

		// 这里大家自定义下数据集合

        // specify an adapter (see also next example)
        mAdapter = new MyAdapter(myDataset);
        recyclerView.setAdapter(mAdapter);
    }
    // ...
}

(详情请参考安卓官网开发手册)