Search code examples
androidandroid-fragmentsdata-binding

Same databinding layout in different fragment


I got question for implementing same data binding layout in 2 fragment.
Example :
fragment_example.xml it will use by ExampleBasicToolbarFragment and ExampleToolbarImageFragment. in each fragment have onclick function.
How to achieve that?

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <data>
        <variable
            name="toolbarFragment"
            type="example.toolbar.ExampleBasicToolbarFragment" />

        <variable
            name="imageToolbarfragment"
            type="example.toolbar.ExampleToolbarImageFragment" />
    </data>

    <id.co.cicil.libs.core.view.viewstate.ViewState
        style="@style/Layout.Match"
        android:id="@+id/viewState">
        <LinearLayout
            android:id="@+id/linear"
            style="@style/Layout.Match"
            android:orientation="vertical"
            android:gravity="center">
            <androidx.appcompat.widget.AppCompatTextView
                style="@style/TextContent.Normal"
                android:text="INI FRAGMENT"/>
            <com.google.android.material.button.MaterialButton
                android:id="@+id/btnSnackbar"
                style="@style/Button.Orange"
                android:text="coba snackbar"
                app:safeOnClick="@{**HOW I PASS MY FUNCTION TO THIS??**}"/>
        </LinearLayout>
    </id.co.cicil.libs.core.view.viewstate.ViewState>
</layout>

Solution

  • Use abstraction principle if you need the ability to generalize several classes by extending an interface or abstract class.

        <data>
            <variable
                name="customInterface"
                type="example.toolbar.CustomInterface" />
        </data>
    
        ...
    
                <com.google.android.material.button.MaterialButton
                    android:id="@+id/btnSnackbar"
                    style="@style/Button.Orange"
                    android:text="coba snackbar"
                    app:safeOnClick="@{() -> customInterface.performClick()}"/>
    

    This interface will force extending classes to implement certain behaviour (certain methods). An example:

    package example.toolbar
    
    interface CustomInterface {
        void performOnClick();
    }
    

    Both of your fragments now can implement this interface. You will be able to pass the interface instance into view binding instance. An example:

    class ExampleBasicToolbarFragment extends Fragment, CustomInterface {
        
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            // create view binding instance
            viewBinding.customInterface = this
        }
    
        @Override
        void performOnClick() {
            ...
        }
    }
    
    class ExampleToolbarImageFragment extends Fragment, CustomInterface {
        
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            // create view binding instance
            viewBinding.customInterface = this
        }
    
        @Override
        void performOnClick() {
            ...
        }
    }