web-dev-qa-db-ja.com

Kotlinを使用してAndroidにParcelableデータクラスを作成する便利な方法はありますか?

現在、Javaプロジェクトで優れた AutoParcel を使用しています。これにより、Parcelableクラスの作成が容易になります。

次のプロジェクトで検討するKotlinには、equals、hashCode、toStringメソッドを自動的に生成するデータクラスという概念があります。

Kotlinデータクラスを便利な方法で(メソッドを手動で実装せずに)Parcelableにする便利な方法はありますか?

100
thalesmello

Kotlin 1.1.4 はアウト

Android Extensionsプラグインに、自動Parcelable実装ジェネレーターが含まれるようになりました。プライマリコンストラクターでシリアル化されたプロパティを宣言し、@ Parcelizeアノテーションを追加すると、writeToParcel()/ createFromParcel()メソッドが自動的に作成されます。

@Parcelize
class User(val firstName: String, val lastName: String) : Parcelable

したがって、モジュールのbuild.gradleにこれを追加できるようにする必要があります。

apply plugin: 'org.jetbrains.kotlin.Android.extensions'

Android {
    androidExtensions {
        experimental = true
    }
}
150
Dhaval Jivani

このプラグインを試すことができます:

Android-parcelable-intellij-plugin-kotlin

KotlinのデータクラスのAndroid Parcelableボイラープレートコードの生成に役立ちます。そして、最終的には次のようになります。

data class Model(var test1: Int, var test2: Int): Parcelable {

    constructor(source: Parcel): this(source.readInt(), source.readInt())

    override fun describeContents(): Int {
        return 0
    }

    override fun writeToParcel(dest: Parcel?, flags: Int) {
        dest?.writeInt(this.test1)
        dest?.writeInt(this.test2)
    }

    companion object {
        @JvmField final val CREATOR: Parcelable.Creator<Model> = object : Parcelable.Creator<Model> {
            override fun createFromParcel(source: Parcel): Model{
                return Model(source)
            }

            override fun newArray(size: Int): Array<Model?> {
                return arrayOfNulls(size)
            }
        }
    }
}
45
nekocode

PaperParcel を試しましたか? Android Parcelableボイラープレートコードを自動的に生成する注釈プロセッサです。

使用法:

データクラスに@PaperParcelアノテーションを付け、PaperParcelableを実装し、生成されたCREATORのJVM静的インスタンスを追加します。例:

@PaperParcel
data class Example(
  val test: Int,
  ...
) : PaperParcelable {
  companion object {
    @JvmField val CREATOR = PaperParcelExample.CREATOR
  }
}

これでデータクラスはParcelableになり、BundleまたはIntentに直接渡すことができます

編集:最新のAPIで更新

19

bestway withnoボイラープレートコードは Smuggler gradleプラグイン。必要なのは、AutoParcelableインターフェイスを実装するだけです

data class Person(val name:String, val age:Int): AutoParcelable

そして、それだけです。シールドクラスでも機能します。また、このプラグインは、すべてのAutoParcelableクラスのコンパイル時検証を提供します。

UPD 17.08.2017今では Kotlin 1.1.4およびKotlin Android拡張プラグイン を使用できます@Parcelize注釈。この場合、上記の例は次のようになります。

@Parcelize class Person(val name:String, val age:Int): Parcelable

data修飾子は不要です。今のところ、最大の欠点は、kotlin-Android-extensionsプラグインを使用していることです。このプラグインには、不要になる可能性のある他の多くの機能があります。

15
Stepango

Kotlinデータクラスのデータキーワードをクリックし、Alt + Enterを押して、"Add Parceable Implementation"という最初のオプションを選択します。

15
Manish Patiyal

Android StudioKotlinプラグインを使用して、簡単な方法を見つけました古いJava Parcelablesを追加のプラグインなしで変換します(必要なのは、新しいdataクラスをParcelableに変換することだけです、4番目のコードスニペットにスキップします)。

すべてのPersonボイラープレートを持つParcelableクラスがあるとしましょう:

public class Person implements Parcelable{
    public static final Creator<Person> CREATOR = new Creator<Person>() {
        @Override
        public Person createFromParcel(Parcel in) {
            return new Person(in);
        }

        @Override
        public Person[] newArray(int size) {
            return new Person[size];
        }
    };

    private final String firstName;
    private final String lastName;
    private final int age;

    public Person(String firstName, String lastName, int age) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
    }

    protected Person(Parcel in) {
        firstName = in.readString();
        lastName = in.readString();
        age = in.readInt();
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(firstName);
        dest.writeString(lastName);
        dest.writeInt(age);
    }

    @Override
    public int describeContents() {
        return 0;
    }

    public String getFirstName() {
        return firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public int getAge() {
        return age;
    }
}

Parcelable実装を削除することから始めて、ベアボーン、プレーン、古いJavaオブジェクトを残します(プロパティは最終的に設定し、コンストラクタ):

public class Person {
    private final String firstName;
    private final String lastName;
    private final int age;

    public Person(String firstName, String lastName, int age) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
    }

    public String getFirstName() {
        return firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public int getAge() {
        return age;
    }
}

それからCode > Convert Java file to Kotlin Fileオプションに魔法をかけてみましょう:

class Person(val firstName: String, val lastName: String, val age: Int)

これをdataクラスに変換します。

data class Person(val firstName: String, val lastName: String, val age: Int)

そして最後に、これを再びParcelableに変えましょう。クラス名にカーソルを合わせると、Android St​​udioにAdd Parcelable Implementationのオプションが表示されます。結果は次のようになります。

data class Person(val firstName: String, val lastName: String, val age: Int) : Parcelable {
    constructor(parcel: Parcel) : this(
            parcel.readString(),
            parcel.readString(),
            parcel.readInt()
    )

    override fun writeToParcel(parcel: Parcel, flags: Int) {
        parcel.writeString(firstName)
        parcel.writeString(lastName)
        parcel.writeInt(age)
    }

    override fun describeContents(): Int {
        return 0
    }

    companion object CREATOR : Parcelable.Creator<Person> {
        override fun createFromParcel(parcel: Parcel): Person {
            return Person(parcel)
        }

        override fun newArray(size: Int): Array<Person?> {
            return arrayOfNulls(size)
        }
    }
}

ご覧のとおり、Parcelable実装は、dataクラス定義に追加される自動生成コードです。

注:

  1. JavaParcelableKotlinに直接変換しようとするとKotlinプラグイン(1.1.3)の現在のバージョンでは同じ結果を生成しません。
  2. 現在のParcelableコードジェネレーターが導入する余分な中括弧を削除する必要がありました。マイナーなバグである必要があります。

このヒントが私にとってもあなたにとってもうまくいくことを願っています。

4
argenkiwi

それが誰かを助けるかもしれない場合に備えて、私は自分のやり方をやめます。

私がしていることは、ジェネリックParcelable

interface DefaultParcelable : Parcelable {
    override fun describeContents(): Int = 0

    companion object {
        fun <T> generateCreator(create: (source: Parcel) -> T): Parcelable.Creator<T> = object: Parcelable.Creator<T> {
            override fun createFromParcel(source: Parcel): T = create(source)

            override fun newArray(size: Int): Array<out T>? = newArray(size)
        }

    }
}

inline fun <reified T> Parcel.read(): T = readValue(T::class.javaClass.classLoader) as T
fun Parcel.write(vararg values: Any?) = values.forEach { writeValue(it) }

そして、私はこのような小包を作成します:

data class MyParcelable(val data1: Data1, val data2: Data2) : DefaultParcelable {
    override fun writeToParcel(dest: Parcel, flags: Int) { dest.write(data1, data2) }
    companion object { @JvmField final val CREATOR = DefaultParcelable.generateCreator { MyParcelable(it.read(), it.read()) } }
}

これにより、ボイラープレートのオーバーライドを取り除くことができます。

4
gmemario

残念ながら、Kotlinにはインターフェースに実際のフィールドを配置する方法がないため、インターフェースアダプターから自由に継承することはできません:data class Par : MyParcelable

あなたは委任を見るかもしれませんが、フィールドに関しては役に立ちません、知る限り: https://kotlinlang.org/docs/reference/delegation.html

したがって、私が見る唯一のオプションは、Parcelable.Creatorのファブリック関数です。

3
voddan

https://github.com/johncarl81/parceler libを使用することを好みます

@Parcel(Parcel.Serialization.BEAN)
data class MyClass(val value)
2
Jan Rabe
  • モデル/データクラスの上に@ Parcelizeアノテーションを使用します
  • Kotlinの最新バージョンを使用する
  • アプリモジュールでKotlin Android Extensionsの最新バージョンを使用する

例:

@Parcelize
data class Item(
    var imageUrl: String,
    var title: String,
    var description: Category
) : Parcelable
1
Manoj Bhadane

Kotlinは@Parcelアノテーションを使用して、Androidでのパーセル化プロセス全体を非常に簡単にしました。

それをするために

ステップ1。アプリモジュールgradleにKotlin拡張機能を追加する

ステップ2。この機能はまだGradleで実験中であるため、experimental = trueを追加します。

androidExtensions {Experimental = true}

ステップ3。@Parcelでデータクラスに注釈を付けます

ここは@Parcelの使用に関する簡単な例です

0

プラグインはありますが、Kotlinが進化するにつれて常に更新されるとは限りません: https://plugins.jetbrains.com/plugin/8086

代替案:Parcelableとリストを使用したカスタムデータクラスの実用例があります。

リスト付きのParcelableを使用するデータクラス:

https://Gist.github.com/juanchosaravia/0b61204551d4ec815bbf

それが役に立てば幸い!

0
Juancho