我正在开发一个Android应用程序,我想在活动和片段之间传递日期。 我的活动有一个按钮,可以打开片段: DatePickerFragment。
在我的活动中,我展示了一个日期,我想要用片段修改它。所以我想传递日期给日期选择器,并将其发送回活动。
我尝试了很多解决方案,但没有一个能够工作。最简单的方法是传递参数,但这在片段中无法实现。
我正在开发一个Android应用程序,我想在活动和片段之间传递日期。 我的活动有一个按钮,可以打开片段: DatePickerFragment。
在我的活动中,我展示了一个日期,我想要用片段修改它。所以我想传递日期给日期选择器,并将其发送回活动。
我尝试了很多解决方案,但没有一个能够工作。最简单的方法是传递参数,但这在片段中无法实现。
传递信息到一个片段,您在创建片段时设置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);
如果你希望从你的片段与你的活动进行交流(发送或不发送数据),你需要使用接口。在通讯片段的文档教程中详细说明了如何做到这一点。由于所有片段都通过活动进行通信,在这个教程中,你可以看到如何将数据从实际片段发送到其活动容器,以便在活动中使用此数据或将其发送到你的活动包含的另一个片段。Activity
发送数据到Fragment
Activity:
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的答案,你必须需要使用接口,更多信息:与其他片段进行通信
Parcelable
,但是导致了 class cast exception
异常。 - viper感谢@ρяσѕρєя K和Terry...他们帮了我很多,并且完美地发挥作用
从Activity中,您可以通过意图将数据发送如下:
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);
}
对于所有的 Kotlin 开发者:
这里是 Android Studio 建议的解决方案将数据发送到您的 Fragment(= 当您使用文件 -> 新建 -> Fragment -> Fragment(Blank),并勾选“包含片段工厂方法”时创建一个空白片段)。
将以下代码放入您的 Fragment 中:
class MyFragment: Fragment {
...
companion object {
@JvmStatic
fun newInstance(isMyBoolean: Boolean) = MyFragment().apply {
arguments = Bundle().apply {
putBoolean("REPLACE WITH A STRING CONSTANT", isMyBoolean)
}
}
}
}
.apply
方法是在创建对象时设置数据的一种不错的技巧,或者如他们在此处所述的那样:
使用当前对象作为接收器调用指定的函数[block],并返回当前对象。
然后在您的Activity或Fragment中执行:
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
享受 Kotlin 带来的魔力吧!
将数据从 Activity 发送到与 XML 相关联的 Fragment
如果您使用 Android Studio 中的模板之一创建 Fragment,例如文件> 新建> Fragment> Fragment(列表),则该 Fragment 通过 XML 进行链接。 newInstance 方法在 Fragment 中创建但从未调用过,因此不能用于传递参数。
相反,在 Activity 中重写 onAttachFragment 方法。
@Override
public void onAttachFragment(Fragment fragment) {
if (fragment instanceof DetailsFragment) {
Bundle args = new Bundle();
args.putInt("index", index);
f.setArguments(args);
}
}
现在,回答2021年的问题,Fragment内置了一些静态方法,用于在创建Fragment时传递参数。未来的开发者们可以尝试使用它们。
当你创建一个Fragment时,它已经定义了以下静态方法:
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;
}
}
Fragment mp=mostpop.newInstance("parameter1","parameter2");
你可以通过一个 bundle 实例化你的 fragment:
Fragment fragment = Fragment.instantiate(this, RolesTeamsListFragment.class.getName(), bundle);
在类中声明公共变量是最简单的方法:
目标类上:
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);
}
...
}