1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

初めてのEpoxy

Last updated at Posted at 2020-06-21

入社して3ヶ月経ちそうですが、まだEpoxyを触ったことなかったので備忘録として書いていきます。
Epoxyを使うとRecyclerViewを簡単に実装できるみたいです!(中毒性があるので注意らしい)

実装

##Gradle
まずはEpoxyを使うためにGradleに依存関係を記述します。

build.gradle
    def epoxy_version = "3.11.0"
    implementation "com.airbnb.android:epoxy:$epoxy_version"
    // databinding使用するなら
    implementation "com.airbnb.android:epoxy-databinding:${epoxy_version}"
    kapt "com.airbnb.android:epoxy-processor:$epoxy_version"

package-info

gradleに依存関係を記述したら、package-info.javaファイルをプロジェクト内に作成します。

package-info.java
@EpoxyDataBindingLayouts({R.layout.recyclerview_item})
package com.example.todo;

import com.airbnb.epoxy.EpoxyDataBindingLayouts;

@EpoxyDataBindingLayoutsアノテーションでレイアウトファイルを指定するとModelが自動生成してくれます。
ここで一旦ビルドをかけてください。

layout

過去の記事のxmlファイルをDataBindingするために<layout>属性で囲います。後に書くControllerからTodoTitleを受け取って表示させます。

recyclerview_item.xml
<?xml version="1.0" encoding="utf-8"?>
<layout 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">

    <data>
        <variable
            name="todoTitle"
            type="String" />
    </data>

    <androidx.cardview.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="8dp"
        android:foreground="?android:attr/selectableItemBackground"
        app:cardElevation="10dp">

        <LinearLayout
            android:id="@+id/LinearLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:background="@android:color/white"
            android:orientation="horizontal">

            <ImageView
                android:id="@+id/sampleImg"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="10dp"
                android:contentDescription="@string/recycler_picture"
                app:srcCompat="@mipmap/ic_launcher_round" />

            <TextView
                android:id="@+id/sampleTxt"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:gravity="center"
                android:text="@{ todoTitle }"
                tools:text="TODO"
                android:textSize="30sp" />

        </LinearLayout>
    </androidx.cardview.widget.CardView>
</layout>

Controller

Controllerは引数が一つの時はTypedEpoxyController<List<Todo>>()を継承します。

これは引数2つの場合は、Typed2EpoxyController()
3つ、Typed3EpoxyController()
4つ、Typed4EpoxyController()

今回は、表示するリストだけをもらえればいいので、TypedEpoxyController()を選択しました。

EpoxyController.kt
class RecyclerViewController(
    lifecycleOwner: LifecycleOwner,
    viewModel: MainViewModel
) : TypedEpoxyController<List<Todo>>() {
    init {
        viewModel.todoList.observe(lifecycleOwner, ::setData)
    }
    override fun buildModels(data: List<Todo>?) {
        data?.forEach {
            recyclerviewItem {
                id(modelCountBuiltSoFar)
                todoTitle(it.todoTitle)
            }
        }
    }
}

順を追ってControllerを見ていきましょう。buildModels()setData()が呼ばれると実行されます。そのため今回はRoomに保存しているLiveDataが更新させるたびにsetData()を呼ぶようにObserveを書きました。

buildModels()内に表示させるものを書いていきます。引数でもらったdataを自動生成された拡張関数recyclerviewItemで表示させます。

inline fun ModelCollector.recyclerviewItem(
    modelInitializer: RecyclerviewItemBindingModelBuilder.() -> Unit
) {
    add(
        RecyclerviewItemBindingModel_().apply {
            modelInitializer()
        }
    )
}

毎回add()を書かずに済むのでとても便利ですね!(これが自動生成されるなんて)
id()とは、表示される要素毎に重複しないものを設定して上げる必要があります。これを指定すると表示させる要素の差分などを判別してくれるらしい。とりあえず被らないようにmodelCountBuiltSoFarを入れました。これは、Epoxyで表示させている要素の数です。idの付け方で迷ったらこれにしてます。

Activity

あとは同じみの記述をするだけでリスト表示ができました! ViewHolderやらを書かなくて済むのはとてもいい感じです。

MainActivity.kt
        recyclerViewController = RecyclerViewController(this, mainViewModel)
        main_recycler_view.apply {
            this.adapter = recyclerViewController.adapter
            this.layoutManager = LinearLayoutManager(this@MainActivity)
        }
1
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?