Есть ли удобный способ создания классов данных Parcelable в Android с помощью Kotlin?
в настоящее время я использую отличный AutoParcel в моем проекте Java, который облегчает создание Parcelable классов.
теперь Kotlin, который я рассматриваю для своего следующего проекта, имеет эту концепцию классов данных, которые автоматически генерируют методы equals, hashCode и toString.
есть ли удобный способ сделать класс данных Kotlin Parcelable удобным способом (без реализации методов вручную)?
12 ответов:
Котлин 1.1.4 выходит
Android расширения плагин теперь включает в себя автоматический генератор Parcelable реализации. Объявите сериализованные свойства в основном конструкторе и добавьте аннотацию @Parcelize, а методы writeToParcel()/createFromParcel () будут созданы автоматически:
@Parcelize class User(val firstName: String, val lastName: String) : Parcelableпоэтому вам нужно включить их добавление этого к вам модуля построить.gradle:
apply plugin: 'org.jetbrains.kotlin.android.extensions' android { androidExtensions { experimental = true } }
вы можете попробовать этот плагин:
android-parcelable-intellij-plugin-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илиIntentEdit: Обновление с последним API
The лучшие С нет шаблонного код на все контрабандист gradle плагин. Все, что вам нужно, это просто реализовать AutoParcelable интерфейс, как
data class Person(val name:String, val age:Int): AutoParcelableи это все. Работает и для закрытых классов. Также Этот плагин обеспечивает проверку времени компиляции для всех классов AutoParcelable.
UPD 17.08.2017 теперь Котлин Котлин и 1.1.4 для Android расширений плагинов вы могли бы использовать
@ParcelizeПримечание. В этом случае приведенный выше пример будет выглядеть так:@Parcelize class Person(val name:String, val age:Int): Parcelableне нужно
dataмодификатор. Самым большим недостатком на данный момент является использование плагина kotlin-android-extensions, который имеет множество других функций, которые могут быть ненужными.
просто нажмите на ключевое слово данных вашего класса данных kotlin, затем нажмите alt + Enter, выберите первый вариант, сказав
"Add Parceable Implementation"
Я оставлю мой способ делать в случае, если это может помочь кому-то.
то, что я делаю, это у меня есть общий
Parcelableinterface 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) }и затем я создаю parcelables, как это:
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вы можете посмотреть делегирование, но это не помогает с полями, AFAIK:https://kotlinlang.org/docs/reference/delegation.html
Так что единственный вариант, который я вижу, это функция fabric для
Parcelable.Creator, что является очевидным.
Я предпочитаю просто использовать https://github.com/johncarl81/parceler lib с
@Parcel(Parcel.Serialization.BEAN) data class MyClass(val value)
используя Android Studio и Котлин плагин, я нашел простой способ конвертировать мой старый Java
ParcelableС никаких дополнительных плагинов (если все, что вы хотите превратить Новыйdataкласс В aParcelable, переходим к 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определение класса.Примечания:
- преобразование Java
Parcelableнепосредственно в Котлин не будет производить тот же результат с текущей версией Котлин плагин (1.1.3).- мне пришлось удалить некоторые дополнительные фигурные скобки текущий
Parcelableгенератор код вводит. Должно быть, небольшая ошибка.я надеюсь, что этот совет работает для вас, а также для меня.
есть плагин, но не всегда обновляется, как Котлин развивается: https://plugins.jetbrains.com/plugin/8086
альтернатива: У меня есть рабочий пример пользовательского класса данных с помощью
Parcelableи списки:классы данных, использующие Parcelable со списками:
надеюсь, что это помогает!
Котлин сделал весь процесс Parcelization в Android чертовски легко с его @ Parcel аннотации.
для этого
Шаг 1. добавьте расширения Kotlin в свой модуль приложения gradle
Шаг 2. добавить экспериментальный = true, так как эта функция все еще находится в эксперименте в gradle.
androidExtensions { экспериментальный = истинный }
Шаг 3. Annonate класс данных с @участков
здесь это простой пример использования @ Parcel
Котлин сделал весь процесс Parcelization в Android чертовски легко с его @ Parcel аннотации.
для этого
Шаг 1. добавьте расширения Kotlin в свой модуль приложения gradle
Шаг 2. добавить экспериментальный = true, так как эта функция все еще находится в эксперименте в gradle.
androidExtensions { экспериментальный = истинный }
Шаг 3. Annonate класс данных с @участков
здесь это простой пример использования @Parcel в Kotlin для передачи данных между компонентами Android.
Comments