Bring a specific fragment to top of other fragments - android

How can I bring fragment to top of other fragments ?
I added fragment like bellow :
#OnClick(R.id.imbEvents)
void clickEvents() {
String tagName = returnStatusFragment(getString(R.string.events_fragment));
if (!TextUtils.isEmpty(tagName) && tagName.equals(getString(R.string.events_fragment))) {
//Fragment is opened
} else {
if (getActivity() != null) {
frameWorkTableFragment.setVisibility(View.VISIBLE);
EventsFragment eventsFragment = new EventsFragment();
getActivity().getSupportFragmentManager().beginTransaction()
.replace(R.id.frame_work_table_fragment,
eventsFragment,
getString(R.string.events_fragment))
.addToBackStack(getString(R.string.events_fragment))
.commit();
}
}
}
I used from bellow code to bring fragment to top but close all last fragments:
getActivity().getSupportFragmentManager().popBackStack(tagName, 0);
Method of returnStatusFragment is :
private String returnStatusFragment(String tagName) {
android.support.v4.app.FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
Fragment tempFragment = fragmentManager.findFragmentByTag(tagName);
if (tempFragment != null) {
return tempFragment.getTag();
} else {
return "";
}
}
My doBackTabZero:
#Override
public void doBackTabZero(String nameFragment) {
android.support.v4.app.FragmentManager fragmentManagers = getActivity().getSupportFragmentManager();
Log.i("ASDSADASDSASD", "3 " + nameFragment + " " + fragmentManagers.getBackStackEntryCount());
if (fragmentManagers.getBackStackEntryCount() > 1) {
fragmentManagers.popBackStackImmediate();
} else {
if (nameFragment.equals("EventsFragment")) {
BusDisplayStatusFrameLayout busDisplayStatusFrameLayout = new BusDisplayStatusFrameLayout();
busDisplayStatusFrameLayout.setDisplayStatusFrameLayout(1);
EventBus.getDefault().post(busDisplayStatusFrameLayout);
android.support.v4.app.FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
android.support.v4.app.FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentManager.popBackStackImmediate();
fragmentTransaction.remove(EventsFragment.this);
fragmentTransaction.commit();
}
}
}

replace this
getActivity().getSupportFragmentManager().popBackStack(tagName, 0);
with
Fragment eventsFragment = fragmentManager.findFragmentByTag(getString(R.string.events_fragment));
getActivity().getSupportFragmentManager().beginTransaction()
.replace(R.id.frame_work_table_fragment,
eventsFragment,
getString(R.string.events_fragment)).commit();//don't add to back stack again
onBackPressed
#Override
public void doBackTabZero(String nameFragment) {
android.support.v4.app.FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
if(fragmentManager.getBackStackEntryCount() > 1 ){
fragmentManager.popBackStackImmediate();
}else{
super.onBackPressed();
}
}

Related

Save state of fragment when using bottom navigation

I am using bottom navigation drawer to switch between fragments, the problem is that every time I switch back to a fragment it gets recreated.
How can I save the state of fragment and resume it when switched back to it?
bottomNavigationBar.setTabSelectedListener(new BottomNavigationBar.OnTabSelectedListener(){
#Override
public void onTabSelected(int position) {
if (position==0){
loadFragment(new Daily());
}
if (position==1){
loadFragment(new Trending());
}
if (position==2){
loadFragment(new Random());
}
}
#Override
public void onTabUnselected(int position) {
}
#Override
public void onTabReselected(int position) {
}
});
private void loadFragment(Fragment fragment) {
// load fragment
FragmentTransaction transaction =
getSupportFragmentManager().beginTransaction();
transaction.attach( fragment);
transaction.addToBackStack(null);
transaction.commit();
}
The issue is that you are always creating a new Fragment on any onTabSelected. So in order to fix it, you need to work with your FragmentManager.
Possible solution: use the add and show/hide methods.
Example:
private static final String DAILY_TAG = BuildConfig.APPLICATION_ID + ".DAILY_TAG";
private static final String TRENDING_TAG = BuildConfig.APPLICATION_ID + ".TRENDING_TAG";
private static final String RANDOM_TAG = BuildConfig.APPLICATION_ID + ".RANDOM_TAG";
public void onTabSelected(int position) {
FragmentManager fragmentManager = getSupportFragmentManager();
if (position == 0) {
hideFragment(TRENDING_TAG)
hideFragment(RANDOM_TAG)
Fragment fragment = fragmentManager.findFragmentByTag(DAILY_TAG);
FragmentTransaction transaction = fragmentManager.beginTransaction()
if (fragment != null) {
transaction.show(fragment)
} else {
transaction.add(content.id, new Daily(), DAILY_TAG)
}
transaction.commitNow()
} else if (position == 1) {
hideFragment(DAILY_TAG)
hideFragment(RANDOM_TAG)
Fragment fragment = fragmentManager.findFragmentByTag(TRENDING_TAG);
FragmentTransaction transaction = fragmentManager.beginTransaction()
if (fragment != null) {
transaction.show(fragment)
} else {
transaction.add(content.id, new Trending(), TRENDING_TAG)
}
transaction.commitNow()
} else {
hideFragment(TRENDING_TAG)
hideFragment(DAILY_TAG)
Fragment fragment = fragmentManager.findFragmentByTag(RANDOM_TAG);
FragmentTransaction transaction = fragmentManager.beginTransaction()
if (fragment != null) {
transaction.show(fragment)
} else {
transaction.add(content.id, new Random(), RANDOM_TAG)
}
transaction.commitNow()
}
fragments.put(position, fragment);
loadFragment(fragment);
}
private void hideFragment(String tag) {
FragmentManager fragmentManager = getSupportFragmentManager()
Fragment currentFragment = fragmentManager.findFragmentByTag(tag)
if (currentFragment != null) {
fragmentManager.beginTransaction().hide(currentFragment).commitNow()
}
}
PS - The code can be optimized.

IllegalStateException Fragment already added - Android

I am adding fragment like bellow :
#OnClick(R.id.lnNews)
void newsList() {
String tagName = returnStatusFragment(getString(R.string.news_list_fragment));
if (!TextUtils.isEmpty(tagName) && tagName.equals(getString(R.string.news_list_fragment))) {
frameWorkTableFragment.setVisibility(View.VISIBLE);
if (getActivity() != null) {
android.support.v4.app.FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
Fragment news = fragmentManager.findFragmentByTag(getString(R.string.news_list_fragment));
getActivity().getSupportFragmentManager().beginTransaction()
.replace(R.id.frame_work_table_fragment,
news,
getString(R.string.news_list_fragment)).commit();
}
//Fragment is opened
} else {
if (getActivity() != null) {
frameWorkTableFragment.setVisibility(View.VISIBLE);
NewsListFragment newsListFragment = new NewsListFragment();
getActivity().getSupportFragmentManager().beginTransaction()
.replace(R.id.frame_work_table_fragment,
newsListFragment,
getString(R.string.news_list_fragment))
.addToBackStack(getString(R.string.news_list_fragment))
.commit();
}
}
}
And in the Fragment I wrote doBackPress like bellow :
#Override
public void doBackTabZero(String nameFragment) {
android.support.v4.app.FragmentManager fragmentManagers = getActivity().getSupportFragmentManager();
if (fragmentManagers.getBackStackEntryCount() > 1) {
fragmentManagers.popBackStackImmediate();
} else {
if (nameFragment.equals("SignsFragment")) {
BusDisplayStatusFrameLayout busDisplayStatusFrameLayout = new BusDisplayStatusFrameLayout();
busDisplayStatusFrameLayout.setDisplayStatusFrameLayout(1);
EventBus.getDefault().post(busDisplayStatusFrameLayout);
android.support.v4.app.FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
android.support.v4.app.FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentManager.popBackStackImmediate();
fragmentTransaction.remove(SignsFragment.this);
fragmentTransaction.commit();
}
}
}
But get me crash often in this line :
fragmentManagers.popBackStackImmediate();
With this message :
java.lang.IllegalStateException: Fragment already added: NewsFragment{aed4cd1 #3 id=0x7f0a006e NewsFragment}
And in my activity my doBack is like bellow :
private Fragment getCurrentFragment() {
FragmentManager fragmentManager = getSupportFragmentManager();
String fragmentTag = fragmentManager.getBackStackEntryAt(fragmentManager.getBackStackEntryCount() - 1).getName();
return fragmentManager.findFragmentByTag(fragmentTag);
}
Then :
#Override
public void onBackPressed() {
int backStackEntryCount = getSupportFragmentManager().getBackStackEntryCount();
if (backStackEntryCount > 0) {
if (onBackPressedListenerTabWorkTable != null || onBackPressedListenerTabMou != null) {
if (getCurrentFragment().getTag() != null && !TextUtils.isEmpty(getCurrentFragment().getTag())) {
if (getCurrentFragment().getTag().equals("EventsFragment")
|| getCurrentFragment().getTag().equals("WebViewListClassFragment")
|| getCurrentFragment().getTag().equals("SignsFragment")
|| getCurrentFragment().getTag().equals("NewsListFragment")) {
if (viewPagerMainActivity.getCurrentItem() != 0) {
viewPagerMainActivity.setCurrentItem(0);
}
onBackPressedListenerTabWorkTable.doBackTabZero(getCurrentFragment().getTag());
} else if (getCurrentFragment().getTag().equals("SpecialNewsMouFragment")) {
if (viewPagerMainActivity.getCurrentItem() != 1) {
viewPagerMainActivity.setCurrentItem(1);
}
onBackPressedListenerTabMou.doBackTabOne(getCurrentFragment().getTag());
}
}
}
} else {
super.onBackPressed();
onBackPressedListenerTabWorkTable = null;
onBackPressedListenerTabMou = null;
finish();
}
}

issue in initializing fragment from the activity in xamarin android?

This is my Activity class:
private void pushFragment(Fragment fragment)
{
if (fragment == null)
return;
FragmentManager fragmentManager = SupportFragmentManager;
if (fragmentManager != null)
{
FragmentTransaction ft = fragmentManager.BeginTransaction();
if (ft != null)
{
ft.AddToBackStack("");
ft.Replace(Resource.Id.rootLayout, fragment);
ft.Commit();
}
}
}
public override void OnBackPressed()
{
if (FragmentManager.BackStackEntryCount > 0)
{
FragmentManager.PopBackStack();
//Finish();
}
else
{
base.OnBackPressed();
}
}
When I click on the close icon of the layout it will call pushFragment(new ParentFragment());
The close button on top of the right, when clicked must go to fragment but it's not working?

Single Instance fragment back stack managerment

I am working on single activity based principle. But I am facing a problem when the same fragment is open again because its again adds in fragment backstack entry. So backstack contains multiple backstack entries for same fragment. This creates problem on back navigation.
Example :- A|B|C|D|A|C|A
So when I press back key same fragment is displaying multiple times. Is there any way to reuse the existing fragment from backstack entry.
I am managing my backstack like this :-
fragmentManager.beginTransaction().setCustomAnimations(R.anim.fragment_enter,
R.anim.fragment_exit, R.anim.pop_enter, R.anim.pop_exit).
add(R.id.frameLayout, fragment).addToBackStack(backStateName).commit();
Any kind of help will be appreciated.
private void createOrResumeFragment(String fragmentTag){
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction ft = manager.beginTransaction();
boolean fragmentPopped = manager.popBackStackImmediate (fragmentTag, 0);
Fragment fragment = manager.findFragmentByTag(fragmentTag);
if(!fragmentPopped && fragment == null){
//Create an new instance if it is null and add it to stack
fragment = new MyFragment();
ft.addToBackStack(fragmentTag);
}
ft.replace(R.id.framelayout, fragment);
ft.commit();
}
Trying this using the fragment list
See the Answer Here
Initialize the fragments list
static List<String> fragments = new ArrayList<String>();
on Start of first fragment on Activity add this
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction().replace(R.id.frame, new AFragment()).commit();
fragments.add("package.fragment.AFragment");
}
Code to fragment change and take in back stack
String backStateName = fragment.getClass().getName();
FragmentManager manager = getSupportFragmentManager();
//fragment not in back stack, create it.
FragmentTransaction ft = manager.beginTransaction();
if(!fragments.contains(backStateName)) {
// ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
// ft.setCustomAnimations(R.anim.fade_in, R.anim.fade_out);
ft.replace(R.id.frame, fragment);
ft.addToBackStack(backStateName);
ft.commit();
fragments.add(backStateName);
System.out.println("backStateName" + fragments);
}
else
{
ft.replace(R.id.frame, fragment);
ft.commit();
}
onBackpressed
#Override
public void onBackPressed() {
if(fragments.size()>0)
{
fragments.remove(fragments.size()-1);
}
super.onBackPressed();
}
for back remove stack
final android.app.FragmentManager fm = getFragmentManager();
fm.addOnBackStackChangedListener(new android.app.FragmentManager.OnBackStackChangedListener() {
#Override
public void onBackStackChanged() {
if (getSupportFragmentManager().getBackStackEntryCount() ==0) {
// dLayout.closeDrawers();
finish();
}
else
{
// dLayout.closeDrawers();
}
}
});
Before adding or replacing the fragment on backstack, check that if the fragment already in backstack or not.
boolean fragmentPopped = fragmentManager.popBackStackImmediate(backStateName, 0);
if (fragmentPopped) {
// fragment is popped from backStack
} else {
// add or replace your fragment here
}
public void changeFragment(Fragment fragment) {
FragmentManager fragmentManager = getSupportFragmentManager();
Fragment currentVisibleFragment = fragmentManager.findFragmentById(R.id.container);
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.container, fragment, fragment.getClass().getSimpleName());
if (!currentVisibleFragment.getClass().getSimpleName().trim().equalsIgnoreCase(fragment.getClass().getSimpleName().trim())) {
for (int i = fragmentManager.getBackStackEntryCount() - 1; i > 0; i--) {
if (fragmentManager.getBackStackEntryAt(i).getName().equalsIgnoreCase(fragment.getClass().getSimpleName())) {
fragmentManager.popBackStack(fragmentManager.getBackStackEntryAt(i).getId(), FragmentManager.POP_BACK_STACK_INCLUSIVE);
}
}
fragmentTransaction.addToBackStack(fragment.getClass().getSimpleName());
} else {
fragmentManager.popBackStack();
fragmentTransaction.addToBackStack(fragment.getClass().getSimpleName());
}
fragmentTransaction.commit();
}
boolean doubleBackToExitPressedOnce = false;
#Override
public void onBackPressed() {
if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
super.onBackPressed();
} else {
if (doubleBackToExitPressedOnce) {
super.onBackPressed();
finish();
return;
}
this.doubleBackToExitPressedOnce = true;
Toast.makeText(this, "Are you sure you want to exit?", Toast.LENGTH_SHORT).show();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
doubleBackToExitPressedOnce = false;
}
}, 2000);
}
}
Call the method to replace fragment with single entry in backstack
changeFragment(new YourFragmentClassName());

On click Blank Area Next Fragment Automaticall call

I have 3 fragments open on condition of First fragments list item Click >> Second fragment open and so on Second. But when I click on first fragment's blank space it automatically open second fragment and click on second fragment's blank space it goes to third fragment
This is class I have maintain for fragment transaction
public static void addABCDHomeFragment(FragmentManager fragManager, String categoryName) {
FragmentTransaction ft = fragManager.beginTransaction();
Fragment abcdHomeFragment = fragManager.findFragmentByTag(ABCD_HOME_FRAGMENT);
if (abcdHomeFragment == null || abcdHomeFragment.isRemoving()) {
ABCDHomeFragment homeFragment = new ABCDHomeFragment(categoryName);
ft.add(R.id.frame_layout, homeFragment, ABCD_HOME_FRAGMENT);
ft.addToBackStack(ABCD_HOME_FRAGMENT);
ft.commit();
} else if (abcdHomeFragment != null && abcdHomeFragment.isAdded()) {
fragManager.popBackStack();
ABCDHomeFragment homeFragment = new ABCDHomeFragment(categoryName);
ft.replace(R.id.frame_layout, homeFragment, ABCD_HOME_FRAGMENT);
ft.addToBackStack(ABCD_HOME_FRAGMENT);
ft.commit();
}
}
public static void addProductListFragment(FragmentManager fragmentManager,String categoryId ,
String parent , int option) {
FragmentTransaction ftproductlist = fragmentManager.beginTransaction();
Fragment plistFragment = fragmentManager.findFragmentByTag(PRODUCT_LIST_FRAGMENT);
ProductListFragment productListFragment = new ProductListFragment(categoryId,parent,option);
if (plistFragment != null && plistFragment.isAdded() && plistFragment.isVisible()) {
fragmentManager.popBackStack();
ftproductlist.add(R.id.frame_layout, productListFragment,PRODUCT_LIST_FRAGMENT);
ftproductlist.addToBackStack(PRODUCT_LIST_FRAGMENT);
ftproductlist.commit();
} else {
ftproductlist.replace(R.id.frame_layout, productListFragment, PRODUCT_LIST_FRAGMENT);
ftproductlist.addToBackStack(PRODUCT_LIST_FRAGMENT);
ftproductlist.commit();
}
}
public static void removeProductListFragment(FragmentManager fragmentManager) {
FragmentTransaction ftproductlist = fragmentManager.beginTransaction();
Fragment productListFragment = fragmentManager.findFragmentByTag(PRODUCT_LIST_FRAGMENT);
if (productListFragment != null && productListFragment.isAdded()) {
ftproductlist.remove(productListFragment);
fragmentManager.popBackStack();
ftproductlist.commit();
}
}
public static void addProductDetailFragment(FragmentManager fragManager,String productId,String parent, String productName) {
FragmentTransaction ftproduct = fragManager.beginTransaction();
Fragment productDetailFragment = fragManager.findFragmentByTag(PRODUCT_DETAIL_FRAGMENT);
if (productDetailFragment == null || productDetailFragment.isRemoving()) {
ProductDetailFragment dtailFragment = new ProductDetailFragment(productId, parent,productName);
ftproduct.add(R.id.frame_layout, dtailFragment, PRODUCT_DETAIL_FRAGMENT);
ftproduct.addToBackStack(PRODUCT_DETAIL_FRAGMENT);
ftproduct.commit();
} else if (productDetailFragment != null && productDetailFragment.isAdded()) {
fragManager.popBackStack();
ProductDetailFragment dtailFragment = new ProductDetailFragment(productId,parent,productName);
ftproduct.replace(R.id.frame_layout, dtailFragment,PRODUCT_DETAIL_FRAGMENT);
ftproduct.addToBackStack(PRODUCT_DETAIL_FRAGMENT);
ftproduct.commit();
}
}

Categories

Resources