简体   繁体   English

了解Fragment.newInstance方法

[英]Understanding the Fragment.newInstance method

I'm implementing an Android fragment. 我正在实现一个Android片段。 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 newInstance method. 有很多帖子(例如这个问题的接受答案)显示了如何通过实现静态newInstance方法为片段提供参数。

What I don't understand is who calls newInstance . 我不明白的是newInstance My first impression was that - since one can define arbitrary arguments for this newInstance method - I should add an explicit call to it somewhere in the app, and that the name newInstance is just a naming convention. 我的第一印象是 - 因为可以为这个newInstance方法定义任意参数 - 我应该在应用程序的某处添加一个显式调用,并且名称newInstance只是一个命名约定。 But then I would be creating a second fragment in addition to the one created by framework calling the default constructor, which confuses me. 但是,除了框架调用默认构造函数创建的第二个片段之外,我将创建第二个片段,这让我很困惑。

So is the above assumption incorrect, and the newInstance method is really somehow an overload of Java's built-in method for instantiating a class? 那么上面的假设是不正确的,而newInstance方法实际上是Java内置方法实例化一个类的重载? In that case, I don't see how I can define a newinstance method that takes an arbitrary argument list. 在这种情况下,我看不出如何定义采用任意参数列表的newinstance方法。 Or is that possible in Java, and I just don't know Java well enough? 或者这可能在Java中,我只是不太了解Java?

You can name the function however you like: newInstance , getInstance , newFragment . 您可以根据需要为函数命名: newInstancegetInstancenewFragment It doesn't matter, it is only a helper method. 没关系,它只是一种辅助方法。 Important is that you put all your arguments with fragment.setArguments(args) . 重要的是你将所有参数都放在fragment.setArguments(args) Android system will remember those arguments and will use them when fragment will be recreated. Android系统会记住这些参数,并在重新创建片段时使用它们。

public static MyFragment newInstance(int arg) {

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

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

newInstance is an Android design pattern because of the fact that Fragment Should not have any other Constructor beside the default Constructor newInstance是一个Android设计模式,因为Fragment不应该在默认的Constructor Constructor旁边有任何其他的Constructor Constructor

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 Activities that 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. 如果您不使用辅助函数您将需要复制代码以实例化片段。

What I don't understand is who calls newInstance 我不明白的是谁叫newInstance

Usually you will use the instantiate method from places that creates Fragments ... Activity , Adapter and such. 通常,您将在创建Fragments ... ActivityAdapter等的地方使用instantiate方法。

SectionPagerAdapter example: 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. 在这种情况下,我看不出如何定义采用任意参数列表的newinstance方法。

You can pass arbitrary argument list but you need to know the value Type because Bundle has only putX() methods, where X is the type of the parameter 您可以传递任意参数列表,但您需要知道值Type因为Bundle只有putX()方法,其中X是参数的类型

Fragment.newInstance(args1,args2...) is used as static construction method. Fragment.newInstance(args1,args2...)用作静态构造方法。 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中,这样做可以帮助我们保存参数,并且我们可以在onCreate()方法中获取这些参数,以便在您的应用程序出现意外时,Android会帮助您使用Constructor无需参数来恢复您的片段。

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 Parcelable instead of Serializable . 请记住使用Parcelable而不是Serializable

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM