this is my ViewPager
private class ViewPagerAdapter extends FragmentPagerAdapter{
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
void addFragment(Fragment fragment, String title){
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
#Override
public CharSequence getPageTitle(int position){
return mFragmentTitleList.get(position);
}
}
and in main activity,
public void setupViewPager() {
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(NowPlayingFragment.newInstance(0), getString(R.string.now_playing));
adapter.addFragment(NowPlayingFragment.newInstance(1), getString(R.string.up_coming));
adapter.addFragment(NowPlayingFragment.newInstance(2), getString(R.string.popular));
mViewPager.setAdapter(adapter);
and this is my fragment.
public static NowPlayingFragment newInstance(int titleId){
NowPlayingFragment fragment = new NowPlayingFragment();
Bundle args = new Bundle();
args.putInt("title_flag", titleId);
NowPlayingFragment.titleId = titleId;
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
args = savedInstanceState;
mContext = getContext();
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_now_playing, container, false);
mUnbinder = ButterKnife.bind(this, view);
Map<String, String> queryString;
queryString = ApiUtils.getQueryStrings(mContext);
Uri uri;
int titleId1 = 0;
if (args != null) {
titleId1 = args.getInt("title_flag");
}
Log.d("tag", "titleId = " + titleId1);
switch (titleId1){
case 0:
uri = ApiUtils.getNowPlayingUri(mContext, queryString);
break;
case 1:
uri = ApiUtils.getUpcomingUri(mContext, queryString);
break;
case 2:
uri = ApiUtils.getPopularUri(mContext, queryString);
break;
default:
uri = ApiUtils.getNowPlayingUri(mContext, queryString);
break;
}
new loadDiscoverList(getContext()).execute(uri);
return view;
}
I try to list three different movie list (now playing, upcoming, popular).
But it only shows now playing list on all three pages.
It seems like passing data from main activity to fragment is not working property, or store fragment argument problem. But I can't find what cause this issue and don't know how to fix it.
The problem is here args = savedInstanceState; it should be args = getArguments(); - at present only your default list in your switch statement is honoured. SavedInstanceState is for configuration changes, you want the Fragment arguments you added with the static Fragment generator method.
You don't have make a cache for fragment like:
private final List mFragmentList = new ArrayList<>();
ViewPager already do it for you.
Try to return the corresponding new instances of fragments inside the method getItem() in your adapter.
Related
I have a viewPager activity that makes multiple fragments with custom FragmentPagerAdapter.
I need to get the List<Audio> audioList and use it in my fragment.
Here is a small part of my MainActivity where I make the fragments. I do not think the rest of the MainActivity code is required in order to answer this question.
ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
PagerAdapter pagerAdapter =
new PagerAdapter(getSupportFragmentManager(), MainActivity.this, audioList);
viewPager.setAdapter(pagerAdapter);
// Give the TabLayout the ViewPager
TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
tabLayout.setupWithViewPager(viewPager);
// Iterate over all tabs and set the custom view
for (int i = 0; i < tabLayout.getTabCount(); i++) {
TabLayout.Tab tab = tabLayout.getTabAt(i);
tab.setCustomView(pagerAdapter.getTabView(i));
}
Here is my custom FragmentPagerAdapter:
public class PagerAdapter extends FragmentPagerAdapter {
String tabTitles[] = new String[] { "Recommended", "Popular", "Rock", "Pop", "Blues", "Chill" };
Context context;
private List<Audio> audioList;
public PagerAdapter(FragmentManager fm, Context context, List<Audio> audioList) {
super(fm);
this.context = context;
this.audioList = audioList;
}
#Override
public int getCount() {
return tabTitles.length;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new BlankFragment();
case 1:
return new BlankFragment();
case 2:
return new BlankFragment();
case 3:
return new BlankFragment();
case 4:
return new BlankFragment();
case 5:
return new BlankFragment();
}
return null;
}
#Override
public CharSequence getPageTitle(int position) {
// Generate title based on item position
return tabTitles[position];
}
public View getTabView(int position) {
View tab = LayoutInflater.from(context).inflate(R.layout.custom_tab, null);
TextView tv = (TextView) tab.findViewById(R.id.custom_text);
tv.setText(tabTitles[position]);
return tab;
}
}
And I need to get the List<Audio> audioList into my Fragment here:
public class BlankFragment extends Fragment {
public BlankFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.content_view, container, false);
//Get auidoList here
return rootView;
}
I also need to get the title of the tab in the future but my guess is that I would get it similarly to the audioList. If it is not then I could also use help on getting the tab title.
Additionally if the code style is wrong then I am always happy to have some feedback on it aswell.
The traditional way of doing this is by having an instance method that moves it all via a bundle.
Like this:
public class BlankFragment extends Fragment {
public static BlankFragment newInstance(String title, ArrayList<Audio> audioList) {
BlankFragment blankFragment = new BlankFragment();
Bundle bundle = new Bundle();
bundle.putString("Title", title);
bundle.putParcelableArrayList("AudioList", audioList);
blankFragment.setArguments(bundle);
return blankFragment;
}
public BlankFragment() {
// Required empty public constructor
}
private String title;
private ArrayList<Audio> audioList;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle bundle = getArguments();
if (bundle != null) {
title = bundle.getString("Title");
audioList = getArguments().getParcelableArrayList("AudioList");
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.content_view, container, false);
//Get auidoList here
return rootView;
}
}
Obviously your Audio class will need to implement parcelable for this to work. I found a great plugin (Android Parcelable Code Generator) in Android Studio for generating parcelable code that makes that quick and easy.
I have faced this issue, maybe there is already the same issue, but I cannot find in this page. So my problem is that I have my activity, which initialize ViewPager and I have 2 fragments in this viewpager.
My Activity:
public class ShoppingDetailsActivity extends BaseActivity {
ViewPagerAdapter adapter;
#Bind(R.id.view_pager)
ViewPager viewPager;
#Bind(R.id.pager_tabs)
PagerSlidingTabStrip pagerSlidingTabStrip;
int shop_id;
int id;
int shop_sub_id;
int subId;
int shop_sub_sub_id;
int subSubId;
int shop_detail_id;
int detailId;
public static final String SHOP_ID = "shop_id";
public static final String SHOP_SUB_ID = "shop_sub_id";
public static final String SHOP_SUB_SUB_ID = "shop_sub_sub_id";
public static final String SHOP_DETAIL_ID = "shop_detail_id";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
activityComponent().inject(this);
setContentView(R.layout.activity_shopping_details);
ButterKnife.bind(this);
adapter = new ViewPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(adapter);
pagerSlidingTabStrip.setViewPager(viewPager);
shop_id = getIntent().getIntExtra(SHOP_ID, id);
shop_sub_id = getIntent().getIntExtra(SHOP_SUB_ID, subId);
shop_sub_sub_id = getIntent().getIntExtra(SHOP_SUB_SUB_ID, subSubId);
shop_detail_id = getIntent().getIntExtra(SHOP_DETAIL_ID, detailId);
}
}
My Adapter:
public class ViewPagerAdapter extends FragmentPagerAdapter {
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
Fragment fragment = null;
switch (position) {
case 0:
fragment = new InfoAdminFragment();
break;
case 1:
fragment = new ViewAdminFragment();
break;
default:
break;
}
return fragment;
}
#Override
public int getCount() {
return 2;
}
#Override
public CharSequence getPageTitle(int position) {
if (position == 0) {
return "InfoAdminFragment";
} else if (position == 1) {
return "ViewAdminFragment";
} else {
return super.getPageTitle(position);
}
}
}
As you can see in My Activity I have a lot of IDs using getIntent() and get them successfully, but I also need somehow to pass to my both fragments in ViewPager, how can I make solve this issue?
Pass the ID's as bundle to ViewPager adapter from your activity
adapter = new ViewPagerAdapter(getSupportFragmentManager(), getIntent().getExtras());
Modify your ViewPager adapter as below
public class ViewPagerAdapter extends FragmentPagerAdapter {
private Bundle bundle;
public ViewPagerAdapter(FragmentManager fm, Bundle bundle) {
super(fm);
this.bundle = bundle;
}
#Override
public Fragment getItem(int position) {
Fragment fragment = null;
switch (position) {
case 0:
fragment = new InfoAdminFragment();
break;
case 1:
fragment = new ViewAdminFragment();
break;
default:
fragment = new InfoAdminFragment();
break;
}
fragment.setArguments(bundle);
return fragment;
}
//other code
}
And retrieve the bundle in your fragments
Bundle bundle = getArguments();
shopId = bundle.getInt(ShoppingDetailsActivity.SHOP_ID);
Check your code with this one:
private int shop_id;
private int shop_sub_id;
private int shop_sub_sub_id;
private int shop_detail_id;
public void setExtraData(int shopId, int shopSubId, shopSubSubId, shopDetailId) {
this.shop_id = shopId;
this.shop_sub_id = shopSubId;
this.shop_sub_sub_id = shopSubSubId;
this.shop_detail_id = shopDetailId;
}
#Override
public Fragment getItem(int position) {
Fragment fragment = null;
switch (position) {
case 0:
fragment = new InfoAdminFragment();
break;
case 1:
fragment = new ViewAdminFragment();
break;
default:
break;
}
setBundleData(fragment);
return fragment;
}
public void setBundleData(Fragment fragment){
Bundle bundle = new Bundle();
bundle.putInt("shop_id", shop_id);
bundle.putInt("shop_sub_id", shop_sub_id);
bundle.putInt("shop_sub_sub_id", shop_sub_sub_id);
bundle.putInt("shop_detail_id", shop_detail_id);
fragment.setArguments(bundle);
}
And in your activity:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
activityComponent().inject(this);
setContentView(R.layout.activity_shopping_details);
ButterKnife.bind(this);
shop_id = getIntent().getIntExtra(SHOP_ID, id);
shop_sub_id = getIntent().getIntExtra(SHOP_SUB_ID, subId);
shop_sub_sub_id = getIntent().getIntExtra(SHOP_SUB_SUB_ID, subSubId);
shop_detail_id = getIntent().getIntExtra(SHOP_DETAIL_ID, detailId);
adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.setExtraData(shop_id, shop_sub_id, shop_sub_sub_id, shop_detail_id);
viewPager.setAdapter(adapter);
pagerSlidingTabStrip.setViewPager(viewPager);
}
In your fragment you can get:
getArguments().getInt(/*Key*/, /*Default value*/);
like:
getArguments().getInt("shop_id", -1);
You can achieve the same above scenario by passing intent rather than single-single values as I am doing here in setExtraData method of adapter.
How many tabs will be created it depends on web service. It means I cannot discover how many Tabs are going to be Created until web service is called.
The tabs contain the products which I want to show in grid view.
In my project I have ShopProductsPageFragments.java where tabs get created. Please have look below code :
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
CatPosition = getArguments().getInt("CatPosition");
StoreID = getArguments().getString("StoreID");
System.out.println("getStoreID in ShopProductsPageFragments="+ StoreID);
System.out.println("getCatPosition in ShopProductsPageFragments="+ CatPosition);
try {
ShopCategoryData = (GetProductCategoriesByStoreResponsePojo) getArguments().getSerializable("ShopCatNames");
}catch (Exception e){
e.printStackTrace();
}
assert ShopCategoryData != null;
List<Datum> shopcatdata = ShopCategoryData.getData();
for (int i = 0; i < shopcatdata.size(); i++) {
System.out.println("ShopCategoryData in ShopProductsPageFragments "+ shopcatdata.get(i).getCatName());
}
ShopProductsPageView = inflater.inflate(R.layout.activity_product_page_fragment ,container ,false);
viewPager = (ViewPager)ShopProductsPageView.findViewById(R.id.product_viewpager);
setupViewPager(viewPager);
tabLayout = (TabLayout)ShopProductsPageView.findViewById(R.id.product_tabs);
tabLayout.setupWithViewPager(viewPager);
return ShopProductsPageView;
}
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getFragmentManager());
List<Datum> shopcatdata = ShopCategoryData.getData();
for (int i = 0; i < shopcatdata.size(); i++) {
CommanShopProductFragment commanShopProductFragment = CommanShopProductFragment.newInstance(i);
String CatName = shopcatdata.get(i).getCatName();
Bundle bundle = new Bundle();
bundle.putString("StoreID",StoreID);
bundle.putString("CatName",CatName);
commanShopProductFragment.setArguments(bundle);
System.out.println("ShopCategoryData in ShopProductsPageFragments "+ shopcatdata.get(i).getCatName());
adapter.addFrag(commanShopProductFragment, shopcatdata.get(i).getCatName());
}
adapter.notifyDataSetChanged();
viewPager.setAdapter(adapter);
viewPager.setCurrentItem(CatPosition);
}
class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
FragmentManager fragmentManager;
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
fragmentManager = manager;
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
void addFrag(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
Here, you can see how tabs are created. I am using same fragment for showing data in Tabs as follows:
public class CommanShopProductFragment extends Fragment {
private static final String ARG_POSITION = "position";
private int position;
View CategoryTabFragmentView;
GetStoreProductsByCategoriesPresenterImpl presenter;
RestClient service;
GridView gridView;
List<Datum> shopProduct;
ProductByCategoryGridViewAdapter mAdapter;
public CommanShopProductFragment() {
// Required empty public constructor
}
public static CommanShopProductFragment newInstance(int position) {
CommanShopProductFragment f = new CommanShopProductFragment();
Bundle b = new Bundle();
b.putInt(ARG_POSITION, position);
f.setArguments(b);
return f;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String CatName = getArguments().getString("CatName");
String StoreID = getArguments().getString("StoreID");
assert CatName != null;
System.out.println("CommanShopProductFragment >>>>>>>> CatName="+CatName);
assert StoreID != null;
System.out.println("CommanShopProductFragment >>>>>>>> StoreID="+StoreID);
CategoryTabFragmentView = inflater.inflate(R.layout.activity_category_tab_fragment ,container ,false);
service = ((LilubiApplication) getActivity().getApplication()).getNetworkService();
presenter = new GetStoreProductsByCategoriesPresenterImpl(this, service);
String page = "1", itemsPerPage = "10";
try {
presenter.GetStoreProductsByCategories(CatName, StoreID, page, itemsPerPage);
}catch (Exception e){
e.printStackTrace();
}
return CategoryTabFragmentView;
}
public void getStoreProductsByCategories(ProductByCategoriesResponsePojo productByCategoriesResponsePojo){
System.out.println("CategoryTabFragment in getMessage="+productByCategoriesResponsePojo.getMessage());
System.out.println("CategoryTabFragment in getStatus="+productByCategoriesResponsePojo.getStatus());
// prepared arraylist and passed it to the Adapter class
shopProduct = productByCategoriesResponsePojo.getData();
mAdapter = new ProductByCategoryGridViewAdapter(getActivity(),shopProduct);
// Set custom adapter to gridview
gridView = (GridView) CategoryTabFragmentView.findViewById(R.id.category_tab_view_grid_view);
gridView.setAdapter(mAdapter);
}
Now what I want is when user selects a tab then list of products should be displayed according to selected category from the tabs.
All product data also comes from web service. Let me know if I missed any thing to explain. Thank you.
I am editing my previous answer
Edit:
you can use viewpager.getCurrentItem() to get current position //include this in your activity with viewpager
I have two fragments (Same class- PlayerFragment) and I set the ViewPager with this method:
private void setupViewPager(ViewPager viewPager) {
FragmentManager fManager = getSupportFragmentManager();
ViewPagerAdapter adapter = new ViewPagerAdapter(fManager);
Bundle args1 = new Bundle();
args1.putInt("Id",1);
PlayerFragment pf1 = new PlayerFragment();
pf1.setArguments(args1);
adapter.addFrag(pf1, "Players 1");
Bundle args2 = new Bundle();
args2.putInt("Id",2);
PlayerFragment pf2 = new PlayerFragment();
pf2.setArguments(args2);
adapter.addFrag(pf2, "Players 2");
viewPager.setAdapter(adapter);
}
I have two tabs but only the first tab shows me content, the other tab is empty.
And the first tabs shows me the contentent of the second one.
static class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
public void addFrag(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
In the activity where I use the fragments I have this code:
final ViewPager viewPager = (ViewPager) findViewById(R.id.vpTeam);
setupViewPager(viewPager);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabsTeam);
tabLayout.setupWithViewPager(viewPager);
Thanks!
Edit: This is the PlayerFragment
public class PlayerFragment extends Fragment {
private ProgressDialog progressDialog;
private List<Player> myPlayers = new ArrayList<>();
private int myTeamId = 14;
public PlayerFragment(){
}
public static PlayerFragment newInstance(int someInt) {
PlayerFragment myFragment = new PlayerFragment();
Bundle args = new Bundle();
args.putInt("TeamId", someInt);
myFragment.setArguments(args);
return myFragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
Bundle args = getArguments();
if(args!=null) {
myTeamId = args.getInt("TeamId");
}
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_player, container, false);
new BackgroundAsyncTask().execute();
return view;
}
}
Can you post the code of PlayerFragment? I'm pretty sure that the error is that you have the variables in that class as static. Also try to use the "new instance()" way for creating fragments --> Best practice for instantiating a new Android Fragment
I have a weird problem.
In the main activity I use this code:
public class MyPagerAdapter extends FragmentPagerAdapter {
private final String[] TITLES = {"Laatste Nieuws", "Uitrukken", "Voertuigen", "Contact", "Top Grossing"};
public MyPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public CharSequence getPageTitle(int position) {
return TITLES[position];
}
#Override
public int getCount() {
return TITLES.length;
}
#Override
public Fragment getItem(int position) {
Fragment fragment = null;
switch (position) {
case 0:
fragment = NaviContentFragment.newInstance(position);
break;
case 1:
fragment = NaviContentFragmentTwo.newInstance(position);
break;
case 2:
fragment = NaviContentFragment.newInstance(position);
break;
case 3:
fragment = NaviContentFragment.newInstance(position);
break;
case 4:
fragment = NaviContentFragment.newInstance(position);
break;
default:
break;
}
return fragment;
}
}
So when I open a tab it will open a new fragment. And when I open tab 1 labeled "Uitrukken" it should open a other fragment than the other ones. This fragment:
public class NaviContentFragmentTwo extends Fragment {
private static final String ARG_POSITION = "position";
public static NaviContentFragment newInstance(int position) {
NaviContentFragment fragment = new NaviContentFragment();
Bundle b = new Bundle();
b.putInt(ARG_POSITION, position);
fragment.setArguments(b);
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = rootView = inflater.inflate(R.layout.navi_content_two, container, false);
TextView textViewNaviConTwo = (TextView) rootView.findViewById(R.id.textViewNaviConTwo);
textViewNaviConTwo.setText("HALLLOOOTJES :)");
return rootView;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
}
With the Text "HALLLOOOTJES :)". And only in that fragment. But the other way around happens. This text is show on all the tabs except for tab number 1.
I'm certainly missing something.
Screenshots:
It should say "HALLLOOOTJES :)"
In your NaviContentFragmentTwo class, you are returning a NaviContentFragment from your newInstance method.
My guess is you should be returning a NaviContentFragmentTwo instance.
So it should be something like..
public class NaviContentFragmentTwo extends Fragment {
private static final String ARG_POSITION = "position";
public static NaviContentFragmentTwo newInstance(int position) {
NaviContentFragmentTwo fragment = new NaviContentFragmentTwo ();
Bundle b = new Bundle();
b.putInt(ARG_POSITION, position);
fragment.setArguments(b);
return fragment;
}
This code could be the possible cause:
public static NaviContentFragment newInstance(int position) {
NaviContentFragment fragment = new NaviContentFragment();
Bundle b = new Bundle();
b.putInt(ARG_POSITION, position);
fragment.setArguments(b);
return fragment;
}
Try replacing NaviContentFragment to NaviContentFragmentTwo.