Android 如何强制PageViewer重新创建片段
我有一些片段,可以根据当前的布局以两种不同的方式进行实例化。 使用从Android 如何强制PageViewer重新创建片段,android,fragment,Android,Fragment,我有一些片段,可以根据当前的布局以两种不同的方式进行实例化。 使用从FragmentStatePageAdapter派生的适配器将这些片段加载到PageViewer中。 如果我只是在纵向或横向模式下运行应用程序,一切都很好。片段加载正确,看起来正常。 问题是当我改变方向时:片段没有改变,似乎它重用了某个方向加载的片段,事实上,如果我在下一个页面之后滚动寻呼机(它已经在上一个方向加载),那么新片段就正确加载了,当我再次滚动时,即使是“起始片段”已正确重新加载 我想通过强制重新创建当前片段和相邻片段
FragmentStatePageAdapter
派生的适配器将这些片段加载到PageViewer
中。
如果我只是在纵向或横向模式下运行应用程序,一切都很好。片段加载正确,看起来正常。
问题是当我改变方向时:片段没有改变,似乎它重用了某个方向加载的片段,事实上,如果我在下一个页面之后滚动寻呼机(它已经在上一个方向加载),那么新片段就正确加载了,当我再次滚动时,即使是“起始片段”已正确重新加载
我想通过强制重新创建当前片段和相邻片段来解决问题,但我尝试的解决方案似乎不完整/不起作用
我已通过以下方式覆盖适配器startUpdate
方法:
public void startUpdate(ViewGroup container) {
if(isPortrait != isLastOrientationPortrait){
container.removeAllViews();
instantiateItem(container, lastPosition);
}
super.startUpdate(container);
}
public void restoreState(Parcelable state, ClassLoader loader) {
Log.d(TAG, "restoreState");
//We don't want to restore the fragments if the orientation changes!
if(isLastOrientationPortrait != isPortrait){
if(state != null){
Bundle bundle = (Bundle) state;
bundle.setClassLoader(loader);
Iterable<String> keys = bundle.keySet();
if (mCurTransaction == null) {
mCurTransaction = mFragmentManager.beginTransaction();
}
for (String key : keys) {
if (key.startsWith("f")) {
Fragment f = mFragmentManager.getFragment(bundle,
key);
mCurTransaction.remove(f);
}
}
}
isLastOrientationPortrait = isPortrait;
}else{
if (state != null) {
Bundle bundle = (Bundle)state;
bundle.setClassLoader(loader);
Parcelable[] fss = bundle.getParcelableArray("states");
mSavedState.clear();
mFragments.clear();
if (fss != null) {
for (int i=0; i<fss.length; i++) {
mSavedState.add((Fragment.SavedState)fss[i]);
}
}
Iterable<String> keys = bundle.keySet();
for (String key: keys) {
if (key.startsWith("f")) {
int index = Integer.parseInt(key.substring(1));
Fragment f = mFragmentManager.getFragment(bundle, key);
if (f != null) {
while (mFragments.size() <= index) {
mFragments.add(null);
}
f.setMenuVisibility(false);
mFragments.set(index, f);
} else {
Log.w(TAG, "Bad fragment at key " + key);
}
}
}
}
}
}
这将强制从容器中清除碎片。但我不知道这是否是一种正确的方法,以及如何将新安装的物品放回容器
有什么建议吗?我找到了这个问题的解决方案: 而不是扩展FragmentStatePagerAdapter类I修改了它的源代码(如果你需要它,你可以在这里找到:) 我所做的只是以这种方式修改了
restoreStateMethod
:
public void startUpdate(ViewGroup container) {
if(isPortrait != isLastOrientationPortrait){
container.removeAllViews();
instantiateItem(container, lastPosition);
}
super.startUpdate(container);
}
public void restoreState(Parcelable state, ClassLoader loader) {
Log.d(TAG, "restoreState");
//We don't want to restore the fragments if the orientation changes!
if(isLastOrientationPortrait != isPortrait){
if(state != null){
Bundle bundle = (Bundle) state;
bundle.setClassLoader(loader);
Iterable<String> keys = bundle.keySet();
if (mCurTransaction == null) {
mCurTransaction = mFragmentManager.beginTransaction();
}
for (String key : keys) {
if (key.startsWith("f")) {
Fragment f = mFragmentManager.getFragment(bundle,
key);
mCurTransaction.remove(f);
}
}
}
isLastOrientationPortrait = isPortrait;
}else{
if (state != null) {
Bundle bundle = (Bundle)state;
bundle.setClassLoader(loader);
Parcelable[] fss = bundle.getParcelableArray("states");
mSavedState.clear();
mFragments.clear();
if (fss != null) {
for (int i=0; i<fss.length; i++) {
mSavedState.add((Fragment.SavedState)fss[i]);
}
}
Iterable<String> keys = bundle.keySet();
for (String key: keys) {
if (key.startsWith("f")) {
int index = Integer.parseInt(key.substring(1));
Fragment f = mFragmentManager.getFragment(bundle, key);
if (f != null) {
while (mFragments.size() <= index) {
mFragments.add(null);
}
f.setMenuVisibility(false);
mFragments.set(index, f);
} else {
Log.w(TAG, "Bad fragment at key " + key);
}
}
}
}
}
}
public void restoreState(可包裹状态,类装入器){
日志d(标签“恢复性房地产”);
//如果方向改变,我们不想恢复碎片!
if(IsLasOrientationPortrait!=isPortrait){
如果(状态!=null){
Bundle=(Bundle)状态;
bundle.setClassLoader(装入器);
Iterable keys=bundle.keySet();
if(mCurTransaction==null){
mCurTransaction=MFFragmentManager.beginTransaction();
}
用于(字符串键:键){
if(带(“f”)的起始键){
片段f=MFFragmentManager.getFragment(bundle,
键);
mCurTransaction.移除(f);
}
}
}
IsLasOrientationPortrait=isPortrait;
}否则{
如果(状态!=null){
Bundle=(Bundle)状态;
bundle.setClassLoader(装入器);
Parcelable[]fss=bundle.getParcelableArray(“状态”);
mSavedState.clear();
mFragments.clear();
如果(fss!=null){
对于(int i=0;i@StefandeBruijn我对答案做了一点修改,以修复内存泄漏问题。如果您使用的是我以前的解决方案,请用上面的代码替换代码。