【问题标题】:Issue with restoring data after device was rotated设备旋转后恢复数据的问题
【发布时间】:2015-12-20 08:42:49
【问题描述】:

我检查了很多与我类似的问题的其他答案,但仍然无法理解那里有什么问题。

我有活动和片段

main_activity.xml

<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">

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical"
        android:id="@+id/fragment_container"
        android:background="#CCC"/>

</LinearLayout>

MainActivity.java

public class MainActivity extends Activity {

    private LinearLayout fragmentContainer;

    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d("LOG", "onCreate");
        setContentView(R.layout.activity_main);
        if (savedInstanceState == null) {
            openFragment();
        } else {
            replaceFragment();
        }
    }

    private void openFragment() {
        final LinearLayout ll = new LinearLayout(this);
        ll.setOrientation(LinearLayout.HORIZONTAL);
        ll.setId(12345);
        getFragmentManager().beginTransaction().add(ll.getId(),
            new SimpleFragment(), "SimpleFragment").commit();

        fragmentContainer = (LinearLayout) findViewById(R.id.fragment_container);
        fragmentContainer.addView(ll);
    }

    private void replaceFragment() {
        final LinearLayout ll = new LinearLayout(this);
        ll.setOrientation(LinearLayout.HORIZONTAL);
        ll.setId(12345);
        getFragmentManager().beginTransaction().replace(ll.getId(),
            new SimpleFragment(), "SimpleFragment").commit();

        fragmentContainer = (LinearLayout) findViewById(R.id.fragment_container);
        fragmentContainer.addView(ll);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d("LOG", "onDestroy");
    }
}

还有简单的片段

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

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

</LinearLayout>
public class SimpleFragment extends Fragment {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);       
        if (savedInstanceState != null) {
            String aaa = savedInstanceState.getString("AAA");
            Toast.makeText(getActivity(), aaa, Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(getActivity(), "NULL", Toast.LENGTH_SHORT).show();
        }
        Log.d("LOG", "onCreate");
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        Log.d("LOG", "fragment onCreateView");
        return inflater.inflate(R.layout.simple_fragment, null);
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        Log.d("LOG", "fragment onDestroyView");
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putString("AAA", "Hello");
    }

}

那么问题出在哪里:

当我旋转设备时,应用程序应该保存一个状态然后恢复它(让我们假设一些变量)。

在旋转 onSaveInstanceState 执行之后。 数据已保存。 然后执行fragment的onCreate,恢复数据。

没关系。这是预期的行为。

但是由于活动也被重新创建,片段应该再次添加(替换)。结果片段的 onCreate 再次执行。我看到没有保存数据的片段。我看到了新创建的片段。

如何避免这种创建?

我旋转设备,数据被保存然后恢复。片段在具有恢复数据的活动上可见。

那么在activity中添加fragment的算法是什么,以便在旋转后不添加,避免重新创建呢?

【问题讨论】:

  • 您的两种方法都在做同样的事情,因为您正在该布局中创建新的线性布局和膨胀片段并将其添加到 fragment_contianer
  • 好的,我明白了。但是添加片段和保存状态的正确方法是什么?一些静态片段之王?或者在活动中保存片段的状态?我找不到正确的解决方案?在安卓中可以吗? )
  • 只有 getFragmentManager().beginTransaction().add(R.id.fragment_container, new SimpleFragment(), "SimpleFragment").commit();将在 R.id.fragment_container 中添加片段,使用 .replace 的同一行代码将替换片段

标签: android android-fragments rotation


【解决方案1】:

从布局添加

一般来说,您不需要从代码中为您的片段添加额外的容器。添加片段的最简单方法是在布局中使用 android:id 属性定义&lt;fragment .../&gt;!!!

您的案例示例:

public class MainActivity extends Activity {

    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d("LOG", "onCreate");
        setContentView(R.layout.activity_main);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d("LOG", "onDestroy");
    }
}

ma​​in_activity.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
    >

    <FrameLayout
        android:id="@+id/fragment_container"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:background="#CCC"
        android:orientation="vertical"
        >

        <fragment
            android:id="@+id/fragment"
            android:name="your.package.name.SimpleFragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            />
    </FrameLayout>

</LinearLayout>

片段代码和布局不需要任何更改。

从代码添加

如果您确实需要从代码中添加它,则无需从代码中添加额外的容器。如果它是第一次启动,只需添加片段 - 系统会为您完成之后。

您的案例示例:

public class MainActivity extends Activity {

    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d("LOG", "onCreate");
        setContentView(R.layout.activity_main);
        if (savedInstanceState == null) {
            openFragment();
        }
    }

    private void openFragment() {
        getFragmentManager().beginTransaction().add(R.id.fragment_container,
                new SimpleFragment(), "SimpleFragment").commit();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d("LOG", "onDestroy");
    }
}

ma​​in_activity.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent">

    <FrameLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical"
        android:id="@+id/fragment_container"
        android:background="#CCC"/>

</LinearLayout>

片段代码和布局不需要任何更改。

【讨论】:

  • 感谢您的回复和抱歉延迟)但不是静态路径,例如 your.package.name.SimpleFragment 我必须以编程方式添加它。我有一个菜单,当我单击项目时,应该打开相应的片段。所以看起来我必须找到如何做同样的事情 (
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-27
  • 2017-05-29
相关资源
最近更新 更多