如何解决与 Jetpack 导航一起使用时,TextField 会中断组合?
我一直在尝试使用 Compose 1.0.0-beta09、Kotlin 1.5.10 和 Jetpack Navigation 2.3.4 将一个简单的应用程序组合在一起。 该应用有一个活动和两个片段。
第一个(主要)片段/屏幕(点击按钮将我带到第二个片段/屏幕):Screen One screenshot
第二个片段:/屏幕:Screen Two screenshot
问题:在与第一个屏幕上的 TextField 交互(将光标置于其中)并随后单击按钮后,第二个屏幕加载但为空(调用了 SecondFragment 的 onCreateView 但 setContent 不起作用/屏幕没有重新组合?)。 如果我不与 TextField 交互,问题就不会发生。 我已经在 API 级别 28 和 30、compose 1.0.0-beta0709、Kotlin 1.4.32 和 1.5.10 的模拟器上进行了测试,结果相似。
主要课程:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
AndroidViewBinding(ContentMainBinding::inflate)
}
}
}
class FirstFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,container: ViewGroup?,savedInstanceState: Bundle?
): View = ComposeView(inflater.context).apply {
setContent {
FirstScreen( onButtonClick = {
findNavController().navigate(R.id.nav_second_fragment)
})
}
}
}
@Composable
fun FirstScreen(onButtonClick: () -> Unit) {
Column {
Text("Screen One",color = Color.Blue,fontSize = 30.sp)
Button(
onClick = {
onButtonClick() },content = {
Text(text = "go to Screen Two",color = Color.White)
})
TextField(
value = "",onValueChange = {},label = { Text(stringResource(R.string.label_enter_value)) },)
}
}
class SecondFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,savedInstanceState: Bundle?
): View = ComposeView(inflater.context).apply {
setContent {
Column {
Text("Screen Two",fontSize = 30.sp)
}
}
}
}
plugins {
id 'com.android.application'
id 'kotlin-android'
}
android {
compileSdk 30
defaultConfig {
applicationId "com.example.composewithnavigation"
minSdk 28
targetSdk 30
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary true
}
}
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'
useIR = true
}
buildFeatures {
compose true
viewBinding true
}
compoSEOptions {
kotlinCompilerExtensionVersion compose_version
kotlinCompilerVersion '1.5.10'
}
}
dependencies {
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.compose.ui:ui:$compose_version"
implementation "androidx.compose.material:material:$compose_version"
implementation "androidx.compose.ui:ui-tooling:$compose_version"
implementation "androidx.compose.ui:ui-viewbinding:$compose_version"
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
implementation 'androidx.activity:activity-compose:1.3.0-beta01'
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.4'
implementation 'androidx.navigation:navigation-ui-ktx:2.3.4'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_version"
}
解决方法
据我所知,Compose 中不鼓励使用 Fragment 进行导航。您应该创建多个屏幕,例如此处的 FirstScreen Composable。无论如何,我认为没有调用 setContent 的原因是它是从第一个片段的另一个 setContent 中调用的。在 setContent 中,您进行导航调用,将其重定向到第二个片段,该片段再次调用 setContent。因为第二个片段已经显示在 FirstScreen Composable 的 setContent 中,您实际上是在嵌套它, compose 可能不支持它,(我的意思是,有道理)。
这就是为什么我们建议放弃 Fragment 并使用 Composables 代替,这不需要显式调用 setContent
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。