onBackStackChanged() 在 backstack 中添加新片段时调用两次
onBackStackChanged() called twice when new fragment is added in backstack
所以,我注意到一个有趣的问题。当我以编程方式添加新片段时,来自 OnBackStackChangedListener 的方法 onBackStackChanged 被调用两次,但它只能被调用一次。这是我的代码 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();
}
}
}
和片段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 和 FragmentThree 与 FragmentOne 相同。
当我启动我的应用程序时,在日志中我看到:
onBackStackChangedListener - 1
onBackStackChangedListener - 1
按下按钮后(显示下一个片段)我看到:
onBackStackChangedListener - 2
onBackStackChangedListener - 2
还有一个:
onBackStackChangedListener - 3
onBackStackChangedListener - 3
并且在改变
.add(R.id.fragments_container, currentFragment, currentFragmentTag)
到
.replace(R.id.fragments_container, currentFragment, currentFragmentTag)
没有解决问题。
但是很奇怪。为什么我的 OnBackStackChangedListener 在添加片段后多次调用自己的方法?
不敢相信这会发生。创建了一个类似的项目并深入调试器。原来这是新支持库中的错误。有一个 bug opened in the tracker.
切换回 25.0.0
将按预期工作。
compile 'com.android.support:appcompat-v7:25.0.0'
compile 'com.android.support:support-v4:25.0.0'
虽然 release notes, but it is mentioned in the issue tracker 中没有提及,但问题已在 25.4.0
中修复,这很好。
只是一个更新。 Google 终于发布了 25.4.0 版,解决了这个问题。
只是,现在要从 Google 的 Maven 存储库中获取支持内容:
maven { url 'https://maven.google.com' }
因此您可以开始使用所有新版本并从 SDK 管理器中卸载本地支持存储库。
所以,我注意到一个有趣的问题。当我以编程方式添加新片段时,来自 OnBackStackChangedListener 的方法 onBackStackChanged 被调用两次,但它只能被调用一次。这是我的代码 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();
}
}
}
和片段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 和 FragmentThree 与 FragmentOne 相同。
当我启动我的应用程序时,在日志中我看到:
onBackStackChangedListener - 1
onBackStackChangedListener - 1
按下按钮后(显示下一个片段)我看到:
onBackStackChangedListener - 2
onBackStackChangedListener - 2
还有一个:
onBackStackChangedListener - 3
onBackStackChangedListener - 3
并且在改变
.add(R.id.fragments_container, currentFragment, currentFragmentTag)
到
.replace(R.id.fragments_container, currentFragment, currentFragmentTag)
没有解决问题。
但是很奇怪。为什么我的 OnBackStackChangedListener 在添加片段后多次调用自己的方法?
不敢相信这会发生。创建了一个类似的项目并深入调试器。原来这是新支持库中的错误。有一个 bug opened in the tracker.
切换回 25.0.0
将按预期工作。
compile 'com.android.support:appcompat-v7:25.0.0'
compile 'com.android.support:support-v4:25.0.0'
虽然 release notes, but it is mentioned in the issue tracker 中没有提及,但问题已在 25.4.0
中修复,这很好。
只是一个更新。 Google 终于发布了 25.4.0 版,解决了这个问题。
只是,现在要从 Google 的 Maven 存储库中获取支持内容:
maven { url 'https://maven.google.com' }
因此您可以开始使用所有新版本并从 SDK 管理器中卸载本地支持存储库。