我有一个
Fragment
FR1
,其中包含多个 Nested
Fragments
; FRa
,FRb
,FRc
。这些 Nested
Fragments
通过按 Buttons
布局上的 FR1
进行更改。每个 Nested
Fragments
中都有多个输入字段;其中包括 EditTexts
、NumberPickers
和 Spinners
等内容。当我的用户浏览并填写 Nested
Fragments
的所有值时,FR1
(父片段)有一个提交按钮。
我怎样才能从我的
Nested
Fragments
检索我的值并将它们带入 FR1
。
Views
均在每个 Nested
Fragment
中声明并以编程方式处理。Fragment
,FR1
处理Nested
Fragments
的交易。我希望这个问题足够清楚,我不确定是否有必要发布代码,但如果有人觉得不然,我可以这样做。
编辑1:
这是我添加我的
Nested
Fragments
:
tempRangeButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
getChildFragmentManager().beginTransaction()
.add(R.id.settings_fragment_tertiary_nest, tempFrag)
.commit();
}
});
scheduleButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
getChildFragmentManager().beginTransaction()
.add(R.id.settings_fragment_tertiary_nest, scheduleFrag)
.commit();
}
});
alertsButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
getChildFragmentManager().beginTransaction()
.add(R.id.settings_fragment_tertiary_nest, alertsFrag)
.commit();
}
});
submitProfile.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
constructNewProfile();
}
});
我的
constructNewProfile()
方法需要我的 Nested
Fragments
中的值。
public Fragment tempFrag = fragment_profile_settings_temperature
.newInstance();
public Fragment scheduleFrag= fragment_profile_settings_schedules
.newInstance();
public Fragment alertsFrag = fragment_profile_settings_alerts
.newInstance();
上面指的是父fragment的字段;以及它们最初是如何实例化的。
最好的方法是使用界面:
在嵌套片段中声明一个接口
// Container Activity or Fragment must implement this interface
public interface OnPlayerSelectionSetListener
{
public void onPlayerSelectionSet(List<Player> players_ist);
}
将接口附加到父片段
// In the child fragment.
public void onAttachToParentFragment(Fragment fragment)
{
try
{
mOnPlayerSelectionSetListener = (OnPlayerSelectionSetListener)fragment;
}
catch (ClassCastException e)
{
throw new ClassCastException(
fragment.toString() + " must implement OnPlayerSelectionSetListener");
}
}
@Override
public void onCreate(Bundle savedInstanceState)
{
Log.i(TAG, "onCreate");
super.onCreate(savedInstanceState);
onAttachToParentFragment(getParentFragment());
// ...
}
单击按钮时调用侦听器。
// In the child fragment.
@Override
public void onClick(View v)
{
switch (v.getId())
{
case R.id.tv_submit:
if (mOnPlayerSelectionSetListener != null)
{
mOnPlayerSelectionSetListener.onPlayerSelectionSet(selectedPlayers);
}
break;
}
}
让您的父片段实现该接口。
public class Fragment_Parent extends Fragment implements Nested_Fragment.OnPlayerSelectionSetListener
{
// ...
@Override
public void onPlayerSelectionSet(final List<Player> players_list)
{
FragmentManager fragmentManager = getChildFragmentManager();
SomeOtherNestFrag someOtherNestFrag = (SomeOtherNestFrag)fragmentManager.findFragmentByTag("Some fragment tag");
//Tag of your fragment which you should use when you add
if(someOtherNestFrag != null)
{
// your some other frag need to provide some data back based on views.
SomeData somedata = someOtherNestFrag.getSomeData();
// it can be a string, or int, or some custom java object.
}
}
}
在进行fragment交易时添加Tag,以便事后查找并调用其方法。 Fragment交易
这是处理fragment和nestfragment之间通信的正确方法,对于activity和fragment来说几乎是一样的。 http://developer.android.com/guide/components/fragments.html#EventCallbacks
实际上还有另一种官方方法,它是使用活动结果,但是这个已经足够好了并且很常见。
您可以通过以下方式调用子片段,而不是使用接口:
( (YourFragmentName) getParentFragment() ).yourMethodName();
在片段之间传递数据的最佳方式是使用接口。您需要执行以下操作: 在您嵌套的片段中:
public interface OnDataPass {
public void OnDataPass(int i);
}
OnDataPass dataPasser;
@Override
public void onAttach(Activity a) {
super.onAttach(a);
dataPasser = (OnDataPass) a;
}
public void passData(int i) {
dataPasser.OnDataPass(i);
}
在您的父片段中:
public class Fragment_Parent extends Fragment implements OnDataPass {
...
@Override
public void OnDataPass(int i) {
this.input = i;
}
btnOk.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Fragment fragment = getSupportFragmentManager().findFragmentByTag("0");
((Fragment_Fr1) fragment).passData();
}
}
}
您可以在片段之间使用共享数据。
public class SharedViewModel extends ViewModel {
private final MutableLiveData<Item> selected = new MutableLiveData<Item>();
public void select(Item item) {
selected.setValue(item);
}
public LiveData<Item> getSelected() {
return selected;
}
}
public class MasterFragment extends Fragment {
private SharedViewModel model;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
itemSelector.setOnClickListener(item -> {
model.select(item);
});
}
}
public class DetailFragment extends Fragment {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SharedViewModel model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
model.getSelected().observe(this, item -> {
// Update the UI.
});
}
}
更多信息 ViewModel 架构
您可以使用
getChildFragmentManager()
查找嵌套片段,获取它们并运行一些方法来检索输入值
在获取父片段之前检查
instanceOf
哪个更好:
if (getParentFragment() instanceof ParentFragmentName) {
getParentFragment().Your_parent_fragment_method();
}
Fragment之间传递数据可以使用FragmentManager来完成。从Fragment 1.3.0-alpha04开始,我们可以使用setFragmentResultListener()和setFragmentResult() API在Fragment之间共享数据。
太晚了,我可以建议在子片段中创建 EditText 对象
EditText tx;
在 Oncreateview 中初始化它。然后为桥创建另一个类
public class bridge{
public static EditText text = null;
}
现在在父片段中获取其引用。
EditText childedtx = bridge.text;
现在点击方法获取值
onclick(view v){
childedtx.getText().tostring();
}
在我的项目中进行了测试,它的工作就像魅力一样。
我们可以使用 Result API 将子片段的数据共享到父片段。
在build.gradle.kts(模块:app)中添加:
implementation("androidx.fragment:fragment-ktx:1.3.0")
在您必须发送数据的子片段中:
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val res = "Top Fragment returned from Child"
setFragmentResult("Data", bundleOf("data" to res))
return inflater.inflate(R.layout.fragment_top_child, container, false)
}
在您必须接收数据的父片段中:
private fun getChildData(): String{
childFragmentManager.setFragmentResultListener("Data", this) {
_, bundle ->
result = bundle.getString("data").toString()
}
return result
}