繁体   English   中英

片段 - 您是否必须在包含整个 Activity 的片段周围使用 Activity Wrapper?

[英]Fragments - Do you have to use an Activity Wrapper around a fragment which comprises the whole Activity?

考虑开发人员的示例应用程序。android.com

这描述了像这样使用片段:

  • 在手机上,您可以在 Activity A 上使用 Fragment 1,在 Activity B 上使用 Fragment 2。
  • 在平板电脑上,您拥有更多空间,因此您在活动 A 中使用片段 1 和片段 2。

伟大的。 ...但是...在第一个示例(带有电话的示例)中,您使用包含单个<fragment>的 xml 文件创建一个活动,仅此而已,在活动中您只在该 xml 上调用setContentView() 这似乎有很多冗余代码(活动、XML 和片段以显示片段):您可以将Fragment设置为Activity还是始终需要 XML 的包装器?

啊,在这里找到了

public class MainMenuHolder extends FragmentActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        // If not already added to the Fragment manager add it. If you don't do this a new Fragment will be added every time this method is called (Such as on orientation change)
        if(savedInstanceState == null)
            getSupportFragmentManager().beginTransaction().add(android.R.id.content, new MainMenuFragment()).commit();
    }
}

FragmentActivity 允许您将 Fragment 设置为android.R.id.content的内容,我假设它是主干视图的 android 内部 ID。

使用这种方法,你仍然会得到一个大部分冗余的活动(如果你想要的只是片段作为活动)。 但是,仍然有一个活动和一个充当容器的 XML 文件的一半。

任何其他答案将不胜感激!

在线示例并未填写所有空白。 我将尝试直接回答您的问题:

“在第一个示例(带有电话的示例)中,您是否应该使用 xml 文件创建一个活动,该文件包含一个活动和一个仅在该 xml 上调用 setContentView() 的活动,仅此而已?”

你从正确的地方开始。 但不仅如此。 在 Android 中总是有不止一种方法可以解决问题,但推荐的方法是根据可用性生成具有动态片段数量的效果。 房地产是:

  1. 在 /layout 中为主要(默认)目标方向/device/form-factor/SDK 创建布局 XML 文件
  2. 为其他目标设备的最小宽度基线创建布局 XML 文件。 您可能还希望针对其他方向、SDK 等。
  3. 每个布局 XML 文件都有自己的一组定义片段
  4. 在 Activity 中,检查以查看存在哪些片段。

显然,可以对程序化布局采用类似的策略。

在原始问题(来自 Google 的文档)中的示例中,您可以:

  • layout/main.xml:: 这个布局只有片段1
  • layout-sw600dp/main.xml:: 此布局将包含片段 1、2

然后在 MainActivity.java 中检查每个片段是否存在。 为此,您可以使用 FragmentManager#findFragmentById() 进行检查,例如:如果 findFragmentById() 返回 Fragment-2 的 null 则 MainActivity 知道设备已加载 layout/main.xml 并且仅支持一个片段。

从示例中“退后一步”可以看出:在使用 Fragments 之前,您可能已经使用 startAcitityForResult(int) 从 Activity A 调用了 Activity B。 在片段范例中,您可能只需要片段 2 的结果导致片段 1 中发生某些事情,因此让 MainActivity 成为看门人是合理的。 随着您对示例的扩展,您可能会看到在其他应用程序中,MainActivity 可能需要调用其他活动 - 无论出于何种原因。 也许您的目标是具有足够空间容纳 3 个片段的大型平板电脑,但在需要 3 个活动的手机上。 事情可能会变得有趣,但片段 API 相当强大。

“您可以将 Fragment 设置为 Activity 还是使用 Fragment 时始终需要 Wrapper?”

片段不是活动。 事实上,片段是由活动加载的,所以是的,有人可能会说总是需要一个包装器。 您正在触及 Fragments 的另一个微妙方面。 尽管 Activity 的行为类似于 MVC 控制器,但 Fragment 可以被称为“迷你控制器”,因为它们的生命周期类似于 Activity 并与 Activity 一起执行。 同样,Fragment 的生命周期包含在(“包装”)管理 Fragment 的 Activity 的生命周期内。 我建议熟悉http://developer.android.com/guide/topics/fundamentals/fragments.html#Lifecycle中记录的片段生命周期。

更一般地,您可以创建一个片段容器 class:

public class SingleFragmentActivity extends Activity {

    public static final String FRAGMENT_NAME = "fragmentName";
    public static final String FRAGMENT_ARGUMENTS = "fragmentArguments";

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        String fragmentName = getIntent().getStringExtra(FRAGMENT_NAME);
        Fragment fragment = Fragment.instantiate(this, fragmentName);
        Bundle fragmentArguments = getIntent().getBundleExtra(FRAGMENT_ARGUMENTS);
        fragment.setArguments(fragmentArguments);
        getSupportFragmentManager().beginTransaction().replace(android.R.id.content,fragment, "tag").commit();
    }
}

现在您使用此 class 将任何片段实例化为独立活动:

public void showFragmentAsActivity() {
    Intent intent = new Intent(this, SingleFragmentActivity.class);
    intent.putExtra(SingleFragmentActivity.FRAGMENT_NAME, MyFragment.class.getName());
    intent.putExtra(SingleFragmentActivity.FRAGMENT_ARGUMENTS,MyFragment.getArgumentsBundle("a string argument"));
    startActivity(intent);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM