I am trying to find a way to replace fragments as fast as I can. The problem is with fragment recreation (inflating layout on recreation).
Why is this a bad idea?
private View view;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
if (view == null)
{
view= inflater.inflate(R.layout.fragment_one, container, false);
Log.e(TAG, "On create view !");
}
return view;
}
Or this variant:
User click on a tab from actionbar
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft)
{
// tab contains a tag with the name of the Fragment, in this case is FRAGMENT_ONE
TabDataHolder tdh = (TabDataHolder) tab.getTag();
replaceFragment(R.id.mainContent, tdh.fragmentTag);
}
Method for replacing fragment:
private void replaceFragment(int fragmentContainerId, String fragmentTag)
{
Log.e(TAG, "Replace fragment !");
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.setCustomAnimations(android.R.animator.fade_in, android.R.animator.fade_out);
ft.replace(fragmentContainerId, getFragment(fragmentTag), fragmentTag).commit();
}
Method which creates or returns an existing fragment
private Fragment getFragment(String fragmentTag)
{
Fragment fg = getFragmentManager().findFragmentByTag(fragmentTag);
if (fg == null)
fg = getFragmentFromStack(fragmentTag);
if (fragmentTag.equals(FRAGMENT_ONE))
{
if (fg == null)
{
fg = new FragmentOne();
addFragmentToStack(fg, fragmentTag, false);
Log.e(TAG, "Adding fg to stack !");
}
}
else
if (fragmentTag.equals(FRAGMENT_TWO))
{
if (fg == null)
{
fg = new FragmentTwo();
addFragmentToStack(fg, fragmentTag, false);
Log.e(TAG, "Adding fg to stack !");
}
}
else
if (fragmentTag.equals(FRAGMENT_THREE))
{
if (fg == null)
{
fg = new FragmentThree();
addFragmentToStack(fg, fragmentTag, false);
Log.e(TAG, "Adding fg to stack !");
}
}
else
if (fragmentTag.equals(FRAGMENT_FOUR))
{
if (fg == null)
{
fg = new FragmentFour();
addFragmentToStack(fg, fragmentTag, false);
Log.e(TAG, "Adding fg to stack !");
}
}
if (fg == null)
new NullPointerException("Fragment not found");
return fg;
}
Method which returns an existing fragment from the stack (ArrayList) by tag
private ArrayList<FragmentData> fragmentDataStack = new ArrayList<FragmentData>();
private Fragment getFragmentFromStack(String fragmentTag)
{
for (FragmentData fgd : fragmentDataStack)
{
if (fgd.getTag().equals(fragmentTag))
return fgd.getFragment();
}
return null;
}
public class FragmentData
{
private Fragment fragment;
private String tag;
public FragmentData (Fragment fragment, String tag)
{
this.fragment = fragment;
this.tag = tag;
}
public Fragment getFragment() {
return fragment;
}
public void setFragment(Fragment fragment) {
this.fragment = fragment;
}
public String getTag() {
return tag;
}
public void setTag(String tag) {
this.tag = tag;
}
}
Method which will add a Fragment to the stack. The last parameter is for deleting the old fragment and adding a new fragment
private void addFragmentToStack(Fragment fragment, String fragmentTag, boolean replaceIfExists)
{
if (replaceIfExists)
{
for (int i = 0; i < fragmentDataStack.size(); i++)
{
if (fragmentDataStack.get(i).getTag().equals(fragmentTag))
{
fragmentDataStack.set(i, new FragmentData(fragment, fragmentTag));
return;
}
}
}
fragmentDataStack.add(new FragmentData(fragment, fragmentTag));
}
I am not sure if this the right procedure for fast fragment replacement.
Related
I am trying to implement ViewPager with multiple Fragment and using static newInstance to instantiate the fragments inside a loop from activity
for(String name : list) {
viewPagerAdapter.addFragment(ProductListFragment.newInstance(name), name);
}
public static ProductListFragment newInstance(String category) {
ProductListFragment fragment = new ProductListFragment();
ProductListFragment.category = category;
Bundle args = new Bundle();
args.putString(CATEGORY_PARAM, category);
fragment.setArguments(args);
return fragment;
}
As the fragment's life cycle are getting called only after loop ends, i am not able to retain the values of parameter i am sending.
For your better understanding, think that there will be three tabs and in each tab i will show products which are related to "name" value and i want to filter those products using "name" value from a productList in fragment. As soon as first fragments lifecycle get calls i will be having the last value of "name" as i have mentioned fragments lifecycle starts only after loop ends which means i will be filtering products only related to last value of "name" and same products will be shown in all three tabs. How to resolve this?
Do not try to use ViewPagerAdapter.addFragment(), fragments should be created in getItem() method.
If you need a dynamic FragmentPagerAdapter, then you can do:
public class DynamicFragmentPagerAdapter extends PagerAdapter {
private static final String TAG = "DynamicFragmentPagerAdapter";
private final FragmentManager fragmentManager;
public static abstract class FragmentIdentifier implements Parcelable {
private final String fragmentTag;
private final Bundle args;
public FragmentIdentifier(#NonNull String fragmentTag, #Nullable Bundle args) {
this.fragmentTag = fragmentTag;
this.args = args;
}
protected FragmentIdentifier(Parcel in) {
fragmentTag = in.readString();
args = in.readBundle(getClass().getClassLoader());
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(fragmentTag);
dest.writeBundle(args);
}
protected final Fragment newFragment() {
Fragment fragment = createFragment();
Bundle oldArgs = fragment.getArguments();
Bundle newArgs = new Bundle();
if(oldArgs != null) {
newArgs.putAll(oldArgs);
}
if(args != null) {
newArgs.putAll(args);
}
fragment.setArguments(newArgs);
return fragment;
}
protected abstract Fragment createFragment();
}
private ArrayList<FragmentIdentifier> fragmentIdentifiers = new ArrayList<>();
private FragmentTransaction currentTransaction = null;
private Fragment currentPrimaryItem = null;
public DynamicFragmentPagerAdapter(FragmentManager fragmentManager) {
this.fragmentManager = fragmentManager;
}
private int findIndexIfAdded(FragmentIdentifier fragmentIdentifier) {
for (int i = 0, size = fragmentIdentifiers.size(); i < size; i++) {
FragmentIdentifier identifier = fragmentIdentifiers.get(i);
if (identifier.fragmentTag.equals(fragmentIdentifier.fragmentTag)) {
return i;
}
}
return -1;
}
public void addFragment(FragmentIdentifier fragmentIdentifier) {
if (findIndexIfAdded(fragmentIdentifier) < 0) {
fragmentIdentifiers.add(fragmentIdentifier);
notifyDataSetChanged();
}
}
public void removeFragment(FragmentIdentifier fragmentIdentifier) {
int index = findIndexIfAdded(fragmentIdentifier);
if (index >= 0) {
fragmentIdentifiers.remove(index);
notifyDataSetChanged();
}
}
#Override
public int getCount() {
return fragmentIdentifiers.size();
}
#Override
public void startUpdate(#NonNull ViewGroup container) {
if (container.getId() == View.NO_ID) {
throw new IllegalStateException("ViewPager with adapter " + this
+ " requires a view id");
}
}
#SuppressWarnings("ReferenceEquality")
#NonNull
#Override
public Object instantiateItem(#NonNull ViewGroup container, int position) {
if (currentTransaction == null) {
currentTransaction = fragmentManager.beginTransaction();
}
final FragmentIdentifier fragmentIdentifier = fragmentIdentifiers.get(position);
// Do we already have this fragment?
final String name = fragmentIdentifier.fragmentTag;
Fragment fragment = fragmentManager.findFragmentByTag(name);
if (fragment != null) {
currentTransaction.attach(fragment);
} else {
fragment = fragmentIdentifier.newFragment();
currentTransaction.add(container.getId(), fragment, fragmentIdentifier.fragmentTag);
}
if (fragment != currentPrimaryItem) {
fragment.setMenuVisibility(false);
fragment.setUserVisibleHint(false);
}
return fragment;
}
#Override
public void destroyItem(#NonNull ViewGroup container, int position, #NonNull Object object) {
if (currentTransaction == null) {
currentTransaction = fragmentManager.beginTransaction();
}
currentTransaction.detach((Fragment) object);
}
#SuppressWarnings("ReferenceEquality")
#Override
public void setPrimaryItem(#NonNull ViewGroup container, int position, #NonNull Object object) {
Fragment fragment = (Fragment) object;
if (fragment != currentPrimaryItem) {
if (currentPrimaryItem != null) {
currentPrimaryItem.setMenuVisibility(false);
currentPrimaryItem.setUserVisibleHint(false);
}
fragment.setMenuVisibility(true);
fragment.setUserVisibleHint(true);
currentPrimaryItem = fragment;
}
}
#Override
public void finishUpdate(#NonNull ViewGroup container) {
if (currentTransaction != null) {
currentTransaction.commitNowAllowingStateLoss();
currentTransaction = null;
}
}
#Override
public boolean isViewFromObject(#NonNull View view, #NonNull Object object) {
return ((Fragment) object).getView() == view;
}
#Override
public Parcelable saveState() {
Bundle bundle = new Bundle();
bundle.putParcelableArrayList("fragmentIdentifiers", fragmentIdentifiers);
return bundle;
}
#Override
public void restoreState(Parcelable state, ClassLoader loader) {
Bundle bundle = ((Bundle)state);
bundle.setClassLoader(loader);
fragmentIdentifiers = bundle.getParcelableArrayList("fragmentIdentifiers");
}
}
I have an activity which consists of three fragments. In one of these fragments I have a viewpager that consists of three other fragments. I call getChildFragmentManager() inside fragment that has viewpager in it. I have searched SO and read almost every answer that are related to this topic for example: this and this and one that seemed most useful was this but could not solve my problem. I think if i can just return POSITION_NONE for getItemPosition(Object object) in FragmentStatePagerAdapter and call notifyDataSetChanged() will solve my problem but every time I do this my app crashes with this error:
java.lang.IllegalStateException: FragmentManager is already executing
transactions!!!
and I mentioned that I am using getChildFragmentManager() inside my fragment.
Anyone thinks of any solution to this problem?
this is the parent fragment:
public class WordDetailFragment extends Fragment {
#BindView(R.id.word_parts_tab_layout)
TabLayout mTabLayout;
#BindView(R.id.word_part_view_pager)
ViewPager mViewPager;
private WordPagerAdapter mPagerAdapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_word_detail, container, false);
ButterKnife.bind(this, view);
mPagerAdapter = new WordPagerAdapter(getChildFragmentManager(), getActivity());
mViewPager.setAdapter(mPagerAdapter);
mTabLayout.setupWithViewPager(mViewPager);
return view;
}
public void notifyTranslateChanged() {
mViewPager.getAdapter().notifyDataSetChanged();
}
}
this is the code for adapter
public class WordPagerAdapter extends FragmentStatePagerAdapter {
final int PAGE_COUNT = 3;
private String[] tabTitles = new String[]{"Definition", "Example", "Col & fam"};
private Context context;
public WordPagerAdapter(FragmentManager fm, Context context) {
super(fm);
this.context = context;
}
#Override
public int getCount() {
return PAGE_COUNT;
}
#Override
public Fragment getItem(int position) {
Fragment fragment;
switch (position) {
case 0:
fragment = new WordDefinitionFragment();
break;
case 1:
fragment = new WordExampleFragment();
break;
case 2:
fragment = new WordColFamFragment();
break;
default: fragment = new WordDefinitionFragment();
}
return fragment;
}
#Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
#Override
public CharSequence getPageTitle(int position) {
// Generate title based on item position
return tabTitles[position];
}
}
One of the fragments in viewpager
public class WordDefinitionFragment extends Fragment {
#BindView(R.id.show_translate_switch)
Switch mShowTranslateSwitch;
private List<WordInfo> mWordInfoList;
private List<Definition> mDefinitionList;
private boolean mShowTranslation;
private View mView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mView = inflater.inflate(R.layout.fragment_word_definition, container, false);
ButterKnife.bind(this, mView);
mShowTranslation = SharedPrefHelper.getBooleanInfo(getActivity(), getString(R.string.show_translate_key));
mShowTranslateSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if (getActivity() != null)
((WordActivity) getActivity()).changeTranslateMode(b);
showTranslation(b);
}
});
return mView;
}
}
and my activity. U have just included the parts that i felt are needed here.
public class WordActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceSate) {
super.onCreate(savedInstanceSate);
setContentView(R.layout.activity_word);
}
public void changeTranslateMode(boolean show) {
SharedPrefHelper.setBooleanInfo(this, getString(R.string.show_translate_ke)y, show);
((WordDetailFragment)mWordDetailFragment).notifyTranslateChanged();
}
}
and my logcat error is
After many searches I could figure out a way which is not very smart but for the time being has solved my problem.
First of all I used the class FixedFragmentStatePagerAdapter from this post. I also had to remove the part in which the fragment bundle is restored because it caches fragment variables and views.
public abstract class FixedFragmentStatePagerAdapter extends PagerAdapter {
private static final String TAG = "PagerAdapter";
private static final boolean DEBUG = false;
private final FragmentManager mFragmentManager;
private FragmentTransaction mCurTransaction = null;
private ArrayList<Fragment.SavedState> mSavedState = new ArrayList<>();
private ArrayList<String> mSavedFragmentTags = new ArrayList<>();
private ArrayList<Fragment> mFragments = new ArrayList<>();
private Fragment mCurrentPrimaryItem = null;
public FixedFragmentStatePagerAdapter(FragmentManager fm) {
mFragmentManager = fm;
}
/**
* Return the Fragment associated with a specified position.
*/
public abstract Fragment getItem(int position);
public String getTag(int position) {
return null;
}
#Override
public void startUpdate(ViewGroup container) {
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
// If we already have this item instantiated, there is nothing
// to do. This can happen when we are restoring the entire pager
// from its saved state, where the fragment manager has already
// taken care of restoring the fragments we previously had instantiated.
if (mFragments.size() > position) {
Fragment f = mFragments.get(position);
if (f != null) {
return f;
}
}
if (mCurTransaction == null) {
mCurTransaction = mFragmentManager.beginTransaction();
}
Fragment fragment = getItem(position);
String fragmentTag = getTag(position);
if (DEBUG) Log.v(TAG, "Adding item #" + position + ": f=" + fragment + " t=" + fragmentTag);
/* if (mSavedState.size() > position) {
String savedTag = mSavedFragmentTags.get(position);
if (TextUtils.equals(fragmentTag, savedTag)) {
Fragment.SavedState fss = mSavedState.get(position);
if (fss != null) {
fragment.setInitialSavedState(fss);
}
}
}*/
while (mFragments.size() <= position) {
mFragments.add(null);
}
fragment.setMenuVisibility(false);
fragment.setUserVisibleHint(false);
mFragments.set(position, fragment);
mCurTransaction.add(container.getId(), fragment, fragmentTag);
return fragment;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
Fragment fragment = (Fragment)object;
if (mCurTransaction == null) {
mCurTransaction = mFragmentManager.beginTransaction();
}
if (DEBUG) Log.v(TAG, "Removing item #" + position + ": f=" + object
+ " v=" + ((Fragment)object).getView() + " t=" + fragment.getTag());
while (mSavedState.size() <= position) {
mSavedState.add(null);
mSavedFragmentTags.add(null);
}
mSavedState.set(position, mFragmentManager.saveFragmentInstanceState(fragment));
mSavedFragmentTags.set(position, fragment.getTag());
mFragments.set(position, null);
mCurTransaction.remove(fragment);
}
#Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
Fragment fragment = (Fragment)object;
if (fragment != mCurrentPrimaryItem) {
if (mCurrentPrimaryItem != null) {
mCurrentPrimaryItem.setMenuVisibility(false);
mCurrentPrimaryItem.setUserVisibleHint(false);
}
if (fragment != null) {
fragment.setMenuVisibility(true);
fragment.setUserVisibleHint(true);
}
mCurrentPrimaryItem = fragment;
}
}
#Override
public void finishUpdate(ViewGroup container) {
if (mCurTransaction != null) {
mCurTransaction.commitAllowingStateLoss();
mCurTransaction = null;
mFragmentManager.executePendingTransactions();
}
}
#Override
public boolean isViewFromObject(View view, Object object) {
return ((Fragment)object).getView() == view;
}
#Override
public Parcelable saveState() {
Bundle state = null;
if (mSavedState.size() > 0) {
state = new Bundle();
Fragment.SavedState[] fss = new Fragment.SavedState[mSavedState.size()];
mSavedState.toArray(fss);
state.putParcelableArray("states", fss);
state.putStringArrayList("tags", mSavedFragmentTags);
}
for (int i=0; i<mFragments.size(); i++) {
Fragment f = mFragments.get(i);
if (f != null) {
if (state == null) {
state = new Bundle();
}
String key = "f" + i;
mFragmentManager.putFragment(state, key, f);
}
}
return state;
}
#Override
public void restoreState(Parcelable state, ClassLoader loader) {
if (state != null) {
Bundle bundle = (Bundle)state;
bundle.setClassLoader(loader);
Parcelable[] fss = bundle.getParcelableArray("states");
mSavedState.clear();
mFragments.clear();
ArrayList<String> tags = bundle.getStringArrayList("tags");
if (tags != null) {
mSavedFragmentTags = tags;
} else {
mSavedFragmentTags.clear();
}
if (fss != null) {
for (int i=0; i<fss.length; i++) {
mSavedState.add((Fragment.SavedState)fss[i]);
}
}
Iterable<String> keys = bundle.keySet();
for (String key: keys) {
if (key.startsWith("f")) {
int index = Integer.parseInt(key.substring(1));
Fragment f = mFragmentManager.getFragment(bundle, key);
if (f != null) {
while (mFragments.size() <= index) {
mFragments.add(null);
}
f.setMenuVisibility(false);
mFragments.set(index, f);
} else {
Log.w(TAG, "Bad fragment at key " + key);
}
}
}
}
}
}
Then I implemented ViewPager.OnPageChangeListener in the fragment that contains the viewpager. And in the void onPageScrollStateChanged(int state) method I updated the view of my fragments in viewpager.
public class WordDetailFragment extends Fragment implements ViewPager.OnPageChangeListener {
#BindView(R.id.word_parts_tab_layout)
TabLayout mTabLayout;
#BindView(R.id.word_part_view_pager)
ViewPager mViewPager;
private WordPagerAdapter mPagerAdapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_word_detail, container, false);
ButterKnife.bind(this, view);
mPagerAdapter = new WordPagerAdapter(getChildFragmentManager(), getActivity());
mViewPager.setAdapter(mPagerAdapter);
mTabLayout.setupWithViewPager(mViewPager);
mViewPager.addOnPageChangeListener(this);
return view;
}
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
Fragment mFragment;
#Override
public void onPageSelected(int position) {
mFragment = mPagerAdapter.getItem(position);
}
#Override
public void onPageScrollStateChanged(int state) {
if (state == ViewPager.SCROLL_STATE_IDLE) {
if (mFragment instanceof WordDefinitionFragment) {
((WordDefinitionFragment) mFragment).showTranslation();
//Log.e("StateChanged", mFragment.getClass().getSimpleName());
}
if (mFragment instanceof WordExampleFragment) {
((WordExampleFragment) mFragment).showTranslation();
//Log.e("StateChanged", mFragment.getClass().getSimpleName());
}
if (mFragment instanceof WordColFamFragment) {
((WordColFamFragment) mFragment).showTranslation();
//Log.e("StateChanged", mFragment.getClass().getSimpleName());
}
}
}
}
And in my fragments, I had a callback interface which was implemented in the activity. And in void setUserVisibleHint(boolean isVisibleToUser) method I updated the UI again because neighbor fragments did not get updated.
public class WordExampleFragment extends Fragment {
#BindView(R.id.example_field_name_id)
TextView mExampleFieldNameTV;
#BindView(R.id.word_tv)
TextView mWordTv;
#BindView(R.id.play_sound_iv)
ImageView mPlaySoundIv;
#BindView(R.id.show_translate_switch)
Switch mShowTranslateSwitch;
private TextView mExample1ContentFaTV;
private List<WordInfo> mWordInfoList;
private List<Example> mExampleList;
private int mWordNumber;
//callback interface
private TranslateModeChangeListener mWordPartFragments;
#Override
public void onAttach(Context context) {
super.onAttach(context);
try {
mWordPartFragments = (TranslateModeChangeListener) context;
} catch (ClassCastException ex) {
throw new ClassCastException("Must implement WordPartFragments interface");
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_word_example, container, false);
ButterKnife.bind(this, view);
mWordInfoList = WordActivity.sWordInfoList;
mWordNumber = WordActivity.sWordNumber;
mExampleList = mWordInfoList.get(mWordNumber).getExamples();
showTranslation();
mShowTranslateSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
//this method is called from activity=> callback interface
mWordPartFragments.changeTranslateMode(b);
showTranslation();
}
});
return view;
}
//this method is called when viewpager shows this fragment and it is visible to user
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
showTranslation();
}
}
//this methoud updates my UI: shows or hides the translation
public void showTranslation() {
if (isAdded()) {
boolean showTranslation = WordActivity.sTranslationShown;
//Log.e("Ex", "added & shown = " + showTranslation);
mShowTranslateSwitch.setChecked(showTranslation);
mExample1ContentFaTV.setVisibility((showTranslation) ? View.VISIBLE : View.INVISIBLE);
}
}
}
I've got a TabLayout in my Activity, it shows one fragment when it's created, but I need to be able to add a new fragment to it after completing an operation (or create both when the activity is created, but show only the first, and then show the second).
I've tried adding the fragment to the viewPagerAdapter and then calling the notifyDataSetChanged() method, the frament it's added, but it's title doesn't show up in the tabLayout and if I try to slide to it, I get an IndexOutOfBoundsException: Invalid index 1, size is 1
Does anyone got some advice to give me?
My activity, where I add the first fragmen:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.act_one);
// Crete a new fragment
FragmentOne fragmentOne = new FragmentoOne();
tabLayout = (TabLayout) findViewById(R.id.tabLayout);
viewPager = (ViewPager) findViewById(R.id.viewPager);
// Creates the viewPagerAdapter
viewPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager());
// Adds the fragment to ViewPagerAdapter
viewPagerAdapter.addFragment(fragmentoOne, "First"); // this line can cause crashes
viewPager.setAdapter(viewPagerAdapter);
tabLayout.setupWithViewPager(viewPager);
}
And here is where I try to add the new fragment:
public void onAddFragment2() {
viewPagerAdapter.addFragment(new FragmentoTwo(), "Second"); // new FragmentoTwo() should be in FragmentPagerAdapter.getItem()
viewPagerAdapter.notifyDataSetChanged();
}
set the adapter again after you added it with setAdapter
This is important, if you have 3 fragment you shout write 3 in your Adapter.
#Override
public int getCount() {
return 3;
}
To modify the contents of a FragmentPagerAdapter, you need to use the following code:
public class DynamicFragmentPagerAdapter extends PagerAdapter {
private static final String TAG = "DynamicFragmentPagerAdapter";
private final FragmentManager fragmentManager;
public static abstract class FragmentIdentifier implements Parcelable {
private final String fragmentTag;
private final Bundle args;
public FragmentIdentifier(#NonNull String fragmentTag, #Nullable Bundle args) {
this.fragmentTag = fragmentTag;
this.args = args;
}
protected FragmentIdentifier(Parcel in) {
fragmentTag = in.readString();
args = in.readBundle(getClass().getClassLoader());
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(fragmentTag);
dest.writeBundle(args);
}
protected final Fragment newFragment() {
Fragment fragment = createFragment();
Bundle oldArgs = fragment.getArguments();
Bundle newArgs = new Bundle();
if(oldArgs != null) {
newArgs.putAll(oldArgs);
}
if(args != null) {
newArgs.putAll(args);
}
fragment.setArguments(newArgs);
return fragment;
}
protected abstract Fragment createFragment();
}
private ArrayList<FragmentIdentifier> fragmentIdentifiers = new ArrayList<>();
private FragmentTransaction currentTransaction = null;
private Fragment currentPrimaryItem = null;
public DynamicFragmentPagerAdapter(FragmentManager fragmentManager) {
this.fragmentManager = fragmentManager;
}
private int findIndexIfAdded(FragmentIdentifier fragmentIdentifier) {
for (int i = 0, size = fragmentIdentifiers.size(); i < size; i++) {
FragmentIdentifier identifier = fragmentIdentifiers.get(i);
if (identifier.fragmentTag.equals(fragmentIdentifier.fragmentTag)) {
return i;
}
}
return -1;
}
public void addFragment(FragmentIdentifier fragmentIdentifier) {
if (findIndexIfAdded(fragmentIdentifier) < 0) {
fragmentIdentifiers.add(fragmentIdentifier);
notifyDataSetChanged();
}
}
public void removeFragment(FragmentIdentifier fragmentIdentifier) {
int index = findIndexIfAdded(fragmentIdentifier);
if (index >= 0) {
fragmentIdentifiers.remove(index);
notifyDataSetChanged();
}
}
#Override
public int getCount() {
return fragmentIdentifiers.size();
}
#Override
public void startUpdate(#NonNull ViewGroup container) {
if (container.getId() == View.NO_ID) {
throw new IllegalStateException("ViewPager with adapter " + this
+ " requires a view id");
}
}
#SuppressWarnings("ReferenceEquality")
#NonNull
#Override
public Object instantiateItem(#NonNull ViewGroup container, int position) {
if (currentTransaction == null) {
currentTransaction = fragmentManager.beginTransaction();
}
final FragmentIdentifier fragmentIdentifier = fragmentIdentifiers.get(position);
// Do we already have this fragment?
final String name = fragmentIdentifier.fragmentTag;
Fragment fragment = fragmentManager.findFragmentByTag(name);
if (fragment != null) {
currentTransaction.attach(fragment);
} else {
fragment = fragmentIdentifier.newFragment();
currentTransaction.add(container.getId(), fragment, fragmentIdentifier.fragmentTag);
}
if (fragment != currentPrimaryItem) {
fragment.setMenuVisibility(false);
fragment.setUserVisibleHint(false);
}
return fragment;
}
#Override
public void destroyItem(#NonNull ViewGroup container, int position, #NonNull Object object) {
if (currentTransaction == null) {
currentTransaction = fragmentManager.beginTransaction();
}
currentTransaction.detach((Fragment) object);
}
#SuppressWarnings("ReferenceEquality")
#Override
public void setPrimaryItem(#NonNull ViewGroup container, int position, #NonNull Object object) {
Fragment fragment = (Fragment) object;
if (fragment != currentPrimaryItem) {
if (currentPrimaryItem != null) {
currentPrimaryItem.setMenuVisibility(false);
currentPrimaryItem.setUserVisibleHint(false);
}
fragment.setMenuVisibility(true);
fragment.setUserVisibleHint(true);
currentPrimaryItem = fragment;
}
}
#Override
public void finishUpdate(#NonNull ViewGroup container) {
if (currentTransaction != null) {
currentTransaction.commitNowAllowingStateLoss();
currentTransaction = null;
}
}
#Override
public boolean isViewFromObject(#NonNull View view, #NonNull Object object) {
return ((Fragment) object).getView() == view;
}
#Override
public Parcelable saveState() {
Bundle bundle = new Bundle();
bundle.putParcelableArrayList("fragmentIdentifiers", fragmentIdentifiers);
return bundle;
}
#Override
public void restoreState(Parcelable state, ClassLoader loader) {
Bundle bundle = ((Bundle)state);
bundle.setClassLoader(loader);
fragmentIdentifiers = bundle.getParcelableArrayList("fragmentIdentifiers");
}
}
Then generally, to make a modification actually happen (because ViewPagers are quirky), you'll most likely need:
viewPager.setAdapter(null);
viewPager.setAdapter(adapter);
My implementation of an AbsListView.OnItemClickListener in a Fragment performs no action and displays no error, when a list item is tapped.
I read the documentation, searched Google & SOF and read the SDK source, but could not solve the problem.
The Activity:
public class VenueActivity extends Activity implements
NBVenuesFragment.OnFragmentInteractionListener,
NBFriendsFragment.OnFragmentInteractionListener,
UploadedPhotosFragment.OnFragmentInteractionListener {
private static final String TAB_KEY_INDEX = "tab_key";
private static final String TAG = "VenueActivity";
private Fragment mCurrentFragment = null;
private Fragment mNewFragment = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_venue);
ActionBar actionbar = getActionBar();
actionbar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
ActionBar.Tab mVenuesFragmentTab = actionbar.newTab().setText(
getString(R.string.ui_nearby_venues_tab));
ActionBar.Tab mNBFriendsFragmentTab = actionbar.newTab().setText(
getString(R.string.ui_nearby_friends_tab));
ActionBar.Tab mUploadedPhotosFragmentTab = actionbar.newTab().setText("Photos Uploaded");
Fragment mVenuesFragment = new NBVenuesFragment();
Fragment mNBFriendsFragment = new NBFriendsFragment();
Fragment mUploadedPhotosFragment = new UploadedPhotosFragment();
mVenuesFragmentTab.setTabListener(new VenueTabsListener(mVenuesFragment,
getApplicationContext()));
mNBFriendsFragmentTab.setTabListener(new VenueTabsListener(mNBFriendsFragment,
getApplicationContext()));
mUploadedPhotosFragmentTab.setTabListener(new VenueTabsListener(mUploadedPhotosFragment,
getApplicationContext()));
actionbar.addTab(mVenuesFragmentTab);
//actionbar.addTab(mNBFriendsFragmentTab);
actionbar.addTab(mUploadedPhotosFragmentTab);
if (savedInstanceState != null) {
actionbar.setSelectedNavigationItem(savedInstanceState.getInt(
TAB_KEY_INDEX, 0));
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu items for use in the action bar
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.venue_activity_actions, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_check_in:
Toast.makeText(this, getString(R.string.action_check_in),
Toast.LENGTH_SHORT).show();
return true;
case android.R.id.home:
// app icon in action bar clicked; goto parent activity.
this.onBackPressed();
return true;
}
return false;
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(TAB_KEY_INDEX, getActionBar()
.getSelectedNavigationIndex());
}
#Override
public void onNearByVenueSelection(VenuesDummyData.VenuesDummyItem venueData){
Bundle args = new Bundle();
args.putString("VENUE_ID", venueData.venueId);
args.putString("VENUE_NAME", venueData.venueName);
args.putString("VENUE_ADDRESS", venueData.venueAddress);
args.putString("VENUE_CHECK_INS", venueData.venueCheckIns);
args.putString("VENUE_LIKES", venueData.venueLikes);
args.putString("VENUE_CHECK_INS_FLIRT", venueData.venueCheckInsflirt);
args.putString("VENUE_CHECK_INS_FRIENDS", venueData.venueCheckInsFriends);
args.putString("OMEGA", venueData.omega);
Fragment mVenueDetailsFragment = new VenueDetailsFragment();
mVenueDetailsFragment.setArguments(args);
mCurrentFragment = new NBVenuesFragment();
mNewFragment = mVenueDetailsFragment;
FragmentManager mFragmentManager = getFragmentManager();
String tag = mVenueDetailsFragment.getTag();
FragmentTransaction ft = mFragmentManager.beginTransaction();
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.replace(R.id.fragment_container, mVenueDetailsFragment, tag);
ft.commit();
}
#Override
public void onNearByFriendSelection(JsonObject mUserInfo){
Bundle args = new Bundle();
args.putString("FRIEND_NAME", mUserInfo.get("name").getAsString());
//args.putString("FRIEND_ID", mUserInfo.friendId);
args.putString("FRIEND_PHOTO", mUserInfo.get("photo_url").getAsString());
//args.putString("VENUE_ID", mUserInfo.venueId);
//args.putString("VENUE_NAME", mUserInfo.venueName);
Fragment mFriendDetailsFragment = new FriendDetailsFragment();
mFriendDetailsFragment.setArguments(args);
mCurrentFragment = new NBFriendsFragment();
mNewFragment = mFriendDetailsFragment;
FragmentManager mFragmentManager = getFragmentManager();
String tag = mFriendDetailsFragment.getTag();
FragmentTransaction ft = mFragmentManager.beginTransaction();
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.replace(R.id.fragment_container, mFriendDetailsFragment, tag);
//ft.addToBackStack(tag);
ft.commit();
}
#Override
public void onUserSelection(JsonObject mUserInfo){
Log.i(TAG, "onUserSelection");
Log.i(TAG, "mUserInfo ==> " + mUserInfo.toString());
Bundle args = new Bundle();
args.putString("USER_NAME", mUserInfo.get("name").getAsString());
//args.putString("FRIEND_ID", mUserInfo.friendId);
args.putString("USER_PHOTO", mUserInfo.get("photo_url").getAsString());
//args.putString("VENUE_ID", mUserInfo.venueId);
//args.putString("VENUE_NAME", mUserInfo.venueName);
Fragment mUserDetailsFragment = new UserDetailsFragment();
mUserDetailsFragment.setArguments(args);
mCurrentFragment = new UploadedPhotosFragment();
mNewFragment = mUserDetailsFragment;
FragmentManager mFragmentManager = getFragmentManager();
String tag = mUserDetailsFragment.getTag();
FragmentTransaction ft = mFragmentManager.beginTransaction();
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.replace(R.id.fragment_container, mUserDetailsFragment, tag);
//ft.addToBackStack(tag);
ft.commit();
}
#Override
public void onBackPressed() {
if (mCurrentFragment != null && mNewFragment != null) {
String tag = mCurrentFragment.getTag();
FragmentManager mFragmentManager = getFragmentManager();
FragmentTransaction ft = mFragmentManager.beginTransaction();
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.remove(mNewFragment);
ft.replace(R.id.fragment_container, mCurrentFragment, tag);
ft.commit();
mCurrentFragment = null;
mNewFragment = null;
} else {
super.onBackPressed();
}
}
}
class VenueTabsListener implements ActionBar.TabListener {
public Fragment fragment;
public Context context;
public VenueTabsListener(Fragment fragment, Context context) {
this.fragment = fragment;
this.context = context;
}
#Override
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
//Toast.makeText(context, "Reselected!", Toast.LENGTH_SHORT).show();
}
#Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
//Toast.makeText(context, "Selected!", Toast.LENGTH_SHORT).show();
ft.replace(R.id.fragment_container, fragment);
}
#Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
//Toast.makeText(context, "Unselected!", Toast.LENGTH_SHORT).show();
ft.remove(fragment);
}
}
The list Fragment:
public class UploadedPhotosFragment extends Fragment implements AbsListView.OnItemClickListener {
private OnFragmentInteractionListener mListener;
private AbsListView mListView;
private JsonObject mUserInfo;
private PhotosAdapter mAdapter;
private JsonArray mDataFromServer;
private String TAG = "UploadedPhotosFragment";
private void getPhotosData() {
Log.i(TAG, "getPhotosData");
AsyncTask<Void, Void, FlefuApiMessagesGetPhotosResponseMessage> photosJsonString;
photosJsonString = new GetPhotos() {
#Override
protected void onPostExecute(FlefuApiMessagesGetPhotosResponseMessage response) {
Log.i(TAG, "#overridden GetPhotos onPostExecute: " + response.getData());
mDataFromServer = (JsonArray)new JsonParser().parse(response.getData());
mUserInfo = new JsonObject();
for (int i = 0; i < mDataFromServer.size(); i++) {
mUserInfo = mDataFromServer.get(i).getAsJsonObject();
mAdapter.add(mUserInfo);
}
}
};
photosJsonString.execute();
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getPhotosData();
mAdapter = new PhotosAdapter(getActivity());
Log.i(TAG, "onCreate");
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.i(TAG, "onCreateView");
View view = inflater.inflate(R.layout.fragment_photo_image, container, false);
//int cols = getResources().getDisplayMetrics().widthPixels / getResources().getDisplayMetrics().densityDpi;
mListView = (AbsListView) view.findViewById(R.id.photos);
//mListView.setNumColumns(3);
mListView.setAdapter(mAdapter);
mListView.setOnItemClickListener(this);
return view;
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (OnFragmentInteractionListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
private class PhotosAdapter extends ArrayAdapter <JsonObject> {
private LayoutInflater inflater;
private class ViewHolder {
TextView name;
//TextView venue;
ImageView thumb;
}
public PhotosAdapter(Context context) {
super(context, R.layout.uploaded_image);
Log.i(TAG, context.toString());
inflater = LayoutInflater.from(context);
Log.i(TAG, "PhotosAdapter");
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Log.i(TAG, "getView");
ViewHolder holder;
if(convertView == null) {
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.uploaded_image, null);
holder.name = (TextView) convertView.findViewById(R.id.name);
holder.thumb = (ImageView) convertView.findViewById(R.id.image);
//holder.venueName = (TextView) convertView.findViewById(R.id.venueName);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
// select the image view
Ion.with(holder.thumb)
.resize(300, 300)
.centerCrop()
//.placeholder(R.drawable.placeholder)
//.error(R.drawable.error)
.load(getItem(position).get("thumb_url").getAsString());
holder.name.setText(getItem(position).get("name").getAsString());
return convertView;
}
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Log.i(TAG, "parent ==> " + parent.toString());
Log.i(TAG, "view ==> " + view.toString());
if (mListener != null) {
Log.i(TAG, "call to onUserSelection ==> " +
mDataFromServer.get(position).getAsJsonObject().toString());
mListener.onUserSelection(mDataFromServer.get(position).getAsJsonObject());
}
}
public interface OnFragmentInteractionListener {
public void onUserSelection(JsonObject mUserInfo);
}
}
You did not initialized Your mListener value. Your mListener is null and nothing happens when You click a ListView item.
I am trying to create facebook like viewpager (swipable tabs and proper backstack) I can create swipable tabs but cant handle the proper back navigation. Bellow is my code
public class MainActivity extends FragmentActivity {
private ViewPager mPager;
// private SlidePagerAdapter mPagerAdapter;
private MyPagerAdapter mPagerAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/* Instantiate a ViewPager and a PagerAdapter. */
mPager = (ViewPager) findViewById(R.id.pager);
mPagerAdapter = new MyPagerAdapter(getSupportFragmentManager());
mPager.setAdapter(mPagerAdapter);
mPager.setOffscreenPageLimit(4);
}
#Override
public void onBackPressed() {
Fragment currentVisibleFragment = mPagerAdapter.getRegisteredFragment(mPager.getCurrentItem());
if (currentVisibleFragment != null && currentVisibleFragment.isVisible()) {
FragmentManager childFm = currentVisibleFragment.getChildFragmentManager();
System.out.println("============================================");
System.out.println("childFm.getBackStackEntryCount()=== " + childFm.getBackStackEntryCount());
System.out.println("============================================");
if (childFm.getBackStackEntryCount() > 0) {
childFm.popBackStack();
return;
}
}
super.onBackPressed();
}
}
Adapter of my class is as bellow
public class MyPagerAdapter extends SmartFragmentStatePagerAdapter {
private static int NUM_ITEMS = 3;
public MyPagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
}
// Returns total number of pages
#Override
public int getCount() {
return NUM_ITEMS;
}
// Returns the fragment to display for that page
#Override
public Fragment getItem(int position) {
switch (position) {
case 0: // Fragment # 0 - This will show FirstFragment
return new FragmentA();
case 1: // Fragment # 0 - This will show FirstFragment different title
return new FragmentB();
case 2: // Fragment # 1 - This will show SecondFragment
return new FragmentC();
default:
return null;
}
}
// Returns the page title for the top indicator
#Override
public CharSequence getPageTitle(int position) {
return "Page " + position;
}
}
here is the exteded adapter
public abstract class SmartFragmentStatePagerAdapter extends FragmentStatePagerAdapter {
// Sparse array to keep track of registered fragments in memory
private SparseArray<Fragment> registeredFragments = new SparseArray<Fragment>();
public SmartFragmentStatePagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
}
// Register the fragment when the item is instantiated
#Override
public Object instantiateItem(ViewGroup container, int position) {
Fragment fragment = (Fragment) super.instantiateItem(container, position);
registeredFragments.put(position, fragment);
return fragment;
}
// Unregister when the item is inactive
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
registeredFragments.remove(position);
super.destroyItem(container, position, object);
}
// Returns the fragment for the position (if instantiated)
public Fragment getRegisteredFragment(int position) {
return registeredFragments.get(position);
}
}
and Fragments are as bellow
public class FragmentA extends Fragment {
public static final String TAG = "FragmentA";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.first_fragment, container, false);
Button btn = (Button) view.findViewById(R.id.btn);
btn.setText(TAG);
btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
FragmentTransaction trans = getChildFragmentManager().beginTransaction();
/*
* IMPORTANT: We use the "root frame" defined in
* "root_fragment.xml" as the reference to replace fragment
*/
trans.replace(R.id.framelayout_infragment_one, new FragmentA1());
/*
* IMPORTANT: The following lines allow us to add the fragment
* to the stack and return to it later, by pressing back
*/
trans.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
trans.addToBackStack(null);
trans.commit();
}
});
return view;
}
}
public class FragmentA1 extends Fragment {
public static final String TAG = "FragmentA1";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.first_fragment, container, false);
view.setBackgroundColor(Color.RED);
Button btn = (Button) view.findViewById(R.id.btn);
btn.setText(TAG);
btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
FragmentTransaction trans = getChildFragmentManager().beginTransaction();
/*
* IMPORTANT: We use the "root frame" defined in
* "root_fragment.xml" as the reference to replace fragment
*/
trans.replace(R.id.framelayout_infragment_one, new FragmentA2());
/*
* IMPORTANT: The following lines allow us to add the fragment
* to the stack and return to it later, by pressing back
*/
trans.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
trans.addToBackStack(null);
trans.commit();
}
});
return view;
}
}
//second inner fragment
public class FragmentA2 extends Fragment {
public static final String TAG = "FragmentA2";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.second_fragment, container, false);
view.setBackgroundColor(Color.GRAY);
Button btn = (Button) view.findViewById(R.id.btn);
btn.setText(TAG);
btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
FragmentTransaction trans = getFragmentManager().beginTransaction();
trans.replace(R.id.root_frame, new FragmentC());
trans.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
trans.addToBackStack(null);
trans.commit();
}
});
return view;
}
}
When I am going to frament A2 expected behaviour when user press back is I want to go to Frament A1 but I am going to Frament A. Fragment B,B1,B2 are same as A A1 A2 resp...
Please help
I managed it by maintaining stacks by myself
public static HashMap<String, Stack<Fragment>> mStacks;
mStacks = new HashMap<String, Stack<Fragment>>();
mStacks.put("TAB1", new Stack<Fragment>());
mStacks.put("TAB2", new Stack<Fragment>());
mStacks.put("TAB3", new Stack<Fragment>());
mStacks.put("TAB4", new Stack<Fragment>());
//when starting new fragment add that to stack like this
public void pushFragments(Fragment fragment) {
setSelectedPageN(pager.getCurrentItem());
mStacks.get(ApplicationConstants.CURRENT_TAB).push(fragment);
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction ft = manager.beginTransaction();
if (ApplicationConstants.CURRENT_TAB.equals("TAB1")) {
ft.replace(R.id.container_feed, fragment);
} else if (ApplicationConstants.CURRENT_TAB.equals("TAB2")) {
ft.replace(R.id.container_chart, fragment);
} else if (ApplicationConstants.CURRENT_TAB.equals("TAB3")) {
ft.replace(R.id.container_explore, fragment);
} else if (ApplicationConstants.CURRENT_TAB.equals("TAB4")) {
ft.replace(R.id.container_profile, fragment);
}
ft.commit();
}
//When you want to finish
public void popFragments() {
/*
* Select the second last fragment in current tab's stack.. which will
* be shown after the fragment transaction given below
*/
setSelectedPageN(pager.getCurrentItem());
Fragment fragment = mStacks.get(ApplicationConstants.CURRENT_TAB).elementAt(mStacks.get(ApplicationConstants.CURRENT_TAB).size() - 2);
if (fragment instanceof ProfileContainerFragment) {
fragment = new ProfileFragment();
} else if (fragment instanceof FeedNewUserGuideline && !isShowFeedTutorial) {
fragment = new FeedFragment();
}
/* pop current fragment from stack.. */
mStacks.get(ApplicationConstants.CURRENT_TAB).pop();
/*
* We have the target fragment in hand.. Just show it.. Show a standard
* navigation animation
*/
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction ft = manager.beginTransaction();
ft.setCustomAnimations(R.anim.abc_fade_in, R.anim.abc_fade_out);
if (ApplicationConstants.CURRENT_TAB.equals(ApplicationConstants.TAB_FEED)) {
ft.replace(R.id.container_feed, fragment);
} else if (ApplicationConstants.CURRENT_TAB.equals(ApplicationConstants.TAB_CHART)) {
ft.replace(R.id.container_chart, fragment);
} else if (ApplicationConstants.CURRENT_TAB.equals(ApplicationConstants.TAB_EXPLORE)) {
ft.replace(R.id.container_explore, fragment);
} else if (ApplicationConstants.CURRENT_TAB.equals(ApplicationConstants.TAB_PROFILE)) {
ft.replace(R.id.container_profile, fragment);
}
ft.commit();
}
//When user back press
#Override
public void onBackPressed() {
try {
if (((BaseFragment) mStacks.get(ApplicationConstants.CURRENT_TAB).lastElement()).onBackPressed() == false) {
switch (pager.getCurrentItem()) {
case KeyConstants.POSITION_ONE_FEED:
if (mStacks.get(ApplicationConstants.TAB_FEED).size() == 1) {
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
this.finish();
// super.onBackPressed(); // or call finish..
} else {
popFragments();
}
break;
case KeyConstants.POSITION_TWO_CHART:
if (mStacks.get(ApplicationConstants.TAB_CHART).size() == 1) {
pager.setCurrentItem(KeyConstants.POSITION_ONE_FEED);
} else {
popFragments();
}
break;
case KeyConstants.POSITION_THREE_EXPLORE:
if (mStacks.get(ApplicationConstants.TAB_EXPLORE).size() == 1) {
pager.setCurrentItem(KeyConstants.POSITION_TWO_CHART);
} else {
popFragments();
}
break;
case KeyConstants.POSITION_FOUR_PROFILE:
if (mStacks.get(ApplicationConstants.TAB_PROFILE).size() == 1) {
pager.setCurrentItem(KeyConstants.POSITION_THREE_EXPLORE);
} else {
popFragments();
}
break;
default:
break;
}
} else {
// do nothing.. fragment already handled back button press.
}
} catch (Exception e) {
e.printStackTrace();
}
}