Ali*_*aka 33 android android-fragments
我通过隐藏最后一个片段并添加一个新片段(参见下面的代码)在片段之间切换- 也将它添加到后栈.这样,用户可以在不重新加载片段数据的情况下快速切换片段.
这很有效,直到应用程序被杀死(场景:用户使用其他几个应用程序,我的应用程序被持久化并被杀死).
当用户打开应用程序时,它将被还原并显示所有片段 - 彼此重叠.
问题:恢复的片段如何以隐藏状态恢复?也许我错过了一些旗帜?某处?也许有更好的解决方案可以快速切换片段(无需重新加载数据)?
添加片段的示例代码 - 在点击某处时,使用不同的片段多次调用:
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.hide(lastFragment);
fragmentTransaction.add(newFragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
lastFragment = newFragment;
Run Code Online (Sandbox Code Playgroud)
Ali*_*aka 16
希望有人找到更好的解决方案.在接受我的解决方案之前,我会等待一个:
通常,我使用生成的标签来查找未隐藏的片段并隐藏它们.
详细说明,我为每个片段(StackEntry)生成一个唯一标记,并在片段本身堆叠时堆叠标记.我将堆栈保留在bundel中并在应用程序恢复时加载它以便继续使用它.然后我使用标签列表找到所有未隐藏的片段并隐藏它们 - 除了最后一个.
下面是示例代码:
public class FragmentActivity extends Activity {
private static final String FRAGMENT_STACK_KEY = "FRAGMENT_STACK_KEY";
private Stack<StackEntry> fragmentsStack = new Stack<StackEntry>();
public FragmentActivity() {
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.content_frame);
if (savedInstanceState == null) {
// Init for the first time - not restore
// ...
} else {
Serializable serializable = savedInstanceState.getSerializable(FRAGMENT_STACK_KEY);
if (serializable != null) {
// Workaround Android bug.
// See: http://stackoverflow.com/questions/13982192/when-using-an-android-bundle-why-does-a-serialised-stack-deserialise-as-an-arra
// And: https://code.google.com/p/android/issues/detail?id=3847
@SuppressWarnings("unchecked")
List<StackEntry> arrayList = (List<StackEntry>) serializable;
fragmentsStack = new Stack<StackEntry>();
fragmentsStack.addAll(arrayList);
}
// Hide all the restored fragments instead of the last one
if (fragmentsStack.size() > 1) {
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
for (int i = 0; i < fragmentsStack.size()-1; i++) {
String fragTag = fragmentsStack.get(i).getFragTag();
Fragment fragment = getFragmentManager().findFragmentByTag(fragTag);
fragmentTransaction.hide(fragment);
}
fragmentTransaction.commit();
}
}
getFragmentManager().addOnBackStackChangedListener(new OnBackStackChangedListener() {
@Override
public void onBackStackChanged() {
Fragment lastFragment = getLastFragment();
if (lastFragment.isHidden()) {
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.show(lastFragment);
fragmentTransaction.commit();
}
}
});
}
private Fragment getLastFragment() {
if (fragmentsStack.isEmpty()) return null;
String fragTag = fragmentsStack.peek().getFragTag();
Fragment fragment = getFragmentManager().findFragmentByTag(fragTag);
return fragment;
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putSerializable(FRAGMENT_STACK_KEY, fragmentsStack);
}
@Override
public void onBackPressed() {
if (!fragmentsStack.isEmpty()) {
fragmentsStack.pop();
}
}
public void switchContent(Fragment fragment) {
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
Fragment lastFragment = getLastFragment();
if (lastFragment != null) {
fragmentTransaction.hide(lastFragment);
}
String fragTag;
if (fragment.isAdded()) {
fragmentTransaction.show(fragment);
fragTag = fragment.getTag();
} else {
fragTag = Long.toString(System.currentTimeMillis());
fragmentTransaction.add(R.id.content_frame, fragment, fragTag);
}
if (!isFirstFragment()) {
// Add to backstack only the first content fragment and not the state before (that has nothing)
fragmentTransaction.addToBackStack(null);
}
fragmentTransaction.commit();
fragmentsStack.push(new StackEntry(fragTag));
}
public boolean isFirstFragment() {
return fragmentsStack.size() == 0;
}
private static class StackEntry implements Serializable {
private static final long serialVersionUID = -6162805540320628024L;
private String fragTag = null;
public StackEntry(String fragTag) {
super();
this.fragTag = fragTag;
}
public String getFragTag() {
return fragTag;
}
}
public static class Intent extends android.content.Intent {
public Intent(Context packageContext) {
super(packageContext, FragmentActivity.class);
}
}
}
Run Code Online (Sandbox Code Playgroud)
小智 9
我也有这个问题,这里有一个可能的解决方案:让每个片段保存自己关于它是否被隐藏的状态,然后将其自身隐藏在onCreate中.
@Override
public void onSaveInstanceState(Bundle bundle) {
super.onSaveInstanceState(bundle);
if (this.isHidden()) {
bundle.putBoolean("hidden", true);
}
}
@Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
if (bundle != null) {
if (bundle.getBoolean("hidden", false)) {
getFragmentManager()
.beginTransaction()
.hide(this)
.commit();
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8719 次 |
| 最近记录: |