【问题标题】:Android Parcelable for Kotlin is not working适用于 Kotlin 的 Android Parcelable 无法正常工作
【发布时间】:2018-02-28 13:39:27
【问题描述】:

我正在尝试将数据从一个片段传递到另一个片段,但我遇到了将数据从一个片段发送到另一个片段的问题。

 class MainFragment : Fragment() {


    companion object {
        public val KEY_PARSE_DATA = "parseData"
    }

    private var parseData: ParseData? = null

    override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?,
                              savedInstanceState: Bundle?): View? {
        // Inflate the layout for this fragment
        return inflater!!.inflate(R.layout.fragment_main, container, false).apply {
            val editName = findViewById(R.id.edit_Name) as EditText
            val editSurname = findViewById(R.id.edit_Surname) as EditText
            val buttonNext = findViewById(R.id.btn_Next) as Button
            buttonNext.setOnClickListener(View.OnClickListener {
                val fragment = AnotherFragment()

                if (parseData != null) {
                    var parseData = ParseData(editName.text.toString(), editSurname.text.toString())
                    val fragment = AnotherFragment()
                    val bundle = Bundle()
                    bundle.putParcelable(KEY_PARSE_DATA, parseData)
                    fragment.setArguments(bundle)
                    fragmentManager.beginTransaction().add(R.id.fragment_container, fragment).commitAllowingStateLoss()

                }

            })
        }
    }


}// Required empty public constructor

用于实现它的 Parcelable 类

 @SuppressLint("ParcelCreator")
@Parcelize
data class ParseData(val firstName: String, val lastName: String) : Parcelable {


    constructor(parcel: Parcel) : this(
            parcel.readString(),
            parcel.readString()) {
    }

    override fun toString(): String {
        return "ParseData(firstName='$firstName', lastName='$lastName')"
    }


    companion object : Parceler<ParseData> {

        override fun ParseData.write(parcel: Parcel, flags: Int) {
            parcel.writeString(firstName)
            parcel.writeString(lastName)
        }

        override fun create(parcel: Parcel): ParseData {
            return ParseData(parcel)
        }
    }
}

还有另一个片段,它从 android 中的 parcelable 类中获取数据

    class AnotherFragment : Fragment() {

    override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?,
                              savedInstanceState: Bundle?): View? {
        // Inflate the layout for this fragment
        return inflater!!.inflate(R.layout.fragment_another, container, false).apply {

            val textName = findViewById<TextView>(R.id.textFirst)
            val textSurname = findViewById<TextView>(R.id.textSecond)
            val bundle = arguments
            if (bundle != null) {
                val parseData = bundle.getParcelable<ParseData>(KEY_PARSE_DATA)
                textName.setText(parseData.firstName)
                textSurname.setText(parseData.lastName)
            }
        }
    }

}

我尝试了一些示例,但我不清楚如何在基于 kotlin 和 build.gradle 文件的 Android 应用程序中实现 parcelable

 apply plugin: 'com.android.application'

apply plugin: 'kotlin-android'

apply plugin: 'kotlin-android-extensions'

android {
    compileSdkVersion 26
    defaultConfig {
        applicationId "com.assignment.ankitt.kotlinsecond"
        minSdkVersion 19
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

androidExtensions {
    experimental = true
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
    implementation 'com.android.support:appcompat-v7:26.1.0'
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
    implementation 'com.android.support:support-v4:26.1.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.1'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
}

【问题讨论】:

    标签: android android-fragments kotlin parcelable


    【解决方案1】:

    将以下代码添加到您的 App Level gradle 中。

    apply plugin: 'kotlin-android'
    apply plugin: 'kotlin-android-extensions'
    apply plugin: 'kotlin-kapt'
    
    androidExtensions {
        experimental = true
    }
    

    【讨论】:

    • 我也做了同样的事情,我添加了所有三个插件和 androidExtensions 但导入仍然出错
    【解决方案2】:

    现在添加 'kotlin-parcelize' 插件就足够了。 比如:

     plugins {
    id 'com.android.application'
    id 'kotlin-android'
    id 'kotlin-parcelize'
    

    }

    【讨论】:

      【解决方案3】:
      apply plugin: 'com.android.application'
      apply plugin: 'kotlin-android'
      apply plugin: 'kotlin-android-extensions'
      
      android {
          //
      
          androidExtensions {
              experimental = true
          }
      
      }
      

      插件的顺序很重要。 kotlin-android 必须在 kotlin-android-extension 之前。然后清理项目。 Unable to add kotlin android extension

      【讨论】:

        【解决方案4】:

        我建议您查看Kotlin Android Extensions 提供的@Parcelize 注释,它会为您生成所有必要的样板,因此您不必自己编写和维护该代码。

        【讨论】:

        • 谢谢它帮助了我
        • 我不建议将仍处于实验模式的功能用于生产应用程序:experimental-mode
        【解决方案5】:

        需要在你的应用级 Gradle 中添加这两个

        apply plugin: 'kotlin-android-extensions'
        

        androidExtensions { 实验=真` }

        【讨论】:

        • 这个插件默认生成 apply plugin: 'kotlin-android-extensions' @Rajneesh
        【解决方案6】:

        Kotlin 插件应该在 'kotlin-android-extensions' 之前启用

        所以把顺序改成

        apply plugin: 'com.android.application' #1
        apply plugin: 'kotlin-android' #2
        apply plugin: 'kotlin-android-extensions' #3
        

        【讨论】:

          【解决方案7】:

          大家好,我已经解决了这个问题,片段交易和可打包存在问题

          MainActivity 设置片段

              class MainActivity : AppCompatActivity() {
          
              val manager = supportFragmentManager
          
              override fun onCreate(savedInstanceState: Bundle?) {
                  super.onCreate(savedInstanceState)
                  setContentView(R.layout.activity_main)
          
                  val fragment = DetailFragment()
                  manager.findFragmentById(R.id.fragmentContainer)
                  manager.beginTransaction().add(R.id.fragmentContainer, fragment).commit()
              }
          }
          

          第一个填充数据的片段

           class DetailFragment : Fragment(), View.OnClickListener {
          
              var editTextName: EditText? = null
              var editTextLast: EditText? = null
              var buttonNextFragment: Button? = null
              var firstName: String? = null
              var lastName: String? = null
          
              companion object {
                  val KEY_PARSE_DATA = "detailData"
              }
          
              override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?,
                                        savedInstanceState: Bundle?): View? {
          
                  val view: View = inflater!!.inflate(R.layout.fragment_detail, container, false)
                  editTextName = view.findViewById(R.id.ed_firstName) as EditText
                  editTextLast = view.findViewById(R.id.ed_lastName) as EditText
                  buttonNextFragment = view.findViewById(R.id.btn_nextfragment) as Button
                  buttonNextFragment!!.setOnClickListener(this)
                  return view
              }
          
              override fun onClick(v: View?) {
                  firstName = editTextName!!.text.toString()
                  lastName = editTextLast!!.text.toString()
                  Toast.makeText(context, firstName, Toast.LENGTH_SHORT).show()
          //        val viewFragment = ViewFragment()
          //        val transaction = fragmentManager.beginTransaction()
          //        transaction.replace(R.id.fragmentContainer, viewFragment)
          //        transaction.commit()
          
                  var details = Details(firstName!!, lastName!!)
                  val viewFragment = ViewFragment()
                  val bundle = Bundle()
                  bundle.putParcelable(KEY_PARSE_DATA, details)
                  viewFragment.setArguments(bundle)
                  val transaction = fragmentManager.beginTransaction()
                  transaction.replace(R.id.fragmentContainer, viewFragment)
                  transaction.commit()
              }
          }
          

          显示来自 parcelable 的数据

              class ViewFragment : Fragment() {
          
              var textViewName: TextView? = null
              var textViewLastName: TextView? = null
          
              override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?,
                                        savedInstanceState: Bundle?): View? {
                  val view: View = inflater!!.inflate(R.layout.fragment_view, container, false)
          
                  textViewName = view.findViewById(R.id.text_name_another) as TextView
                  textViewLastName = view.findViewById(R.id.text_surname_another) as TextView
          
                  val bundle = arguments
                  if (bundle != null) {
                      val details = bundle.getParcelable<Details>(KEY_PARSE_DATA)
                      textViewName!!.setText(details.firstName)
                      textViewLastName!!.setText(details.lastName)
                  }
          
          
                  return view
              }
          
          }
          

          parcelable实现的模型类

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

          还有我的 gradle 文件

              android {
              compileSdkVersion 26
              defaultConfig {
                  applicationId "com.assignment.ankitt.kotlintwo"
                  minSdkVersion 19
                  targetSdkVersion 26
                  versionCode 1
                  versionName "1.0"
                  testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
              }
              buildTypes {
                  release {
                      minifyEnabled false
                      proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
                  }
              }
          
              androidExtensions {
                  experimental = true
              }
          }
          

          【讨论】:

            猜你喜欢
            • 2021-03-14
            • 1970-01-01
            • 2015-10-23
            • 1970-01-01
            • 2021-10-16
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多