Reload fragments inside ViewPager which inside another fragment inViewPager - android

I have an activity, which includes ViewPager with three fragments. In the second fragment i have ViewPager with two different fragments too.
This my MainActivityPagerAdapter which connected with ViewPager in MainActivity:
public class MainActivityPagerAdapter extends FragmentStatePagerAdapter implements LoginView.LoginStateChangeListener {
private static final String TAG = MainActivityPagerAdapter.class.getName();
private MapFragment mapFragment = new MapFragment();
private UserProfileFragment userProfileFragment = new UserProfileFragment();
private CompanyProfileFragment CompanyProfileFragment = new DiveCenterProfileFragment();
private NotificationsFragment notificationsFragment = new notificationsFragment();
public MainActivityPagerAdapter(FragmentManager manager) {
super(manager);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return mapFragment;
case 1:
return notificationsFragment;
case 2:
switch (MyApplication.getInstance().getSharedPreferenceHelper().getActiveUserType()) {
case DIVECENTER:
return companyProfileFragment;
case DIVER:
case INSTRUCTOR:
return userProfileFragment;
case NONE:
return userProfileFragment;
}
default:
return null;
}
}
#Override
public int getCount() {
return 3;
}
#Override
public int getItemPosition(Object object) {
Log.i(TAG, "getItemPosition");
return POSITION_NONE;
}
#Override
public CharSequence getPageTitle(int position) {
return null;
}
}
This my pager adapter for ViewPager at the second fragment:
public class NotificationsPagerAdapter extends FragmentStatePagerAdapter {
private PersonalNotificationsFragment personalNotificationsFragment = new PersonalNotificationsFragment();
private ActivityNotificationsFragment activityNotificationsFragment = new ActivityNotificationsFragment();
public NotificationsPagerAdapter(FragmentManager manager) {
super(manager);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return personalNotificationsFragment;
case 1:
return activityNotificationsFragment;
default:
return null;
}
}
#Override
public int getCount() {
return 2;
}
public void setPersonalNotificationsFragment(PersonalNotificationsFragment personalNotificationsFragment) {
this.personalNotificationsFragment = personalNotificationsFragment;
}
public void setActivityNotificationsFragment(ActivityNotificationsFragment activityNotificationsFragment) {
this.activityNotificationsFragment = activityNotificationsFragment;
}
#Override
public CharSequence getPageTitle(int position) {
return null;
}
#Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
}
So, there are two user types in app:
Simple user
Company
When user changing his type i need to refresh all fragments in MainActivity including fragments inside second fragment. For this I'm using notifyDataSetChanged() for MainActivityViewPager, it work correctly, but fragments inside second fragment don't update(onCreateView don't called, and i see only empty views).
In what may be a problem?

Use getChildFragmentManager() for inner viewPager

Use getChildFragmentManager() instead of getFragmentManager() for changing fragments inside the viewPager

Related

How to get viewPager fragment at a specific index in FragmentStatePageAdapter from FragmentActivity?

I have setup my viewPager adapter like this:
private class ViewPagerFragmentAdapter extends FragmentStateAdapter {
public ViewPagerFragmentAdapter(#NonNull FragmentActivity fragmentActivity) {
super(fragmentActivity);
}
#NonNull
#Override
public Fragment createFragment(int position) {
return EpisodeFragment.newInstance(id, episodeSequence);
}
#Override
public int getItemCount() {
return tabTitles.size();
}
}
How can I find a fragment at a specific index from the FragmentActivity later on so that I can update the dataset or perform some other operation?
During fragment transaction, FragmentStateAdapter creates tag in the following way:
this.mFragmentManager.beginTransaction()
.add(fragment, "f" + holder.getItemId())
.setMaxLifecycle(fragment, State.STARTED)
.commitNow();
As we can see from above, it's a combination of static string "f" and the value of getItemId() of the adapter's holder. The default getItemId(int position) inside FragmentStateAdapter is as follows:
public long getItemId(int position) {
return (long)position;
}
In this case, using the desired index value we can find the fragment at that specific index of the adapter as follows:
private EpisodeFragment getEpisodeFragment() {
Fragment fragment = getSupportFragmentManager().findFragmentByTag(getFragmentTag(itemId));
if (fragment instanceof EpisodeFragment) {
return (EpisodeFragment) fragment;
}
return null;
}
Where getFragmentTag() is defined as follows:
private static String getFragmentTag(long itemId) {
return "f" + itemId;
}
If we want to assign specific long values as itemIds, we can assign those values in order to specify particular fragments at particular indices later on. We need to update the adapter to override getItemId(int position) as follows:
private class ViewPagerFragmentAdapter extends FragmentStateAdapter {
public ViewPagerFragmentAdapter(#NonNull FragmentActivity fragmentActivity) {
super(fragmentActivity);
}
#NonNull
#Override
public Fragment createFragment(int position) {
return EpisodeFragment.newInstance(id, episodeSequence);
}
#Override
public int getItemCount() {
return tabTitles.size();
}
#Override
public long getItemId(int position) {
long fragmentTag;
switch (position) {
default:
case 0:
fragmentTag = 1;
break;
case 1:
fragmentTag = 2;
break;
case 2:
fragmentTag = 3;
break;
}
return fragmentTag;
}
}
Later on, we can find the desired fragment using these unique itemIds inside getEpisodeFragment().

not able to differ the contains of the two different fragments

I'm developing android screen for showing 2 different dashboard using tablayout & viewpager but only one screen shown at two different tabs(i.e. on MyDashboard & TeamDashboard).Please check my code.I'm new to android development.
I tried to use viewpager with pageradapter for swipe the screen.
public class ViewPagerAdapter extends FragmentPagerAdapter {
private int position;
private String tabTitles[] = new String[]{"MyDashboard", "Team` `Dashboard"};
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int i) {
// MyDashboard_Fragment dashboard_fragment=new `MyDashboard_Fragment();
// TeamDashboard_Fragment dashboard_fragment1=new `TeamDashboard_Fragment();
// position = position + 1;
// Bundle bundle=new Bundle();
// bundle.putString("message","Fragment :" +position);
// dashboard_fragment.setArguments(bundle);
// return dashboard_fragment;
Fragment fragment = null;
switch (position) {
case 0:
fragment = new MyDashboard_Fragment();
break;
case 1:
fragment = new TeamDashboard_Fragment();
break;
}
return fragment;
}
#Override
public int getCount() {
return 2;
}
#Nullable
#Override
public CharSequence getPageTitle(int position) {
return tabTitles[position];
}
}
Problem is because you are not assigning the new value to position variable before use it, please update your code like bellow
public class ViewPagerAdapter extends FragmentPagerAdapter {
private int position;
private String tabTitles[] = new String[]{"MyDashboard", "Team` `Dashboard"};
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int i) {
// MyDashboard_Fragment dashboard_fragment=new `MyDashboard_Fragment();
// TeamDashboard_Fragment dashboard_fragment1=new `TeamDashboard_Fragment();
// position = position + 1;
// Bundle bundle=new Bundle();
// bundle.putString("message","Fragment :" +position);
// dashboard_fragment.setArguments(bundle);
// return dashboard_fragment;
position=i;
Fragment fragment = null;
switch (position) {
case 0:
fragment = new MyDashboard_Fragment();
break;
case 1:
fragment = new TeamDashboard_Fragment();
break;
}
return fragment;
}
#Override
public int getCount() {
return 2;
}
#Nullable
#Override
public CharSequence getPageTitle(int position) {
return tabTitles[position];
}
}

Android: How to set tag to fragments in FragmentPagerAdapter?

Here's the inner class that contains fragments and changes fragment views on swipe. This class is defined in an Activity.
private class ViewPagerAdapter extends FragmentPagerAdapter {
private int count;
ViewPagerAdapter(FragmentManager fm, int count) {
super(fm);
this.count = count;
}
#Override
public Fragment getItem(int position) {
switch(position) {
case 0:
return new FriendsListFragment();
case 1:
Bundle bundle = new Bundle();
bundle.putString(Keys.TAG, ChatListFragment.class.getSimpleName());
ChatListFragment chatListFragment = new ChatListFragment();
chatListFragment.setArguments(bundle);
return chatListFragment;
case 2:
return new MoreFragment();
default:
return null;
}
}
#Override
public int getCount() {
return count;
}
}
Here I would like to add a code that sets tags to each fragment, so that I can recognize which fragment I'm at.
I searched quite much, and I haven't found a proper answer for this question, so please help.
You can override the setPrimaryItem method of your FragmentPagerAdapter.
private class ViewPagerAdapter extends FragmentPagerAdapter {
protected int currentPosition = -1;
protected Fragment currentFragment;
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
// ....
}
#Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
super.setPrimaryItem(container, position, object);
this.currentPosition = position;
if (object instanceof Fragment) {
this.currentFragment = (Fragment) object;
}
}
public int getCurrentPosition() {
return currentPosition;
}
public Fragment getCurrentFragment() {
return currentFragment;
}
}
Just use getCurrentPosition or getCurrentFragment methods to get information about current Fragment.

Communicate between Activity and ViewPager Fragments

Like in the image below, I have an Activity with a ViewPager (with TabLayout) inside.
Now I want to refresh for example the text of an TextView in a ViewPager Fragment. How can I do this?
http://imgur.com/0kWQCfx
[Sorry for the image link, but I don't have enough reputations yet.]
I already tried something like this:
//In Activity
View root = getLayoutInflater().inflate(R.layout.fragment_home, null);
TextView textView = (TextView) root.findViewById(R.id.text_view);
textView.setText("test");
But I get a NullPointerException for the textView.
Edit 1:
I only need to access the components inside one Fragment, so I am not using an array inside the Adapter.
I changed my ViewPagerAdapter to this:
public class ViewPagerAdapter extends FragmentPagerAdapter {
public HomeFragment fragment;
...
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return fragment = new HomeFragment();
case 1:
...
default:
return null;
}
}
But I still get a NullPointerException here:
final Fragment root = viewPagerAdapter.fragment;
Log.d("testtest", String.valueOf(root == null));
Write this code in your activity where you want to change fragment value. Your fragment id is e.g. my_fragment
Fragment frag = getFragmentManager().findFragmentById(R.id.my_fragment)
((TextView) frag.getView().findViewById(R.id.text_view)).setText(s);
You can create your own Adapter:
private class YourAdapter extends FragmentPagerAdapter implements ViewPager.OnPageChangeListener
{
Fragment screens[];
public CheckinHistoryAdapter(FragmentManager fm) {
super(fm);
screens = new Fragment[3];
screens[0] = new CoachFragment();
screens[1] = new LogingFragment();
screens[2] = new HistoryFragment();
}
#Override
public Fragment getItem(int index) {
if(index <= screens.length)
{
return screens[index];
}
return null;
}
#Override
public int getCount() {
return screens.length;
}
}
Use it like this
mViewPager.setAdapter(this.mPagerAdapter);
You can access fragment object with getItem method.
If you only need a reference to one Fragment, then just use the position parameter passed into instantiateItem(), and only assign your Fragment reference for the desired position:
public class ViewPagerAdapter extends FragmentPagerAdapter {
public HomeFragment fragment;
//...
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new HomeFragment(); //modified
case 1:
...
default:
return null;
}
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
Fragment createdFragment = (Fragment) super.instantiateItem(container, position);
if (position == 0) {
fragment = (HomeFragment) createdFragment;
}
return createdFragment;
}
}

Replace a Fragment in ViewPager after configuration change

I have a ViewPager with 2 pages. The first page is a list which have different layouts depending on the type and orientation of the device. In case of portrait mode the list is a classic list and in landscape mode a grid should be shown.
For those two kind of layouts I created 2 different fragments: ResultListFragment and ResultGridFragment.
Here is my pager adapter:
public static class GSPagerAdapter extends FragmentStatePagerAdapter {
private Context mContext;
private FragmentManager mFragmentManager;
private AbstractResultFragment mResultFragment;
public GSPagerAdapter(FragmentManager fm, Context context) {
super(fm);
mContext = context;
mFragmentManager = fm;
}
#Override
public Fragment getItem(int i) {
Log.v("pager", "GSPagerAdapter.getItem(" + i + ")");
switch (i) {
case 0: {
// if the device is in portrait mode, use a list
if (mContext.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT ) {
Log.v("pager","return new list fragment");
mResultFragment = new ResultListFragment();
return mResultFragment;
// else use a grid
} else {
Log.v("pager","return new grid fragment");
mResultFragment = new ResultGridFragment();
return mResultFragment;
}
}
case 1: {
Log.v("pager", "return the new filter fragment");
return new FilterFragment();
}
default: {
Log.v("pager", "return null");
return null;
}
}
}
#Override
public CharSequence getPageTitle(int i) {
switch (i) {
case 0:
return "Result";
case 1:
return "Filter";
}
return "";
}
#Override
public int getCount() {
return 2;
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
Log.v("pager","instantiateItem: "+position);
return super.instantiateItem(container, position);
}
#Override
public int getItemPosition(Object object){
Log.v("pager","getItemPosition: "+object);
return POSITION_NONE;
}
}
OnResume of the Activity:
public void onResume() {
super.onResume();
Log.v("lifecycle", "MainActivity.onResume()");
if(mViewPager != null)
mGSPagerAdapter.notifyDataSetChanged();
}
What do I do wrong? I have read several questions and answers but I cannot figure out what is the problem.

Categories

Resources