Je développe une application qui a une disposition d'onglet comme image.
J'aimerais utiliser l'architecture MVVM avec la bibliothèque de liaison de données, mais je suis nouveau avec ce cadre.
Je peux le faire sans utiliser MVVM en configurant normalement la mise en page de l'onglet en utilisant ViewPager comme exemple.
Disposition normale des onglets sans MVVM et liaison de données:
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);
}
}
}
Disposition des onglets dans MVVM:
Lors de l'utilisation de MVVM avec la bibliothèque de liaison de données, nous devrons utiliser un modèle de vue pour la vue de présentation des onglets.
Et je ne sais pas comment configurer la disposition des onglets dans le XML et dans le modèle de vue. Comment gérer des événements tels que "appuyer sur un onglet de la mise en page" à l'aide de la bibliothèque de liaison de données
Existe-t-il un exemple d'utilisation de la disposition des onglets dans MVVM avec la bibliothèque de liaison de données?
Merci de votre aide.
Activité principale -
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>
Adaptateur -
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;
}
}
Je ne sais pas si cela a été récemment introduit, mais avec Android Supporte la version 27.1.1, vous n'avez même pas besoin d'un adaptateur de liaison de données personnalisé, vous pouvez simplement utiliser:
<Android.support.design.widget.TabLayout
Android:id="@+id/tl_1"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
app:setupWithViewPager="@{some_fragment_viewpager}"
app:tabSelectedTextColor="@Android:color/white"
app:tabTextColor="@color/v5_grey_55"
/>
<Android.support.v4.view.ViewPager
Android:id="@+id/some_fragment_viewpager"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
app:addOnPageChangeListener="@{vm.pageChangeListener}"
app:setAdapter="@{vm.pageAdapter}"
app:setCurrentItem="@{vm.pageChangeListener.currentPosition}"
/>
Notez que la variable viewPager
dans app:setupWithViewPager="@{some_fragment_viewpager}"
pointe vers Android:id="@+id/some_fragment_viewpager"
. Voilà comment se fait la référence au ViewPager (comme par magie je sais)!
ViewModel
public class SomeViewModel {
public ViewPager.OnPageChangeListener pageChangeListener;
public SomeFragmentPagerAdapter pagerAdapter;
// ...
}
FragmentPagerAdapter
public classs SomeFragmentPagerAdapter extends FragmentPagerAdapter {
public Boolean currentPosition;
}
Voici ma solution pour setUpWithViewpager
en utilisant databinding
:
public class BindingUtil
{
@BindingAdapter({ "setUpWithViewpager" })
public static void setUpWithViewpager(final TabLayout tabLayout, ViewPager viewPager)
{
viewPager.addOnAdapterChangeListener(new ViewPager.OnAdapterChangeListener()
{
@Override
public void onAdapterChanged(@NonNull ViewPager viewPager, @Nullable PagerAdapter oldAdapter, @Nullable PagerAdapter newAdapter)
{
if (oldAdapter == null && (newAdapter == null || newAdapter.getCount() == 0))
{
// this function will helpful when
// we don't create viewpager immediately
// when view created (this mean we create
// will pager after a period time)
return;
}
tabLayout.setupWithViewPager(viewPager);
}
});
}
}
xml
<Android.support.design.widget.TabLayout
...
app:setUpWithViewpager="@{ viewPager }"
/>
<Android.support.v4.view.ViewPager
...
Android:id="@+id/viewPager"
app:adapter="@{viewModel.pagerAdapter}"
/>
ViewModel
public class MainViewModel extends BaseObservable
{
@Bindable
public PagerAdapter getPagerAdapter()
{
return adapter;
}
private void createViewPagerAdapter()
{
...
notifyPropertyChanged(BR.pagerAdapter);
}
}
projet de démonstration complet ici
J'espère que ça aide