現在、Javaプロジェクトで優れた AutoParcel を使用しています。これにより、Parcelableクラスの作成が容易になります。
次のプロジェクトで検討するKotlinには、equals、hashCode、toStringメソッドを自動的に生成するデータクラスという概念があります。
Kotlinデータクラスを便利な方法で(メソッドを手動で実装せずに)Parcelableにする便利な方法はありますか?
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
}
}
このプラグインを試すことができます:
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)
}
}
}
}
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で更新
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プラグインを使用していることです。このプラグインには、不要になる可能性のある他の多くの機能があります。
Kotlinデータクラスのデータキーワードをクリックし、Alt + Enterを押して、"Add Parceable Implementation"
という最初のオプションを選択します。
Android StudioとKotlinプラグインを使用して、簡単な方法を見つけました古いJava Parcelable
sを追加のプラグインなしで変換します(必要なのは、新しい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 Studioに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
クラス定義に追加される自動生成コードです。
注:
Parcelable
をKotlinに直接変換しようとするとKotlinプラグイン(1.1.3
)の現在のバージョンでは同じ結果を生成しません。Parcelable
コードジェネレーターが導入する余分な中括弧を削除する必要がありました。マイナーなバグである必要があります。このヒントが私にとってもあなたにとってもうまくいくことを願っています。
それが誰かを助けるかもしれない場合に備えて、私は自分のやり方をやめます。
私がしていることは、ジェネリック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()) } }
}
これにより、ボイラープレートのオーバーライドを取り除くことができます。
残念ながら、Kotlinにはインターフェースに実際のフィールドを配置する方法がないため、インターフェースアダプターから自由に継承することはできません:data class Par : MyParcelable
あなたは委任を見るかもしれませんが、フィールドに関しては役に立ちません、知る限り: https://kotlinlang.org/docs/reference/delegation.html
したがって、私が見る唯一のオプションは、Parcelable.Creator
のファブリック関数です。
https://github.com/johncarl81/parceler libを使用することを好みます
@Parcel(Parcel.Serialization.BEAN)
data class MyClass(val value)
例:
@Parcelize
data class Item(
var imageUrl: String,
var title: String,
var description: Category
) : Parcelable
Kotlinは@Parcelアノテーションを使用して、Androidでのパーセル化プロセス全体を非常に簡単にしました。
それをするために
ステップ1。アプリモジュールgradleにKotlin拡張機能を追加する
ステップ2。この機能はまだGradleで実験中であるため、experimental = trueを追加します。
androidExtensions {Experimental = true}
ステップ3。@Parcelでデータクラスに注釈を付けます
ここは@Parcelの使用に関する簡単な例です
プラグインはありますが、Kotlinが進化するにつれて常に更新されるとは限りません: https://plugins.jetbrains.com/plugin/8086
代替案:Parcelable
とリストを使用したカスタムデータクラスの実用例があります。
リスト付きのParcelableを使用するデータクラス:
それが役に立てば幸い!