简体   繁体   English

片段无法还原旋转时正确的视图

[英]Fragment unable to restore correct View on rotate

I'm using a fragment with two primary views that have setVisibility() to show or hide based on the results of an AsyncTask used to search for data online. 我正在使用一个片段,其中包含两个具有setVisibility()的主视图,这些视图基于用于在线搜索数据的AsyncTask的结果显示或隐藏。

For example, here is the method to switch between Views: 例如,以下是在视图之间切换的方法:

private void switchView()
{
    Log.d(LOG_TAG, "switchView(): show = " + show);
    mListView.setVisibility(show ? View.VISIBLE : View.GONE);
    searchView.setVisibility(show ? View.GONE : View.VISIBLE);
    mCompanyArrayAdapter.notifyDataSetChanged();
}

I'm taking this approach so that when the AsyncTask is complete it can parse the data into wrapper classes and create an ArrayList of these objects for use in the ListView adapter. 我采用这种方法,以便在AsyncTask完成时可以将数据解析为包装器类,并创建这些对象的ArrayList以便在ListView适配器中使用。 (If there is another way to pass custom classes to another fragment, I would be open to using that.) (如果有另一种方法可以将自定义类传递给另一个片段,则我可以使用它。)

Once result == true from Async it hides the searchView and shows the mListView. 一旦来自异步的结果== true,它将隐藏searchView并显示mListView。 However on rotate, the screen returns back to the searchView instead of continuing to display the mListView results. 但是,旋转时,屏幕将返回到searchView,而不是继续显示mListView结果。

I'm confused by the Log output that shows what I believe to two calls to onCreateView from the same fragment (DiscoverFragment), seen here: 我对Log输出感到困惑,该输出显示了我相信对同一片段(DiscoverFragment)的两次onCreateView调用的理解,如下所示:

10-17 10:29:21.872    6603-6603/nz.co.exium.panther D/DiscoverFragment﹕ onCreateView: savedinstancestate is null = false
10-17 10:29:21.877    6603-6603/nz.co.exium.panther D/AbsListView﹕ Get MotionRecognitionManager
10-17 10:29:21.882    6603-6603/nz.co.exium.panther D/DiscoverFragment﹕ onCreateView: savedinstancestate is null = true

So the first shows that the savedInstanceState is found != null and sets the boolean value appropriately but then another onCreateView() is called where savedInstanceState is null and sets it back to false. 因此,第一个结果表明找到了savedInstanceState!= null并适当地设置了布尔值,然后调用了另一个onCreateView(),其中saveInstanceState为null并将其设置为false。 Why the double onCreateView() after rotate? 为什么旋转后会出现两次onCreateView()?

Thanks for the help. 谢谢您的帮助。

As requested, code that replaces the fragments in the MainActivity (using a FrameLayout for the content_frame and position == DrawerLayout position item).: 根据要求,替换MainActivity中的片段的代码(对content_frame和position == DrawerLayout位置项使用FrameLayout):

getFragmentManager().beginTransaction()
                    .replace(R.id.content_frame, Fragment.instantiate(
                            getApplicationContext(), mClasses[position]))
                    .commit();

From my MainActivity.onCreate(): 从我的MainActivity.onCreate()中:

if (savedInstanceState == null) {
        selectItem(0);
    } else if (placeID == null || placeID.isEmpty()) {
        selectItem(savedInstanceState.getInt(SELECTED_KEY));
    }   else    {
        selectItem(2);
    }

I already perform a check for a previous savedInstanceState, if null set the default Fragment. 我已经对以前的saveInstanceState进行了检查,如果为null,则设置默认的Fragment。 If the variable placeID (from a BroadcastReceiver) is null/empty then restore previous state. 如果变量placeID(来自BroadcastReceiver)为空/空,则恢复先前状态。 Else, go to the Fragment that will display the Notifications data. 否则,转到将显示通知数据的片段。

Fragments are automatically recreated on rotation as part of restoring the state. 旋转时会自动重新创建片段,这是恢复状态的一部分。 Therefore you should only call selectItem() when savedInstanceState == null - otherwise you'll get your restored fragment (with its restored state), then immediately replace it with a brand new instance (without the restored state). 因此,仅当savedInstanceState == null时才应调用selectItem() -否则,您将获得还原的片段(具有其还原状态),然后立即将其替换为全新的实例(无还原状态)。

So, what happens here is this: 因此,这里发生的是这样的:

  • Your activity is created, and one fragment is added to it 您的活动已创建,并且其中添加了一个片段
  • You rotate your device 您旋转设备
  • Your activity gets recreated (along with the fragment previously added), and in onCreate, you add a new fragment, which means you have two fragments added in your activity 重新创建您的活动(以及先前添加的片段),然后在onCreate中添加一个新片段,这意味着您在活动中添加了两个片段

the easiest way to deal with this is to perform a check in your activity: 解决此问题的最简单方法是对您的活动进行检查:

if (savedInstanceState == null){    // add fragment }

the other method is to prevent activity recreation by specifying config changes in your AndroidManifest.xml 另一种方法是通过在AndroidManifest.xml中指定配置更改来防止重新创建活动

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM