Fragment update view in view pager - android

I am using view pager which is having 3 fragments
public class ViewPagerAdapter extends FragmentStatePagerAdapter {
private static final String TAG="ViewPageAdapter";
private final int PAGES = 3;
private String[] title = new String[]{"Frag1",
"Frag2", "Frag2"};
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
Log.d(TAG, "position is " + position);
switch (position) {
case 0:
return new Frag1();
case 1:
return new Frag2();
case 2:
return new Frag3();
default:
throw new IllegalArgumentException(
"The item position should be less or equal to:" + PAGES);
}
}
#Override
public int getCount() {
return PAGES;
}
#Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
#Override
public CharSequence getPageTitle(int position) {
return title[position];
}
}
I am setting view pager from main activity:
viewPageAdapter = new ViewPagerAdapter(getSupportFragmentManager());
viewPager.addOnPageChangeListener(onPageChangeListener);
viewPager.setAdapter(viewPageAdapter);
When i execute viewPageAdapter.notifyDataSetChanged();
or viewPager.setAdapter(viewPageAdapter); method to recreate fragments the activity is getting destroyed.don't know what causing the issue.
I checked many solution nothing worked.
ViewPager PagerAdapter not updating the View
Update ViewPager dynamically?
I am asking another problem because which is related to above question.
The problem which is described in link
ViewPager onPageSelected for first page
where i am not able to get first page tab title on load.i am using android.support.v4.view.PagerTabStrip
Please help me in getting solved. Wasted my whole day to get rid of this :(

Related

View Adaper swiping issues in adapter

actually i have 4 fragments in my app and i switch the fragments by swiping left or right. I used view pager for swiping the fragments are swiping perfectly but there is a problem if i swipe and fragment B shows but the backend functionality of fragment C runs. If i go to C then backend functionality of D runs. At fragment A first backend functionality of fragment A runs then it automatically shifted to fragment B but front end view is of fragment A
This is adapter
public class TabsPagerAdapter extends FragmentPagerAdapter {
private int mNumTabs;
public TabsPagerAdapter(FragmentManager fm, int numTabs) {
super(fm);
this.mNumTabs= numTabs;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
PersonalSettings tab0 = new PersonalSettings();
return tab0;
case 1:
Health tab1 = new Health();
return tab1;
case 2:
Statistics tab2 = new Statistics();
return tab2;
case 3:
Motivation tab3 = new Motivation();
return tab3;
default:
return null;
}
}
#Override
public int getCount() {
return mNumTabs;
}
}
This is main activity
viewPager = (ViewPager) findViewById(R.id.pager);
mAdapter = new TabsPagerAdapter(getSupportFragmentManager(),4);
viewPager.setAdapter(mAdapter);
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
});
}
If u want further code i will give u
It because the viewpager will preload the item next to the current item to improve UX (in your case, the item is the fragment)
You can set offscreenPageLimit to ViewPager to limit it:
viewPager.setOffscreenPageLimit(1);
But if you do this, you will found the fragment will reload everytime you enter, IMO this is not a good practice.
Override destroyItem method in FragmentpagerAdapter
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
// remove your fragment obj from here
}

Displaying Fragments with data in a ViewPager on screen rotation

So in my MainActivity OnCreate I create 3 Fragments, each filled with different data. I then add these Fragments to my ViewPagerAdapter.
ViewPagerAdapter viewPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager());
MealsFragment exploreFragment = null;
MealsFragment favoriteFragment = null;
MealsFragment localFragment = null;
//if there is no saved instance, create fragments with passed data as args and add them to the viewpageradapter
if(savedInstanceState == null){
exploreFragment = fetchExploreMealsDataAndCreateFragment();
favoriteFragment = fetchFavoriteMealsDataAndCreateFragment();
localFragment = fetchLocalMealsDataAndCreateFragment();
}
//add fragments to the adapter
viewPagerAdapter.addFragment(exploreFragment, "EXPLORE");
viewPagerAdapter.addFragment(favoriteFragment, "FAVORITES");
viewPagerAdapter.addFragment(localFragment, "LOCAL");
//set adapter to the viewpager and link it with the different tabs
mviewPager.setAdapter(viewPagerAdapter);
mtabLayout.setupWithViewPager(mviewPager);
The 3 different fetch methods get the data from an API or DB, so I don't want to call these methods every time I rotate my screen and go through my lifecycle. That's why I firstly check if the savedInstanceState is null. But what happens now is that if my savedInstanceState is not null, the Fragments will be null since i initialised them that way.
Apparently this is not a problem since when I rotate the screen, the fragments remain the same. I was wondering what is going on here behind the scenes as I don't think this is the correct way of handling my situation. Any suggestions of improvement are appreciated aswell.
Thanks in advance!
EDIT:
Forgot to mention that ViewPagerAdapter is my own implementation of FragmentPageAdapter
public class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> fragmentList = new ArrayList<>();
private final List<String> fragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int i) {
return fragmentList.get(i);
}
#Override
public int getCount() {
return fragmentList.size();
}
#Nullable
#Override
public CharSequence getPageTitle(int position) {
return fragmentTitleList.get(position);
}
public void addFragment(Fragment fragment, String title){
fragmentList.add(fragment);
fragmentTitleList.add(title);
}
}
I was wondering what is going on here behind the scenes
Alright, so, this is going to involve looking at the source for FragmentPagerAdapter. What's relevant is the implementation of the instantiateItem() method... though really just a portion of it.
#NonNull
#Override
public Object instantiateItem(#NonNull ViewGroup container, int position) {
[...]
// Do we already have this fragment?
String name = makeFragmentName(container.getId(), itemId);
Fragment fragment = mFragmentManager.findFragmentByTag(name);
if (fragment != null) {
if (DEBUG) Log.v(TAG, "Attaching item #" + itemId + ": f=" + fragment);
mCurTransaction.attach(fragment);
} else {
fragment = getItem(position);
if (DEBUG) Log.v(TAG, "Adding item #" + itemId + ": f=" + fragment);
mCurTransaction.add(container.getId(), fragment,
makeFragmentName(container.getId(), itemId));
}
[...]
}
Essentially, the getItem() method from your ViewPagerAdapter is only called once for each position for the lifetime of the Activity (even across configuration changes). Every time other than the first, the Fragment object is retrieved directly from the FragmentManager as opposed to the Adapter.
So yes, for all re-creations of your Activity, your Adapter is holding a List<Fragment> that is just null, null, null... but it doesn't matter, because this list is not accessed again.
HOWEVER
The above statements assume that every Fragment in your adapter was constructed and added to the FragmentManager before your configuration change, and this is not necessarily guaranteed.
By default, the off-screen page limit for the ViewPager is 1. That means that your third page (your localFragment), is not necessarily added to the ViewPager, and therefore the FragmentManager, on first launch. If you scroll over to the next page even one time, it will be, but this is not necessarily true.
Or perhaps you have manually set the off-screen page limit to be 2, in which case all the pages/Fragments will be added immediately.
Probably the best thing to do is to change how you're using FragmentPagerAdapter altogether. I'd put this inside your Activity as an inner class:
private class ExampleAdapter extends FragmentPagerAdapter {
public ExampleAdapter() {
super(getSupportFragmentManager());
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0: return fetchExploreMealsDataAndCreateFragment();
case 1: return fetchFavoriteMealsDataAndCreateFragment();
case 2: return fetchLocalMealsDataAndCreateFragment();
default: throw new IllegalArgumentException("unexpected position: " + position);
}
}
#Nullable
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0: return "EXPLORE";
case 1: return "FAVORITES";
case 2: return "LOCAL";
default: throw new IllegalArgumentException("unexpected position: " + position);
}
}
#Override
public int getCount() {
return 3;
}
}
And then your onCreate() could be changed to this:
FragmentPagerAdapter viewPagerAdapter = new ExampleAdapter();
mviewPager.setAdapter(viewPagerAdapter);
mtabLayout.setupWithViewPager(mviewPager);
The advantage of doing it this way is that you only call the "fetch and create" methods on demand, but still have the ability to call them after a configuration change in situations where they weren't loaded before the configuration change.

How To Start Second tab's Content By View pager Adaptor android

i am Suffering In Little problem .My Second Tab Of Fragment Is Not Performing The Task
my first tab is working
i m using View Page Adapter for Tab
Here Is Tutorial same way of this tutorial i used
but my second tab showing nothing
please help me ..
i will appreciate your suggestion
thanks in adavance
here is my view page adapter
public class ViewPagerAdapter extends FragmentPagerAdapter {
// Declare the number of ViewPager pages
final int PAGE_COUNT = 2;
private String titles[] = new String[] { "Friends Request", "FriendsList" };
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
// Open FragmentTab1.java
case 0:
MyFriendsList fragmenttab1 = new MyFriendsList();
return fragmenttab1;
// Open Friendlist.java
case 1:
FriendsList fragmenttab2 = new FriendsList();
return fragmenttab2;
}
return null;
}
public CharSequence getPageTitle(int position) {
return titles[position];
}
#Override
public int getCount() {
return PAGE_COUNT;
}
}
in this my first tab of myfriendlist is working but Why Second tab Is not Calling It show blank page in frienlist
please help me

How to set Activity-Class es for each page of ViewPager in android?

i want to set different pages for ViewPager from class. for example:
i have 4 activity A + B + C and D.
A include my ViewPager.
B +C + D are different pages that must be shown in ViewPager.(each of them have different contex)
my question is that, how can i recognize these pages into ViewPager?
thanks
You can add but better way is that you will create a activity and your four activity should be child fragment of the same .
In short your all activity should be fragments jst load the fregment when you swipe viewpage indicater
sample code for adapter
//User adapter according condition
final FragmentPagerAdapter adapter = new FragmentChildPageAdapter(getChildFragmentManager());
//final FragmentPagerAdapter adapter = new FragmentChildPageAdapter(getActivity().getSupportFragmentManager()));
final ViewPager pager = (ViewPager) v.findViewById(R.id.pager);
pager.setAdapter(adapter);
final TabPageIndicator indicator = (TabPageIndicator) v.findViewById(R.id.indicator);
indicator.setViewPager(pager);
//Adapter
class FragmentChildPageAdapter extends FragmentPagerAdapter implements
IconPagerAdapter {
public FragmentChildPageAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
Fragment fragment = null;
switch (position) {
case 0:
//first fregment
break;
case 1:
//Second fregment
break;
case 2:
//third fragment
break;
case 3:
//Forth fragment
break;
}
return fragment;
}
#SuppressLint("DefaultLocale")
/*#Override
public CharSequence getPageTitle(int position) {
return CONTENT[position % CONTENT.length].toUpperCase();
}*/
#Override
public int getCount() {
//return CONTENT.length;
return CONTENT.size();
}
#Override
public int getIconResId(int position) {
return (Integer) Icon.get(position % CONTENT.size());
}
}

Update gridview in viewpager

I have been searching for a while for a way to refresh a gridview within a viewpager and I am yet to find an answer. More specificaly my problem is that I have a view pager with three gridviews. Each gridview is populated by an arraylist and if the arraylist is changed the gridview stays the same. How can I make it update? I have tried calling notifydatasetchange on the adapter and that doesnt help.
here is my code for the view pager adapter
public class FavoritesViewPager extends FragmentStatePagerAdapter {
public FavoritesViewPager(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int i) {
UserDatabaseHandler UDH = new UserDatabaseHandler(getActivity());
switch (i) {
case 0:
ArrayList<Exercise> strengthList = UDH.getFavoriteExercises("strengthexercises");
UDH.close();
return FavoriteExercises.newInstance(strengthList);
case 1:
ArrayList<Exercise> stretchList = UDH.getFavoriteExercises("stretchingexercises");
UDH.close();
return FavoriteExercises.newInstance(stretchList);
case 2:
ArrayList<Exercise> warmupList = UDH.getFavoriteExercises("warmupexercises");
UDH.close();
return FavoriteExercises.newInstance(warmupList);
default:
ArrayList<Exercise> temp = UDH
.getFavoriteExercises("warmupexercises");
UDH.close();
return FavoriteExercises.newInstance(temp);
}
}
#Override
public int getCount() {
return 3;
}
}
If your pager has only two pages, you should use FragmentPagerAdapter. You can get the fragment by findFragmentByTag then call update method of this fragment.
String fragmentName = makeFragmentName(_viewPager.getId(), i);
Fragment frag = _fragmentManager.findFragmentByTag(fragmentName);
private static String makeFragmentName(int viewId, int index) {
return "android:switcher:" + viewId + ":" + index;
}

Categories

Resources