2011-07-13 33 views
20

考虑从developers.android.com片段 - 您是否必须在构成整个活动的片段周围使用活动包装器?

样品应用此描述了使用片段如下所示:

  • 论活性B.
  • 一个电话可以在活动A使用片段1和片段2在平板你有更多的房地产,所以你使用活动A上的片段1和片段2.

太棒了! ...但是...在第一个示例(带电话的示例)中,您创建了一个包含单个<fragment>的xml文件的活动,就这一切而言,您只需在该xml上调用setContentView()?这似乎是很多冗余代码(活动,XML &显示片段的片段):您可以将Fragment设置为Activity,还是始终需要XML的包装器?

回答

34

啊,发现它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允许的您设置片段的android.R.id.content我以为是树干鉴于Android的内部ID的内容。

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

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

+1

考虑您的解决方案一步正向创建通用'SingleFragmentActivity'获得一个片段作为构造器参数,并将其添加到'onCreate'中。然后在每次需要某个单个片段活动时使用此活动。 – shem

+2

@shem - 我做的事情完全一样 - 我将片段规范名称作为Action来传递,以便它可以从String中实例化。 – Graeme

+0

那么,你也可以停止使用碎片,除非你真的需要碎片。在大多数情况下,使用简单的活动也可以完成这项工作 –

2

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

“在第一个例子中(带电话的那个例子),你应该创建一个Activity,其中包含一个单一的xml文件和一个只调用该xml的setContentView就这样?”

你已经开始在正确的地方。但除此之外还有更多。总是有不止一种方法可以解决Android中的问题,但推荐的方式是基于可用的方式产生具有动态数量片段的效果。房地产是:

  1. 在/布局主(默认)有针对性的定向/设备/外形/ SDK创建布局XML文件
  2. 创建最小宽度的基线为其他有针对性的布局XML文件设备。您可能还想要定位其他方向,SDK等。
  3. 每个布局XML文件都有它自己的一组定义片段
  4. 在活动中,检查以查看哪些片段存在。

很明显,类似的策略可以用于编程式布局。

在原来的问题你的例子(从谷歌的文档),你可以有:

  • 布局/主。XML ::这种布局将仅具有片段1
  • 布局sw600dp/main.xml中::这种布局将具有片段1,2

然后在MainActivity.java你会检查每个碎片的存在。要做到这一点,你可以使用FragmentManager#findFragmentById()来进行检查:if findFragmentById()为Fragment-2返回null,那么MainActivity知道设备已经加载了layout/main.xml并且只支持一个片段。

从示例中逐步“回退”可以发现:在使用碎片之前,您可能会使用startAcitityForResult(int)从活动A中调用Activity B。在Fragment范例中,你可能只需要从Fragment 2中得到一个结果就会在Fragment 1中发生一些事情,所以MainActivity成为它的守门员是合理的。当你展示这个例子时,你会发现在其他应用程序中,MainActivity可能需要调用其他活动 - 无论出于何种原因。也许你的目标是一个足够大的平板电脑,用于3个片段,但是在需要3个活动的手机上。事情会变得有趣,但Fragment API相当强大。

“你可以设置一个片段作为一个活动,或者是使用片段时总是需要的包装?”

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

+10

我不知道你在这里回答什么......? – Graeme

1

更一般地,你可以创建一个片段容器类:

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); 
}