山崎屋の技術メモ

IT業界で働く中でテクノロジーを愛するSIerのシステムエンジニア👨‍💻 | AndroidとWebアプリの二刀流🧙‍♂️ | コードの裏にあるストーリーを綴るブログ執筆者✍️ | 日々進化するデジタル世界で学び続ける探究者🚀 | #TechLover #CodeArtisan、気になること、メモしておきたいことを書いていきます。

【Android】簡潔に RecyclerView を使う。

ListView を拡張した RecyclerView について簡単な使い方をメモしておきたいと思います。

完成形です。

f:id:yyama1556:20200725164812p:plain:w200

公式ページ:
RecyclerView で動的リストを作成する  |  Android デベロッパー  |  Android Developers

バージョン:
minSdkVersion 16
targetSdkVersion 29

RecyclerView とは

ListView に機能追加されたもの。

ScrollView を使わなくてもアイテムが増えたら自動でスクロールが行えます。

また、ドラッグ等によるアイテムの順番入れ替えを簡単に実装できます。

やること

やることを一覧にするとこのような感じです。

  • Empty Activity のプロジェクトを新規作成する
  • ライブラリの依存関係を追加( アプリ モジュールの build.gradle を修正 )
  • レイアウトファイルを修正し RecyclerView を追加( activity_main.xml を修正 )
  • アダプターを作成( MyAdapter クラスを作成 )
  • アクティビティを修正( MainActivity クラスを修正 )

まずは Empty Activity のプロジェクトを作成しておいてください。

当記事で説明は省略するので以下のサイトなどを参考に。
Android プロジェクトを作成する  |  Android デベロッパー  |  Android Developers
 

ライブラリの依存関係を追加

アプリ モジュールの build.gradle を修正します。

dependencies のところで RecyclerView のライブラリを追加します。

dependencies {
    ・・・(省略)・・・
    implementation 'androidx.recyclerview:recyclerview:1.1.0'
}

公式ページをチェックして最新バージョンを使うようにしましょう。
Recyclerview  |  Android デベロッパー  |  Android Developers

レイアウトファイルを修正し RecyclerView を追加

activity_main.xml を修正し、RecyclerView を使うように変更します。

修正前

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

TextView を消して RecyclerView を使うように変更しました。

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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=".MainActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
    
</androidx.constraintlayout.widget.ConstraintLayout>

 

アダプターを作成

RecyclerView.Adapter クラスを継承した MyAdapter クラスを作成 します。

アダプターはリストに表示するデータを保持し、要求に応じ適切なデータを View にセットしたり、View の値を返したりしてくれます。

「Adapter(アダプター)」は直訳すると「仲介役」。

ここではデータと View の間を取り持つ「仲介役」という意味になります。

package org.yyama.recyclerviewsample;

import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.recyclerview.widget.RecyclerView;

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
    private String[] myDataset;

    public static class MyViewHolder extends RecyclerView.ViewHolder {
        public TextView textView;
        public MyViewHolder(TextView v) {
            super(v);
            textView = v;
            textView.setTextSize(30);
        }
    }

    public MyAdapter(String[] myDataset) {
        this.myDataset = myDataset;
    }

    @Override
    public MyAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent,
                                                     int viewType) {
        TextView v = new TextView(parent.getContext());
        MyViewHolder vh = new MyViewHolder(v);
        return vh;
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        holder.textView.setText(myDataset[position]);
    }

    @Override
    public int getItemCount() {
        return myDataset.length;
    }
}

 
一部、部分ごとに記載されている内容を説明します。

    private String[] myDataset;

リストに表示するデータです。今回は String 配列ですが、任意のクラスのリストでも可能です(例えば List<MyClass>)。
 

    public static class MyViewHolder extends RecyclerView.ViewHolder {
        public TextView textView;
        public MyViewHolder(TextView v) {
            super(v);
            textView = v;
            textView.setTextSize(30);
        }
    }

このインナークラスのインスタンスが一行分の View を保持します。今回は TextView 一つだけですが、複数の View を持つこともできます。

MyViewHolder コンストラクタが呼ばれた時点ではデータはバインドされません。バインドは「onBindViewHolder」メソッドで行われます。

View にクリックイベントを付与したい場合は、コンストラクタ内で「setOnClickListener」を呼び出します。

「textView.setTextSize(30);」はなくても動きます。(文字が小さすぎたので入れました。)
 

    public MyAdapter(String[] myDataset) {
        this.myDataset = myDataset;
    }

MyAdapter クラスのコンストラクタです。リストに表示するデータを受け取ります。
 
 

    @Override
    public MyAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent,
                                                     int viewType) {
        TextView v = new TextView(parent.getContext());
        MyViewHolder vh = new MyViewHolder(v);
        return vh;
    }

1行分の ViewHolder を組み立てて返します。

ここではデータのバインドは行われません。
 

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        holder.textView.setText(myDataset[position]);
    }

ViewHolder にデータをバインドしています。

 

    @Override
    public int getItemCount() {
        return myDataset.length;
    }

表示するリストの件数(行数)を返します。
 

アクティビティを修正

プロジェクト作成時に自動生成された MainActivity クラスを修正します。
 
修正前

package org.yyama.recyclerviewsample;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

 
修正後

package org.yyama.recyclerviewsample;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.os.Bundle;

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
        RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(layoutManager);
        String[] myDataset = {"aaa","bbb","ccc"};
        RecyclerView.Adapter mAdapter = new MyAdapter(myDataset);
        recyclerView.setAdapter(mAdapter);
    }
}

onCreate で RecyclerView とアダプタの関連付けを行うコードを追加しています。
 

これで準備が整いました。

プロジェクトを実行すると冒頭の画像のような画面が表示されます。

RecyclerView を使うのまとめ

単純なテキストを表示する RecyclerView の動かし方をメモしました。
 
複数テキストやイメージなど、じゃっかん複雑な行を持つ RecyclerView の使い方も学習しておきたいですね。

2021年2月14日追記 書きました!
www.shookuro.com