I am developing an app that has a tab layout as the image.
I’d like to use MVVM architecture with data binding library but I am new with this framework.
I can do this without using MVVM by normally setup tab layout using ViewPager as this sample.
Normal tab layout without MVVM and data binding:
activity_main.xml:
<android.support.design.widget.CoordinatorLayout 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"> <android.support.design.widget.AppBarLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" app:layout_scrollFlags="scroll|enterAlways" app:popupTheme="@style/ThemeOverlay.AppCompat.Light" /> <android.support.design.widget.TabLayout android:id="@+id/tabs" android:layout_width="match_parent" android:layout_height="wrap_content" app:tabMode="fixed" app:tabGravity="fill"/> </android.support.design.widget.AppBarLayout> <android.support.v4.view.ViewPager android:id="@+id/viewpager" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior" /> </android.support.design.widget.CoordinatorLayout>
MainActivity.java:
public class MainActivity extends AppCompatActivity { private Toolbar toolbar; private TabLayout tabLayout; private ViewPager viewPager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); getSupportActionBar().setDisplayHomeAsUpEnabled(true); viewPager = (ViewPager) findViewById(R.id.viewpager); setupViewPager(viewPager); tabLayout = (TabLayout) findViewById(R.id.tabs); tabLayout.setupWithViewPager(viewPager); } private void setupViewPager(ViewPager viewPager) { ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager()); adapter.addFragment(new OneFragment(), "ONE"); adapter.addFragment(new TwoFragment(), "TWO"); adapter.addFragment(new ThreeFragment(), "THREE"); viewPager.setAdapter(adapter); } class ViewPagerAdapter extends FragmentPagerAdapter { private final List<Fragment> mFragmentList = new ArrayList<>(); private final List<String> mFragmentTitleList = new ArrayList<>(); public ViewPagerAdapter(FragmentManager manager) { super(manager); } @Override public Fragment getItem(int position) { return mFragmentList.get(position); } @Override public int getCount() { return mFragmentList.size(); } public void addFragment(Fragment fragment, String title) { mFragmentList.add(fragment); mFragmentTitleList.add(title); } @Override public CharSequence getPageTitle(int position) { return mFragmentTitleList.get(position); } } }
Tab layout in MVVM:
When using MVVM with data binding library, we will have to use a view model for the tab layout view.
And I don’t know how to setup tab layout in the XML and also in the view model. How to handle events such as “tap on one tab of the layout” using data binding library
Is there any sample of using Tab layout in MVVM with data binding library?
Thanks for your help.
Answer
MainActivity –
public class MainActivity extends Activity { @Override protected void onCreate(@Nullable final Bundle savedInstanceState) { super.onCreate(savedInstanceState); App.get(this).component().inject(this); ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main); binding.setHandler(this); binding.setManager(getSupportFragmentManager()); } @BindingAdapter({"bind:handler"}) public static void bindViewPagerAdapter(final ViewPager view, final MainActivity activity) { final MainActionsAdapter adapter = new MainActionsAdapter(view.getContext(), activity.getSupportFragmentManager()); view.setAdapter(adapter); } @BindingAdapter({"bind:pager"}) public static void bindViewPagerTabs(final TabLayout view, final ViewPager pagerView) { view.setupWithViewPager(pagerView, true); } }
xml –
<layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:fresco="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools"> <data> <import type="android.view.View" /> <variable name="handler" type="com.ui.main.MainActivity" /> <variable name="manager" type="android.support.v4.app.FragmentManager" /> </data> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="wrap_content" android:animateLayoutChanges="true" app:title="@string/app_name" app:titleMarginStart="8dp" /> <android.support.design.widget.TabLayout android:id="@+id/tab_layout" android:layout_width="match_parent" android:layout_height="wrap_content" app:pager="@{(pager)}"> </android.support.design.widget.TabLayout> <android.support.v4.view.ViewPager android:id="@+id/pager" android:layout_width="match_parent" android:layout_height="match_parent" app:handler="@{handler}" /> </LinearLayout> </layout>
Adapter –
public class MainSectionsAdapter extends FragmentPagerAdapter { private static final int CONTACTS = 0; private static final int CALLS = 1; private static final int CHATS = 2; private static final int[] TABS = new int[]{CONTACTS, CALLS, CHATS}; private Context mContext; public MainSectionsAdapter(final Context context, final FragmentManager fm) { super(fm); mContext = context.getApplicationContext(); } @Override public Fragment getItem(int position) { switch (TABS[position]) { case CONTACTS: return ContactsFragment.newInstance(); case CALLS: return CallsFragment.newInstance(); case CHATS: return ChatsFragment.newInstance(); } return null; } @Override public int getCount() { return TABS.length; } @Override public CharSequence getPageTitle(int position) { switch (TABS[position]) { case CONTACTS: return mContext.getResources().getString(R.string.contacts); case CALLS: return mContext.getResources().getString(R.string.calls); case CHATS: return mContext.getResources().getString(R.string.chats); } return null; } }