java 理解 Fragment.newInstance 方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36113134/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 00:58:13  来源:igfitidea点击:

Understanding the Fragment.newInstance method

javaandroidfragment

提问by Dabbler

I'm implementing an Android fragment. I understand that the framework can automatically destroy and recreate the fragment, and that recreating a fragment calls its default constructor, as opposed to a constructor that has arguments. There are many posts (such as the accepted answer to this question) that show how to provide arguments to the fragment by implementing a static newInstancemethod.

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

What I don't understand is who calls newInstance. My first impression was that - since one can define arbitrary arguments for this newInstancemethod - I should add an explicit call to it somewhere in the app, and that the name newInstanceis just a naming convention. But then I would be creating a second fragment in addition to the one created by framework calling the default constructor, which confuses me.

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

So is the above assumption incorrect, and the newInstancemethod is really somehow an overload of Java's built-in method for instantiating a class? In that case, I don't see how I can define a newinstancemethod that takes an arbitrary argument list. Or is that possible in Java, and I just don't know Java well enough?

那么上面的假设是否不正确,并且该newInstance方法实际上是Java 用于实例化类的内置方法的重载?在那种情况下,我看不到如何定义newinstance采用任意参数列表的方法。或者这在 Java 中是可能的,而我只是不太了解 Java?

回答by Arkadiusz Konior

You can name the function however you like: newInstance, getInstance, newFragment. It doesn't matter, it is only a helper method. Important is that you put all your arguments with fragment.setArguments(args). Android system will remember those arguments and will use them when fragment will be recreated.

您可以随意命名函数:newInstance, getInstance, newFragment。没关系,它只是一个辅助方法。重要的是,您将所有参数都放在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;
}

回答by royB

newInstanceis an Android design pattern because of the fact that FragmentShould not have any other Constructorbeside the default Constructor

newInstance是一种 Android 设计模式,因为除了默认之外Fragment不应有任何其他设计模式ConstructorConstructor

Thus you define an Helper function in order to pass Arguments to the Fragment

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

You don't have to use it but Let's say you have 2 Activitiesthat both starts FragmentA

您不必使用它,但假设您有 2 个Activities同时启动FragmentA

If you will not Use the helper function You will need to duplicate the code to instantiate the Fragment.

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

What I don't understand is who calls newInstance

我不明白是谁在调用 newInstance

Usually you will use the instantiatemethod from places that creates Fragments...Activity, Adapterand such.

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

SectionPagerAdapterexample:

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

Where PlaceholderFragment.newInstance(int position)is

哪里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;
    }

In that case, I don't see how I can define a newinstance method that takes an arbitrary argument list.

在那种情况下,我不知道如何定义一个接受任意参数列表的新实例方法。

You can pass arbitrary argument list but you need to know the value Typebecause Bundlehas only putX()methods, where X is the type of the parameter

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

回答by HenryHaoson

Fragment.newInstance(args1,args2...)is used as static construction method. The benefits of static construction method is Needless to say. But in Fragment, doing this can help us to save arguments, and we can get these arguments in onCreate()Method for when accidentally your app boom,and Android help you to restore your fragment with Constructor without arguments.

Fragment.newInstance(args1,args2...)用作静态构造方法。静态构造方法的好处是不用多说的。但是在 Fragment 中,这样做可以帮助我们保存参数,并且我们可以在onCreate()Method 中获取这些参数,以便在您的应用程序不小心繁荣时,Android 帮助您使用没有参数的构造函数来恢复您的片段。

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

Remember to use Parcelableinstead of Serializable.

记得使用Parcelable而不是Serializable.