问题
I need some help. em adding fragment to activity this way. problem is on each call of openFragment it create fragment and add. which is obvious. Question: what modification i do, so it can add fragment only once. on the next call with same fragment tag it will do nothing.
case: press button first time it add fragment and shows. i press again same button it response nothing.
public static void openFragment(Activity activity, Fragment fragment) {
FragmentManager fragmentManager = ((ActionBarActivity) activity)
.getSupportFragmentManager();
FragmentTransaction ftx = fragmentManager.beginTransaction();
ftx.addToBackStack(fragment.getClass().getSimpleName());
ftx.setCustomAnimations(R.anim.slide_in_right,
R.anim.slide_out_left, R.anim.slide_in_left,
R.anim.slide_out_right);
ftx.add(R.id.main_content, fragment);
ftx.commit();
}
回答1:
Here's the solution, It will only allow you to add fragment once in stack otherwise it will pop-out the very same fragment from stack.
public static void openFragment(Activity activity, Fragment fragment) {
String fragmentTag = fragment.getClass().getName();
FragmentManager fragmentManager= ((ActionBarActivity) activity)
.getSupportFragmentManager();
boolean fragmentPopped = fragmentManager
.popBackStackImmediate(fragmentTag , 0);
if (!fragmentPopped && fragmentManager.findFragmentByTag(fragmentTag) == null) {
FragmentTransaction ftx = fragmentManager.beginTransaction();
ftx.addToBackStack(fragment.getClass().getSimpleName());
ftx.setCustomAnimations(R.anim.slide_in_right,
R.anim.slide_out_left, R.anim.slide_in_left,
R.anim.slide_out_right);
ftx.add(R.id.main_content, fragment);
ftx.commit();
}
}
slide_in_right
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="true">
<translate android:fromXDelta="100%"
android:toXDelta="0%" android:fromYDelta="0%"
android:toYDelta="0%" android:duration="200">
</translate>
</set>
slide_out_right
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<translate android:fromXDelta="0%" android:toXDelta="100%"
android:fromYDelta="0%" android:toYDelta="0%"
android:duration="200">
</translate>
</set>
slide_in_left
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="true">
<translate android:fromXDelta="-100%"
android:toXDelta="0%" android:fromYDelta="0%"
android:toYDelta="0%" android:duration="200">
</translate>
</set>
slide_out_left
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="true">
<translate android:fromXDelta="0%"
android:toXDelta="-100%" android:fromYDelta="0%"
android:toYDelta="0%" android:duration="200">
</translate>
</set>
And this is how you call this function:
openFragment(activity, new MyFragment());
回答2:
Use FragmentTransaction.replace() instead of FragmentTransaction.add()
:
This is essentially the same as calling
remove(Fragment)
for all currently added fragments that were added with the samecontainerViewId
and thenadd(int, Fragment, String)
with the same arguments given here.
The first call to FragmentTransaction.replace()
will simply add the fragment as there were no fragments to remove.
回答3:
check if fragment is already added or not by using this method:
if(!Fragment.isAdded()){
//add fragment
}
回答4:
Depending on your needs, there are multiple ways to approach this:
- Disable or remove the button after it's clicked once.
- As @hidro suggested, use replace() instead of add() when calling the FragmentTransaction.
- Keep a List of string that will contain the class name of each fragment as it is added to the UI.
E.g.
List<String> fragments = new ArrayList<String>();
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
FragmentTransaction ftx = fragmentManager.beginTransaction();
ftx.add(R.id.main_content, fragment);
ftx.commit();
fragments.add(fragment.getClass().toString());
}
});
Before adding the fragment using FragmenTransaction.commit() check if its class exists in the list and if it does, don't add it.
Again, these 3 approaches work but which one will pick will depend on your app.
回答5:
To add a fragment only once,
You need to check every time before adding the fragment to backstack, that if previously it is already added or not. If it is added already, then you should pop that entry and add another entry.
So, you can do this using :
boolean fragmentPopped = manager.popBackStackImmediate (backStateName, 0);
If fragmentPopped
is true then there was a fragment added to backstack and itt is popped and you can add your fragment now to backstack. It is safe to call :
ftx.addToBackStack(fragment.getClass().getSimpleName());
If fragmentPopped
is false then there was not any fragment added in backstack
Very nice information you can get : here
回答6:
You can use show() method of fragment transaction
FragmentManager fragmentManager = ((ActionBarActivity) activity)
.getSupportFragmentManager();
FragmentTransaction ftx = fragmentManager.beginTransaction();
ftx.setCustomAnimations(R.anim.slide_in_right,
R.anim.slide_out_left, R.anim.slide_in_left,
R.anim.slide_out_right);
if(!fragment.isAdded())
{
//add fragment;
ftx.add(R.id.main_content, fragment).comit();
}
else
{
ftx.show(fragment).comit();
}
Updated
来源:https://stackoverflow.com/questions/29144341/how-to-avoid-adding-same-fragment-to-stack