【问题标题】:Pass object data between fragments and activity in android在android中的片段和活动之间传递对象数据
【发布时间】:2016-02-11 06:11:19
【问题描述】:

我想在活动和片段之间以及片段和片段之间传递一个复杂的对象。目前,主要活动创建一个片段输入对象并将其设置为需要打开的片段的成员。同样,当另一个片段想要加载另一个片段时,它会创建片段输入并通知主要活动。请参阅下面的主要和子片段代码。我的问题,这是正确的实现。如果活动暂停并重新启动,有时我在子活动中遇到输入为空。

请告诉我我做错了什么,传递数据的最佳方式是什么。

 public class FragmentInput {

    public String url = "";
    public String title = "";
    public String time = "";
     ... other memebers
}

主要活动

fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
                            .beginTransaction();
 BaseFragment fragment = new LandingFragment();
 **FragmentInput input = new FragmentInput();
 input.stringinput = stringinput;
 fragment.input = input;
 fragmentTransaction.replace(R.id.fragment, fragment);
 fragmentTransaction.commit();**



    public void replaceFragment(BaseFragment fragment) {

            if (fragment == null)
                return;

            if (fragment instanceof firstFragment) {
                FragmentTransaction fragmentTransaction = fragmentManager
                        .beginTransaction();
                fragmentTransaction.setCustomAnimations(0, 0);

                fragmentManager.popBackStackImmediate(null,
                        FragmentManager.POP_BACK_STACK_INCLUSIVE);

                fragmentTransaction.addToBackStack(null);
                fragmentTransaction.commit();

            } else {

                String ttag = fragment
                        .getClass().toString();

                Fragment tempF = fragmentManager.findFragmentByTag(ttag);
                if (tempF != null)
                    return;
                FragmentTransaction fragmentTransaction = fragmentManager
                        .beginTransaction();
                fragmentTransaction.setCustomAnimations(R.anim.fragment_enter,
                        R.anim.fragment_exit, R.anim.fragment_leftenter,
                        R.anim.fragment_leftexit);

                fragmentTransaction.replace(R.id.fragment, fragment, ttag);
                fragmentTransaction.addToBackStack(null);
                fragmentTransaction.commit();
            }


        }

子片段

@Override
    public void onActivityCreated(Bundle bundle) {
        super.onActivityCreated(bundle);
        try {
            activity = getActivity();
            resource = activity.getResources();
            view = getView();

            **if (input != null) {
                String url= input.url;**

       button.onclick(){
            FragmentInput input = new FragmentInput();
            input.url = path;
            input.title = resource.getString(R.string.txt_from_gallery);

            **BaseFragment fr = new otherFragment();
            FragmentChangeListener fc = (FragmentChangeListener)     getActivity();
            fr.setInput(input);
            fc.replaceFragment(fr);**
}
}

【问题讨论】:

  • 什么时候传递值?
  • fragment.input = 输入;我设置了值并从其他片段中读取它,ChildFragment onclick 显示了我如何设置值并通知调用 replacefragment 方法来更改片段的主要活动

标签: android android-fragments


【解决方案1】:

如果您的片段附加到同一个活动,您可以将您的对象存储在活动中并访问如下对象:

((YourActivity)getActivity()).getYourObjects();

如果您将对象打包存储在您的活动中,我建议调用我上面在片段的 onActivityCreated() 方法中提供的代码示例,以避免空指针异常。

如果您想在捆绑的活动或片段之间传递您的对象。您应该为您的对象实现 Parcelable 并传递它们。

什么是 Parcelable? http://developer.android.com/reference/android/os/Parcelable.html

Parcelable 更高效,但您可以检查 Serializable: http://developer.android.com/reference/java/io/Serializable.html

捆绑传递大型对象不是一个好的设计。

您也可以使用接口传递对象,也可以使用总线事件传递它们。您可以检查 Guava 或 OttoBus。 http://square.github.io/otto/

【讨论】:

  • 感谢您的回复。我有一个活动,其中多个片段根据用户事件发生变化。使用第一种方法,您是说活动应该存储片段的输入对象。当片段进出后台堆栈时,我如何管理它们。但主要问题是,如果应用程序处于非活动状态(用户接到电话)并返回应用程序,该商店能否存活下来。我觉得 Parcelable 是这样,但我的输入有 19 个成员,字符串、int 和 long。
  • 如果您的活动不破坏您的片段可以访问您存储在活动中的对象。如果您从后台获取您的片段,只需检查您的活动中的对象是否为空。如果它们不为空,则初始化您的片段数据。但是当你的活动被破坏时会发生什么?如果您的数据很重要,您可以将其保存在 SaveInstanceSatete 并在 RestoreInstancestate 上恢复它。正如我上面所说,在这种情况下,从片段的 onActivityCreated 方法中的片段访问恢复的活动数据至关重要。
【解决方案2】:

在这种情况下,您可以使用静态 holder(它有点类似于单例模式)。

创建一个新类

public class Holder
{
    private static FragmentInput input = null;

    public static void setInput(FragmentInput value) { this.input = value; }
    public static FragmentInput getInput() { return input; }
}

在您的主要活动中,在您创建新的 FragmentInput 对象之后 把它放在支架上

Holder.setInput(input);

而且你可以在任何地方访问它,只需调用

FragmentInput myInput = Holder.getInput();

【讨论】:

  • 感谢您的回复。我不能使用静态变量,因为该应用程序有一个活动,并且该活动有许多基于用户事件的片段更改。他们也去后面的堆栈。
猜你喜欢
  • 1970-01-01
  • 2013-06-21
  • 1970-01-01
  • 2014-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多