Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android include layout dynamically with data-binding library

I'm using MVVM framework for Android application with data-binding library.

I have some reusable compoments, that should have every activity. f.e. toolbar, menu, floating action button.

I want to create a generic activity, that will implement all these reusable features and then every activity class will be inherited from this generic activity. I also have GenericViewModel class and every other ViewModel is inherited from this generic class.

But I have a problem with layout. I want to create generic layout file and include there sublayout dinamically. f.e.

    <?xml version="1.0" encoding="utf-8"?>
<layout 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">

    <data>

        <variable
            name="data"
            type="com.mypackage.genericViewModel" />
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <include
            bind:data="@{data}"
            layout="@layout/toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

        <include
            layout="@{Here i want to have dynamic variable}"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </LinearLayout></layout>

I do not want to copy / paste this code for each activity, but data-binding library does not allow to include layout dynamically. Is there any solution for such cases?

like image 473
Sandro Gedevanishvili Avatar asked Apr 04 '16 13:04

Sandro Gedevanishvili


1 Answers

Here is my solution,hope it will help you,I do not think it's a good way.If you find a better way,please tell me .thanks!

Although data-binding library does not allow to include layout dynamically,we can use different ViewModel for different layout .I used a LinearLayout as a container to host dynamic layout,then override Activity setContentView method to add view to my container(LinearLayout).

GenericActivity

    protected GenericViewBinding mBinding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);           
        mBinding = DataBindingUtil.setContentView(this, R.layout.generic_view);        
}

    @Override
    public void setContentView(View view) {
        LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        mBinding.container.addView(view,lp);
}

generic_view layout

    <data>
        <variable
            name="genericViewModel"
            type=".viewModel.GenericViewModel"/>
    </data>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/white">
        <!--a custom view,some generic layout -->
        <.view.base.BaseTitleView 
            android:id="@+id/base_title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
        <LinearLayout
            android:id="@+id/container"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_below="@id/base_title"
            android:orientation="vertical">
        </LinearLayout>
    </RelativeLayout>

In concrete Activity you use it like this:

ConcreteActivity

//different layout use different ViewModel here,generic logic&layout is in GenericActivity&generic_view layout.
private ActivityConcreteBinding mActivityConcreteBinding;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mActivityConcreteBinding = DataBindingUtil.inflate(getLayoutInflater(), R.layout.activity_concrete,null,false);
    setContentView(mActivityConcreteBinding.getRoot());
    ConcreteViewModel concreteViewModel = new ConcreteViewModel(mBinding);//mBinding from GenericActivity, deliver it into ConcreteViewModel to do some generic logic.
    ...
}

For me ,no need to copy paste generic layout for every activity any more.

like image 195
Yelin Wu Avatar answered Nov 19 '22 12:11

Yelin Wu