我目前正在Java项目中使用优秀的AutoParcel,这有助于创建Parcelable类。
现在,我考虑用于下一个项目的Kotlin具有这种数据类概念,可以自动生成equals,hashCode和toString方法。
是否有方便的方法以便捷的方式制作Kotlin数据类Parcelable(不手动实现方法)?
答案 0 :(得分:145)
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
}
}
答案 1 :(得分:45)
你可以尝试这个插件:
<强> android-parcelable-intellij-plugin-kotlin 强>
它可以帮助您为kotlin的数据类生成Android Parcelable样板代码。它最终看起来像这样:
[Codes to show progressDialog]
Ion.with(MainActivity.this)
.load("--URL TO POST JSON DATA--")
.setJsonObjectBody(params[0])
.asJsonObject()
.withResponse()
.setCallback(new FutureCallback<Response<JsonObject>>()
{
@Override
public void onCompleted(Exception e, Response<JsonObject> result) {
if(progressDialog.isShowing()){
progressDialog.dismiss();
//TODO Something
}
if (result != null) {
if (result.getHeaders().code() == 200) {
Toast.makeText(MainActivity.this, "Login Success", Toast.LENGTH_SHORT).show();
} else if (result.getHeaders().code() == 401) {
Toast.makeText(MainActivity.this, "Invalid Username or password", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(MainActivity.this, "Something wrong check connection !!!", Toast.LENGTH_SHORT).show();
}
}
}
});
答案 2 :(得分:19)
你试过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进行更新
答案 3 :(得分:15)
使用无样板代码的最佳方式是Smuggler gradle插件。您只需要实现AutoParcelable接口,如
data class Person(val name:String, val age:Int): AutoParcelable
这就是全部。适用于密封课程。此插件还为所有AutoParcelable类提供编译时验证。
UPD 17.08.2017 现在使用Kotlin 1.1.4 and Kotlin Android extensions plugin,您可以使用@Parcelize
注释。在这种情况下,上面的示例将如下所示:
@Parcelize class Person(val name:String, val age:Int): Parcelable
无需data
修饰符。目前最大的缺点是使用kotlin-android-extensions插件,它有许多其他功能,可能是不必要的。
答案 4 :(得分:14)
只需点击你的kotlin数据类的data关键字,然后按alt + Enter,选择第一个选项"Add Parceable Implementation"
答案 5 :(得分:4)
我会离开我的路,以防它可以帮助某人。
我所做的是我有一个通用After gtkThread declaration
5
4
3
2
1
<LinearLayout
android:id="@+id/tabs_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_alignParentBottom="true">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="2dp"
android:orientation="vertical"
android:background="@color/lfp_yellow"/>
<com.astuetz.PagerSlidingTabStrip
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="48dip"
app:pstsDividerColor="@android:color/transparent"
app:pstsIndicatorColor="@color/light_yellow"
app:pstsIndicatorHeight="4px"
app:pstsShouldExpand="true"/>
</LinearLayout>
然后我创建这样的parcelables:
Parcelable
这让我摆脱了样板覆盖。
答案 6 :(得分:4)
使用 Android Studio 和 Kotlin 插件,我找到了一种简单的方法来转换我的旧Java Parcelable
,其中没有额外的插件(如果您想要将全新的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
代码生成器引入的一些额外花括号。必须是一个小错误。 我希望这个提示对你有效,对我来说也是如此。
答案 7 :(得分:4)
您可以使用@Parcelize
注释来做到这一点。这是一个自动的Parcelable实现生成器。
首先,您需要允许他们将其添加到模块的build.gradle:
apply plugin: 'org.jetbrains.kotlin.android.extensions'
在主构造函数中声明序列化的属性,并添加一个@Parcelize
批注,然后将自动创建writeToParcel()
/ createFromParcel()
方法:
@Parcelize
class User(val firstName: String, val lastName: String) : Parcelable
您不要需要在experimental = true
块内添加androidExtensions
。
答案 8 :(得分:3)
不幸的是,Kotlin无法在界面中放置真实字段,因此您无法从接口适配器免费继承它:
data class Par : MyParcelable
您可以查看代表团,但它对字段没有帮助,AFAIK:https://kotlinlang.org/docs/reference/delegation.html
所以我看到的唯一选项是Parcelable.Creator
的结构函数,这很明显。
答案 9 :(得分:2)
我更喜欢使用https://github.com/johncarl81/parceler lib和
@Parcel(Parcel.Serialization.BEAN)
data class MyClass(val value)
答案 10 :(得分:0)
有一个插件,但并不总是像Kotlin正在发展的那样更新: https://plugins.jetbrains.com/plugin/8086
<强>替代:强>
我有一个使用atp install nodejs
的自定义数据类的工作示例,并列出:
使用带列表的Parcelable的数据类:
希望它有所帮助!
答案 11 :(得分:0)
Kotlin的@Parcel批注使Android该死的整个打包过程变得容易。
要这样做
第1步。在应用模块gradle中添加Kotlin扩展
第2步。添加experimental = true,因为此功能仍在gradle中进行实验。
androidExtensions { 实验=真 }
第3步。使用@Parcel取消数据类
Here 是有关@Parcel使用情况的简单示例
答案 12 :(得分:0)
示例:
@Parcelize
data class Item(
var imageUrl: String,
var title: String,
var description: Category
) : Parcelable
答案 13 :(得分:0)
以下Kotlin代码可以帮助您使用父级和子级数据类创建Parcelable数据类
父数据类-MyPostModel
data class MyPostModel(
@SerializedName("post_id") val post_id: String? = "",
@SerializedName("category_id") val category_id: String? = "",
@SerializedName("images") val images: ArrayList<ImagesModel>? = null
) : Parcelable {
constructor(parcel: Parcel) : this(
parcel.readString(),
parcel.readString(),
parcel.createTypedArrayList(ImagesModel.CREATOR)
)
override fun writeToParcel(parcel: Parcel, flags: Int) {
parcel.writeString(post_id)
parcel.writeString(category_id)
parcel.writeTypedList(images)
}
override fun describeContents(): Int {
return 0
}
companion object CREATOR : Parcelable.Creator<MyPostModel> {
override fun createFromParcel(parcel: Parcel): MyPostModel {
return MyPostModel(parcel)
}
override fun newArray(size: Int): Array<MyPostModel?> {
return arrayOfNulls(size)
}
}
}
子数据类-ImagesModel
data class ImagesModel(
@SerializedName("image_id") val image_id: String? = "",
@SerializedName("image_url") val image_url: String? = ""
) : Parcelable {
constructor(parcel: Parcel) : this(
parcel.readString(),
parcel.readString()
)
override fun writeToParcel(parcel: Parcel, flags: Int) {
parcel.writeString(image_id)
parcel.writeString(image_url)
}
override fun describeContents(): Int {
return 0
}
companion object CREATOR : Parcelable.Creator<ImagesModel> {
override fun createFromParcel(parcel: Parcel): ImagesModel {
return ImagesModel(parcel)
}
override fun newArray(size: Int): Array<ImagesModel?> {
return arrayOfNulls(size)
}
}
}
答案 14 :(得分:0)
一种更简单,最新的方法是使用@Parcelize
批注,该批注消除了实现Parcelable的繁琐工作
build.gradle(应用程序模块)
apply plugin: "kotlin-parcelize"
// If you are using the new plugin format use this instead.
plugins{
...
id "kotlin-parcelize"
}
YourClass.kt
import kotlinx.parcelize
@Parcelize
class User(val firstName: String, val lastName: String, val age: Int): Parcelable