具有setRetainInstance(true)的ListFragment在屏幕旋转后不显示列表视图

时间:2013-08-06 22:04:16

标签: android android-listview android-listfragment

我正在尝试在ListFragment上使用setRetainInstance(true),直到onCreateView它像魅力一样工作,类中的所有属性都被保留,似乎没问题。但是一旦屏幕旋转并生成视图,就会显示listView,尽管适配器和数据都在那里。

我想请你在这个主题上提供一些指导,因为它是我最好的。

我将粘贴活动,片段和布局的代码:

ContentActivity.java

public class ContentActivity extends SherlockFragmentActivity {

    private final String LOG_TAG = ContentActivity.class.getName();
    private ContentListFragment contentFragment = null;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // set the content layout
        setContentView(R.layout.content);

        if (savedInstanceState == null) {
            // Creates the fragment for the ContentList
            contentFragment = new ContentListFragment();
            // Add the fragment to the 'content_container' FrameLayout
            getSupportFragmentManager()
                    .beginTransaction()
                    .add(R.id.content_container, contentFragment,
                            getResources().getString(R.id.content_container))
                    .commit();
        } else {
            // If we're being restored from a previous state,
            // then we don't need to do anything and should return or else
            // we could end up with overlapping fragments.
            contentFragment = (ContentListFragment) getSupportFragmentManager()
                    .findFragmentByTag(
                            getResources().getString(R.id.content_container));
        }
    }

}

这是ContentActivity content.xml的布局

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/content_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

这是ContentListFragment.java

public class ContentListFragment extends SherlockListFragment implements
            LoaderCallbacks<HTTPRequestLoader.RESTResponse> {


    private final String LOG_TAG = ContentListFragment.class.getName();

    private static final int LOADER_PREFERENCES = 0x1f;
    private ContentListAdapter contentAdapter = null;
    private List<Content> contents = new ArrayList<Content>();

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        View v = inflater.inflate(R.layout.content_list, container, false);
        Log.i(LOG_TAG, "onCreateView");
        contentAdapter = new ContentListAdapter(getActivity(),
                R.layout.content_block_item, contents);
        Log.i(LOG_TAG,
                "savedInstanceState==null size of the adapter in onCreateView "
                        + contentAdapter.getCount());
        Log.i(LOG_TAG, "savedInstanceState==null size of the contents "
                + contents.size());
        setListAdapter(contentAdapter);
        contentAdapter.notifyDataSetChanged();

        return v;
    }


    @Override
    public void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
         setRetainInstance(true);
        // If there is no data, prepare the loader. Either re-connect with an
        // existing one,
        // or start a new one.
        getActivity().getSupportLoaderManager().initLoader(LOADER_PREFERENCES,
                null, this);
        Log.i(LOG_TAG, "onCreate");
    }

    @Override
    public Loader<RESTResponse> onCreateLoader(int id, Bundle params) {
        return ConnectionManager.getInstance().getPreferencesLoader(
                getActivity(), params);
    }

    @Override
    public void onLoadFinished(Loader<HTTPRequestLoader.RESTResponse> loader,
            HTTPRequestLoader.RESTResponse data) {
        int code = data.getCode();
        String json = data.getData();
        Log.i(LOG_TAG, "loaderFinished");
        // Check to see if we got an HTTP 200 code and have some data.
        if (code == 200 && !json.equals("")) {

            contentAdapter.clear();
            contents = ParserJson.getPreferencesFromJson(json);

            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
                contentAdapter.addAll(contents);
            } else {
                for (Content content : contents) {
                    contentAdapter.add(content);
                }
            }
            contentAdapter.notifyDataSetChanged();

        } else {
            // TODO: extract string
            Toast.makeText(
                    getActivity(),
                    "Failed to load Preferences data. Check your internet settings.",
                    Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    public void onLoaderReset(Loader<RESTResponse> loader) {
    }

    public void deselectItems() {
        for (Content content : contents) {
            for (Section section : content.getSections()) {
                section.setSelected(false);
            }
        }
        contentAdapter.notifyDataSetChanged();

    }


}

这是content_list.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="hello_world" />

    <ListView
        android:id="@id/android:list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:divider="@null" />

    <FrameLayout
        android:id="@+id/content_dialog"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >
    </FrameLayout>

</LinearLayout>

如您所见,我只在检查savedInstanceState时创建片段,当创建片段时,它会执行加载器并设置视图。一旦加载程序完成加载,它就会毫无问题地升级视图。

一旦我旋转模拟器的屏幕,只显示content_list.xml中的“hello_world”。

我试图将适配器的配置移动到onViewCreated而没有成功。

1 个答案:

答案 0 :(得分:1)

如果您使用的是保留片段,那么您不应该尝试更新该片段中的UI:

http://www.vogella.com/articles/AndroidFragments/article.html#fragmentspersistence_configurationrestarts

第4.2节:

  

除此之外,您还可以使用setRetainState(true)方法调用   在片段上。这保留了片段之间的实例   配置更改但仅在未添加片段时才有效   靠背。 Google不建议使用此方法   具有用户界面的片段。在这种情况下,数据必须是   存储为成员(字段)。

您可以将UI内容移动到其他片段或父活动。