# airbnb/epoxy Epoxyは、RecyclerViewで複雑な画面を構築するためのAndroidライブラリです。Modelは、アノテーションによってカスタムビューまたはデータバインディングレイアウトから自動的に生成されます。Modelは、EpoxyControllerで RecyclerViewに表示するアイテムを宣言するために使用されます。 epoxyによって、ViewHolderの作成や、itemType, itemId, spanCountなどが抽象化され、複数のビュータイプで画面を構築することが簡素化されます。さらに、Epoxyは、ビューステートの保存と差分更新のサポートします。 私たちはAirbnbでEpoxyを開発し、RecyclerViewsでの作業プロセスを簡素化し、必要な機能を追加しました。現在、アプリのほとんどのメイン画面にエポキシを使用しており、開発者のエクスペリエンスが大幅に向上しています。 ## インストール サポートされているビルド構成はGradleだけなので、プロジェクトbuild.gradleファイルに依存関係を追加するだけです。 ``` dependencies { implementation "com.airbnb.android:epoxy:$epoxyVersion" // Add the annotation processor if you are using Epoxy's annotations (recommended) annotationProcessor "com.airbnb.android:epoxy-processor:$epoxyVersion" } ``` Kotlinを使用している場合は、追加する必要があります。 ``` apply plugin: 'kotlin-kapt' kapt { correctErrorTypes = true } ``` `AutoModel`アノテーションが正しく機能するようにします。詳細はこちら。 また、`annotationProcessor`ではなく、`kapt`を使用してください。 ## Library Project エポキシアノテーションでレイアウトリソースを使用している場合は、ライブラリプロジェクト用にButterknifeのgradleプラグインをに追加します。 ``` buildscript { repositories { mavenCentral() } dependencies { classpath 'com.jakewharton:butterknife-gradle-plugin:10.1.0' } } ``` ``` apply plugin: 'com.android.library' apply plugin: 'com.jakewharton.butterknife' ``` ここで、すべてのepoxyアノテーションでRではなくR2を使用していることを確認してください。 ```kotlin @ModelView(defaultLayout = R2.layout.view_holder_header) public class HeaderView extends LinearLayout { .... } ``` ## Basic Usage epoxyには2つの主要なコンポーネントがあります。 1. `EpoxyModel`: ViewをRecyclerViewでどのように表示するのかを示すモデル 2. `EpoxyController`: データをどのようなModelで表示するのかを制御します ### 実装の流れ 1. Viewの作成 2. Viewと対応するModelの作成 3. Controllerの作成 4. RecyclerViewへのControllerの設定 ### モデルの作成 epoxyは、ビューやレイアウトに基づいてモデルを生成します。生成されたモデルクラスは、サフィックスにアンダースコア(_)を付けられ、 EpoxyControllerクラスの中で直接使用します。 #### カスタムビューから `@ModelView`アノテーションをビューのクラスに追加します。次に、各setterメソッドに「prop」アノテーションを追加して、モデルのプロパティとしてマークします。 ```java @ModelView(autoLayout = Size.MATCH_WIDTH_WRAP_HEIGHT) public class HeaderView extends LinearLayout { ... // Initialization omitted @TextProp public void setTitle(CharSequence text) { titleView.setText(text); } } ``` `HeaderViewModel_`クラスが自動生成されます #### データバインディングから Android DataBindingを使用したモデルの作成が可能です。 ```xml <layout xmlns:android="http://schemas.android.com/apk/res/android"> <data> <variable name="title" type="String" /> </data> <TextView android:layout_width="120dp" android:layout_height="40dp" android:text="@{title}" /> </layout> ``` 任意のパッケージに`EpoxyDataBindingLayouts`アノテーションを追加したインターフェースを追加し、databindingのレイアウトを設定してください。 ```java package com.airbnb.epoxy.sample; import com.airbnb.epoxy.EpoxyDataBindingLayouts; @EpoxyDataBindingLayouts({R.layout.header_view, ... // other layouts }) interface EpoxyConfig {} ``` `HeaderViewBindingModel_`クラスが自動生成されます。 #### ViewHolderから DataBindingを使用していないxmlからモデルを作成することも可能です。 ```java= @EpoxyModelClass(layout = R.layout.header_view) public abstract class HeaderModel extends EpoxyModelWithHolder<Holder> { @EpoxyAttribute String title; @Override public void bind(Holder holder) { holder.header.setText(title); } static class Holder extends BaseEpoxyHolder { @BindView(R.id.text) TextView header; } } ``` `HeaderModel_`クラスが自動生成されます。 ### モデルをコントローラーから使用する コントローラーには、RecyclerViewで表示する順にモデルを追加します。 コントローラーの`buildModels`メソッドでは、表示するアイテムを宣言します。データが変更された場合は、`requestModelBuild`を呼び出し、`buildModels`をトリガーします。これによってepoxyはモデルの変更を追跡し、ビューを自動的にバインドして更新します。 例として、PhotoControllerではヘッダー、写真のリスト、およびローダー(さらに写真が読み込まれている場合)を示します。写真が読み込まれるたびにコントローラーの`setData(photos, loadingMore)`メソッドが呼び出され、`buildModels`が呼び出しがトリガーされるため、新しいデータの状態を表すモデルを構築できます。 ```java= public class PhotoController extends Typed2EpoxyController<List<Photo>, Boolean> { @AutoModel HeaderModel_ headerModel; @AutoModel LoaderModel_ loaderModel; @Override protected void buildModels(List<Photo> photos, Boolean loadingMore) { headerModel .title("My Photos") .description("My album description!") .addTo(this); for (Photo photo : photos) { new PhotoModel() .id(photo.id()) .url(photo.url()) .addTo(this); } loaderModel .addIf(loadingMore, this); } } ``` #### Kotlinを使用している場合 各モデルの拡張関数が生成されるため、このように記述することができます。 ```kotlin class PhotoController : Typed2EpoxyController<List<Photo>, Boolean>() { override fun buildModels(photos: List<Photo>, loadingMore: Boolean) { header { id("header") title("My Photos") description("My album description!") } photos.forEach { photoView { id(it.id()) url(it.url()) } } if (loadingMore) loaderView { id("loader") } } } ``` ### RecyclerViewの設定 ```java= MyController controller = new MyController(); recyclerView.setAdapter(controller.getAdapter()); // Request a model build whenever your data changes controller.requestModelBuild(); // Or if you are using a TypedEpoxyController controller.setData(myData); ``` `EpoxyRecyclerView`を使用している場合、より簡単に記述できます。 ```java= epoxyRecyclerView.setControllerAndBuildModels(new MyController()); // Request a model build on the recyclerview when data changes epoxyRecyclerView.requestModelBuild(); ``` #### Kotlin `Kotlin Extensions`を使用すると、コントローラーの作成が不要になります。 ```kotlin= epoxyRecyclerView.withModels { header { id("header") title("My Photos") description("My album description!") } photos.forEach { photoView { id(it.id()) url(it.url()) } } if (loadingMore) loaderView { id("loader") } } } ```
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up