Listen Dialog Positive button click in each ViewPager fragment

Sam Chen :

I'm testing a function of listening the AlertDialog button click (Positive & Neutral) in each ViewPager fragment. And I am using the Interface method right now but getting some troubles.

So the structure is like this, I have an AlertDialog created by DialogFragment, and I put a ViewPager with two fragments into this DialogFragment. My goal is, when I click on the Positive button on the AlertDialog, I want some methods inside those two ViewPager fragments get called so that I can collect the data on those fragments.

Now the problem is, only the second fragment responses, I don't know why.

Here are the codes:

  1. I created an Interface file

    public interface Communicator {
        void onConfirmClick();
    }
    
  2. I have a DialogFragment

    public class MainDialogFragment extends DialogFragment {
        View dialogLayout;
        Communicator communicator;
    
        @Override
        public void onAttachFragment(Fragment childFragment) {
            communicator = (Communicator) childFragment;
        }
    
        @Nullable
        @Override
        public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            return dialogLayout;
        }
    
        @NonNull
        @Override
        public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
            AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(getActivity());
            dialogLayout = getActivity().getLayoutInflater().inflate(R.layout.dialog_main, null);
            ViewPager viewPager = dialogLayout.findViewById(R.id.main_viewPager);
    
            final MainPagerAdapter adapter = new MainPagerAdapter(getChildFragmentManager());
            viewPager.setAdapter(adapter);
    
            dialogBuilder.setView(dialogLayout);
            dialogBuilder.setPositiveButton("Confirm", null);
            dialogBuilder.setNegativeButton("Cancel", null);
            dialogBuilder.setNeutralButton("Change", null);
    
            final AlertDialog dialog = dialogBuilder.create();
    
            dialog.setOnShowListener(new DialogInterface.OnShowListener() {
                @Override
                public void onShow(DialogInterface dialogInterface) {
                    dialog.getButton(DialogInterface.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            communicator.onConfirmClick();
                        }
                    });
    
            dialog.getButton(DialogInterface.BUTTON_NEUTRAL).setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            Toast.makeText(view.getContext(), "Change click!!", Toast.LENGTH_SHORT).show();
                        }
                    });
                }
            });
    
            return dialog;
        }
    }
    
  3. My fragment A

    public class MainFragmentA extends Fragment implements Communicator{
        View rootView;
    
        @Nullable
        @Override
        public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            rootView = inflater.inflate(R.layout.fragment_a, container, false);
    
            return rootView;
        }
    
        @Override
        public void onConfirmClick() {
            Toast.makeText(getContext(), "Fragment A!!", Toast.LENGTH_SHORT).show();
        }
    }
    
  4. My fragment B

    public class MainFragmentB extends Fragment implements Communicator{
        View rootView;
    
        @Nullable
        @Override
        public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            rootView = inflater.inflate(R.layout.fragment_b, container, false);
    
            return rootView;
        }
    
        @Override
        public void onConfirmClick() {
            Toast.makeText(getContext(), "Fragment B!!", Toast.LENGTH_SHORT).show();
        }
    }
    
  5. My ViewPager adapter used inside DialogFragment

    public class MainPagerAdapter extends FragmentPagerAdapter {
        public MainPagerAdapter(FragmentManager fragmentManager) {
            super(fragmentManager);
        }
    
        @Override
        public Fragment getItem(int position) {
            switch (position) {
                case 0:
                    return new MainFragmentA();
    
                case 1:
                    return new MainFragmentB();
    
                default:
                    throw new IllegalArgumentException("Wrong position!!");
            }
        }
    
        @Override
        public int getCount() {
            return 2;
        }
    }
    
  6. My MainActivity

    public class MainActivity extends AppCompatActivity{
        Button showDialogButton;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            showDialogButton = findViewById(R.id.main_show_dialog_button);
    
            showDialogButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    MainDialogFragment mainDialogFragment = new MainDialogFragment();
                    mainDialogFragment.show(getSupportFragmentManager(), "mainDialogFragment");
                }
            });
        }
    }
    

Anyone can help? I'll so appreciate that!!!

Bartek Lipinski :

Use a collection of some sort of Communicator interfaces instead of a single one. You're overwriting the communicator every time a child fragment is attached.

public class MainDialogFragment extends DialogFragment {
    View dialogLayout;
    List<Communicator> communicators = new ArrayList<>();

    @Override
    public void onAttachFragment(Fragment childFragment) {
        communicators.add((Communicator) childFragment);
    }

    // all the other things from the MainDialogFragment...
}

And in the BUTTON_POSITIVE callback iterate through the list.

dialog.getButton(DialogInterface.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
        for (Communicator communicator : communicators) { 
            communicator.onConfirmClick();
        }
    }
});

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=135130&siteId=1