我在将数据从一个片段传递到另一个片段时遇到问题。我通过 Safe Args 插件发送数据对象,例如自定义 parcelable。有两个嵌套数据类,当我在 navigation.xml 中将 argType 设置为该数据类的路径时,使用点表示法 (Movies.Result),应用程序崩溃并从标题中显示此错误。它仅适用于 $ 符号 (Movies$Result),但问题在于片段中的其他数据。
数据期望 Movies.Result 但找到Movies$Result
。无论错误如何,应用程序都能正常工作,但看到红色下划线很麻烦。如何摆脱这个问题?
MoviesModel.kt
@Parcelize
data class Movies ( val results : List<Result>) : Parcelable {
@JsonClass(generateAdapter = true)
@Parcelize
data class Result(
val id: Int,
val title: String,
val overview: String,
@Json(name = "poster_path")
val posterPath: String,
@Json(name = "vote_average")
val voteAverage: String
): Parcelable
}
导航.xml
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/nav_graph"
app:startDestination="@id/introFragment">
<fragment
android:id="@+id/introFragment"
android:name="com.example.androidwebapi.screens.intro.IntroFragment"
android:label="fragment_intro"
tools:layout="@layout/fragment_intro">
<action
android:id="@+id/action_introFragment_to_dataGroupFragment"
app:destination="@id/dataGroupFragment" />
</fragment>
<fragment
android:id="@+id/dataGroupFragment"
android:name="com.example.androidwebapi.screens.datagroup.DataGroupFragment"
android:label="fragment_data_group"
tools:layout="@layout/fragment_data_group">
<action
android:id="@+id/action_dataGroupFragment_to_moviesFragment"
app:destination="@id/moviesFragment" />
</fragment>
<fragment
android:id="@+id/aboutFragment"
android:name="com.example.androidwebapi.screens.AboutFragment"
android:label="AboutFragment"
tools:layout="@layout/fragment_about" />
<fragment
android:id="@+id/moviesFragment"
android:name="com.example.androidwebapi.screens.movies_overview.MoviesFragment"
android:label="MoviesFragment"
tools:layout="@layout/fragment_movies">
<action
android:id="@+id/action_showDetails"
app:destination="@id/detailsFragment" />
</fragment>
<fragment
android:id="@+id/detailsFragment"
android:name="com.example.androidwebapi.screens.details.DetailsFragment"
android:label="DetailsFragment"
tools:layout="@layout/fragment_details">
<argument
android:name="selectedMovie"
app:argType="com.example.androidwebapi.network.Movies$Result" />
</fragment>
</navigation>
DetailsFragment.kt
package com.example.androidwebapi.screens.details
import android.content.Intent
import android.os.Bundle
import android.view.*
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import com.example.androidwebapi.R
import com.example.androidwebapi.databinding.FragmentDetailsBinding
import com.example.androidwebapi.network.Movies
class DetailsFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
val application = requireNotNull(activity).application
val binding = FragmentDetailsBinding.inflate(inflater)
binding.lifecycleOwner = this
val movie = DetailsFragmentArgs.fromBundle(requireArguments()).selectedMovie
val viewModelFactory = DetailsViewModelFactory(movie, application)
binding.viewModel = ViewModelProvider(
this, viewModelFactory).get(DetailsViewModel::class.java)
setHasOptionsMenu(true)
return binding.root
}
// Creating our Share Intent
private fun getShareIntent() : Intent {
val args = DetailsFragmentArgs.fromBundle(requireArguments()).selectedMovie
val shareIntent = Intent(Intent.ACTION_SEND)
shareIntent.setType("text/*")
.putExtra(Intent.EXTRA_TEXT, getString(R.string.share_movie_details_text, args))
return shareIntent
}
private fun shareSuccess() {
startActivity(getShareIntent())
}
// Showing the Share Menu Item Dynamically
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
super.onCreateOptionsMenu(menu, inflater)
inflater.inflate(R.menu.summary_menu, menu)
if(getShareIntent().resolveActivity(requireActivity().packageManager)==null){
menu.findItem(R.id.share).isVisible = false
}
}
// Sharing from the Menu
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when(item.itemId){
R.id.share -> shareSuccess()
}
return super.onOptionsItemSelected(item)
}
}
这些代码行会导致问题:
val movie = DetailsFragmentArgs.fromBundle(requireArguments()).selectedMovie,
val viewModelFactory = DetailsViewModelFactory(movie, application)
其中参数电影期望 Movies.Result 但找到 Movies$Result
项目build.gradle
:
buildscript {
ext {
kotlin_version = "1.4.32"
navigationVersion = "2.3.5"
version_retrofit = "2.9.0"
version_recyclerview = "1.0.0"
version_lifecycle = "2.2.0"
version_moshi = "1.8.0"
version_glide = "4.8.0"
}
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.2.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$navigationVersion"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
模块:build.gradle
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-parcelize'
id 'kotlin-kapt'
id 'androidx.navigation.safeargs'
}
android {
compileSdkVersion 30
buildToolsVersion "30.0.3"
android.defaultConfig.vectorDrawables.useSupportLibrary = true
defaultConfig {
applicationId "com.example.androidwebapi"
minSdkVersion 19
targetSdkVersion 30
versionCode 1
versionName "1.0"
multiDexEnabled true
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
buildFeatures {
viewBinding true
dataBinding true
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = JavaVersion.VERSION_1_8.toString()
}
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
implementation 'androidx.core:core-ktx:1.5.0'
implementation 'androidx.appcompat:appcompat:1.3.0'
implementation 'com.google.android.material:material:1.3.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
implementation "androidx.navigation:navigation-fragment-ktx:$navigationVersion"
implementation "androidx.navigation:navigation-ui-ktx:$navigationVersion"
implementation "com.google.android.material:material:$version"
implementation 'com.jakewharton.timber:timber:4.7.1'
implementation "com.squareup.moshi:moshi-kotlin:$version_moshi"
implementation "com.squareup.retrofit2:retrofit:$version_retrofit"
implementation "com.squareup.retrofit2:converter-moshi:$version_retrofit"
implementation 'com.android.support:multidex:1.0.3'
implementation "com.github.bumptech.glide:glide:$version_glide"
}