【问题标题】:Complex Android UI design guidance needed (fragments)需要复杂的 Android UI 设计指导(片段)
【发布时间】:2012-07-25 07:26:02
【问题描述】:

我正在开发一个针对平板电脑和 Google TV 的应用程序。它将像许多标准的 Google TV 应用程序一样,带有一个 LeftNavBar 和一个所有应用程序屏幕通用的顶部搜索栏。它将类似于下图:

主屏幕

所有其他屏幕的红色区域都会有所不同。它可能包含以下屏幕模型之类的数据:

Activity One 加载到主容器中

Activity 2 加载到主容器中

所以你可以看到在主区域可以加载完全不同的部分。

在选择屏幕 2 中的任何列表项时(例如在片段列表中),屏幕 3 可以作为详细部分加载,也可以通过选择选项卡(将出现在 LeftNavBar 中)加载。

这是我尝试实现它的方式。

第 1 步。我使用以下 XML 创建了一个主 Activity:

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

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="#9ccc" >

        <!-- Top Bar -->

    </LinearLayout>

    <FrameLayout
        android:id="@+id/mainContainer"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1">

        <!-- main Red Container that will load other Activities -->

    </FrameLayout>
</LinearLayout>

mainContainer 是我要加载活动的 RED 容器。 LeftNavBar 将作为 All 的父级添加到此 Activity。

第 2 步我创建了 ActivityOneActivityTwo,其中分别包含两个和三个 Fragment(如上图第二和第三张图片所示)。

*第 3 步 我正在尝试在主页的 ma​​inContainer FrameLayout 中加载ActivityOne...但我无法添加它。

我尝试将ActivityOne 添加到mainContainer,如下所示:

View v = (new ActivityOne()).getWindow().getDecorView();
FrameLayout mainContainer = (FrameLayout) findViewById(R.id.mainContainer);
mainContainer.addView(v);

但是getWindow() 返回null....

发生其他问题是因为所有数据都来自远程服务 ..所以还请建议我如何能够以某种方式保存对 mainContainer 中所有已加载活动的引用stack ...所以我可以重新加载已经加载的活动,而不是创建它的新实例。这将在按下 BACK 按钮时使用。

我应该创建两个活动,每个活动都有自己的片段和一个 LeftNavBar,而不是将活动加载到上述 RED 容器中。这可能比上述方法更容易。或者这可能是唯一的解决方案....但是我觉得为 BACK 按钮保存状态可能会变得混乱..但我会尝试实现这个

如果您必须创建这种类型的应用程序,您会怎么做? 您将如何设计 UI 布局以获得最佳性能/实践?

非常感谢您在帮助我设置此应用的布局方面提出的建议。

【问题讨论】:

  • 你能压缩你的代码,上传到某个地方并发送一个链接吗?你永远不能实例化一个活动,框架会这样做。我不知道 ActivityOne 是否实际上是您代码中的 Activity。浏览 Panoramio for Google TV 示例应用程序。它会做你打算在这里做的事情。
  • 感谢您的回复。我查看了 Panoramio 示例应用程序。它有两个活动,它们包括活动的 onCreate() 事件中的 LeftNavBar。如果这是在所有活动中包含 LeftNavBar 的正确方法,我会这样做。我试图找到一种替代方式,因为我的应用程序中有很多活动(7-10)。就是这样,我正在尝试上述方法.. 使用 LeftNavBar 进行父活动并将其他活动/片段加载到某个主容器中。

标签: android android-layout android-fragments google-tv


【解决方案1】:

免责声明

这是片段变得棘手的地方。如果 Activity 1 和 2 具有相同的布局,那么问题会很简单,这样您就可以简单地附加/分离片段并使用片段返回堆栈来展开。

因为您想要 2 种独特的布局来容纳您的片段,所以事情会更复杂一些。如果可能的话,我会尝试使用相同的布局,这样你就可以走捷径。

作为另一种选择,您可以使用上面概述的两个活动,并使用 Intent 来回发送数据。

也就是说,如果我真的必须按照所写的方式实施这个解决方案,我会这样做。 请注意,我不提倡这种解决方案,但我自己不知道更好的做事方式。

解决方案

创建一个 FragmentActivity,其视图将是您在上面定义的主屏幕。主屏幕的布局将包含:

  • 左侧导航栏
  • 顶栏
  • 2 种布局。布局1和布局2。这些将包含在父布局中,即RelativeLayout 或LinearLayout,并将包含您的片段所需的FrameLayout 元素。

使用您的 XML 的示例(注意,标签有点简短):

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

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="#9ccc" >

        <!-- Top Bar -->

    </LinearLayout>

    <LinearLayout android:id="@+id/layout1">
        <FrameLayout android:id="@+id/listFragment" />
        <FrameLayout android:id="@+id/contentFragment" />
    </LinearLayout>

    <LinearLayout android:id="@+id/layout2">
        <FrameLayout android:id="@+id/imageFragment" />
        <FrameLayout android:id="@+id/boxFragment1" />
        <FrameLayout android:id="@+id/boxFragment2" />
        <FrameLayout android:id="@+id/boxFragment3" />
    </LinearLayout>

</LinearLayout>

主要思想是然后显示/隐藏 layout1 和 layout2,即根据应用的状态设置 android:visibility="gone"。

这种方法的缺点是:

  • 可能无法使用片段 backstack,而是必须跟踪用户在 UI 流中的位置并管理后退按钮以显示/隐藏布局
  • 在显示/隐藏其父视图时,您可能需要特别注意附加/分离片段,以减少片段不可见时的资源消耗

优点是:

  • 片段和基础活动之间的轻松通信,因为只使用了 1 个活动

【讨论】:

  • 谢谢...如果我有两个活动要加载到那个 mainContainer 中,这可能是一种可能性。但是我有很多活动(7-10 个或更多),每个活动都有其独特的布局..所以这个解决方案不适用。我决定将所有活动与它们的子片段分开加载..所有这些活动都将派生自 baseActivity,它将将 LeftNavBar 插入该活动......这似乎更容易和易于管理
  • plus ...我没有将您的评论标记为答案,但已授予您赏金..因为您是唯一一个费心思考和详细回复的人...所以再次感谢您
  • 是的,有了这么多活动,您的解决方案似乎更易于管理。
【解决方案2】:

Re:嵌套片段问题

为了解决我们应用程序中的“嵌套片段”问题(正如您正确指出的那样)Fragments 无法添加 Fragments 我在活动下托管了一个模板片段,其唯一目的是为要锚定的其他片段定义一组占位符。在向 Activity 添加更多 Fragment 时,我使用模板 Fragment 的视图占位符 +@ids 来识别正在添加的 Fragment 的“根”或父视图 ID。

    getSupportFragmentManager().beginTransaction().add(#someIdFromTheTemplateFrag, fragment, fragmentTag).commit();

我添加的 Fragment 然后知道在当前布局中将自己锚定在哪里,当然然后开始使用它添加它的视图的快乐方式。这具有将片段附加到另一个片段的效果,从而实现所需的视觉“嵌套”......

【讨论】:

  • 这不仅没有回答他的问题,您还在宣传片段的不正确使用,嵌套片段可能会导致微妙的生命周期错误,并且不承诺在未来的版本中工作。他可以使用简单的布局轻松创建所需的效果,将他的片段组合在一起,无需嵌套。参考:stackoverflow.com/questions/6221763/…
  • 这里描述的内容没有分层嵌套。该活动仍然直接拥有所有片段。这种方法允许您流动由模块化、可重用的片段控制的视图——不会有细微的错误,因为活动仍然直接拥有片段,它可以随意销毁、重新创建和附加,但片段的位置可以通过这个来控制控制器的片段。
  • “我在活动下托管了一个模板片段,其唯一目的是定义一组占位符以供其他片段锚定到。” - 对我来说听起来像是在片段中放置片段
  • 您链接到的问题是关于将片段添加到代码中的片段(或者至少我是这样阅读的),从而模糊了谁可以控制片段之间的界限 - 这是关于“放置view 层中的那个 XML。如果你觉得这不对,我想继续这个聊天吗?聊天室?
  • HandlerExploit 指出这种行为不受支持,并在我们上面的聊天中提供了替代方案。每天都是学习日!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-12-14
  • 2011-01-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-22
相关资源
最近更新 更多