2

I've encountered a weird behaviour when using a Custom View together with a Navigation Component and a back button.

For user text input, I'm using the Material Design text field (which is a combination of TextInputLayout and TextInputEditText). In order to avoid code duplication, I've created a Custom View - CustomTextField (following this guide) that combines those two views into a single one.

I'm also using Navigation Component to navigate between Fragments in a single Activity.

The problem - in my LoginFragment, I'm using 2 instances of that Custom View to display fields for user input. The weird behaviour happens when I input 2 different values into those text fields, navigate to another Fragment (using the Register button - for now it's just a blank Fragment) and then using a Back button (or gesture) to go back into the LoginFragment. Value (text) of the first text field becomes a duplicate of the second text field.

For example: (screenshots uploaded as links as it's my first question on StackOverflow ever and I'm not allowed to insert them directly to the question)

LoginFragment with 2 different values provided by user

LoginFragment after navigating to another fragment and going back using the button/gesture - first field is now a duplicate of "pass"

In order to troubleshoot the issue, I've reduced the code to minimum but the problem still happens. Here's the code I'm using:

Custom Text Field xml (custom_text_field.xml):

<?xml version="1.0" encoding="utf-8"?>
<merge
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.google.android.material.textfield.TextInputLayout
        android:id="@+id/customTextLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <com.google.android.material.textfield.TextInputEditText
            android:id="@+id/customEditText"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

    </com.google.android.material.textfield.TextInputLayout>
</merge>

Custom Text Field class:

class CustomTextField(context: Context, attrs: AttributeSet): LinearLayout(context, attrs) {

    init {
        inflate(context, R.layout.custom_text_field, this)
    }
}

Usage of the CustomTextField in LoginFragment xml:

        <com.example.app.views.CustomTextField
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

        <com.example.app.views.CustomTextField
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

Navigation to another fragment is done using:

        binding = FragmentLoginBinding.inflate(layoutInflater)

        binding.buttonRegister.setOnClickListener {
            findNavController().navigate(R.id.action_loginFragment_to_registerFragment)
        }

I've also noticed that not only the text is "duplicated" but also some other properties like for example hint. Some properties like inputType are working just as expected and are not duplicated.

I'd appreciate any help with troubleshooting of that issue. Thank you in advance!

Falco
  • 23
  • 2

2 Answers2

2

This is to do with the way that the system restores view state. By default the ID is used to uniquely identify a view for state restoration, so having a duplicate ID for your TextInputEditText would explain the mirrored state.

Henry Twist
  • 5,666
  • 3
  • 19
  • 44
  • Thank you - in the meantime I've stumpled upon an already existing question regarding that issue. Here is the question if someone else is looking for solution - [link](https://stackoverflow.com/questions/45818015/restore-fragment-with-two-views-having-the-same-id) – Falco Apr 29 '21 at 11:15
  • Ah then I would close this one as a duplicate of the other one to keep the site tidy. – Henry Twist Apr 29 '21 at 11:17
0

you just need add, on custome view

binding.edittext.setId(getId());