【问题标题】:Understanding the Fragment.newInstance method了解 Fragment.newInstance 方法
【发布时间】:2016-07-06 21:43:11
【问题描述】:

我正在实现一个 Android 片段。我知道框架可以自动销毁和重新创建片段,并且重新创建片段会调用其默认构造函数,而不是具有参数的构造函数。 有许多帖子(例如对this question 的接受答案)展示了如何通过实现静态newInstance 方法为片段提供参数。

我不明白是谁打电话给newInstance。我的第一印象是 - 因为可以为这个 newInstance 方法定义任意参数 - 我应该在应用程序的某个地方添加一个显式调用,并且名称 newInstance 只是一个命名约定。但是,除了由框架调用默认构造函数创建的片段之外,我还要创建第二个片段,这让我感到困惑。

那么上面的假设是不是不正确,newInstance 方法在某种程度上真的是 Java 用于实例化类的内置方法的重载?在这种情况下,我看不出如何定义一个采用任意参数列表的newinstance 方法。或者这在 Java 中是否可行,而我只是对 Java 不太了解?

【问题讨论】:

  • 是的,您需要在代码中调用newInstance(),如果需要重新创建,框架将使用空构造函数。
  • P.S:有没有任何情况下您使用了 Fragment 而没有实例化它?即不使用...= new ... ?
  • 实际上,是的 - 它没有使用新的。在活动布局的 XML 中,我有一个 元素,据我所知,这就是片段的实例化方式。我在任何地方都没有明确的电话。无论如何,不​​确定它是如何工作的。
  • 正确,此案例框架将使用空构造函数,没有参数,如果您直接使用new 或使用newInstance(),则需要空构造函数来重新创建片段(如果它被销毁了),newInstance 不是一个被覆盖的方法,你可以随意命名它。

标签: java android fragment


【解决方案1】:

您可以随意命名函数:newInstancegetInstancenewFragment。没关系,它只是一个辅助方法。重要的是你把你所有的论点都放在fragment.setArguments(args) 上。 Android 系统会记住这些参数,并在片段重新创建时使用它们。

public static MyFragment newInstance(int arg) {

    Bundle args = new Bundle();
    args.putInt("ARG", arg);

    MyFragment fragment = new MyFragment();
    fragment.setArguments(args);
    return fragment;
}

【讨论】:

  • "Android 系统会记住这些参数,并在片段重新创建时使用它们。"也许这是我缺少的信息。所以首先我通过 newInstance 创建片段。而当 Android 随后重新创建 Fragment 时,它首先调用默认构造函数,然后使用它存储的参数调用 setArguments?
  • 如上所述,在活动布局的 XML 中,我有一个 元素,据我所知,这就是片段的实例化方式。那么它是如何工作的呢?也许我一开始就没有正确创建活动。
  • 第一个问题:是的。检查片段 setArguments javadoc:“此处提供的参数将在片段销毁和创建中保留”关于 xml 片段创建检查:stackoverflow.com/questions/13034746/… 创建片段有两种方法:通过代码(然后调用 newInstance())和使用 XML 标记. XML 标记片段由系统使用默认构造函数自动创建。因此,在这种情况下,您需要以不同的方式传递参数。在这种情况下永远不会调用 newInstance 方法。
  • 谢谢,Arkadiusz!
【解决方案2】:

newInstance 是 Android 设计模式,因为 Fragment 不应该有任何其他 Constructor beside the default Constructor

因此,您定义了一个 Helper 函数,以便将参数传递给 Fragment

您不必使用它,但假设您有 2 个Activities,它们都以FragmentA 开头

如果不使用辅助函数,则需要复制代码来实例化 Fragment。

我不明白是谁调用了newInstance

通常你会从创建Fragments...ActivityAdapter等的地方使用instantiate方法。

SectionPagerAdapter 示例:

    @Override
    public Fragment getItem(int position) {
        // getItem is called to instantiate the fragment for the given page.
        // Return a PlaceholderFragment (defined as a static inner class below).
        return PlaceholderFragment.newInstance(position + 1);
    }

PlaceholderFragment.newInstance(int position) 在哪里

public static PlaceholderFragment newInstance(int sectionNumber) {
        PlaceholderFragment fragment = new PlaceholderFragment();
        Bundle args = new Bundle();
        args.putInt(ARG_SECTION_NUMBER, sectionNumber);
        fragment.setArguments(args);
        return fragment;
    }

在这种情况下,我看不出如何定义一个采用任意参数列表的 newinstance 方法。

您可以传递任意参数列表,但您需要知道 Type 的值,因为 Bundle 只有 putX() 方法,其中 X 是参数的类型

【讨论】:

    【解决方案3】:

    Fragment.newInstance(args1,args2...)用作静态构造方法。 静态构造方法的好处是不用多说的。但是在 Fragment 中,这样做可以帮助我们保存参数,并且我们可以在 onCreate() 方法中获取这些参数,以便在您的应用程序意外繁荣时使用,Android 可以帮助您使用 Constructor 恢复您的 Fragment 而无需参数。

    public static StudyFragment newInstance(ArrayList<DailyWordBean.DataBean> list) {
        Bundle args = new Bundle();
        args.putSerializable("data", list);
        StudyFragment fragment = new StudyFragment();
        fragment.setArguments(args);
        return fragment;
    }
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            list = (ArrayList<DailyWordBean.DataBean>) getArguments().getSerializable("data");
            Log.e("study", list.size() + list.get(0).getWordContent());
        }
    }
    

    记得使用Parcelable 而不是Serializable

    【讨论】:

      猜你喜欢
      • 2014-07-20
      • 2015-08-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-01
      • 2014-09-13
      相关资源
      最近更新 更多