如何传递一个变量从活动到片段,并传递回来?

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

在我的活动中,我显示了一个日期,我想用片段来修改它。因此,我想将日期传递给数据采集器,并将其发送回活动。

我试过很多方法,但都不管用。简单的方法是传递一个参数,但这不能用片段来完成。

176142 次浏览

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

Https://github.com/greenrobot/eventbus

要将信息传递给片段 ,需要在创建它时设置 Arguments,稍后可以在片段的 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

将数据从 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");
...
...
...
}

但是如果您想要将值从片段发送到 Activity,阅读 jpardogo 的答案,您必须需要接口,更多信息: 与其他碎片通信

您可以简单地用一个 bundle 实例化您的片段:

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

感谢@ρ σ ρ 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);
}

参考文献: 在机器人中将数据从活动发送到片段

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

如果您使用其中一个模板在 Android Studio 中创建一个片段,例如 File > New > Fragment > Fragment (List) ,那么该片段将通过 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 方法中的参数

对于所有 Kotlin 开发商而言:

下面是 Android Studio 提出的解决方案 发送数据到你的碎片(= 当您使用文件-> 新建-> 片段-> 片段(Blank)创建一个空白片段,并检查“包含片段工厂方法”)。

把这个放进你的碎片里:

class MyFragment: Fragment {


...


companion object {


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

在创建对象或者将对象设置为 他们在这里陈述时,.apply是一个很好的设置数据的技巧:

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

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

享受 Kotlin 的魔力吧!

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

目标类别:

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 等)时要小心,因为 你可能处于一种“战斗”的情况,在这种情况下,不止一个人分配了一个 变量。结果将是变量有时不会 更改或将神奇地返回到最后一个值。

更多的组合使用你的创造力。 :)

在2021年回答现在一个天片段已经内置了静态方法,用于 在创建片段时传递参数尝试将来的编码器

当您创建一个片段时,它具有以下已定义的静态方法

 public static categoryfrag newInstance(String param1, String param2) {
categoryfrag fragment = new categoryfrag();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}

片段中的 onCreate 方法通过已定义的代码接收参数

   public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
//  rr=getArguments().getInt("ky");
sn1=mParam1;
sn2=mParam2;
}
}

如果您希望其他数据类型修改这些内置代码行或使用 bundle,那么下面的代码可以用于活动,其中 most pop 是片段类的名称

Fragment mp=mostpop.newInstance("parameter1","parameter2");