web-dev-qa-db-ja.com

ネストされたフラグメントから親フラグメントへのデータの送信

複数のFragmentNested;を含むFragments _FR1_があります。 FRaFRbFRc。これらのNestedFragmentsを変更するには、_FR1_のレイアウトでButtonsを押します。 NestedFragmentsのそれぞれには、いくつかの入力フィールドが含まれています。 EditTextsNumberPickersSpinnersなどが含まれます。ユーザーがNestedFragmentsのすべての値を入力して入力すると、_FR1_(親フラグメント)には送信ボタンがあります。

どうすればNestedFragmentsから値を取得し、_FR1_に入れることができますか。

  1. すべてのViewsが宣言され、各NestedFragment内でプログラムによって処理されます。
  2. Fragment、_FR1_は、NestedFragmentsのトランザクションを処理します。

この質問が十分に明確であり、投稿にコードが必要かどうかはわかりませんが、誰かがそうでないと感じた場合はそうすることができます。

編集1:

NestedFragmentsを追加する方法は次のとおりです。

_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()メソッドにはNestedFragmentsの値が必要です。

_public Fragment tempFrag = fragment_profile_settings_temperature
        .newInstance();
public Fragment scheduleFrag= fragment_profile_settings_schedules
            .newInstance();
public Fragment alertsFrag = fragment_profile_settings_alerts
        .newInstance();
_

上記は親フラグメントのフィールドを参照しています。そして、それらが最初にインスタンス化される方法。

43
Tukajo

最良の方法は、インターフェースを使用することです:

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

フラグメントトランザクションを行うときにタグを追加して、後でそのメソッドを呼び出して呼び出せるようにします。 FragmentTransaction

これは、フラグメントとネストフラグメント間の通信を処理する適切な方法です。アクティビティとフラグメントの場合もほぼ同じです。 http://developer.Android.com/guide/components/fragments.html#EventCallbacks

実際には別の公式な方法があります。アクティビティの結果を使用していますが、これは十分で一般的な方法です。

85
uDevel

インターフェイスを使用する代わりに、以下から子フラグメントを呼び出すことができます。

( (YourFragmentName) getParentFragment() ).yourMethodName();
29
Raja Jawahar

getChildFragmentManager()を使用して、ネストされたフラグメントを見つけ、それらを取得し、いくつかのメソッドを実行して入力値を取得できます。

3
michal.luszczuk

フラグメント間でデータを渡す最良の方法は、インターフェイスを使用することです。必要なことは次のとおりです。ネストされたフラグメント内:

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

}
3
Dariush Malek

親フラグメントを取得する前に、instanceOfを確認してください。

if (getParentFragment() instanceof ParentFragmentName) {
  getParentFragment().Your_parent_fragment_method();
}
3
Pankaj

フラグメント間でデータを共有することができます。

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アーキテクチャ

2
Ahmad Aghazadeh