如何将变量从Activity传递到Fragment,然后传递回去?


135

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

在我的活动中,我显示一个日期,我想用该片段进行修改。所以我想将日期传递给日期选择器,然后将其发送回活动。

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


我的问题和你的完全一样。我想知道为什么这些示例仅将片段本身视为日期选择器的“用户”,而不是启动它们的活动。
克劳迪欧(Claudio)

Answers:


213

要将信息传递给片段,请在创建片段时设置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;
}

然后在该方法的片段内,onCreate或者onCreateView您可以像这样检索参数:

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

如果现在要通过片段与活动(发送或不发送数据)进行通信,则需要使用接口。片段之间的通信文档教程中很好地说明了您可以执行此操作的方法。因为所有片段都通过活动相互通信,所以在本教程中,您可以看到如何将数据从实际片段发送到其活动容器,以在活动上使用此数据或将其发送到活动包含的另一个片段。

文档教程:

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


10
我认为人们一次又一次地问这个问题的意思是,在文档中并没有很好地解释它。
Michael Alan Huff 2014年

1
我仍然对哪种方法是最佳使用方法,您的方法还是@@ Elenasys回答的方法感到困惑
Yoann Hercouet

有一种使用架构组件(I / O '17)在片段之间共享数据的新方法:developer.android.com/topic/libraries/architecture/…–
jpardogo

在XML布局内创建的那些片段怎么样?
ralphgabb

我不想再使用静态方法。
Ahamadullah Saikat

89

传送资料ActivityFragment

活动:

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的答案,则必须使用接口,以及更多信息:与其他Fragments进行通信


2
如何传递自定义对象?我曾经用过,Parcelable但这给了我class cast exception
毒蛇

此解决方案对我不起作用,找不到从何处导入交易
thebeancounter

好吧,如果您将Fragment加载到Activity中,则可以通过事务中定义的bundle发送值。请说明您的情况是什么?
Jorgesys

8

感谢@ρяσsρєяK和Terry ...这对我有很大帮助,并且效果很好

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

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

并在Fragment 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);
}

参考: 将数据从活动发送到android中的片段


7

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

https://github.com/greenrobot/EventBus


4
我不能说这不是一个很好的解决方案,但请注意。尽管EventBus非常易于使用,但它也存在危险。如果您开始添加过多的信号,那么松散耦合的本质将使跟踪谁正在呼叫谁以及发生不同事件的位置变得非常困难。
约翰·保罗

2

对于所有Kotlin开发人员:

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

将其放在您的片段中:

class MyFragment: Fragment {

...

    companion object {

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

.apply创建对象时或在此处说明时,设置数据是一个很好的技巧:

thisvalue作为接收者调用指定的函数[block] 并返回thisvalue。

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

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,只需在Activity中定义一个函数,然后在Fragment中执行以下操作:

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

享受科特林的魔力!


1

将活动中的数据发送到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方法中的参数


0

您可以使用bundle实例化片段:

Fragment fragment = Fragment.instantiate(this, RolesTeamsListFragment.class.getName(), bundle);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.