【问题标题】:How to callback different clicks from DialogFragment to Activity?如何将不同的点击从 DialogFragment 回调到 Activity?
【发布时间】:2021-12-16 15:31:44
【问题描述】:

我有一个带有 RecyclerView 的 DialogFragment,我可以在其中单击一些项目,这些项目必须从 Activity 添加到“父”项目,并且我还有其他 4 个按钮在该对话框中执行不同的操作。

如何管理来自 RecyclerView 和 Activity 中按钮的点击?

就像我的对话框是这样的:

@NonNull
@Override
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
    AlertDialog.Builder builder = new AlertDialog.Builder(requireActivity());

    final Comanda prodotto = (Comanda) getArguments().getSerializable("PRODOTTO");
    final int menuSelezionato = getArguments().getInt("ACTIVE_MENU");

    List<Varianti> variantiAggiunte = prodotto.getVarianti();


    DataBaseHandler dbContext = DataBaseHandler.getInstance(requireActivity());
    ArrayList<VariantiBinding> variantiList = dbContext.getVarianti();
    ArrayList<VariantiBinding> variantiFilteredList = selectVariantiByMenu(variantiList, menuSelezionato);

    AdapterVariantiAggiunte adapterVariantiAggiunte = aggiunteRecycler(recyclerVariantiAdded, variantiAggiunte);
    AdapterVarianti adapterVarianti = variantiRecycler(recyclerVarianti, variantiFilteredList);

    title.setText(prodotto.getDescrizione());

    builder.setView(view);

    adapterVarianti.setOnItemClickListener(positionVariante -> {
        search.clearFocus();
        VariantiBinding varianteSelezionata = adapterVarianti.getList().get(positionVariante);
        Varianti variante = getVariante(varianteSelezionata);
        if (variante != null) {
            //adapterComanda.addVariante(variante); adapterComanda is in Activity
            adapterVariantiAggiunte.notifyItemInserted(adapterVariantiAggiunte.getItemCount() - 1);
            recyclerVariantiAdded.scrollToPosition(adapterVariantiAggiunte.getItemCount() - 1);
        }
    });
    
    return builder.create();
}

我必须在 VariantiDialog 和 My Activity 中处理adapterVarianti 点击,现在只处理 Dialog 中的点击,但就像我需要在我的 Activity 中获得回调之类的东西并调用:

adapterComanda.addVariante(variante);

在所有这些都处于同一级别之前,但我的所有 AlertDialogs 都在我的 Activity 中,我正在将它们移动到 DialogFragment。

【问题讨论】:

    标签: android


    【解决方案1】:

    您可以使用接口来提供回调,一个用于对话框片段到活动,一个从回收器视图到对话框片段

    1接口(用于从对话片段回调到活动)

    public interface OnDialogCountryChangeListener {
        public void onDialogCountryChange(String country);
    }
    

    2 Activity.java(开始对话片段的类)

    public class MyActivity extends AppCompactActivity implements OnDialogCountryChangeListener {
        
        ...
    
        private void showDialog() {
            FragmentManager fm = getSupportFragmentManager();
            CountryDialogFragment countryDialog = new CountryDialogFragment();
            countryDialog.setTargetFragment(this, 0); // set target fragment for callback listener
            countryDialog.show(fm, "add_dialog");
        }
    
        @Override
        public void onDialogCountryChange(String country) {
            // Your callback from dialog fragment to activity
            // Do your stuff
        }
    }
    

    3 CountryDialogFragment.java

     @Override
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);
    
           try {
                countryActivitycallback = (OnDialogCountryChangeListener) getTargetFragment(); // callback instance 
            } catch (ClassCastException e) {
                throw new ClassCastException("Calling Fragment must implement OnDialogCountryChangeListener"); 
            }
     }
    

    用于从 recyclerview 回调到对话框片段

    1创建界面(您也可以使用相同的界面,但我认为最好使用新的不同的界面来解释,因为它可能会变得混乱)

    public interface OnItemClickListener {
         void onItemClick(String countryItem);
     }
    

    2接下来修改您的 Adapter 类,在您的情况下为 RecycleView Adapter

    i) 在构造函数中将侦听器作为参数发送

    private final OnItemClickListener listener;
    public RecycleViewCountryAdapter(OnItemClickListener listener) {
             this.listener = listener;
         }
    

    ii) 在 ViewHolder 类中的某个视图上设置 onCLick 监听器

    public MyViewHolder(View itemView) {
             super(itemView);
             imageOnCard = (ImageView) itemView.findViewById(R.id.image_on_cardview);
             // change your listener on any other view if you want
             imageOnCard..setOnClickListener(new View.OnClickListener() {
                     @Override public void onClick(View v) {
                           listener.onItemClick(worldDataModelArrayList.get(getAdapterPosition()));
                     }
            });
    
         }
    

    3现在修改你的DialogFragment类来监听你的接口回调,

     recyclerView.setLayoutManager(new LinearLayoutManager(this.getContext()));
     RecycleViewCountryAdapter adapter = new RecycleViewCountryAdapter(new OnItemClickListener() {
         @Override public void onItemClick(String countryItem) {
            // implement click listener as per your requirement
    
           // handle your work in dialog fragment and also give callback to activity
         if(countryActivitycallback!=null) // callback for activity
           {
                    countryActivitycallback.onDialogCountryChange(countryItem);
            }
    
         });
     recyclerView.setAdapter(adapter);
    

    编辑: setTargetFragment 现已弃用。作为一种替代方式,您可以使用共享 ViewModel 或使用新 API FragmentResultListener 执行相同操作。

    【讨论】:

    • 我直接在 countryDialog 上设置了回调,而不是在 Activity 中覆盖它,这是一个好习惯吗?
    • 您的意思是在构造函数中传递侦听器?(在这种情况下,如果 Android 决定稍后重新创建您的 Fragment,它将调用您的 Fragment 的无参数构造函数。)同样使用 setTarget 方法也没有什么优势就像您可以及早检查托管活动是否覆盖接口一样,在分离片段后持有托管上下文引用的风险较小。但是我说谁,我自己的项目使用的项目直接将回调传递给fragment
    猜你喜欢
    • 1970-01-01
    • 2017-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多