Android Kotlin 将片段膨胀到容器中失败



我在我的 Android 项目中使用Kotlin,在将片段添加到容器时,我收到一条错误消息,指出特定 Id 的视图不可用并且应用程序崩溃。这是从添加第二个片段开始发生的。

首先,我认为这可能是约束布局的问题,并将活动布局实现更改为相对布局实现,并意识到它在这种情况下没有问题。这是某种奇怪的行为,因为我在 Java 中做了同样的事情,它工作正常,在我的实现中没有找到任何解决方案或可见的问题。

我的活动布局是这样实现的

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentStart="true" />
</RelativeLayout>

我的片段交易是这样完成

supportFragmentManager
.beginTransaction()
.add(R.id.content_frame, CreateAccountFragment.newInstance())
.addToBackStack(CreateAccountFragment.javaClass.simpleName)
.commit()

我的片段实现如下所示

片段布局

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="viewModel"
type="test.feature.createAccount.CreateAccountViewModel"/>
</data>
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- AppBar and Toolbar -->
<include
android:id="@+id/include"
layout="@layout/appbar_layout"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/padding_m"
android:layout_marginEnd="@dimen/padding_m"
android:layout_marginStart="@dimen/padding_m"
android:layout_marginTop="@dimen/padding_xxl"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/include"
app:layout_constraintVertical_bias="0.0"
app:srcCompat="@drawable/test_logo_large" />
<!-- Content -->
<test.feature.shared.EditTextWithIcon
android:id="@+id/nameEditTextWithLabel"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="40dp"
android:layout_marginStart="40dp"
android:layout_marginTop="32dp"
android:imeOptions="actionNext"
android:nextFocusDown="@+id/passwordEditTextWithLabel"
app:edit_text_email="true"
app:edit_text_hint="@string/name_hint"
app:edit_text_icon="@drawable/ic_name_24dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/imageView"
app:text="@{viewModel.email}" />
<test.feature.shared.EditTextWithIcon
android:id="@+id/emailEditTextWithLabel"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="40dp"
android:layout_marginStart="40dp"
android:imeOptions="actionNext"
android:nextFocusDown="@+id/passwordEditTextWithLabel"
app:edit_text_email="true"
app:edit_text_hint="@string/email_hint"
app:edit_text_icon="@drawable/ic_email_24dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/nameEditTextWithLabel"
app:text="@{viewModel.email}" />
<test.feature.shared.EditTextWithIcon
android:id="@+id/passwordEditTextWithLabel"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="40dp"
android:layout_marginStart="40dp"
android:imeOptions="actionDone"
app:edit_text_hint="@string/password_hint"
app:edit_text_icon="@drawable/ic_password_24dp"
app:edit_text_password="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/emailEditTextWithLabel"
app:text="@{viewModel.password}" />
<test.feature.shared.CheckBoxWithHint
android:id="@+id/acceptTermsCheckBox"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="40dp"
android:layout_marginStart="40dp"
app:checkbox_text="@string/accept_saving_data_checkbox_text"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/passwordEditTextWithLabel" />
<Button
android:id="@+id/goToSignUpButton"
style="@style/SecondaryButton"
android:text="@string/sign_up_button"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/acceptTermsCheckBox" />
</android.support.constraint.ConstraintLayout>
</layout>

片段类

class CreateAccountFragment : Fragment() {
companion object {
fun newInstance(): CreateAccountFragment {
return CreateAccountFragment()
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
retainInstance = true
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_create_account, container, false)
}
private val viewModel: CreateAccountViewModel by lazy {
ViewModelProviders.of(this).get(CreateAccountViewModel::class.java)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
//setup ui
setTitle(R.string.create_account_title)
setSupportActionBar(toolbar)
val binding = activity?.let { DataBindingUtil.setContentView<FragmentCreateAccountBinding>(it, R.layout.fragment_create_account) }
binding?.viewModel = viewModel
binding?.setLifecycleOwner(activity)
binding?.executePendingBindings()
nameEditTextWithLabel.toObservableValue().subscribe {
viewModel.setName(it)
}
emailEditTextWithLabel.toObservableValue().subscribe {
viewModel.setEmail(it)
}
passwordEditTextWithLabel.toObservableValue().subscribe {
viewModel.setPassword(it)
}
}
}

当应用程序崩溃时,日志如下所示

08-22 14:48:25.393 6905-6905/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: ec.test.android.debug, PID: 6905
java.lang.IllegalArgumentException: No view found for id 0x7f09003c (ec.test.android.debug:id/content_frame) for fragment CreateAccountFragment{82d27b9 #1 id=0x7f09003c}
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1422)
at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1759)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1827)
at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:797)
at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2596)
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2383)
at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2338)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2245)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:703)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

我无法确定崩溃的原因,它添加了第一个片段,从下一个片段中它给出了此错误并崩溃。

尝试使用替换方法而不是添加方法。

supportFragmentManager
.beginTransaction()
.replace(R.id.content_frame, CreateAccountFragment.newInstance())
.addToBackStack(CreateAccountFragment.javaClass.simpleName)
.commit()

最新更新