代码之家  ›  专栏  ›  技术社区  ›  Andrew Lam

即使从横向旋转到垂直方向,细节片段也会重新开始。(主细节流)

  •  3
  • Andrew Lam  · 技术社区  · 9 年前

    在一个活动中,我们称之为MasterActivity,我想只在横向模式下加载带有媒体播放的细节片段。准备好后,介质会自动启动。

    我有两个XML,activity\u master和activity\u master。xml(土地)。id为“detail\u container”的容器视图仅在横向xml中。带有细节容器的横向xml的目的是在同一屏幕上以宽度>900

    if (findViewById(R.id.detail_container) != null) {
    // The detail container view will be present only in the
    // large-screen layouts (res/values-w900dp).
    // If this view is present, then the
        mTwoPane = true;
    }
    

    if (mTwoPane) {
        getSupportFragmentManager().beginTransaction()
        .replace(R.id.detail_container,
                 someFragment.newInstance(MEDIA_URI))
        .commit();
    }
    

    问题:

    当我垂直启动活动时,片段没有加载(预期)。

    在屏幕旋转时,片段被销毁(预期,播放停止,资源仅在onDestory()中释放);

    重新启动

    我的目标: 我希望当设备在大屏幕设备上处于横向时自动加载片段,在设备旋转时,片段不应再次加载。

    在垂直模式下,片段不应自动加载,用户将单击主活动,打开细节活动,细节活动将承载细节片段。

    额外信息:测试物理设备是一个运行安卓5.0 API 21的7英寸平板电脑,emulator中也存在这个问题。

    3 回复  |  直到 9 年前
        1
  •  3
  •   Jon    9 年前

    当配置发生更改时,Android将确保重新创建连接到活动的所有片段,并将其重新连接到新活动的FragmentManager setRetainInstance(...) 考虑在内。

    看来你要做的是 碎片的自动重新附着。我对此也很好奇,所以我深入研究了一下 FragmentActivity.onCreate(...) 和 FragmentManager FragmentTransaction 通过在代码中执行以下操作:

    FragmentManager manager = getSupportFragmentManager();
    
    if (mTwoPane) {
      // set up your two pane
      manager.beginTransaction()
        .replace(R.id.detail_container,
          someFragment.newInstance(MEDIA_URI),
          someFragment.TAG)
        .commit();
    } else {
      // this is not two pane, so remove the fragment if it is attached
      Fragment detail = manager.findFragmentByTag(someFragment.TAG);
      if (detail != null) {
        manager.beginTransaction()
          .remove(detail)
          .commit();
      }
    }
    
        2
  •  0
  •   Ewald Benes    9 年前

    我不知道布局XML是什么样子,但我建议只通过创建一个名为 /res/layout-land 如果不存在。

    布局可能类似于此:

    <SomeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        ...
        <fragment android:name="com.example.YourPlaybackFragment"
                android:id="@id/playback_fragment"
                android:layout_weight="1"
                android:layout_width="0dp"
                android:layout_height="match_parent" />
        ...
    </SomeLayout>
    

    这里有一个关于官方网站的有用链接 Android doc .



    您的播放逻辑进入片段。如果活动出于任何原因需要访问片段,那么您可以使用

    YourPlaybackFragment fragment = (YourPlaybackFragment) getFragmentManager().findFragmentById(R.id.playback_fragment);
    

    希望这能给你正确的方向。

    在这种情况下,最好是以编程方式将片段添加到 onCreate()

    if (findViewById(R.id.detail_container) != null) {
       // detect the landscape
       Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
       if(display.getRotation() == Surface.ROTATION_90) {
          // add the fragment
          getSupportFragmentManager().beginTransaction().add/replace(...)
       }
    }
    

    免责声明:未经测试。

        3
  •  0
  •   Jon    9 年前

    由于您有两个不同的活动,片段不再存在于同一个上下文中,因此可能有点难以产生您要寻找的行为。尝试执行以下操作:

    MasterFragment DetailFragment 选择时。

    横向:具有两个容器的xml布局,一个用于 一个用于 DetailFragment . 如果 已经存在(用户在方向更改之前在纵向中查看),碎片管理器知道它。找到现有片段并将其附加到适当的容器。

    假设您允许在方向更改时重新创建活动,如果您使用 setRetainInstance(true) replace(...)

    if (mTwoPane) {
            if (getSupportFragmentManager().findFragmentByTag(someFragment.TAG) != null) {
                // fragment already exists so either do nothing (auto reattach to R.id.detail_container)
                // or manually attach it to a different container
                return;
            }
            fragment = someFragment.newInstance(MEDIA_URI);
            getSupportFragmentManager().beginTransaction()
                    .replace(R.id.detail_container,
                             someFragment.newInstance(MEDIA_URI),
                             someFragment.TAG)
                    .commit();
    }
    
    推荐文章