【问题标题】:Fragment vs. Custom View in AndroidAndroid 中的 Fragment 与自定义视图
【发布时间】:2015-09-23 00:28:30
【问题描述】:

片段和自定义视图可以实现类似的功能,我知道片段比自定义视图更可重用,使用片段还有其他好处/增强吗?片段应该替换自定义视图,还是只是出于某些特定目的的增强?

比如下面的代码是fragment:

public class TestFragment extends Fragment {

    private TextView tv_name;
    private Button btn_play;
    private Button btn_delete;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.testfragment, container, false);
    }

    @Override
    public void onStart() {
        super.onStart();

        tv_name = (TextView)getView().findViewById(R.id.tv_name);
        btn_play = (Button)getView().findViewById(R.id.btn_play);
        btn_delete = (Button)getView().findViewById(R.id.btn_delete);

    }
}

自定义视图的代码:

public class TestCustomView extends LinearLayout {

    private TextView tv_name;
    private Button btn_play;
    private Button btn_delete;

    public TestCustomView(Context context, AttributeSet attrs){
        super(context, attrs);

        setOrientation(LinearLayout.HORIZONTAL);
        setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));

        tv_name = new TextView(context);
        addView(tv_name);

        btn_play = new Button(context);
        addView(btn_play);

        btn_delete = new Button(context);
        addView(btn_delete);
    }

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.testfragment, container, false);
    }
}

TestFragment和TestCustomView都可以创建一个由TextView和Buttons组成的视图,并使用Framelayout/fragment和com.packagename.TestCustomView的标签在activity的xml布局文件中声明,但是有什么好处呢?使用片段?

【问题讨论】:

  • 我发现片段在您需要访问视图没有的东西时很有用,例如有关 Fragment 生命周期的信息,或类似“LoaderManager”的信息。

标签: android fragment android-custom-view


【解决方案1】:

片段可以用于不同的场景,但最常用的是:

  • 围绕视图包装
  • 无头片段 - 即没有视图 => 通常不是很有帮助,但可以使用
  • 可保留片段 - 可以是上述任何一种。通过使用Fragment.setRetainInstance(true),您可以绕过Fragment.onDestroy(),即可以在配置更改时保留片段数据,但片段视图结构仍会被破坏/重新创建
  • 可以添加到activity返回栈,即简单的返回按钮之前的状态恢复

有片段是颈部完全疼痛的情况,那么也有可以更快见效的情况。

对于一些自定义和更灵活的情况,片段可能会变得杂乱无章,管理起来会很困难。因此,在某些情况下,直接处理视图非常方便且更有帮助。但一切都以需求为基础。

注意 View 也有自己的生命周期,可以存储/重新创建已保存的实例状态。更多的工作,但它也有选择。

【讨论】:

  • 感谢您的回答。很高兴看到一些具体的例子来展示使用片段而不是视图的优缺点,反之亦然,以帮助更好地理解哪种方法更合适。目前,在我看来,片段是要走的路,但一些例子可能有助于理解这种方法可能存在的缺点。
【解决方案2】:

自定义视图具有简单的优点,其主要目的是在屏幕上显示一段数据。他们必须依赖其他组件才能做得更多。

将片段视为一个功能单元,一种使用一个或多个视图来显示具有特定目的的部分 UI 的方式。 Fragment 连接到 Activity 生命周期,它们可以包含和控制 Loaders 以使用数据填充 View。它们还可以包括子片段。最后,它们也可以添加到合成后堆栈中。他们可以做很多事情,但学习起来有些复杂。

如您所见,与自定义视图相比,片段与活动的共同点要多得多。

附带说明,片段也可以是无头的(没有 UI)。无头片段提供了一种将依赖于 Activity 生命周期的非可视功能封装在单独组件中的方法。

【讨论】:

  • 都是正确的,但这并不能解释使用片段比自定义视图有什么优势
  • 在问题中给出的示例中没有任何优势,因为它只是显示布局中的一些静态数据。在现实世界的示例中,当您需要构建依赖于用户交互的复杂界面、加载数据、在应用程序中创建部分等时,您需要同时使用这两者。我的回答的重点是你不能在同一水平上比较它们,因为它们有不同的目的。
【解决方案3】:

片段有自己的生命周期,这可能是障碍或奖励,具体取决于您的需要。

Fragment 获得诸如 onResume 或 onSavedInstanceState 之类的生命周期方法,它们可以帮助您处理应用程序中的状态转换。如果您使用自定义视图,则需要自己处理此类事情。

有人反对使用碎片,建议阅读https://developer.squareup.com/blog/advocating-against-android-fragments/

【讨论】:

    【解决方案4】:

    使用Fragments而不是Custom Views最有用的功能是它们有自己的生命周期回调,即我们可以注册自己的FragmentLifecycleCallbacks在Fragment创建/销毁之前/之后做一些操作。

    我们可以创建自己的FragmentLifecycleCallbacks 并将其注册到Activity 以在Fragment 到Dagger 中注入依赖项。 也有一些解决方法可以在 Custom Views 中注入依赖项,但是通过 FragmentLifecycleCallbacks 执行此操作更清洁且更容易执行。

    【讨论】:

      猜你喜欢
      • 2015-09-02
      • 1970-01-01
      • 2013-01-25
      • 2013-11-29
      • 2016-04-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多