ViewPager - 带 LiveData 的 TabLayout

ViewPager - TabLayout with LiveData

我在回收商视图中有一个产品列表。按下某个项目后,您将转到第二个 activity 以显示与该产品相关的更多信息。我正在尝试实现 viewPager。正在学习 CodingWithMitch 的教程,但在他的示例中,他有随机数据并且可以轻松获取它们。

ArrayList<Fragment> fragments = new ArrayList<>();
    Hat[] hats = Hats.getHats();
    for(Hat hat: hats){
        ViewPagerItemFragment fragment = ViewPagerItemFragment.getInstance(hat);
        fragments.add(fragment);
    }
    MyPagerAdapter pagerAdapter = new MyPagerAdapter(getSupportFragmentManager(), fragments);
    mMyViewPager.setAdapter(pagerAdapter);
    mTabLayout.setupWithViewPager(mMyViewPager, true);

不幸的是,对我来说,数据是从 Livedata 对象中获取的。我如何循环或迭代实时数据以提取所有产品对象,以便我可以设置片段!

ArrayList<Fragment> fragments = new ArrayList<>();
    final MarketViewModel marketViewModel = new ViewModelProvider(this).get(MarketViewModel.class);
    MutableLiveData<List<Product>> products = marketViewModel.getProductInfo("parentID");
    //What to do here !!!
    /*for (:) {
        ProductInfoFragment fragment = ProductInfoFragment.getInstance(products);
        fragments.add(fragment);
    }*/
    ProductPagerAdapter adapter = new ProductPagerAdapter(getSupportFragmentManager(), 0, fragments);
    viewPager.setAdapter(adapter);
    tabLayout.setupWithViewPager(viewPager, true);

此外,这显示了整个产品。但是如何首先显示按下的项目。用户点击的那个。然后用户将能够左右交换浏览整个列表!?

编辑:我试过了!但现在它显示一个空白的白页。

ArrayList<Fragment> fragments = new ArrayList<>();
    final MarketViewModel marketViewModel = new ViewModelProvider(this).get(MarketViewModel.class);
    marketViewModel.getProductInfo("parentID");
    marketViewModel.getProductInfo("parentID").observe(this, products -> {
        for (int i = 0; i < products.size(); i++) {
            Product product = products.get(i);
            ProductInfoFragment fragment = ProductInfoFragment.getInstance(product);
            fragments.add(fragment);
        }
    });
    ProductPagerAdapter adapter = new ProductPagerAdapter(getSupportFragmentManager(), 0, fragments);
    viewPager.setAdapter(adapter);
    tabLayout.setupWithViewPager(viewPager, true);

请在您的 LiveData 提交新数据后尝试构建 ViewPager 适配器,因为 ViewPager 似乎是使用无数据适配器初始化的,其中它代码在 LiveData 返回之前运行。

所以你会尝试:

ArrayList<Fragment> fragments = new ArrayList<>();
    final MarketViewModel marketViewModel = new ViewModelProvider(this).get(MarketViewModel.class);
    marketViewModel.getProductInfo("parentID");
    marketViewModel.getProductInfo("parentID").observe(this, products -> {
        for (int i = 0; i < products.size(); i++) {
            Product product = products.get(i);
            ProductInfoFragment fragment = ProductInfoFragment.getInstance(product);
            fragments.add(fragment);
        }

        ProductPagerAdapter adapter = new ProductPagerAdapter(getSupportFragmentManager(), 0, fragments);
        viewPager.setAdapter(adapter);
        tabLayout.setupWithViewPager(viewPager, true);

    });

Edit: I fixed the code but the issue persists. it shows blank while page looks like it got stuck into an infinite loop! It's so abnormal to me.

现在我将尝试只更新 LiveData 观察器中的 ViewPager 片段,而不重建适配器。

因此,我们将保持原始代码不变,将适配器设为 class 字段,并调用 mAdapter.notifyDataSetChanged() 获取 LiveData 返回的新数据。

ProductPagerAdapter mAdapter;

ArrayList<Fragment> fragments = new ArrayList<>();
    mAdapter = new ProductPagerAdapter(getSupportFragmentManager(), 0, fragments);
    viewPager.setAdapter(mAdapter);
    tabLayout.setupWithViewPager(viewPager, true);

    final MarketViewModel marketViewModel = new ViewModelProvider(this).get(MarketViewModel.class);
    marketViewModel.getProductInfo("parentID");
    marketViewModel.getProductInfo("parentID").observe(this, products -> {
        for (int i = 0; i < products.size(); i++) {
            Product product = products.get(i);
            ProductInfoFragment fragment = ProductInfoFragment.getInstance(product);
            fragments.add(fragment);
        }

         mAdapter.notifyDataSetChanged();  // <<<<<< here updating adapter fragemnts

    });

此外,this answer 可以帮助您正确更新适配器片段。