Search code examples
androiddata-bindingkotlinandroid-recyclerviewandroid-databinding

Find similar views from DataBinding instance


I'm using Android DataBinding and looking for a way to get references to a/set view(s) from the ViewDataBinding instance.

I'm looking for a way to find view(s) by a unique identifier, in this code below, is it possible to get all the views that have the same tag "MYTAG" in xml from my data binding instance(in Activity,Fragment class)?

android:tag="MYTAG"

My Actual use case is, that I need to know all the views that have the 'android:transitionName' attribute set in xml to make Scene Transition Animation (where I need to pass all the shared views and TransitionName in Bundle options when start new start activity which going to animate)

Currently Im using findViewById() to get all the interested views but I'm looking for a way to archive the same by just using data-binding without manully finding view by it's IDs

This is my xml layout :

`

<data>
    <variable name="item" type="demo.com.entities.Recommendation" />
</data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="?android:attr/selectableItemBackground"
        >



        <ImageView
            android:id="@+id/room_card_icon"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:scaleType="fitXY"
            app:layout_constraintBottom_toTopOf="@+id/guide75"
            app:layout_constraintTop_toTopOf="parent"
            app:srcCompat="@drawable/tour_placeholder"
            android:transitionName="@{item.uid}"
            app:imageUrl="@{item.image}"
            android:tag="MYTAG"
            />

        <TextView
            android:id="@+id/title_recommendations"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toBottomOf="@+id/room_card_icon"
            app:layout_constraintStart_toStartOf="parent"
            android:transitionName="@{`title`+item.uid}"
            android:text="@{item.poi.name}"
            tools:text="The Southern Ridges"
            android:tag="MYTAG"
             />

        <TextView
            android:id="@+id/typeTV"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toTopOf="@+id/title_recommendations"
            app:layout_constraintStart_toStartOf="@+id/title_recommendations"
            android:transitionName="@{`Category`+item.uid}"
            android:text="@{item.poi.dataset}"
            tools:text="Attractions"
            android:tag="MYTAG" />

        <TextView
            android:id="@+id/descriptionTV"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/guide75"
            android:text="@{item.recommendation}"
            tools:text="A magical place in nature. Take a morning walk or go for a sunset walk" />

           <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guide75"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_percent="0.75" />

    </androidx.constraintlayout.widget.ConstraintLayout>

`

Thank you in advance!


Solution

  • My question ends up as a stupid question! After I read this 😩 I should have solved this simply.

    Anyways to answer my own question:

    I should get the root view from binding instance ( "mBinding.getRoot()" ) and the then can iterate through the child views to find views by almost using anything, by any attributes (Eg: By Tag or by transitionName, etc..).

    In My case I can directly get all the child views that have a 'transitionName' name set.

       private fun getAllViewsWithTransitionName(root: ViewGroup): List<View> {
            val views = mutableListOf<View>()
            val childCount = root.childCount
            for (i in 0 until childCount) {
                val child = root.getChildAt(i)
                if (child is ViewGroup) {
                    views.addAll(getAllViewsWithTransitionName(child))
                }
    
                val tagObj = child.transitionName
                if (!tagObj.isNullOrBlank()) {
                    views.add(child)
                }
    
            }
            return views
        }

    And now can call this to get the list of all the views that have TransitionName

    getAllViewsWithTransitionName(mBinding.root)
    

    Same thing can be used to get all views that have the same tag defined in XML. By simply replace this line :

    val tagObj = child.transitionName

    to

    val tagObj = child.tag

    Thanks!!!!