FragmentPagerAdapter和ViewModel类之间如何通信?

时间:2019-07-28 08:53:29

标签: android android-fragments mvvm

创建活动包含MVVM体系结构的标签(使用FragmentPagerAdapter)。

我知道什么? (或者我想我知道) FragmentPagerAdapter类-需要管理每个选项卡的内容切换。此类无法与数据库/共享首选项或类似内容进行交谈。

ViewModel类(扩展BaseObservable)-与数据库对话以获取要绑定到视图的数据。

如果正确,我需要在ViewModel类中获取数据,并将其传递给FragmentPagerAdapter的构造方法,该方法将实例创建为Fragment类(特定选项卡的View类)。

因此,问题是-如何做到这一点并保持MVVM体系结构的规则? 请查看下面的代码(除了将ViewModel的数据(字符串名称)一直传递到InteractiveTemplate之外,这段代码是其他所有内容

我的MVVM体系结构: 双向数据绑定

activity_choose_feed.xml

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:bind="http://schemas.android.com/tools">

    <data>
        <import type="android.view.View" />

        <variable
            name="handler"
            type="com.....ChooseFeedActivity" />

        <variable
            name="manager"
            type="android.support.v4.app.FragmentManager" />

        <variable
            name="viewModel"
            type="com......ChooseFeedViewModel" />
    </data>

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

        <LinearLayout
            android:id="@+id/templateWorkSpace"
            android:layout_width="match_parent"
            android:layout_height="0px"
            android:layout_weight="33"
            android:orientation="horizontal">

        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0px"
            android:layout_weight="66"
            android:orientation="vertical">

            <android.support.design.widget.TabLayout
                android:id="@+id/streams_categories"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:elevation="6dp"
                android:minHeight="?attr/actionBarSize"
                bind:pager="@{(pager)}" />

            <android.support.v4.view.ViewPager
                android:id="@+id/pager"
                android:layout_width="match_parent"
                android:layout_height="fill_parent"
                android:layout_below="@id/streams_categories"
                bind:handler="@{handler}" />
        </LinearLayout>

    </LinearLayout>

</layout>

ChooseFeedActivity.java

public class ChooseFeedActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        ActivityChooseFeedBinding activityBinding = DataBindingUtil.setContentView(this, R.layout.activity_choose_feed);
        activityBinding.setViewModel(new ChooseFeedViewModel());
        activityBinding.setHandler(this);
        activityBinding.setManager(getSupportFragmentManager());
    }

    @BindingAdapter({"handler"})
    public static void bindViewPagerAdapter(final ViewPager view, final ChooseFeedActivity activity)
    {
        final ChooseFeedViewModel.PagerAdapter adapter = new ChooseFeedViewModel.PagerAdapter(activity.getSupportFragmentManager());
        view.setAdapter(adapter);
    }

    @BindingAdapter({"pager"})
    public static void bindViewPagerTabs(final TabLayout view, final ViewPager pagerView)
    {
        view.setupWithViewPager(pagerView, true);
    }
}

interactive_temple.xml

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data>
        <variable
            name="viewModel"
            type="com....ChooseFeedViewModel" />
    </data>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <TextView
            android:id="@+id/textView3"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="This text need to come from viewmodel" />
    </LinearLayout>
</layout>

InteractiveTemplate.java

@SuppressLint("ValidFragment")
public class InteractiveTemplate extends Fragment {
    @SuppressLint("ValidFragment")
    public InteractiveTemplate() { }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        InteractiveTemplateBinding binding = DataBindingUtil.inflate(inflater,R.layout.interactive_template, container, false);
        View view = binding.getRoot();
        binding.setViewModel(new ChooseFeedViewModel());

        return view;
    }
}

ChooseFeedViewModel.java

public class ChooseFeedViewModel extends BaseObservable {
    private String name; // This is the data that i want to bind all the way to InteractiveTemplate.java

    public ChooseFeedViewModel() {
    }
}

PagerAdapter.java

    public static class PagerAdapter extends FragmentPagerAdapter {
        private static final int CAMS = 0;
        private static final int STAT_SOCIAL = 1;
        private static final int VLOG = 2;
        private static final int FRIEND = 3;
        private final int[] TABS = new int[]{CAMS, STAT_SOCIAL, VLOG, FRIEND};

        public PagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int position) {

            return new InteractiveTemplate(); // This is the point to pass the data?!
        }

        @Override
        public int getCount() {
            return TABS.length;
        }

        @Override
        public String getPageTitle(int position) {
            switch (TABS[position]) {
                case CAMS:
                    return "Cams";
                case STAT_SOCIAL:
                    return "Stat & Social";
                case VLOG:
                    return "VLog";
                case FRIEND:
                    return "Friend";
                default:
                    return null;
            }
        }
    }

0 个答案:

没有答案