如何将变量从Activity传递给Fragment,并将其传回去?

时间:2013-07-02 21:42:13

标签: android android-fragments android-activity

我目前正在制作一个Android应用程序,我想在活动和片段之间传递一个日期。 我的活动有一个按钮,用于打开片段:DatePickerFragment。

在我的活动中,我显示了一个日期,我想用片段修改它。所以我想将日期传递给datepicker,然后将其发送回活动。

我尝试了很多解决方案,但都没有。简单的方法会传递一个参数,但这不能用碎片来完成。

8 个答案:

答案 0 :(得分:198)

要将信息传递给片段,请在创建时调整setArguments,然后可以在片段的onCreate或onCreateView方法上检索此参数。

在片段的newInstance函数中,添加要发送给它的参数:

/**
 * Create a new instance of DetailsFragment, initialized to
 * show the text at 'index'.
 */
public static DetailsFragment newInstance(int index) {
    DetailsFragment f = new DetailsFragment();
    // Supply index input as an argument.
    Bundle args = new Bundle();
    args.putInt("index", index);
    f.setArguments(args);
    return f;
}

然后在方法onCreateonCreateView的片段内,你可以检索这样的参数:

Bundle args = getArguments();
int index = args.getInt("index", 0);

如果您现在想要从您的片段与您的活动(发送或不发送数据)进行通信,您需要使用接口。你可以这样做的方式在片段之间的通信文档教程中得到了很好的解释。由于所有片段都通过活动在彼此之间进行通信,因此在本教程中,您可以看到如何将数据从实际片段发送到其活动容器,以便在活动上使用此数据或将其发送到您的活动包含的另一个片段。

文档教程:

http://developer.android.com/training/basics/fragments/communicating.html

答案 1 :(得分:83)

将数据从Activity发送到Fragment

<强>活动:

Bundle bundle = new Bundle();
String myMessage = "Stackoverflow is cool!";
bundle.putString("message", myMessage );
FragmentClass fragInfo = new FragmentClass();
fragInfo.setArguments(bundle);
transaction.replace(R.id.fragment_single, fragInfo);
transaction.commit();

<强>片段:

读取片段中的值

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    String myValue = this.getArguments().getString("message");
    ...
    ...
    ...
}

但是如果你想将值从Fragment发送到Activity,请阅读jpardogo的答案,你必须需要接口,更多信息:Communicating with other Fragments

答案 2 :(得分:7)

使用库EventBus传递可能来回包含变量的事件。这是一个很好的解决方案,因为它可以保持您的活动和片段松散耦合

https://github.com/greenrobot/EventBus

答案 3 :(得分:7)

感谢@ρяσsρєяK和Terry……对我有很大帮助,完美运行

从“活动”中,您发送数据的意图是:

Bundle bundle = new Bundle(); 
bundle.putString("edttext", "From Activity"); 
// set Fragmentclass Arguments
Fragmentclass fragobj = new Fragmentclass();
fragobj.setArguments(bundle);

以及在片段的onCreateView方法中:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    // get arguments
    String strtext = getArguments().getString("edttext");    
    return inflater.inflate(R.layout.fragment, container, false);
}

参考: Send data from activity to fragment in android

答案 4 :(得分:1)

对于所有Kotlin开发人员:

这是Android Studio建议的解决方案,将数据发送到您的片段(=,当您使用文件创建空白片段->新建->片段->片段(空白),然后选中“包括片段工厂方法”)。

将其放入片段中

class MyFragment: Fragment {

...

    companion object {

            @JvmStatic
            fun newInstance(isMyBoolean: Boolean) = MyFragment().apply {
                arguments = Bundle().apply {
                    putBoolean("REPLACE WITH A STRING CONSTANT", isMyBoolean)
                }
            }
     }
}

.apply是在创建对象或设置为they state here时设置数据的好技巧:

  

使用值为this的指定函数[block]作为接收者   并返回this值。

然后在“活动”或“片段”中执行以下操作:

val fragment = MyFragment.newInstance(false)
... // transaction stuff happening here

并读取片段中的参数,例如:

private var isMyBoolean = false

override fun onAttach(context: Context?) {
    super.onAttach(context)
    arguments?.getBoolean("REPLACE WITH A STRING CONSTANT")?.let {
        isMyBoolean = it
    }
}

要将数据“发送”回您的活动,只需在“活动”中定义一个函数,然后在“片段”中执行以下操作:

(activity as? YourActivityClass)?.callYourFunctionLikeThis(date) // your function will not be called if your Activity is null or is a different Class

享受科特林的魔力!

答案 5 :(得分:0)

您可以使用捆绑包简单地实例化您的片段:

Fragment fragment = Fragment.instantiate(this, RolesTeamsListFragment.class.getName(), bundle);

答案 6 :(得分:0)

将活动中的数据发送到XML链接的片段中

如果您使用以下模板之一在Android Studio中创建片段,例如文件>新建>片段>片段(列表),然后通过XML链接该片段。 newInstance方法是在片段中创建的,但从未调用过,因此不能用于传递参数。

相反,在Activity中重写onAttachFragment方法

@Override
public void onAttachFragment(Fragment fragment) {
    if (fragment instanceof DetailsFragment) {
        Bundle args = new Bundle();
        args.putInt("index", index);
        f.setArguments(args);        
     }
}

然后按照其他答案读取片段onCreate方法中的参数

答案 7 :(得分:-2)

类中的公共变量声明是最简单的方法:

针对目标班级:

public class MyFragment extends Fragment {
    public MyCallerFragment caller; // Declare the caller var
...
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
           Bundle savedInstanceState) {
        // Do what you want with the vars
        caller.str = "I changed your value!";
        caller.i = 9999;
        ...
        return inflater.inflate(R.layout.my_fragment, container, false);
    }
...
}

在呼叫方上:

public class MyCallerFragment extends Fragment {
    public Integer i; // Declared public var
    public String str; // Declared public var
        ...
            FragmentManager fragmentManager = getParentFragmentManager();
            FragmentTransaction transaction = fragmentManager.beginTransaction();

            myFragment = new MyFragment();
            myFragment.caller = this;
            transaction.replace(R.id.nav_host_fragment, myFragment)
                    .addToBackStack(null).commit();
        ...
}

如果您想使用主要活动,也很容易:

关于主要活动课程:

public class MainActivity extends AppCompatActivity {
    public String str; // Declare public var
    public EditText myEditText; // You can declare public elements too.
                                // Taking care that you have it assigned
                                // correctly.
...
}

在被叫课程上:

public class MyFragment extends Fragment {
    private MainActivity main; // Declare the activity var
...
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
           Bundle savedInstanceState) {
        // Assign the main activity var
        main = (MainActivity) getActivity();

        // Do what you want with the vars
        main.str = "I changed your value!";
        main.myEditText.setText("Wow I can modify the EditText too!");
        ...
        return inflater.inflate(R.layout.my_fragment, container, false);
    }
...
}

注意:使用事件(onClick,onChanged等)时要小心,因为 您可能处于“战斗”状态,其中不止一个分配了一个 变量。结果将是变量有时不会 更改或将神奇地返回到最后一个值。

更多组合可发挥您的创造力。 :)