将嵌套片段中的数据发送到父片段

Tuk*_*ajo 46 android parameter-passing android-fragments android-nested-fragment

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

那么我怎样才能从我的Nested Fragments身上找回我的价值并将其带入FR1.

  1. 所有Views都在每个中声明并以编程方式处理Nested Fragment.
  2. 父母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();
        }
    });
Run Code Online (Sandbox Code Playgroud)

我的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();
Run Code Online (Sandbox Code Playgroud)

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

uDe*_*vel 90

最好的方法是使用界面:

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

    // Container Activity or Fragment must implement this interface
    public interface OnPlayerSelectionSetListener
    {
        public void onPlayerSelectionSet(List<Player> players_ist);
    }
    
    Run Code Online (Sandbox Code Playgroud)
  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());
    
        // ...
    }
    
    Run Code Online (Sandbox Code Playgroud)
  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;
            }
        }
    
    Run Code Online (Sandbox Code Playgroud)
  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.
               }
          }
     }
    
    Run Code Online (Sandbox Code Playgroud)

在对事务进行分段时添加标记,以便以后可以查找它以调用其方法.FragmentTransaction

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

实际上还有另一种官方方式,即使用活动结果,但这个方法足够好且很常见.

  • @ShrimpCrackers可能会有一些混乱,因为自从原生Android中的支持库v24.0.0或API 24以来,Google工程师引入了一种名为[**onAttachFragment(Fragment)**]的新方法(https://developer.android. com/reference/android/app/Fragment.html#onAttachFragment(android.app.Fragment))这里的答案实际上与这个答案略有不同.uDevei在2年前写这个答案时碰巧选择了相同的方法名称.要明确的是:你没有覆盖Android框架中的`onAttachFragment()`,你是**自己实现**. (7认同)
  • getParentFragment()仅适用于API 17+,所以这个答案应该明确这个,或者说不够清楚 (2认同)

Raj*_*har 30

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

( (YourFragmentName) getParentFragment() ).yourMethodName();
Run Code Online (Sandbox Code Playgroud)

  • 如果可能,您应该避免这种解决方案 片段的重点在于它是UI的可重用部分.如果您的子片段包含对父片段的硬编码引用,那么您将失去对子片段的可重用性.这就是接口很棒的原因,父母将选择如何实现它们. (37认同)
  • 这应该是恕我直言的答案.这是一行代码,完全可以满足需要.希望我能更多地投票 (5认同)
  • 这不是一个好的解决方案。您的子片段与您的父片段紧密耦合 (3认同)
  • @uDevel有时您必须使用子Fragments-假设您想在父Fragment中使用选项卡。在这种情况下,可能使子片段仅与父片段一起使用。我想在那种情况下,单线解决方案很棒。 (2认同)