在ViewPager的多个选项卡中使用单个片段

4
我正在使用ViewPager来左右滑动页面,我已经添加了选项卡。选项卡的数目取决于服务器数据,所以我不能将选项卡数量固定下来。为此,我只使用了单个Fragment和一个RecyclerView来在RecyclerView中显示JSON数据。当应用程序首次启动时,应该显示在第二个选项卡中的数据实际上被显示在了第一个选项卡中。当我向右滑动到第三个选项卡并再次返回到第一个选项卡时,数据才会正确地显示。
这与GooglePlayStore相同。我认为只有一个Fragment,因为所有选项卡的UI都是相同的。
以下是添加Fragment并在RecyclerView中显示数据的代码。
PagerAdapter.java
    private class PagerAdapter extends FragmentStatePagerAdapter {
    int mNumOfTabs;
    List<List<ProductInfo>> data;



    public PagerAdapter(FragmentManager fm, int NumofTabs, List<List<ProductInfo>> data) {
        super(fm);
        mNumOfTabs = NumofTabs;
        this.data = data;
    }

    @Override
    public Fragment getItem(int position) {
       /* ProductFragment pf = ProductFragment.newInstance(data.get(position),position);
        return pf;*/

        return ProductFragment.newInstance(data.get(position),0);
    }



    @Override
    public int getCount() {
        return mNumOfTabs;
    }
}

Fragment.java

public class ProductFragment extends Fragment {
   private static final String ARG_PRODUCTS = "PRODS";
   private static List<ProductInfo> allProducts;
   int position = 0;
   RecyclerView prodList;


public static ProductFragment newInstance(List<ProductInfo> products,int position) {        
    ProductFragment fragment = new ProductFragment();
    Bundle args = new Bundle();
    args.putParcelableArrayList(ARG_PRODUCTS, (ArrayList<ProductInfo>) products);
    args.putInt("KEY_POSITION",position);
    args.putInt("KEY_ID",id);
    fragment.setArguments(args);
    return fragment;
}

 @Override
 public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //if(isVisibleToUser){
        if (getArguments() != null) {
            allProducts = getArguments().getParcelableArrayList(ARG_PRODUCTS);
            this.position = getArguments().getInt("KEY_POSITION");
        }
   // }
}


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View view = inflater.inflate(R.layout.fragment_product, container, false);
    prodList = (RecyclerView) view.findViewById(R.id.product_list);
    return view;
}



 @Override
 public void onViewCreated(View view, Bundle savedInstanceState) {

    prodList.setLayoutManager(new LinearLayoutManager(getActivity()));
    prodList.setAdapter(new ProductAdapter(getActivity(), allProducts));
    Log.e("ProductFragment " ,"" + allProducts.get(position).getName());
}

EDITED: Activity.java

onCreate(){
TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
    allProducts = new ArrayList<>();

    for (Category cat : catList) {
        tabLayout.addTab(tabLayout.newTab().setText(cat.getName()));
        tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
        //tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
        allProducts.add(cat.getProductsList());
    }
 viewPager = (ViewPager) findViewById(R.id.pager);
    adapter = new PagerAdapter
            (getSupportFragmentManager(), tabLayout.getTabCount(), allProducts);
    viewPager.setOffscreenPageLimit(0);
    viewPager.setAdapter(adapter);

    viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
    tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
        @Override
        public void onTabSelected(TabLayout.Tab tab) {
            Log.e("ViewPager "," getCurrentItem() "+viewPager.getCurrentItem());
            viewPager.setCurrentItem(tab.getPosition());
        }

        @Override
        public void onTabUnselected(TabLayout.Tab tab) {

        }

        @Override
        public void onTabReselected(TabLayout.Tab tab) {

        }
    });

 }

输入图像描述:

输入图像描述:

输入图像描述:


请添加您的Activity代码和PagerAdapter代码。 - Dharvik shah
已编辑... 请检查 - Mohd Asif Ahmed
@Drv.... 更新了问题,请查看。 - Mohd Asif Ahmed
@Dharvikshah 编辑了,伙计。 - Mohd Asif Ahmed
@DemoMail 我也有同样的问题,请回复一下如果你找到了解决方案? - vicky
显示剩余6条评论
3个回答

3

在PagerAdapter中进行以下编辑,可能会有所帮助:

@Override
public Fragment getItem(int position) {
   /* ProductFragment pf = ProductFragment.newInstance(data.get(position),position);
    return pf;*/

    return ProductFragment.newInstance(data.get(position),position);
}

在你的Fragment中,按照以下方式进行更改:

public class ProductFragment extends Fragment {
private static final String ARG_PRODUCTS = "PRODS";
private static List<ProductInfo> allProducts;
int position = 0;
RecyclerView prodList;
ProductAdapter productAdapter=null;


public static ProductFragment newInstance(List<ProductInfo> products,int position) {        
ProductFragment fragment = new ProductFragment();
Bundle args = new Bundle();
args.putParcelableArrayList(ARG_PRODUCTS, (ArrayList<ProductInfo>) products);
args.putInt("KEY_POSITION",position);
args.putInt("KEY_ID",id);
fragment.setArguments(args);
return fragment;
}

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
  if(isVisibleToUser){
      productAdapter.notifyDataSetChanged();
    }
}



  @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //if(isVisibleToUser){
        if (getArguments() != null) {
            allProducts = getArguments().getParcelableArrayList(ARG_PRODUCTS);
            this.position = getArguments().getInt("KEY_POSITION");
        }
   // }
   }

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                     Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_product, container, false);
prodList = (RecyclerView) view.findViewById(R.id.product_list);
prodList.setLayoutManager(new LinearLayoutManager(getActivity()));
productAdapter= new ProductAdapter(getActivity(), allProducts)
prodList.setAdapter(productAdapter);
        return view;
   }
}

prodList.setAdapter(new ProductAdapter(getActivity(), allProducts)); // 在setUserVisibleHint方法中,此行代码会导致NullPointerException异常。 - Mohd Asif Ahmed
productAdapter.notifyDataSetChanged(); //现在这里出现了空指针异常 - Mohd Asif Ahmed
请调试并找出为什么它会返回nullpointer,并且贴出您的日志,这样我也能帮忙。 - Dhruvi
@Drv 我正在使用相同的代码,但问题是我的最后一个 TabLayout 的 RecyclerView 可以滚动,而之前的 TabLayout 的 RecyclerView 却无法滚动。 - Deepak Rana

0

修改PagerAdapter.java文件中的这一行:

        @Override
        public Fragment getItem(int position) {
          ProductFragment fragment = new ProductFragment();
          Bundle args = new Bundle();
          args.putParcelableArrayList(ARG_PRODUCTS, (ArrayList<ProductInfo>) products);
          args.putInt("KEY_POSITION",position);
          args.putInt("KEY_ID",id);
          fragment.setArguments(args);
          return fragment;
        }

然后从片段中删除静态方法:

public static ProductFragment newInstance()

因为这个静态方法可以从viewPager设置最新页面的数据。而且,值得一提的是,viewPager会提前加载下一页到内存中。使用静态方法可以让它现在显示,而不是未来才显示。

1
我会添加图片,看起来会怎样。 - Mohd Asif Ahmed
好的,可以的。请补充。 - Dharvik shah
请检查图片,第一张是应用程序启动并在Starrer中显示鸡蛋项目,第二张图片是当我滑动到最后一个选项卡,然后再通过滑动返回时,数据是正确的。 - Mohd Asif Ahmed
当我点击选项卡而不是滑动时,数据仍然不正确。 - Mohd Asif Ahmed
好的,我会尽快在有空的时候帮助你。保持联系:dharvikca@gmail.com。如果你早日得到答案,祝你好运。 - Dharvik shah

0

我遇到了一个小问题,我在使用单个片段与多个TabLayout。我一直得到的是我的片段中错误的位置,这是TabLayout中的最后一个位置。

问题在于将片段位置保存在静态变量或Bundle中将保存最后创建的片段,ViewPager将在当前位置之前创建片段,因此我们失去了当前位置。

所以我为了解决这个问题,创建了一个本地变量来保存已创建片段的选项卡位置。

Kotlin代码

class TabFragment : Fragment() {
private var tabPosition = 0

companion object {
    fun newInstance(tabPosition: Int): TabFragment {
        val tabFragment = TabFragment()
        tabFragment.tabPosition = tabPosition
        return tabFragment
     }
  }
}

Java 代码

public class TabFragment extends Fragment {
private int tabPosition = 0;
static TabFragment newInstance(int tabPosition){
    TabFragment tabFragment = new TabFragment();
    tabFragment.tabPosition = tabPosition;
    return tabFragment;
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接