Android 片段在屏幕旋转后重叠

发布于 2025-01-07 07:05:26 字数 1830 浏览 7 评论 0原文

这个应用程序对我来说是一个使用片段等的学习练习。它有一个管理一些不同片段的活动。第一个是 ListFragment (A),它显示应用程序何时启动并从光标加载列表项。单击列表项会通知活动将 ListFragment 替换为该项的 DetailFragment (B)。如果在查看 (B) 时旋转屏幕,我会看到 (B) 在 (A) 之上,如下所示:

http://postimage.org/image/uhy016ds7/

我最好的猜测是,这与 Android 在配置更改时销毁并重新创建 Activity 有关。我想知道这个问题最干净的解决方案是什么。接下来是一些代码片段,如果我还应该发布其他内容,请告诉我。

res/layout/home.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/fragment_container"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <fragment
        android:id="@+id/fragment_place_list"
        android:name="com.simbiosys.apps.foodfast.ui.PlaceListFragment"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >
    </fragment>
</FrameLayout>

MyActivity.onCreate

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.home);

    placeListFragment = (PlaceListFragment) getSupportFragmentManager().findFragmentById(
            R.id.fragment_place_list);

}

MyActivity.showDetailPane

public void showDetailPane(String id, String reference) {
    placeDetailFragment = PlaceDetailFragment.newInstance(id, reference);
    FragmentManager fragmentManager = getSupportFragmentManager();
    FragmentTransaction ft = fragmentManager.beginTransaction();
    ft.addToBackStack(null);
    ft.hide(placeListFragment);
    ft.replace(R.id.fragment_container, placeDetailFragment);
    ft.show(placeDetailFragment);
    ft.commit();
}

This app is a learning exercise for me using fragments, among other things. It has a single activity that manages some different fragments. The first is a ListFragment (A), which shows when the app starts and loads list items from a cursor. Clicking a list item notifies the activity to replace the ListFragment with a DetailFragment (B) for that item. If while looking at (B) I rotate the screen, I see (B) on top of (A), like this:

http://postimage.org/image/uhy016ds7/

My best guess is it has to do with Android destroying and re-creating the activity on a configuration change. I am wondering what is the cleanest solution for this problem. Some code snippets follow, let me know if there's something else I should post.

res/layout/home.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/fragment_container"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <fragment
        android:id="@+id/fragment_place_list"
        android:name="com.simbiosys.apps.foodfast.ui.PlaceListFragment"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >
    </fragment>
</FrameLayout>

MyActivity.onCreate

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.home);

    placeListFragment = (PlaceListFragment) getSupportFragmentManager().findFragmentById(
            R.id.fragment_place_list);

}

MyActivity.showDetailPane

public void showDetailPane(String id, String reference) {
    placeDetailFragment = PlaceDetailFragment.newInstance(id, reference);
    FragmentManager fragmentManager = getSupportFragmentManager();
    FragmentTransaction ft = fragmentManager.beginTransaction();
    ft.addToBackStack(null);
    ft.hide(placeListFragment);
    ft.replace(R.id.fragment_container, placeDetailFragment);
    ft.show(placeDetailFragment);
    ft.commit();
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

悲歌长辞 2025-01-14 07:05:26

根据 Android 开发 page,在 Activity 的 onCreate 方法中,您应该检查如果在将片段添加到活动之前savedInstanceState 为null。 此页面中 Activity 的 onCreate 方法的代码片段指出了这一点。

// However, 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.
if (savedInstanceState != null) {
     return;
}

As per Android dev page, in Activity's onCreate method you should check if the savedInstanceState is null before adding the fragment to the activity. Code snippet of onCreate method of Activity from this page states that.

// However, 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.
if (savedInstanceState != null) {
     return;
}
混浊又暗下来 2025-01-14 07:05:26

这是因为您使用框架布局作为容器。
它不会与其他布局重叠。

对于您想要实现的最佳实践,是将 XML 文件放入您的布局/文件夹中,其中仅使用您的列表片段。
在你的layout-land/中,你放置了一个XML文件,其中包含使用和排列的两个片段。

然后系统处理所有的创建。碎片。您的活动基本上减少为 setContentView() 调用。

在列表项上单击您,然后使用片段管理器检查您的详细片段是否已创建。如果创建了它,您可以调用详细信息片段中的公共函数来设置数据。

如果未创建,您可以使用新活动创建意图。

我知道 2 个很好的教程:android 开发者页面上的 Fragments 页面和 vogella.de 都会为您提供详细的示例/教程。

It is because you use a frame layout as container.
It wouldn't be overlapping for other layouts.

And for what you want to achieve best practice is to make a XML file into your layout/ folder where only your listfragment is used.
In your layout-land/ you put a XML file with both fragments used and arranged.

Then the system handles all the creation of the. fragments. And your activity basically reduces to a setContentView() call.

On a list item click you then check with the fragment manager whether or not your detail fragment is created. If it is created you your call a public function within the detail fragment to set the data.

If it is not created, you create a intent with a new activity.

I know 2 good tutorials: the fragments page on the android developers page and vogella.de both will give you a detailed example/tutorial.

魔法唧唧 2025-01-14 07:05:26

将FrameLayout改为LinerLayout,问题就解决了。

这是一个与 FrameLayout 相关的问题。

Change the FrameLayout for LinerLayout and the problem will be solved.

This is a FrameLayout related problem.

长梦不多时 2025-01-14 07:05:26

这对我有用。

public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    ....
    fragment = getFragmentManager().findFragmentByTag(TAG);
    if(fragment == null) fragment = new Fragment();
    ....

}

This works for me.

public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    ....
    fragment = getFragmentManager().findFragmentByTag(TAG);
    if(fragment == null) fragment = new Fragment();
    ....

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文