MvvmCross: TextView binding inside ViewPager

274 Views Asked by At

Can anyone please suggest binding for TextView inside ViewPager's fragment.

Please have look into below code for investigation.

ViewPager's fragment resource file (about_fragment.axml)

Here i'm trying to bind AboutDetail with ViewModel.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:local="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:background="@android:color/white">
    <TextView
        android:id="@+id/idAboutDetail"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="32.5dp"
        android:layout_marginLeft="25dp"
        android:layout_marginRight="8dp"
        android:textColor="@android:color/black"
        android:textSize="17sp"      
local:MvxBind="Text AboutDetail"/>
</LinearLayout>

ViewPager's fragment VM

DetailViewModel belong to DetailFragment which contains ViewPager.

    [AddINotifyPropertyChangedInterface]
    public class AboutDetailViewModel : MvxViewModel<DetailViewModel>
    {
        public override void Prepare(DetailViewModel parameter)
        {
            AboutDetail = "Yes loaded";
        }

        private string _aboutDetail;
        public string AboutDetail
        {

            get
            {
                return _aboutDetail;
            }

            set
            {

                _aboutDetail = value;

                RaisePropertyChanged(() => AboutDetail);
            }

        }
    }

ViewPager's Fragment

public class UCAboutFragment :BaseFragment<AboutDetailViewModel>
{
    protected override int FragmentId => Resource.Layout.fragment_details_about;

    public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {

        View view = base.OnCreateView(inflater, container, savedInstanceState);

        return view;
    }

}

DetailFragment code which contains ViewPager.

DetailPagerAdapter pageAdapter = new DetailPagerAdapter(ChildFragmentManager);
            ViewPager pager = thisView.FindViewById<ViewPager>(Resource.Id.viewpager);

            pager.Adapter = pageAdapter;

            TabLayout tabLayout = thisView.FindViewById<TabLayout>(Resource.Id.tabs);
            tabLayout.SetupWithViewPager(pager);

DetailPagerAdapter

   private class DetailPagerAdapter : FragmentPagerAdapter
    {
        private List<Android.Support.V4.App.Fragment> mFragmentList;
        private List<string> mFragmentTitleList = new List<string>();

        public SectionsPagerAdapter(Android.Support.V4.App.FragmentManager fm) : base(fm)
        {
            this.mFragmentList = new List<Android.Support.V4.App.Fragment>();
            addFragment(new UCAboutFragment(), "About");
            addFragment(new UCServicesFragment(), "Services");
            addFragment(new UCInsuranceFragment(), "Insurance");


        }

        #region implemented abstract members of PagerAdapter
        public override int Count
        {
            get
            {
                return mFragmentList.Count;
            }
        }
        #endregion
        #region implemented abstract members of FragmentPagerAdapter
        public override Android.Support.V4.App.Fragment GetItem(int position)
        {
            return mFragmentList[position];
        }
        #endregion

        public override ICharSequence GetPageTitleFormatted(int position)
        {
            return new Java.Lang.String(mFragmentTitleList[position].ToLower());
        }

        private void addFragment(Android.Support.V4.App.Fragment fragment, string title)
        {
            mFragmentList.Add(fragment);
            mFragmentTitleList.Add(title);
        }
    }

BaseFragment

{
        public abstract class BaseFragment : MvxFragment
            {
                protected Toolbar Toolbar { get; private set; }
                protected BaseFragment()
                {
                    RetainInstance = true;
                }

                public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
                {
                    var ignore = base.OnCreateView(inflater, container, savedInstanceState);
                    var view = this.BindingInflate(FragmentId, null);

                    return view;
                 }

          protected abstract int FragmentId { get; }

        }

        public abstract class BaseFragment<TViewModel> : BaseFragment where TViewModel : class, IMvxViewModel
            {
                public new TViewModel ViewModel
                {
                    get { return (TViewModel)base.ViewModel; }
                    set { base.ViewModel = value; }
                }
            }
}
1

There are 1 best solutions below

2
Cheesebaron On

In the Fragments you have in your ViewPager, you need to use BindingInflate to inflate your View:

public class UCAboutFragment :BaseFragment<AboutDetailViewModel>
{
    protected override int FragmentId => Resource.Layout.fragment_details_about;

    public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        var _ = base.OnCreateView(inflater, container, savedInstanceState);

        var view = this.BindingInflate(FragmentId, container, false);
        return view;
    }
}

BindingInflate is what discovers the binding expressions in your layout and connects the ViewModel with the View iteself.