Android RecyclerView基本使用

203 阅读3分钟

为什么要使用 RecyclerView

假如说要创建一个包含100个项的列表项,如果单独为他们创建100个View,显然非常的不好。建议使用 RecyclerView 代替,它只创建刚好充满屏幕的12个View,而不是100个。用户滑动屏幕切换视图时,上一个视图>会回收利用

如何使用

RecyclerView能够显示数据还离不开另外两个类的支持:ViewHolder子类和Adapter子类

ViewHolder:  
    ViewHolder只做一件事:容纳View视图
    
Adapter:
    创建必要的ViewHolder
    绑定ViewHolder至模型层数据

示例

1. 先编写一个activity_game.xml视图容纳 RecyclerView

<?xml version="1.0" encoding="utf-8"?>
<androidx.recyclerview.widget.RecyclerView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/recycler_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
</androidx.recyclerview.widget.RecyclerView>

2.activity_game.xml对应的gameActivity

public class gameActivity extends AppCompatActivity {
    private gameAdapter mAdapter; // 在下面有实现
    private RecyclerView mList;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_game);

        // 1.获取到 RecyclerView
        mList = findViewById(R.id.recycler_view); 
        /*  
            2.
                RecyclerView视图创建完成后,就立即转交给了LayoutManager对象 
                这里使用LinearLayoutManager类,它支持以竖直列表的形式展示列表项
        */
        mList.setLayoutManager(new LinearLayoutManager(gameActivity.this));
        
        mAdapter = new gameAdapter();
        mList.setAdapter(mAdapter);
    }
}

注意,没有LayoutManager的支持,不仅RecyclerView无法工作,还会导致应用崩溃。所 以,RecyclerView视图创建完成后,就立即转交给了LayoutManager对象。 RecyclerView类不会亲自摆放屏幕上的列表项。实际上,摆放的任务被委托给了 LayoutManager。除了在屏幕上摆放列表项,LayoutManager还负责定义屏幕滚动行为。因此, 没有LayoutManager,RecyclerView也就没法正常工作。 除了一些Android操作系统内置版实现,LayoutManager还有很多第三方库实现版本。我们 使用的是LinearLayoutManager类,它支持以竖直列表的形式展示列表项。我们在本书后续章 节中还会使用GridLayoutManager类,以网格形式展示列表项。 运行应用,应该还是看不到内容;现在看到的是一个RecyclerView空视图。要显示出crime 列表项,还需要完成Adapter和ViewHolder的实现。

3. 实现 ViewHolder
这里需要实现指定每个列表项的视图 game_list_item.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:orientation="vertical">

    <TextView
        android:id="@+id/gameTitle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="标题"/>

    <TextView
        android:id="@+id/gameContent"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="内容"/>

</LinearLayout>

实现 ViewHolder,绑定上面的game_list_item.xml视图

private class gameHolder extends RecyclerView.ViewHolder{
     // 在构造方法里先实例化game_list_item布局
     public gameHolder(LayoutInflater inflater, ViewGroup parent){
         super(inflater.inflate(R.layout.game_list_item, parent, false));
     }
}

4. 实现 Adapter

private class gameAdapter extends RecyclerView.Adapter{
        // 第一步指定 列表项个数
        @Override
        public int getItemCount() {
            return 20;
        }
		
        @NonNull
        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            LayoutInflater layoutInflater = LayoutInflater.from(gameActivity.this);
            // 使用上面的ViewHolder
            return new gameHolder(layoutInflater, parent);
        }

        @Override
        public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
		
        }
    }
}

完整代码

  1. activity_game.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.recyclerview.widget.RecyclerView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/recycler_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
</androidx.recyclerview.widget.RecyclerView>

3.game_list_item.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:orientation="vertical">

    <TextView
        android:id="@+id/gameTitle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="标题"/>

    <TextView
        android:id="@+id/gameContent"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="内容"/>

</LinearLayout>

4.gameActivity.java

public class gameActivity extends AppCompatActivity {
    private gameAdapter mAdapter;
    private RecyclerView mList;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_game);

        mList = findViewById(R.id.recycler_view);
        mList.setLayoutManager(new LinearLayoutManager(gameActivity.this));
        mAdapter = new gameAdapter();
        mList.setAdapter(mAdapter);
    }


    private class gameHolder extends RecyclerView.ViewHolder{
         private TextView mgameTitle;
         private TextView mgameContent;
         public gameHolder(LayoutInflater inflater, ViewGroup parent){
             super(inflater.inflate(R.layout.game_list_item, parent, false));

             // 可以对视图内的控件进行操作,如绑定按钮事件之类 ...
             // 请在此执行操作
         }
         public void bind(HashMap<String,String> hashMap){
             mgameTitle = findViewById(R.id.gameTitle);
             mgameContent = findViewById(R.id.gameContent);

         }
    }

    private class gameAdapter extends RecyclerView.Adapter{

        /* 第一步 调用Adapter的getItemCount()方法,RecyclerView询问数组列表中包含多少个对象 */
        @Override
        public int getItemCount() {
            return 20;
        }


        /* 第二步:
                调用Adapter的onCreateViewHolder(ViewGroup, int)方法创建ViewHolder及其要显示的视图
                RecyclerView需要新的ViewHolder来显示列表项时,会调用onCreateViewHolder方法
         */
        @NonNull
        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            LayoutInflater layoutInflater = LayoutInflater.from(gameActivity.this);
            return new gameHolder(layoutInflater, parent);
        }

        /*
            第三步:
            RecyclerView会传入ViewHolder及其位置,调用onBindViewHolder(ViewHolder,int)方法
            Adapter会找到目标位置的数据并将其绑定到ViewHolder的视图上。
            所谓绑定,就是使用模型数据填充视图。
        */
        @Override
        public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        
        }
    }
}