首页 文章

为什么碎片,何时使用碎片而不是活动?

提问于
浏览
391

在Android API 11中,Google发布了一个名为 Fragment 的新类 .

在视频中,谷歌建议尽可能(link1link2),我们应该使用片段而不是活动,但他们没有解释确切原因 .

片段的目的是什么以及它们的一些可能的用途(除了一些可以通过简单的视图/布局轻松实现的UI示例)?

我的问题是片段:

  • 使用片段的目的是什么?

  • 与使用活动/视图/布局相比,使用片段有哪些优缺点?

奖金问题:

  • 你能为片段提供一些非常有趣的用途吗?谷歌在他们的视频中没有提到的事情?

  • 片段与包含片段的活动之间进行通信的最佳方式是什么?

  • 使用碎片时要记住哪些最重要的事情?您的经验提示和警告?

12 回答

  • 244
    • 片段是活动的一部分,它为自己的UI提供了该活动 . 片段可以被认为是子活动,而用户与之交互的完整屏幕被称为“活动” .

    • 一个活动可以包含多个片段 . 活动可以包含基于屏幕大小的0或多个片段 .

    • 片段可以在多个活动中重用,因此它就像活动中的可重用组件 .

    • 片段不能独立存在 . 它应该始终是活动的一部分 . 活动可以存在,其中没有任何片段 .

  • 0

    片段存在于Activity中,并具有:

    • 自己的生命周期

    • 自己的布局

    • 自己的孩子碎片等

    将Fragments视为它所属的主要活动的子活动,它不能自己存在,并且可以一次又一次地调用/重用 . 希望这可以帮助 :)

  • 90

    不确定你指的是哪些视频,但我怀疑他们是说你应该使用片段而不是活动,因为它们不能直接互换 . 在开发指南中实际上有一个相当detailed entry,考虑阅读它的详细信息 .

    简而言之,片段存在于活动内部,每个活动都可以容纳许多片段 . 与活动一样,它们具有特定的生命周期,与活动不同,它们不是顶级应用程序组件 . 片段的优点包括代码重用和模块化(例如,在许多活动中使用相同的列表视图),包括构建多窗格界面的能力(主要用于平板电脑) . 主要缺点是(某些)增加了复杂性 . 通常,您可以使用非标准且不太稳健的方式(自定义)视图实现相同的功能 .

  • 0

    Activity是应用程序中带有工具栏的全屏组件,其他所有内容最好是Fragments . 带工具栏的一个全屏父活动可以有多个窗格,可滚动页面,对话框等(所有片段),所有这些都可以从父级访问并通过父级进行通信 .

    示例 -

    Activity A, Activity B, Activity C -

    • 所有活动都需要重复相同的代码,例如显示基本工具栏或从父活动继承(管理变得很麻烦) .

    • 要从一个活动移动到另一个活动,要么所有活动都需要在内存中(开销),要么需要销毁一个活动才能打开另一个活动 .

    • 活动之间的通信可以通过Intents完成 .

    VS

    Activity A, Fragment 1, Fragment 2, Fragment 3 -

    • 没有代码重复,所有屏幕都有来自那个Activity的工具栏等 .

    • 从一个片段移动到下一个片段的几种方法 - 查看寻呼机,多窗格等 .

    • 活动具有大多数数据,因此需要最少的片段间通信 . 如果仍然需要,可以通过接口轻松完成 .

    • 碎片不需要全屏,在设计时需要灵活性 .

    • 如果不需要视图,片段不需要扩充布局 .

    • 几个活动可以使用相同的片段 .

  • 0

    片段在某些情况下特别有用,例如我们想在所有页面中保留导航抽屉 . 您可以使用您想要的任何片段为框架布局充气,并且仍然可以访问导航抽屉 .

    如果您使用过某个活动,则必须将抽屉保留在所有可能导致冗余代码的活动中 . 这是片段的一个有趣用法 .

    我是Android新手,仍然认为片段有用这种方式 .

  • 1

    #1&#2使用片段的目的是什么?与使用活动/视图/布局相比,使用片段的优点和缺点是什么?

    片段是Android创建可重用用户界面的解决方案 . 您可以使用活动和布局(例如使用包含)来实现某些相同的功能 . 然而;片段从HoneyComb连接到Android API,然后连接到 . 让我详细说明;

    • ActionBar . 如果您希望使用标签来浏览您的应用,请快速进行看到 ActionBar.TabListener 接口给你一个 FragmentTransaction 作为 onTabSelected 方法的输入参数 . 你可能会忽略这一点,做一些别的和聪明的事情,但是你要反对API而不是它 .

    • FragmentManager 以非常聪明的方式处理«返回» . 返回并不意味着回到最后一个活动,就像常规活动一样 . 这意味着回到之前的片段状态 .

    • 您可以使用带有 FragmentPagerAdapter 的cool ViewPager 来创建滑动界面 . FragmentPagerAdapter 代码比常规适配器更清晰,并且它控制各个片段的实例化 .

    • 如果在尝试为手机和平板电脑创建应用程序时使用Fragments,您的生活将会轻松多了 . 由于片段与Honeycomb API紧密相关,因此您还需要在手机上使用它们以重用代码 . 这就是兼容性库派上用场的地方 .

    • 您甚至可以而且应该将片段用于仅适用于手机的应用程序 . 如果你有可携带性 . 我使用 ActionBarSherlock 和兼容性库来创建"ICS looking"应用程序,它们看起来一直回到1.6版本 . 你会得到像 ActionBar 这样的最新功能,包括标签,溢出,分割操作栏,viewpager等 .

    奖金2

    在片段之间进行通信的最佳方式是意图 . 当您在片段中按某些内容时,通常会在其上调用数据 StartActivity() . 意图将传递给您启动的活动的所有片段 .

  • 4

    Fragment是应用程序的用户界面或行为的一部分,可以放置在Activity中,从而实现更模块化的活动设计 . 如果我们说片段是一种子活动就没有错 .

    以下是关于片段的重要观点:

    • 一个片段有自己的布局和自己的行为以及它自己的生命周期回调 .

    • 您可以在活动运行时添加或删除活动中的片段 .

    • 您可以在单个活动中组合多个片段以构建多窗格UI .

    • 片段可用于多个活动 .

    • 片段生命周期与其宿主活动的生命周期密切相关 .

    • 当活动暂停时,活动中可用的所有片段也将停止 .

    • 片段可以实现没有用户界面组件的行为 .

    • 片段在API版本11的Android 3(Honeycomb)中添加到Android API中 .

    有关详细信息,请访问官方网站Fragments .

  • 65

    这是我在片段上发现的重要信息:

    历史上,Android应用中的每个屏幕都是作为单独的Activity实现的 . 这在屏幕之间传递信息时产生了挑战,因为Android Intent机制不允许在活动之间直接传递引用类型(即对象) . 相反,必须序列化对象或提供可全局访问的引用 . 通过使每个屏幕成为一个单独的片段,完全避免了这种数据传递的麻烦 . 片段始终存在于给定Activity的上下文中,并且始终可以访问该Activity . 通过在Activity中存储感兴趣的信息,每个屏幕的片段可以通过Activity简单地访问对象引用 .

  • 0

    1.使用片段的目的?

    • 答:

    • 处理设备形状因素差异 .

    • 在应用程序屏幕之间传递信息 .

    • 用户界面组织 .

    • 高级用户界面隐喻 .

  • 43

    片段存在于活动中 .

    虽然活动依然存在 .

  • 13

    片段表示活动中的行为或用户界面的一部分 . 您可以在单个活动中组合多个片段以构建多窗格UI,并在多个活动中重用片段 . 您可以将片段视为活动的模块化部分,它具有自己的生命周期,接收自己的输入事件,并且可以在活动运行时添加或删除 .

    • 您可以独立操作每个片段,例如添加或删除它们 . 执行此类片段事务时,还可以将其添加到由活动管理的后台堆栈中 - 活动中的每个后台堆栈条目都是发生的片段事务的记录 . 后向堆栈允许用户通过按“返回”按钮来反转片段事务(向后导航) .

    • 当您将片段添加为活动布局的一部分时,它将位于活动视图层次结构内的ViewGroup中,并且片段定义自己的视图布局 . 您可以通过将活动的布局文件中的片段声明为元素,或者通过将其添加到现有ViewGroup,从应用程序代码中将片段插入到活动布局中 . 但是,片段不需要是活动布局的一部分;您也可以使用没有自己的UI的片段作为活动的隐形工作者 .

    • For example: 如果您要使用NavigationDrawer如果没有片段,最好将NavigationDrawer实例保存在单个Activity中,当您通过选择NavigationDrawer中的项目导航应用程序时,启动的每个活动都不应实现NavigationDrawer,而应实现后退按钮导航回到实现NavigationDrawer的"Main" / single活动 .

    注意:如果您确实想要在多个活动中实现NavigationDrawer,则必须在每个要显示它的Activity中重新创建NavigationDrawer的新实例 .

    我想这对使用Fragments来说是一个缺点,而如果你使用了一个片段,你就不需要很多抽屉实例,你只需要一个 .

    带有碎片而不是活动的抽屉

    如果将NavigationDrawer与Fragments一起使用,则抽屉应在单个Activity中实现,并且当选择每个抽屉项时,它们的内容将显示在每个自己的片段中 .

    • Communicate between fragment to its Activity :要允许Fragment与其Activity通信,您可以在Fragment类中定义一个接口并在Activity中实现它.Fragment在其 onAttach() 生命周期方法中捕获接口实现,然后可以按顺序调用Interface方法与活动沟通 .
    public class YourFragment extends ListFragment {
    OnSelectedListener mCallback;
    
    // Container Activity must implement this interface
    public interface OnSelectedListener {
        public void onItemSelected(int position);
    }
    
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.your_view, container, false);
    }
    
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
    
        // This makes sure that the container activity has implemented
        // the callback interface. If not, it throws an exception
        try {
            mCallback = (OnSelectedListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                    + " must implement OnSelectedListener");
        }
    }
    
    }...
    

    现在,片段可以通过使用OnSelectedListener接口的mCallback实例调用onItemSelected()方法(或接口中的其他方法)来向活动传递消息 .

    public static class MainActivity extends Activity
            implements YourFragment.OnSelectedListener{
        ...
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main_activity);
        }
    
        public void onItemSelected(int position) {
            // The user selected the headline of an article from the YourFragment
            // Do something here to display that article
    
            YourFragment yourFrag = (YourFragment)
                    getSupportFragmentManager().findFragmentById(R.id.your_fragment);
    
            if (yourFrag != null) {
                // If your frag is available, we're in two-pane layout...
    
                // Call a method in the YourFragment to update its content
                yourFrag.updateView(position);
            } else {
                // Otherwise, we're in the one-pane layout and must swap frags...
    
                // Create fragment and give it an argument for the selected item
                YourFragment newFragment = new YourFragment();
                Bundle args = new Bundle();
                args.putInt(YourFragment.ARG_POSITION, position);
                newFragment.setArguments(args);
    
                FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
    
                // Replace whatever is in the fragment_container view with this fragment,
                // and add the transaction to the back stack so the user can navigate back
                transaction.replace(R.id.fragment_container, newFragment);
                transaction.addToBackStack(null);
    
                // Commit the transaction
                transaction.commit();
            }
        }
    }
    
  • 7

    我知道这已经讨论过死亡,但我想补充一点:

    • Frags可用于填充 Menu 并可自行处理 MenuItem 次点击 . 从而为您的活动提供更多调制选项 . 你可以在没有你的Activity知道的情况下做ContextualActionBar等等,并且基本上可以将它与你的Activity处理的基本内容(Navigation / Settings / About)分开 .

    • 带有子Frags的父Frag可以为您提供模块化组件的更多选项 . 例如 . 你可以轻松地交换Frags,将新的Frags放入寻呼机或删除它们,重新排列它们 . 所有没有你的活动知道任何关于它只是专注于更高级别的东西 .

相关问题