【发布时间】:2011-11-27 04:34:31
【问题描述】:
我正在为平板电脑开发一个 Android 应用,但不使用兼容性库。
只有一个 Activity,它使用带有 3 个选项卡的 ActionBar。 在 TabListener 中,我使用 setContentView 加载特定于该选项卡的布局,然后将相关片段添加到它们的框架中。 这几乎的工作方式与我想要的完全一样,除非您在选项卡之间切换的速度足够快,应用程序会崩溃。
我使用三星 Galaxy Tab 作为我的调试设备,切换标签非常快。以正常的速度,我可以在它们之间来回点击,页面会立即加载。问题是当我在选项卡之间进行超级切换时。
一开始我有一个
IllegalStateException: Fragment not added
如此处所示: http://code.google.com/p/android/issues/detail?id=17029 按照在 onTabUnselected 中使用 try/catch 块的建议,我使应用程序更加健壮,但这导致了手头的问题:
IllegalArgumentException: No view found for id 0x... for fragment ...
我在网上没有发现任何其他人遇到同样问题的案例,所以我担心我可能正在做一些不受支持的事情。 再次,我想做的是在一个 Activity 中使用 3 种不同的布局 - 当您单击选项卡时,侦听器将调用 setContentView 来更改布局,然后添加片段。除非您开始积极地在标签之间切换,否则它会很好地工作。
我的想法来自:http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/app/FragmentTabs.html 而不是 TabListener 保持对一个片段的引用,我有一个它们的数组。另外,我没有使用附加/分离,因为它们只是在 API 13 中添加的。
我的理论是SetContentView尚未完成创建视图,这就是为什么FropmentTransaction无法添加它们,或者在选择另一个选项卡时,将在一个选项卡中添加片段并调用setContentView,销毁其他组件的意见。
我试图破解一些东西来减慢标签切换的速度,但没有成功。
这是我的 TabListener 的代码:
private class BTabListener<T extends Fragment> implements ActionBar.TabListener{
private int mLayout;
private Fragment[] mFrags;
private TabData mTabData;
private Activity mAct;
private boolean mNoNewFrags;
public BTabListener(Activity act, int layout, TabData td, boolean frags){
mLayout = layout;
mTabData = td;
mAct = act;
mNoNewFrags = frags;
mFrags = new Fragment[mTabData.fragTags.length];
for(int i=0; i<mFrags.length; i++){
//on an orientation change, this will find the fragments that were recreated by the system
mFrags[i] = mAct.getFragmentManager().findFragmentByTag(mTabData.fragTags[i]);
}
}
@Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
//this gets called _after_ unselected
//note: unselected wont have been called after an orientation change!
//we also need to watch out because tab 0 always gets selected when adding the tabs
//set the view for this tab
mAct.setContentView(mLayout);
for(int i=0; i<mFrags.length; i++){
//this will be null when the tab is first selected
if(mFrags[i]==null ){
mFrags[i] = Fragment.instantiate(GUITablet.this, mTabData.classes[i].getName());
}
//if there was an orientation change when we were on this page, the fragment is already added
if(!mNoNewFrags || mDefaultTab!=tab.getPosition()){
ft.add(mTabData.containterIDs[i], mFrags[i], mTabData.fragTags[i]);
}
}
mNoNewFrags = false;
}
@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
// this gets called when another tab is selected, before it's onSelected method
for(Fragment f : mFrags){
try{ //extra safety measure
ft.remove(f);
}catch(Exception e){
e.printStackTrace();
System.out.println("unselect couldnt remove");
}
}
}
}
最后,堆栈跟踪:
09-29 01:53:08.200: ERROR/AndroidRuntime(4611): java.lang.IllegalArgumentException: No view found for id 0x7f0b0078 for fragment Fraggle{40ab2230 #2 id=0x7f0b0078 dummy2}
09-29 01:53:08.200: ERROR/AndroidRuntime(4611): at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:729)
09-29 01:53:08.200: ERROR/AndroidRuntime(4611): at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:926)
09-29 01:53:08.200: ERROR/AndroidRuntime(4611): at android.app.BackStackRecord.run(BackStackRecord.java:578)
09-29 01:53:08.200: ERROR/AndroidRuntime(4611): at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1226)
09-29 01:53:08.200: ERROR/AndroidRuntime(4611): at android.app.FragmentManagerImpl$1.run(FragmentManager.java:374)
09-29 01:53:08.200: ERROR/AndroidRuntime(4611): at android.os.Handler.handleCallback(Handler.java:587)
09-29 01:53:08.200: ERROR/AndroidRuntime(4611): at android.os.Handler.dispatchMessage(Handler.java:92)
09-29 01:53:08.200: ERROR/AndroidRuntime(4611): at android.os.Looper.loop(Looper.java:132)
09-29 01:53:08.200: ERROR/AndroidRuntime(4611): at android.app.ActivityThread.main(ActivityThread.java:4028)
09-29 01:53:08.200: ERROR/AndroidRuntime(4611): at java.lang.reflect.Method.invokeNative(Native Method)
09-29 01:53:08.200: ERROR/AndroidRuntime(4611): at java.lang.reflect.Method.invoke(Method.java:491)
09-29 01:53:08.200: ERROR/AndroidRuntime(4611): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:844)
09-29 01:53:08.200: ERROR/AndroidRuntime(4611): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)
09-29 01:53:08.200: ERROR/AndroidRuntime(4611): at dalvik.system.NativeStart.main(Native Method)
谢谢!!
【问题讨论】:
-
谁能帮我摆脱这个错误.... [link][1] [1]: stackoverflow.com/questions/25400641/…
-
@SamKazmi,您是否尝试过建议的答案...?
标签: android-3.0-honeycomb android-fragments android