更换碎片和方向变化 [英] Replacing fragments and orientation change

查看:187
本文介绍了更换碎片和方向变化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发针对2.x和3.0设备的Andr​​oid应用程序,因此我使用的相容性API。我测试在Android 2.0。

I'm developing an Android application targeting 2.x and 3.0 devices and thus I'm using the compatibilty API. I'm testing on Android 2.0.

我想替换另一个(与搜索结果的搜索形式)所显示的片段,我经历的方向变化的碰撞将显示第二(成绩)的片段时。

I'm trying to replace a displayed fragment with another one (search form with search results) and I'm experiencing a crash on orientation change when the second (results) fragment is displayed.

基本上,我有一个活动,包括在布局XML定义的片段

Basically, I have an activity, that includes a fragment defined in layout xml as

    <fragment class="org.prevoz.android.search.SearchFormFragment"
              android:id = "@+id/search_form_fragment"
              android:layout_width = "fill_parent"
              android:layout_height = "fill_parent" />

第一个片段(SearchFormFragment)显示为默认。当用户点击搜索按钮,我更换SearchResultsFragment,它运行的AsyncTask的的SearchFormFragment(这就是为什么我要保留它)与

The first fragment (SearchFormFragment) is displayed as a default. When user taps a "search" button, I replace the SearchFormFragment with SearchResultsFragment, which runs an AsyncTask (that's why I want to retain it) with

    // Show the search results fragment
SearchResultsFragment newSearch = new SearchResultsFragment(from, to, when);
newSearch.setRetainInstance(true);

FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out);
transaction.replace(R.id.search_form_fragment, newSearch);      
transaction.addToBackStack(null);
transaction.commit();

然而,当显示SearchFormFragment和方向改变时,我的应用程序崩溃以

However, when the SearchFormFragment is displayed and orientation is changed, my application crashes with

ERROR/AndroidRuntime(334): FATAL EXCEPTION: main
ERROR/AndroidRuntime(334): java.lang.RuntimeException: Unable to start activity ComponentInfo{org.prevoz.android/org.prevoz.android.search.MainActivity}: android.view.InflateException: Binary XML file line #13: Error inflating class fragment
ERROR/AndroidRuntime(334):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663)
ERROR/AndroidRuntime(334):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
ERROR/AndroidRuntime(334):     at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3815)
ERROR/AndroidRuntime(334):     at android.app.ActivityThread.access$2400(ActivityThread.java:125)
ERROR/AndroidRuntime(334):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2037)
ERROR/AndroidRuntime(334):     at android.os.Handler.dispatchMessage(Handler.java:99)
ERROR/AndroidRuntime(334):     at android.os.Looper.loop(Looper.java:123)
ERROR/AndroidRuntime(334):     at android.app.ActivityThread.main(ActivityThread.java:4627)
ERROR/AndroidRuntime(334):     at java.lang.reflect.Method.invokeNative(Native Method)
ERROR/AndroidRuntime(334):     at java.lang.reflect.Method.invoke(Method.java:521)
ERROR/AndroidRuntime(334):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
ERROR/AndroidRuntime(334):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
ERROR/AndroidRuntime(334):     at dalvik.system.NativeStart.main(Native Method)
ERROR/AndroidRuntime(334): Caused by: android.view.InflateException: Binary XML file line #13: Error inflating class fragment
ERROR/AndroidRuntime(334):     at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:582)
ERROR/AndroidRuntime(334):     at android.view.LayoutInflater.rInflate(LayoutInflater.java:618)
ERROR/AndroidRuntime(334):     at android.view.LayoutInflater.inflate(LayoutInflater.java:407)
ERROR/AndroidRuntime(334):     at android.view.LayoutInflater.inflate(LayoutInflater.java:320)
ERROR/AndroidRuntime(334):     at android.view.LayoutInflater.inflate(LayoutInflater.java:276)
ERROR/AndroidRuntime(334):     at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:198)
ERROR/AndroidRuntime(334):     at android.app.Activity.setContentView(Activity.java:1647)
ERROR/AndroidRuntime(334):     at org.prevoz.android.search.MainActivity.onCreate(MainActivity.java:40)
ERROR/AndroidRuntime(334):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
ERROR/AndroidRuntime(334):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
ERROR/AndroidRuntime(334):     ... 12 more
ERROR/AndroidRuntime(334): Caused by: java.lang.IllegalStateException: Fragment org.prevoz.android.search.SearchFormFragment did not create a view.
ERROR/AndroidRuntime(334):     at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:281)
ERROR/AndroidRuntime(334):     at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:558)
ERROR/AndroidRuntime(334):     ... 21 more
WARN/ActivityManager(59):   Force finishing activity org.prevoz.android/.search.MainActivity

从SearchFormFragment相关onCreateView code不被调用,我返回一个有效的观点:

The relevant onCreateView code from SearchFormFragment does get called and I return a valid view:

@Override
public View onCreateView(LayoutInflater inflater, 
                         ViewGroup container,
                         Bundle savedInstanceState) 
{       
    View newView = inflater.inflate(R.layout.search_form_frag, container, false);
    return newView;
}

如果SearchResultsFragment显示,如果显示的默认SearchFormFragment变化工作正常。这次事故只发生

The crash only happens if the SearchResultsFragment is shown, the change works fine if the default SearchFormFragment is displayed.

那么,如何留住第二个片段的状态通过方向改变?在API和状态变化的文件确实是欠缺的。

So how do I retain the second fragment state through the orientation change? The documentation on API and state changes is really lacking.

推荐答案

不要在XML创建 SearchFormFragment 。相反,有一个空的的FrameLayout 您在 Activity.onCreate()填充,而不将其添加到后面堆栈。这样,活动将保持当前的片段,而不是试图增加在XML中指定的。

Don't create the SearchFormFragment in XML. Instead have an empty FrameLayout which you populate in Activity.onCreate() without adding it to the back stack. This way the Activity will keep the current Fragment instead of trying to add the one specified in XML.

此外,使用 AsyncLoader 可能是一个更好的方法,请参阅<一href="http://$c$c.google.com/p/android/issues/detail?id=14944">http://$c$c.google.com/p/android/issues/detail?id=14944

Also, using AsyncLoader may be a better approach, see http://code.google.com/p/android/issues/detail?id=14944

这篇关于更换碎片和方向变化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆