【问题标题】:Android <include> layout change after navigateUp()navigateUp() 后的 Android <include> 布局更改
【发布时间】:2021-06-09 09:42:08
【问题描述】:

我有一个包含两个片段的活动。我创建了一个可重复使用的布局,如下所示:

这是自定义布局的xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 
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:layout_width="match_parent"
android:layout_height="wrap_content">

<androidx.appcompat.widget.AppCompatTextView
    android:id="@+id/tvFormTitle"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textColor="@color/black1"
    android:textSize="@dimen/ssp_10"
    android:visibility="visible"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    tools:text="Email" />

<androidx.constraintlayout.widget.ConstraintLayout
    android:id="@+id/clForm"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="@dimen/sdp_4"
    android:background="@drawable/sh_all_round_form"
    android:paddingStart="@dimen/sdp_12"
    android:paddingEnd="@dimen/sdp_12"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/tvFormTitle">

    <androidx.appcompat.widget.AppCompatEditText
        android:id="@+id/etForm"
        style="@style/et_form"
        android:layout_width="0dp"
        android:layout_weight="1"
        app:layout_constraintEnd_toStartOf="@+id/ivSwitchPassword"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <androidx.appcompat.widget.AppCompatImageView
        android:id="@+id/ivSwitchPassword"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:paddingStart="@dimen/sdp_8"
        android:paddingTop="@dimen/sdp_8"
        android:paddingEnd="@dimen/sdp_2"
        android:paddingBottom="@dimen/sdp_8"
        android:src="@drawable/ic_eye"
        android:visibility="gone"
        app:layout_constraintBottom_toBottomOf="@+id/etForm"
        app:layout_constraintEnd_toStartOf="@+id/ivCancel"
        app:layout_constraintTop_toTopOf="@+id/etForm" />

    <androidx.appcompat.widget.AppCompatImageView
        android:id="@+id/ivCancel"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:paddingStart="@dimen/sdp_12"
        android:paddingTop="@dimen/sdp_12"
        android:paddingBottom="@dimen/sdp_12"
        android:src="@drawable/white_close"
        android:visibility="gone"
        app:layout_constraintBottom_toBottomOf="@+id/etForm"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="@+id/etForm"
        app:tint="@color/grey_shade5" />
</androidx.constraintlayout.widget.ConstraintLayout>

<androidx.appcompat.widget.AppCompatTextView
    android:id="@+id/tvMessage"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="@dimen/sdp_5"
    android:textColor="@color/colorError"
    android:textSize="@dimen/ssp_10"
    android:visibility="visible"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/clForm"
    tools:text="This field is required" />

</androidx.constraintlayout.widget.ConstraintLayout>

我在 Fragment A 中使用这个自定义 la 如下:

                <include
                    android:id="@+id/email"
                    layout="@layout/layout_form_edittext"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="@dimen/sdp_36"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toBottomOf="@+id/tvDescription" />

                <include
                    android:id="@+id/password"
                    layout="@layout/layout_form_edittext"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="@dimen/sdp_12"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toBottomOf="@+id/email" />

我正在使用片段导航从片段 A 移动到 B。在电子邮件和密码中输入值并移动到片段 B,然后通过按返回或 navigateUp() 返回片段 A。电子邮件字段包含密码字段的值。

编辑:

它在自定义复合类中使用的布局与以下问题相同。

class FormView @JvmOverloads
constructor(
private val ctx: Context,
private val attributeSet: AttributeSet? = null,
private val defStyleAttr: Int = 0
) : ConstraintLayout(ctx, attributeSet, defStyleAttr) {

private var formTitle = ""
private var passwordType = false
private var showMessage = false

init {
    val inflater = ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
    val attributes = ctx.obtainStyledAttributes(attributeSet, R.styleable.FormView)
    attributes.getString(R.styleable.FormView_formTitle)?.let { formTitle = it }
    passwordType = attributes.getBoolean(R.styleable.FormView_passwordType, passwordType)
    showMessage = attributes.getBoolean(R.styleable.FormView_showErrorMessage, false)
    attributes.recycle()

    inflater.inflate(R.layout.layout_form_edittext, this)

    setTitle(formTitle)
    setPasswordType(passwordType)
    errorMessageVisibility(showMessage)
    borderVisibility(false)


    ivSwitchPassword.setOnClickListener {
        updatePasswordVisibility()
    }

    ivCancel.setOnClickListener {
        etForm.text?.clear()
        clearError()
    }
}

fun showError(msg: String) {
    msg?.let {
        tvMessage.text = it
        cancelBtnVisibility(true)
        errorMessageVisibility(true)
        borderVisibility(true)
    }
}

fun clearError() {
    tvMessage.text = ""
    cancelBtnVisibility(false)
    errorMessageVisibility(false)
    borderVisibility(false)
}

private fun errorMessageVisibility(flag: Boolean) {
    if (flag) tvMessage.visible() else tvMessage.gone()
}

private fun cancelBtnVisibility(flag: Boolean) {
    if (flag) ivCancel.visible() else ivCancel.gone()
}

private fun borderVisibility(flag: Boolean) {
    val drawable = clForm.background as GradientDrawable
    if(flag) drawable.setStroke(1, Color.parseColor("#c32329"))
    else drawable.setStroke(0, Color.TRANSPARENT)
}

fun setPasswordType(passwordType: Boolean) {
    if(!passwordType) ivSwitchPassword.gone()
    else {
        ivSwitchPassword.visible()
        etForm.inputType = InputTypeUtils.getInputTypeByProperty("textPassword")
    }
}

fun setTitle(title: String) {
    tvFormTitle.text = title
}

private fun updatePasswordVisibility() {
    if (etForm.transformationMethod is PasswordTransformationMethod) {
        etForm.transformationMethod = null
    } else {
        etForm.transformationMethod = PasswordTransformationMethod()
    }
    etForm.setSelection(etForm.length())
}
}

【问题讨论】:

    标签: android android-fragments navigation android-custom-view


    【解决方案1】:

    这是因为包含编辑文本对于两个字段都有一个 id,解决方案是生成新的 id 在 onViewCreated 方法中添加此代码:

    email.etForm.id = View.generateViewId()
    password.etForm.id = View.generateViewId()
    

    【讨论】:

    • 但如果我使用活动,它工作正常。另外实际上我没有使用 ,我使用的是自定义类我已经更新了问题你能建议如何在自定义复合类 FormView 中使用 generateViewId。
    • 因为从 backstack 视图返回的片段被重新创建,如果你现在使用不包含你不需要生成 Id
    猜你喜欢
    • 1970-01-01
    • 2021-07-14
    • 1970-01-01
    • 2016-11-03
    • 2011-11-05
    • 1970-01-01
    • 2014-03-23
    • 2017-02-06
    • 2021-10-03
    相关资源
    最近更新 更多