57

我有一个Fragment FR1包含几个Nested FragmentsFRa, FRb, FRc. 这些Nested Fragments是通过按ButtonsonFR1的布局来改变的。每个Nested Fragments都有几个输入字段;其中包括EditTexts,NumberPickersSpinners. 当我的用户通过并填写所有值时Nested FragmentsFR1(父片段)有一个提交按钮。

那么我怎样才能从我的值中检索我的值Nested Fragments并将它们带入FR1.

  1. 所有Views都在每个Nested Fragment.
  2. 父级FragmentFR1处理 的事务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();

以上是指父片段的字段;以及它们最初是如何实例化的。

4

8 回答 8

108

最好的方法是使用接口:

  1. 在嵌套片段中声明一个接口

    // Container Activity or Fragment must implement this interface
    public interface OnPlayerSelectionSetListener
    {
        public void onPlayerSelectionSet(List<Player> players_ist);
    }
    
  2. 将接口附加到父片段

    // 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());
    
        // ...
    }
    
  3. 单击按钮时调用侦听器。

    // 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;
            }
        }
    
  4. 让您的父片段实现接口。

     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.
               }
          }
     }
    

在进行片段交易时添加标签,以便您可以在之后查找它以调用其方法。分片交易

这是处理片段和嵌套片段之间通信的正确方法,对于活动和片段几乎相同。 http://developer.android.com/guide/components/fragments.html#EventCallbacks

其实官方还有另外一种方式,就是使用activity result,但是这个已经够用了,也很常用。

于 2014-04-17T22:44:02.963 回答
34

您可以通过以下方式调用子片段,而不是使用接口:

( (YourFragmentName) getParentFragment() ).yourMethodName();
于 2015-04-16T10:40:06.070 回答
4

在片段之间传递数据的最佳方式是使用接口。这是您需要做的: 在嵌套片段中:

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();
        }
    }

}
于 2014-04-17T20:56:29.723 回答
4

您可以在片段之间使用共享数据。

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 架构

于 2018-08-10T06:44:16.523 回答
3

您可以使用getChildFragmentManager()和查找嵌套片段,获取它们并运行一些方法来检索输入值

于 2014-04-17T20:39:56.140 回答
3

instanceOf在获取更好的父片段之前检查:

if (getParentFragment() instanceof ParentFragmentName) {
  getParentFragment().Your_parent_fragment_method();
}
于 2017-01-06T16:34:35.127 回答
2

FragmentManager 可以在 Fragment 之间传递数据。从 Fragment 1.3.0-alpha04 开始,我们可以使用 setFragmentResultListener() 和 setFragmentResult() API 在 Fragment 之间共享数据。

官方文档

于 2020-09-30T13:11:56.743 回答
0

太晚回答 bt 我可以建议在子片段中创建 EditText 对象

EditText tx;

在 Oncreateview 中对其进行初始化。然后为桥创建另一个类

public class bridge{
public static EditText text = null; 
}

现在在父片段中得到它的引用。

EditText childedtx = bridge.text;

现在点击方法获取价值

onclick(view v){
childedtx.getText().tostring();
}

在我的项目中进行了测试,它的工作就像魅力一样。

于 2020-03-04T18:37:29.780 回答