[Android]RecyclerViewの実装


Androidアプリを開発する際には、リスト形式のフォーマットがよく使われます.
現在ではKakaoTalkのみを見ていても,リスト形式で友人ディレクトリ,会話ディレクトリなどが表現されている.
今回は、これらのリストを表示するAndroid要素に優れたRecyclerViewの実装方法について説明します.

RecyclerView実施手順


RecyclerViewの実装は、次の順序で行われます.
  • レイアウト構成
  • アダプタ実装
  • ビューフレーム実施
  • で作成したアダプタをRecyclerView
  • に割り当てます.

    レイアウトの設定


    activity_main.xml

    <?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"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
       <androidx.recyclerview.widget.RecyclerView
    	android:id="@+id/my_Rv"
    	android:layout_width="match_parent"
    	android:layout_height="match_parent"/>
    
    </androidx.constraintlayout.widget.ConstraintLayout>
    この例では、単純な画像ビューとテキストビューのビューアを実装します.

    view_holder_item.xml

    <?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"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <ImageView
            android:id="@+id/back_img"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toTopOf="@+id/img_desc"
            app:layout_constraintTop_toTopOf="parent" />
    
        <TextView
            android:id="@+id/img_desc"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/back_img" />
    
    </androidx.constraintlayout.widget.ConstraintLayout>
    メインアクティブデバイスに画面全体を上書きするRecyclerViewを作成し、RecyclerViewのツールを使用してImageViewとTextViewのレイアウトを作成します.

    RecyclerViewアダプタの実装

    class MyAdapter(val init: ArrayList<Pair<String, String>> = ArrayList()) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
    
    	private var data = init
    
    	override fun getItemCount(): Int = data.size
    
    	// 뷰홀더를 생성해서 리턴
    	override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder =
            MyViewHolder(ViewHolderItemBinding.inflate(LayoutInflater.from(parent.context), parent, false))
    
    	// 생성된 뷰홀더에 아이템을 바인드
    	override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int){
    		(holder as MyViewHolder).apply{
            		// 뷰홀더에서 구현한 bindItem메서드를 호출해 뷰홀더에 아이템을 바인딩
    			bindItem(data.get(position))	
    		}
    	}
    
    // ...
    }
    ここでは,3種類のgetItemCount(),onCreateViewHolder(),onBindViewHolder()関数を遍歴的に実現する必要がある.
    各関数は、RecyclerViewが表現するすべてのデータのサイズ、RecyclerViewに貼り付けるViewHolderの作成、生成したViewHolderの貼り付けの処理の順に担当します.

    RecyclerView ViewHolderの実装

    class MyAdapter:RecyclerView.Adapter(){
    
    	// ...
    
    	inner class MyViewHolder(val binding:ViewHolderItemBinding):RecyclerView.ViewHolder(binding.root){
    		fun bindItem(item: Pair<String,String>){
    			binding.imgDesc.text = item.second
    			Glide.with(binding.root.context)
    				.load(item.first)
    				.into(binding.backImg)
    		}
    	}
    }
    innserクラスを使用してアダプタクラス内にビューholderクラスを作成しました.
    ビュー領域を実装する部分では、ビュー領域をRecyclerViewにバインドするときに表示する項目をビュー領域にバインドすればよい.

    RecyclerViewにアダプタを割り当てる

    class MainActivity:AppCompatActivity(){
    	private val binding by lazy {
    		ActivityMainBinding.inflate(layoutInflater)
    	}
        
    	override fun onCreate(savedInstanceState: Bundle?) {
    		super.onCreate(savedInstanceState)
    		setContentView(binding.root)
            
            	val data = arrayListOf<Pair<String, String>>(
                		Pair("https://picsum.photos/200", "설명1"),
    			Pair("https://picsum.photos/200", "설명2"),
        	        	Pair("https://picsum.photos/200", "설명3")
    		)
            
    		binding.myRv.apply{
    			adapter = MyAdapter()
    			layoutManager = LinearLayoutManager(context, RecyclerView.VERTICAL, false)
    		}
    	}
    }
    上で作成したアダプタをレイアウトからインポートしたRecyclerViewのアダプタに割り当て、LayoutManagerを割り当てます.

    テスト



    上図に示すように、各項目には画像ビューとテキストビューがあり、これら3つの項目がリスト形式でリストされていることがわかります.
    テストで使用したデータはLorem Picsumのデータであり,本明細書ではリストされていないが,品物を区別するために枠線を表すレイアウト要素が加わっている.