Android problem creating multiple AutoCompleteTextViews dynamically

Viewed 79

I want to dynamically create input views, which each contain an AutoCompleteTextView. Each AutoCompleteTextView shows a Dropdown list.

I have defined an item view (item_new_product.xml), which gets inflated and added to the viewContainer (activity_main.xml).

Each AutoCompleteTextView has defined a dropDownAnchor in xml, which is the view ID of its parent TextInputLayout. This is where the dropdown list should show up.

For the first item the Dropdown appears in the right place (see Screenshot 1). But each additional Dropdown is associated to the first AutoCompleteTextView's TextInputLayout, because they all have the same dropDownAnchor id(see Screenshot 2).

Is there a clean way to show the Dropdown lists at the right place having multiple dynamically created AutoCompleteTextViews? I have not found anything related to this specific issue.

activity_main.xml

<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="match_parent"
    tools:context=".MainActivity">

    <com.google.android.material.card.MaterialCardView
        android:id="@+id/cardView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="16dp"
        android:backgroundTint="@android:color/holo_blue_dark"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">


        <com.google.android.material.button.MaterialButton
            android:id="@+id/addButton"
            android:layout_width="52dp"
            android:layout_height="52dp"
            android:layout_gravity="start"
            android:background="@color/holo_blue_bright"
            android:elevation="5dp"
            android:text="+" />

        <com.google.android.material.button.MaterialButton
            android:id="@+id/removeButton"
            android:layout_width="52dp"
            android:layout_height="52dp"
            android:layout_gravity="end"
            android:background="@color/holo_blue_bright"
            android:elevation="5dp"
            android:text="-" />

    </com.google.android.material.card.MaterialCardView>

    <LinearLayout
        android:id="@+id/viewContainer"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:layout_margin="16dp"
        android:animateLayoutChanges="true"
        android:background="@color/holo_blue_dark"
        android:orientation="vertical"
        android:padding="8dp"
        app:layout_constraintTop_toBottomOf="@id/cardView"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        >
    </LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

item_new_product.xml

<androidx.constraintlayout.widget.ConstraintLayout 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">

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:orientation="vertical"
        app:layout_constraintGuide_percent=".5" />

    <com.google.android.material.textfield.TextInputLayout
        android:id="@+id/productText"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_margin="16dp"
        android:hint="Product"
        app:hintTextColor="@color/holo_blue_dark"
        app:helperText=" "
        app:boxBackgroundColor="@color/holo_blue_bright"
        app:boxStrokeColor="@color/holo_blue_dark"
        app:layout_constraintEnd_toStartOf="@+id/guideline"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <com.google.android.material.textfield.TextInputEditText
            android:id="@+id/productEditText"
            android:layout_width="match_parent"
            android:layout_height="52dp"
            android:textSize="12sp"
            android:imeOptions="actionNext"
            android:inputType="textPersonName"
            android:textCursorDrawable="@null" />
    </com.google.android.material.textfield.TextInputLayout>

    <com.google.android.material.textfield.TextInputLayout
        android:id="@+id/productTypeLayout"
        style="@style/DropdownLayoutStyle"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_margin="16dp"
        android:hint="Type"
        app:helperText=" "
        android:inputType="none"
        app:boxBackgroundColor="@color/holo_blue_bright"
        app:boxStrokeColor="@color/holo_blue_dark"
        app:endIconTint="@color/holo_blue_dark"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toEndOf="@id/guideline"
        app:layout_constraintEnd_toEndOf="parent">

        <AutoCompleteTextView
            android:id="@+id/productTypeAutoCompleteTv"
            android:layout_width="match_parent"
            android:layout_height="52dp"
            android:dropDownAnchor="@id/productTypeLayout"
            android:dropDownHeight="120dp"
            android:inputType="none"
            android:maxLines="1"
            android:textSize="12sp"
            android:singleLine="true"
            android:paddingStart="16dp"
            android:paddingEnd="16dp"/>

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

</androidx.constraintlayout.widget.ConstraintLayout>

MainActivity.kt

class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding
    
    private var IDs = mutableListOf<Int>()
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    
        binding = ActivityMainBinding.inflate(layoutInflater)
    
        binding.addButton.setOnClickListener {
            Timber.d("add clicked")
            addView()
        }
        binding.removeButton.setOnClickListener {
            Timber.d("remove clicked")
            removeView()
        }
      
        setContentView(binding.root)
    }
    
    private fun addView() {
        Timber.d("addView")
        val rootView = binding.viewContainer
        val inflater = LayoutInflater.from(this)
        val child: View = inflater.inflate(R.layout.item_new_product, rootView, false)
        // generate new view id and remember it for later removal
        val childId = View.generateViewId()
        child.id = childId
        IDs.add(childId)
    
        val items: List<String> = listOf("Beverages", "Cocktails", "Pasta", "Pizza", "Salads")
        val adapter = ArrayAdapter(this, R.layout.item_product_dropdown, items)
    
        val productAutoComplete =
            child.findViewById(R.id.productTypeAutoCompleteTv) as AutoCompleteTextView
        productAutoComplete.setAdapter(adapter)
        rootView.addView(child)
    }

    private fun removeView() {
        if (IDs.size == 0) {
            return
        }
        val view: View? = findViewById<View>(IDs.last())
        IDs.removeLast()
        if (view != null) {
            (view.parent as ViewGroup).removeView(view)
        }
    }

styles.xml

<resources>
    <style name="DropdownLayoutStyle" parent="Widget.MaterialComponents.TextInputLayout.FilledBox.ExposedDropdownMenu">
        <item name="endIconTint">@color/holo_blue_dark</item>
        <item name="hintTextColor">@color/holo_blue_dark</item>
    </style>
</resources>

item_product_dropdown.xml

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="52dp"
    android:background="@color/holo_blue_bright"
    android:maxLines="1"
    android:padding="16dp"
    android:textColor="@color/white" />
0 Answers
Related