Reputation: 2170
I am using ViewPager to slide left and right, I have also added the tabs, The number of tabs is depends on the server data, So, I cannot make the number of tabs as Fixed. To do this I used only Single Fragment and a RecyclerView to display JSON Data in the recyclerView. When First app launches, the data which should be shown in 2nd tab is getting displayed in 1st Tab itself. After I swipe to 3rd Tab and come Back again to 1st Tab, then the data is displaying correctly.
It is as same as GooglePlayStore. I think there is only one fragment, because the UI is same in all the tabs.
Here is the code to Add Fragment and displaying data to 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) {
}
});
}
enter image description here
Upvotes: 4
Views: 9481
Reputation: 1981
In PagerAdapter edit as below, it might help:
@Override
public Fragment getItem(int position) {
/* ProductFragment pf = ProductFragment.newInstance(data.get(position),position);
return pf;*/
return ProductFragment.newInstance(data.get(position),position);
}
And in your Fragment make changes as below:
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;
}
}
Upvotes: 3
Reputation: 5157
I had a smaller issue, I was using a single fragment with multiple TabLayout. I kept getting the wrong position in my fragment which was the last position in the TabLayout.
The problem is saving fragment position in a static variable or in Bundle will save the last created fragment and the ViewPager will create fragment ahead of the current position so that is why we're losing the current position.
So what I've done to solve this issue is creating a local variable holding the tab position of the created fragment.
The code in Kotlin
class TabFragment : Fragment() {
private var tabPosition = 0
companion object {
fun newInstance(tabPosition: Int): TabFragment {
val tabFragment = TabFragment()
tabFragment.tabPosition = tabPosition
return tabFragment
}
}
}
The code in Java
public class TabFragment extends Fragment {
private int tabPosition = 0;
static TabFragment newInstance(int tabPosition){
TabFragment tabFragment = new TabFragment();
tabFragment.tabPosition = tabPosition;
return tabFragment;
}
}
Upvotes: 0
Reputation: 1989
change this line in : 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;
}
and remove static method from fragment as :
public static ProductFragment newInstance()
bcoz this static method set data of the latest page from viewPager. and FYI viewPager load next page in memory in advance. and static method makes it show now rather then show in future.
Upvotes: 0