简体   繁体   English

将对象作为参数传递给片段的最佳方式

[英]Best way to pass objects to fragments as parameter

I need to pass objects to my fragments in order to initialize them.我需要将对象传递给我的片段以初始化它们。 Currently I am doing this with ((MyActivity)getActivity()).getX() .目前我正在用((MyActivity)getActivity()).getX()做这个。 (direct access to the activity) (直接进入活动)

However, I would like to pass the required objects as parameter.但是,我想将所需的对象作为参数传递。

I definitely do not want to add parcelable objects to the bundle, since they require an excessive amount of useless boilerplate code.我绝对不想将 Parcelable 对象添加到包中,因为它们需要大量无用的样板代码。 My goal is to reduce complexity, not increasing it.我的目标是降低复杂性,而不是增加它。

And I do not want to add serializable objects to the bundle, since they are slow and cause an unnecessary overhead.而且我不想将可序列化的对象添加到包中,因为它们很慢并且会导致不必要的开销。

What is the best way to pass objects to fragments?将对象传递给片段的最佳方法是什么? Any ideas to solve the problem in a more convenient way?任何想法以更方便的方式解决问题?

I definitely do not want to add parcelable objects to the bundle, since they require an excessive amount of useless boilerplate code.我绝对不想将 Parcelable 对象添加到包中,因为它们需要大量无用的样板代码。 My goal is to reduce complexity, not increasing it.我的目标是降低复杂性,而不是增加它。

You write this code in your model classes which is separated from your activities and fragments.您在与活动和片段分开的模型类中编写此代码。 There is no complexity in implementing Parcelable .实现Parcelable并不复杂。 And it is a common way to pass objects to a Fragment .这是将对象传递给Fragment的常用方法。

Any other solutions?还有其他解决方案吗? Well, you still can do this ((MyActivity)getActivity()).getX() as long as your fragment is attached to your activity.好吧,只要您的片段附加到您的活动,您仍然可以执行此操作((MyActivity)getActivity()).getX() In this case it is even faster than Parcelable because there is no serialization at all.在这种情况下,它甚至比Parcelable更快,因为根本没有序列化。

Other ways would be to write objects to database, pass their ids to a Fragment and then use a query to retrieve objects.其他方法是将对象写入数据库,将它们的 id 传递给Fragment ,然后使用查询来检索对象。

You can also use SharedPreferences , but that's rarely used.您也可以使用SharedPreferences ,但很少使用。 For this you will need to convert your object to String .为此,您需要将对象转换为String

You can do the Android way: Parcelable.您可以使用 Android 方式:Parcelable。

You can serialize then.然后就可以序列化了。

You can do the poor way : static你可以做的不好:静态

You can do the retained way: Create a Fragment with setRetainInstance(true) and save your objects references.您可以采用保留方式:使用 setRetainInstance(true) 创建一个 Fragment 并保存您的对象引用。

I understand you don't want to use parcelable / serializable objects to a Bundle.我知道您不想将可打包/可序列化的对象用于 Bundle。 I also agree with you since I got lazy, and my phone app is getting complicated.我也同意你的看法,因为我懒惰了,我的手机应用程序变得越来越复杂。

Here's what you can do, and it works reliably.这是您可以执行的操作,并且它运行可靠。

  • Make a public method in your Fragment class, sample below.在您的 Fragment 类中创建一个公共方法,示例如下。
  • Have the Activity, preferably no other place, call that public method.有Activity,最好没有别的地方,调用那个公共方法。 Remember Activity is always present, Fragments and Adapters may not due to its lifecycle.记住 Activity 总是存在的,Fragment 和 Adapters 可能不是因为它的生命周期。
  • The timing of the call is crucial if you're not using Bundles.如果您不使用 Bundle,则通话时间至关重要。 I have used it without any problems.我已经使用它没有任何问题。
  • The advantage of this technique is that it is fast, especially compared to Bundles.这种技术的优点是速度快,尤其是与 Bundles 相比。 Many developers do not consider this however.然而,许多开发人员并不考虑这一点。
  • Note : If you are using simple fundamental Java types, do use Bundles!注意:如果您使用简单的基本 Java 类型,请使用 Bundles! As suggested by Google.正如谷歌建议的那样。

Sample code:示例代码:

public class MyFragment extends Fragment {
...
   public void setList(final ArrayList<String> arrayList) {
   ...
   }

In the Activity:在活动中:

MyFragment fragment1 = MyFragment.newInstance(<parameters>);
fragment1.setList( arrayList );

Do you need to change the properties once they have been set on the fragment?一旦在片段上设置了属性,您是否需要更改属性? If not, you can use setArguments(Bundle).如果没有,您可以使用 setArguments(Bundle)。 If it is a fairly light object you can even skip implementing Parcelable and just set each property individually.如果它是一个相当轻的对象,您甚至可以跳过实现 Parcelable 并单独设置每个属性。 The advantage is that the arguments are preserved upon orientation change.优点是在方向改变时保留参数。 The disadvantage is that you need to call this method before attaching your fragment, hence it is not very useful once the fragment is in use.缺点是您需要在附加片段之前调用此方法,因此一旦片段被使用,它就不是很有用。

It's way too late for my answer, but if someone else is wondering.我的答案为时已晚,但如果其他人想知道。 The recommended way is to use Parcelable or Serializable, but you can always do something like this:推荐的方法是使用 Parcelable 或 Serializable,但你总是可以这样做:

public class ObjectManager {

    private static final String TAG = "ObjectManager";

    private static ObjectManager instance;

    private Object currentObject;

    public static ObjectManager getInstance() {
        if (instance == null)
            instance = new ObjectManager();
        return instance;
    }

    public Object getCurrentObject() {
        return currentObject;
    }

    public void setCurrentObject(Object object) {
        this.currentObject = object;
    }
}

And then use it: where you needed as long as your app is running然后使用它:只要您的应用程序正在运行,您就可以在需要的地方使用它

//Use on the object you would like to save
ObjectManager.getInstance().setCurrentObject(object);

//Get the instance from pretty much everywhere 
Object = ObjectManager.getInstance().getCurrentObject();

You can use it always, but it will be most likely to be useful, if you pass objects bigger than the Bundle max size.您可以始终使用它,但如果您传递大于 Bundle 最大大小的对象,它最有可能很有用。

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

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