So, i have notice interesting problem. When i add new fragment programmatically, method onBackStackChanged from OnBackStackChangedListener is called twice, but it must be call only one time. Here is my code of activity:
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity implements FragmentManager.OnBackStackChangedListener{
private FragmentManager fragmentManager;
private Button button1;
private Button button2;
private Button button3;
private Fragment defaultFragment;
private Fragment previousFragment;
private Fragment currentFragment;
private String currentFragmentTag;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button1 = (Button) findViewById(R.id.button);
button2 = (Button) findViewById(R.id.button2);
button3 = (Button) findViewById(R.id.button3);
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showFragment(new FragmentOne(), FragmentOne.TAG);
}
});
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showFragment(new FragmentTwo(), FragmentTwo.TAG);
}
});
button3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showFragment(new FragmentThree(), FragmentThree.TAG);
}
});
setupFragmentManager();
}
private void setupFragmentManager() {
fragmentManager = getSupportFragmentManager();
fragmentManager.addOnBackStackChangedListener(this);
FragmentOne fragmentOne = new FragmentOne();
defaultFragment = fragmentOne; // fragment for default
currentFragmentTag = FragmentOne.TAG;
currentFragment = fragmentOne;
fragmentManager.beginTransaction()
.add(R.id.fragments_container, currentFragment, currentFragmentTag)
.addToBackStack(currentFragmentTag)
.commit();
}
public void showFragment(Fragment fragment, String fragmentTag) {
previousFragment = currentFragment;
currentFragment = fragment;
fragmentManager.beginTransaction()
.hide(previousFragment)
.add(R.id.fragments_container, fragment, fragmentTag)
.addToBackStack(fragmentTag)
.commit();
}
@Override
public void onBackStackChanged() {
Log.d("MY_TAG" , "onBackStackChangedListener - " + fragmentManager.getBackStackEntryCount() );
if (fragmentManager.getBackStackEntryCount() > 0) {
String fragmentTag = fragmentManager.getBackStackEntryAt(fragmentManager.getBackStackEntryCount() - 1).getName();
currentFragment = fragmentManager.findFragmentByTag(fragmentTag);
} else {
currentFragment = defaultFragment;
}
// some code...
}
@Override
public void onBackPressed() {
if (fragmentManager.getBackStackEntryCount() == 1) {
finish();
} else {
super.onBackPressed();
}
}
}
And fragment class:
public class FragmentOne extends Fragment {
public static final String TAG = FragmentOne.class.getSimpleName();
private Context context;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
context = getActivity();
View topLevelView = LayoutInflater.from(context).inflate(R.layout.fragment_layout, container, false);
TextView textView = (TextView) topLevelView.findViewById(R.id.fragment_Text);
textView.setText("This is FRAGMENT ONE");
return topLevelView;
}
}
FragmentTwo and FragmentThree are identical to FragmentOne.
And when i start my app, in log i see:
onBackStackChangedListener - 1
onBackStackChangedListener - 1
after pressed of button (show next fragment) i see:
onBackStackChangedListener - 2
onBackStackChangedListener - 2
and another one:
onBackStackChangedListener - 3
onBackStackChangedListener - 3
And changing
.add(R.id.fragments_container, currentFragment, currentFragmentTag)
to
.replace(R.id.fragments_container, currentFragment, currentFragmentTag)
doesnt solve the problem.
But it is very strange. Why my OnBackStackChangedListener calls more than one time own method after one addiing the fragment?
Couldn't believe it can happen. Created a similar project and dived into the debugger. Turns out it's a bug in new support library. There's is a bug opened in the tracker.
Switching back to 25.0.0
will work as expected.
compile 'com.android.support:appcompat-v7:25.0.0'
compile 'com.android.support:support-v4:25.0.0'
Though not mentioned in release notes, but it is mentioned in the issue tracker, that the issue is fixed in 25.4.0
, which is good 😊.
Just an update. Google finally released version 25.4.0 with that issue fixed.
Only, now the support stuff is meant to be fetched from the Google's Maven repository:
maven { url 'https://maven.google.com' }
So you can start using the new versions of everything and uninstall the local support repository from the SDK Manager.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With