片段 - 您是不是必须在包含整个 Activity 的片段周围使用 Activity Wrapper?
Posted
技术标签:
【中文标题】片段 - 您是不是必须在包含整个 Activity 的片段周围使用 Activity Wrapper?【英文标题】:Fragments - Do you have to use an Activity Wrapper around a fragment which comprises the whole Activity?片段 - 您是否必须在包含整个 Activity 的片段周围使用 Activity Wrapper? 【发布时间】:2011-10-04 08:25:05 【问题描述】:考虑来自developers.android.com的示例应用
这描述了像这样使用片段:
在手机上,您可以在 Activity A 上使用 Fragment 1,在 Activity B 上使用 Fragment 2。 在平板电脑上,您拥有更多空间,因此您在活动 A 中使用 Fragment 1 和 Fragment 2。太棒了! ...但是...在第一个示例(带有电话的示例)中,您使用包含单个<fragment>
的xml 文件创建了一个活动,仅此而已,在活动中您只在该xml 上调用setContentView()
?这似乎有很多冗余代码(用于显示片段的活动、XML 和片段):您可以将Fragment
设置为Activity
还是始终需要带有 XML 的 Wrapper?
【问题讨论】:
【参考方案1】:啊,找到了here
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 文件的一半。
任何其他答案将不胜感激!
【讨论】:
让您的解决方案向前迈出一步——创建通用SingleFragmentActivity
,获取一个片段作为构造函数参数,然后添加它onCreate
。然后在每次需要单个片段活动时使用此活动。
@shem - 我做同样的事情 - 我将片段规范名称作为操作传递,因此它可以从字符串中实例化。
好吧,你也可以停止使用 Fragments,除非你真的需要一个。在大多数情况下,使用简单的 Activity 也可以完成这项工作
我创建了一个通用的 SimpleFragmentActivity 来执行此操作(只是嵌入一个片段) - 它还有一个用于实例化的构建器,以便您可以设置标题、主题等。github.com/jt-gilkeson/fragment-utils【参考方案2】:
在线示例并未填写所有空白。我会尽量直接回答你的问题:
“在第一个示例(带有电话的示例)中,您是否应该创建一个带有 xml 文件的 Activity,其中包含单个和一个仅在该 xml 上调用 setContentView() 的 Activity,仅此而已?”
您已经从正确的地方开始。但不仅如此。在 Android 中解决问题的方法总是不止一种,但推荐的方法是根据可用性生成具有动态片段数量的效果。房地产是:
-
在 /layout 中为主要(默认)目标方向/device/form-factor/SDK 创建布局 XML 文件
为其他目标设备的最小宽度基线创建布局 XML 文件。您可能还想定位其他方向、SDK 等。
每个布局 XML 文件都有自己定义的片段集
在 Activity 中,检查存在哪些片段。
显然,程序化布局可以采用类似的策略。
在原始问题(来自 Google 的文档)中的示例中,您可以:
layout/main.xml :: 这个布局只有 Fragment 1 layout-sw600dp/main.xml :: 此布局将包含 Fragments 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 个活动的手机上。事情可能会变得有趣,但 Fragment API 相当强大。
“你可以将 Fragment 设置为 Activity 还是在使用 Fragment 时始终需要 Wrapper?”
片段不是活动。事实上,片段是由活动加载的,所以是的,有人可能会说总是需要一个包装器。您正在触及 Fragments 的另一个微妙方面。尽管 Activity 的行为类似于 MVC 控制器,但 Fragment 可以被称为“迷你控制器”,因为它们的生命周期类似于 Activity 并与 Activity 一起执行。同样,Fragment 的生命周期包含在(“包装”)管理 Fragment 的 Activity 的生命周期内。我建议熟悉 http://developer.android.com/guide/topics/fundamentals/fragments.html#Lifecycle 中记录的 Fragment 生命周期。
【讨论】:
我不知道你在这里回答什么......?【参考方案3】:更一般地,您可以创建一个片段容器类:
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();
现在您可以使用此类将任何片段实例化为独立活动:
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);
【讨论】:
以上是关于片段 - 您是不是必须在包含整个 Activity 的片段周围使用 Activity Wrapper?的主要内容,如果未能解决你的问题,请参考以下文章