Fragment's EditTexts are triggered when it is replaced - android

So, I have this problem: I am initializing a fragment - AddingTaskFragment
here's code:
Initializing AddingTaskFragment
private void initFragment()
{
// Get fragment manager
FragmentManager fm = getSupportFragmentManager();
// Begin transaction
FragmentTransaction ft = fm.beginTransaction();
// Create the Fragment and add
addingTaskFragment = new AddingTaskFragment();
ft.add(R.id.fragment_task_type_container, addingTaskFragment, "addTaskFragment");
// ft.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out);
// Commit the changes
ft.commit();
}
And it works fine
But then, I call some event, that replaces this fragment with other one(AddingScheduleFragment).
Replacing fragment
#Override
public void onScheduleTypePick()
{
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
// Create the fragment and attach book index
addingScheduleFragment = new AddingScheduleFragment();
// Replace the book list with the description
ft.replace(R.id.fragment_task_type_container, addingScheduleFragment, "addScheduleFragment");
ft.addToBackStack(null);
ft.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out);
ft.commit();
}
And when I'm poping my previous fragment(AddingTaskFragment) from the stack. All of my EditViews are gaining focus.
Returning previous fragment
#Override
public void onTaskTypePick()
{
getSupportFragmentManager().popBackStack();
}
What can be wrong? Why is this happening? Thanks for answers.
Important: When I replacing AddingTaskFragent with new object everything works great.

So, I've solved the problem by myself. Rather found the similar one.
afterTextChanged() callback being called without the text being actually changed
When the fragment was attached second time(because of .replace() method) it was restoring the previous state of the views. And then all textChangeListeners triggered.

Related

Fragment transaction doesn't always work as intended

I have this problem in an app, where that method below doesn't always effectively hide the currently visible fragment (contentFragment) and shows the new one (fragment). Basically, sometimes, it does the complete opposite of what it's supposed to do, that is, the current fragment remaining visible, and the new one not showing at all. And what is worth, is that I can't always replicate when it happens.
I'm really at wits' end here. Anyone got any ideas?
public void addContentFragment(GenericFragment fragment) {
FragmentManager fragmentManager = slidingMenusActivity.getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.add(R.id.ContentLayout, fragment, fragment.getFragmentTag());
transaction.addToBackStack(fragment.getFragmentTag());
Log.d(TAG, "addContentFragment hiding contentFragment=" + contentFragment);
transaction.hide(contentFragment);
transaction.commit();
fragmentManager.executePendingTransactions();
contentFragment = fragment;
}
Your contentFragment sometimes do not have the value you are expecting, try to retrieve the current fragment to ensure you are really hiding the fragment before your new transaction.
Modify your addContentFragment(GenericFragment fragment) as the follows:
public void addContentFragment(GenericFragment fragment) {
FragmentManager fragmentManager = slidingMenusActivity.getSupportFragmentManager();
Fragment currentFragment = fragmentManager.findFragmentById(R.id.ContentLayout);
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.add(R.id.ContentLayout, fragment, fragment.getFragmentTag());
transaction.addToBackStack(fragment.getFragmentTag());
Log.d(TAG, "addContentFragment hiding contentFragment=" + contentFragment);
transaction.hide(currentFragment);
transaction.commit();
}

Memory leak on fragment transaction

I have two fragments one list and one detail fragment. On list item click I a hiding list fragment and adding detail fragment on back press detail fragment is popped automatically I am just calling super.onBackPressed() but issue is it is creating so many references of detail fragments resulting is memory leaks
Following is my code
FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
ft.hide(this);
ft.add(containerId, detailFragment, "detail");
ft.addToBackStack("detail");
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.commit();
I don't want to view to be recreated view when user press back button on detail fragment thats why I used above approach. Also with current implementation when I press back button recylerview scroll possition and other data I don't have to save
My Activity has only following code it inflates list fragment
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.FragmentContainer1, ListFragment.newInstance(), TAG).commit();
}
I think what you are doing wrong is that you are adding fragments each time to the container again and again by calling add method:
In your case you should use replace method and add your list fragment to the backstack. Here's how you should start your detail fragment:
FragmentManager fm = getFragmentManager();
fm.beginTransaction()
.replace(R.id.container, new DetailFragment())
.addToBackstack(null)
.commit();
To get back to your list fragment, which is in the back stack, just call:
fm.popBackStack();
EDIT:
Try this to show your list fragment:
protected void displayListFragment() {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
if (listFragment.isAdded()) {
ft.show(listFragment);
} else {
ft.add(R.id.flContainer, listFragment, "ListFragment");
}
if (detailFragment.isAdded()) {
ft.remove(detailFragment);
}
ft.commit();
}
And this to show your detail fragment:
protected void displayDetailFragment() {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
if (listFragment.isAdded()) {
ft.hide(listFragment);
}
if (!detailFragment.isAdded()) {
ft.add(R.id.flContainer, detailFragment, "DetailFragment");
}
ft.commit();
}

Nested fragment and back stack

I have a fragment in which there is a nested fragment which I add in this way:
if (home == null) {
home = new MyFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
transaction.addToBackStack(MyFragment.class.getName());
transaction.add(R.id.child_fragment, home).commit();
}
When I enter another fragment and go back the child fragment from above is not there. I checked and the instance is different from null.
UPDATE: I changed the code as suggested by Ashwin S Ashok but it's still not working.
Try using these methods:
// Use this if you don't want to retain the fragment.
protected void replaceFragmentStack(int container, Fragment fragment) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(container, fragment);
fragmentTransaction.commit();
}
// Use this if you want to add the fragments in a stack.
protected void addFragmentStack(int container, Fragment fragment, String tag) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
fragmentTransaction.add(container, fragment, tag);
fragmentTransaction.addToBackStack(tag);
fragmentTransaction.commit();
}
I would suggest you to use getChildFragmentManager() when making transactions inside a fragment. And its a bug i guess.
You can check out this thread it will help you alot Android 4.2: back stack behaviour with nested fragments
Also you need to go through The Curious Techizen's blog
Here is the link for the github project sample for same mechanism
I hope this will help you.

Issue in Fragments in android

When I click on the back icon in the layout then it goes to previous fragment but it doesn't go to the fragment it was killed. what is the solution for this?
I'm using finish() and backstack but it not works for me
back.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
android.support.v4.app.Fragment onlineFragments = new OnlineFragments();
android.support.v4.app.FragmentManager fragmentManagerprofile = getActivity().getSupportFragmentManager();
android.support.v4.app.FragmentTransaction fragmentprofileTransaction = fragmentManagerprofile.beginTransaction();
fragmentprofileTransaction.replace(R.id.background_fragment, onlineFragments);
fragmentprofileTransaction.commit();
}
});
Fragment A
case R.id.recharge:
HomeActvity.toolbar.setVisibility(View.GONE);
android.support.v4.app.Fragment Recharge = new Prepaid_recharge();
android.support.v4.app.FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
android.support.v4.app.FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.containerView, Recharge);
fragmentTransaction.commit();
break;
Whenever your making Transactions between fragments and you want to navigate back to the previous fragment(s) (Back Button), in the transaction, you must add this transaction to the backStack before committing:
Android docs:
"Before you call commit(), however, you might want to call addToBackStack(), in order to add the transaction to a back stack of fragment transactions. This back stack is managed by the activity and allows the user to return to the previous fragment state, by pressing the Back button."
https://developer.android.com/guide/components/fragments.html#Transactions
// Create new fragment and transaction
Fragment newFragment = new ExampleFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
I use this code to add and remove the fragment. In case I do not need that fragment to be in the back stack I send the boolean value as false. Doing this when pressing back button from toolbar It open the correct activity
public static void changeFragment (MyActivity activity, Fragment fragment, int fragmentContainer, boolean addToBackStack){
FragmentManager fragmentManager = activity.getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(fragmentContainer, fragment);
/*here we keep track of fragments and avoiding last blank fragment by passing true*/
if(addToBackStack){
fragmentTransaction.addToBackStack(null);
}
fragmentTransaction.commit();
}

List view reload when back pressed in fragment

I have Fragment XYZFragment where i display the list view.On the Listview item click i replace the Fragment like this.
Fragment fragment=new XYZFragment();
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction ft= fragmentManager.beginTransaction();
ft.addToBackStack(null);
ft.replace(R.id.content_frame, fragment).commit();
But my problem is when i click back button the fragment reload the listview.It is never happen when i used to use Activity.
So my question is how to save the instance of previous fragment so that it will prevent the reloading of Data.
without seeing your code we can't help you out but from your question i can figure out the problem, this solution may help you out.
create stack such that
private static Stack<Fragment> myFragStack;
myFragStack = new Stack<Fragment>();
//To Load the fragment
public void loadFragment(Fragment fragment){
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
myFragStack.lastElement().onPause();
ft.hide(myFragStack.lastElement());
myFragStack.push(fragment);
}
//onBackPressed
public void onBackPressed() {
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
if (myFragStack.size() > 1) {
ft.remove(myFragStack.pop());
myFragStack.lastElement().onResume();
ft.show(myFragStack.lastElement());
ft.commit();
}
}
It's a sample code.. you can change it as per your requirement.
ft.replace() will completely remove the view & will lose the context so you can't maintain your list state, but using stacks maintaining fragments with hide-show will solve your problem.

Categories

Resources