現在、Javaプロジェクトで優れたAutoParcelを使用しています。これにより、Parcelableクラスの作成が容易になります。
現在、次のプロジェクトで検討するKotlinには、equals、hashCode、およびtoStringメソッドを自動的に生成するデータクラスの概念があります。
(メソッドを手動で実装せずに)Kotlinデータクラスを便利な方法でParcelableにする便利な方法はありますか?
現在、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
}
}
this calss implements Parcelable but does not provice CREATOR field
。あなたの答えは十分(十分)ですか?
@SuppressLint("ParcelCreator")
lint警告を取り除くために使用できます。
このプラグインを試すことができます:
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
、生成されたJVM静的インスタンスを追加します。CREATOR
例:
@PaperParcel
data class Example(
val test: Int,
...
) : PaperParcelable {
companion object {
@JvmField val CREATOR = PaperParcelExample.CREATOR
}
}
これで、データクラスはまたはにParcelable
直接渡すことができます。Bundle
Intent
編集:最新のAPIで更新
kotlinデータクラスのdataキーワードをクリックして、Alt + Enterキーを押し、最初のオプションを選択してください "Add Parceable Implementation"
parcel.read...
とTODO
フィールドがない場合は、val/var
。List
クラス内で使用すると、実装が問題になります。だから私@Parcelize
は受け入れられた答えに頼った。
最善との双方向無定型のすべてのコードがあるスマグラーのGradleプラグイン。必要なのは、AutoParcelableインターフェイスを実装するだけです。
data class Person(val name:String, val age:Int): AutoParcelable
そして、それだけです。密封されたクラスでも動作します。また、このプラグインは、すべてのAutoParcelableクラスのコンパイル時検証を提供します。
UPD 2017年8月17日で今Kotlin 1.1.4とKotlin Androidの拡張プラグインあなたが使用できる@Parcelize
注釈を。この場合、上記の例は次のようになります。
@Parcelize class Person(val name:String, val age:Int): Parcelable
data
修飾子は必要ありません。今のところ最大の欠点は、不要になる可能性のある他の多くの機能を備えたkotlin-android-extensionsプラグインを使用していることです。
Android StudioとKotlinプラグインを使用Parcelable
して、余分なプラグインなしで古いJavaを簡単に変換する方法を見つけました(まったく新しい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オブジェクトを残します(プロパティはfinalであり、コンストラクターによって設定される必要があります)。
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()) } }
}
これにより、ボイラープレートオーバーライドを取り除くことができます。
私はhttps://github.com/johncarl81/parceler libを
@Parcel(Parcel.Serialization.BEAN)
data class MyClass(val value)
@Parcelize
アノテーションを使用してそれを行うことができます。これは自動Parcelable実装ジェネレーターです。
まず、これを有効にして、これをモジュールのbuild.gradleに追加する必要があります。
apply plugin: 'org.jetbrains.kotlin.android.extensions'
プライマリコンストラクターでシリアル化されたプロパティを宣言し、@Parcelize
注釈を追加すると、writeToParcel()
/ createFromParcel()
メソッドが自動的に作成されます。
@Parcelize
class User(val firstName: String, val lastName: String) : Parcelable
あなたDONTの追加の必要性experimental = true
内部androidExtensions
ブロックを。
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を使用するデータクラス:
それが役に立てば幸い!