Listen Dialog Positive 按钮在每个 ViewPager 片段中单击

Listen Dialog Positive button click in each ViewPager fragment

我正在测试在每个 ViewPager 片段中监听 AlertDialog 按钮点击(正面和中性)的功能。我现在正在使用 Interface 方法,但遇到了一些麻烦。

所以结构是这样的,我有一个由DialogFragment创建的AlertDialog,我把一个有两个片段的ViewPager放到这个DialogFragment里面。我的目标是,当我单击 AlertDialog 上的肯定按钮时,我希望调用这两个 ViewPager 片段中的一些方法,以便我可以收集这些片段的数据。

现在的问题是,只有第二个片段响应,我不知道为什么。

代码如下:

  1. 我创建了一个接口文件

    public interface Communicator {
        void onConfirmClick();
    }
    
  2. 我有一个 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. 我的片段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. 我的片段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. 我的 ViewPager 适配器在 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. 我的 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");
                }
            });
        }
    }
    

有人可以帮忙吗?非常感谢!!!

使用 collection 的某种 Communicator 接口,而不是单个接口。每次附加子片段时,您都会覆盖 communicator

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

然后在 BUTTON_POSITIVE 回调中遍历列表。

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

Only the communicator from the second fragment works

这是因为您的每个片段中都有两个不同的通信器实例。当您设置 ViewPager 时,第二个片段是最后一个与父片段关联的片段。因此,您在 MainDialogFragment class 的 onAttachFragment 函数中初始化的 communicator 仅存储来自第二个片段的引用,因为这是最后一个片段附在这里。

对于您的情况,我宁愿建议使用 Fragment 的生命周期函数进行非常简单的实现。只需在 MainDialogFragment class 中添加一个 public static 变量,它将指示是否单击了确定按钮。然后从 onResume 函数中的每个 Fragment class 检查该变量的值,并相应地执行任务。要了解实施情况,请检查以下内容。

在您的 MainDialogFragment class 中获取一个变量,如下所示。

public static boolean isDialogOkayClicked = false; // Default false

现在在您的 MainFragmentA 中,实现 onResume 函数并检查 MainDialogFragment 中的值。采取相应的措施。

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
    protected void onResume() {
        super.onResume();
        if(MainDialogFragment.isDialogOkayClicked) 
            doSomething();
    }

    @Override
    public void onConfirmClick() {
        Toast.makeText(getContext(), "Fragment A!!", Toast.LENGTH_SHORT).show();
    }
}

对你的另一个片段做同样的事情。

希望对您有所帮助!