【问题标题】:How to refresh DialogFragment after dismiss of another DialogFragment如何在关闭另一个 DialogFragment 后刷新 DialogFragment
【发布时间】:2017-04-14 22:19:22
【问题描述】:

我有一个AppCompatActivity,在某些时候会显示一个DialogFragment。在此对话框中,有些项目在删除之前我要求确认。通过另一个是/否DialogFragment 要求确认。当用户在第二个对话框中单击“是”时,我希望第一个对话框刷新其ListView(只需要更新适配器并调用其notifyDataSetChanged 方法)。问题是我不知道何时更新列表视图。

因为删除功能是从各种来源调用的,所以我在活动级别实现了一个侦听器接口,并在我需要删除项目时从该接口调用“onDeleteRequest”事件,这就是打开确认的活动对话框并执行实际删除。

由于我不太关心在不必要的情况下刷新 ListView,因此我尝试在 onResume 事件中更新列表,但是当我在确认后返回第一个对话框时未调用该事件被解雇了。

所以我的问题是:我如何知道显示在对话框 A 顶部的对话框 B 何时被关闭,以便我可以相应地刷新对话框 A?

编辑:一些代码来支持我的问题:

我的活动课:

public class MonthActivity
        extends AppCompatActivity
        implements OnEditCalendarsDialogListener
{
    ...

    //That's where dialog A is shown
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();

        ...

        if (id == R.id.action_select_calendar) {
            final CalendarSelection currentSelection = mCalendarSelectionAdapter.getCurrentCalendarSelection();

            if (currentSelection != null) {
                EditCalendarsDialogFragment dialogFragment = EditCalendarsDialogFragment.newInstance(currentSelection);
                dialogFragment.show(getSupportFragmentManager());
            }
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    ...

    //OnEditCalendarsDialogListener interface implementation

    //That's where Dialog B is shown over Dialog A
    @Override
    public void onEditCalendarsDialogDelete(long calendarID) {
        final Repository repository = Repository.getInstance(this);
        final Calendar calendar = repository.fetchOneByID(Calendar.class, calendarID);

        if (calendar != null) {
            YesNoDialog yesNoDialog = YesNoDialog.newInstance(this, R.string.yes_no_dialog_confirmation, R.string.yes_no_dialog_calendar_delete);
            setCurrentOnDecisionClickListener(new OnPositiveClickListener() {
                @Override
                public boolean onPositiveClick(DialogInterface dialog) {
                    //Delete calendar
                    repository.delete(calendar);
                    //That's where I'd like to notify Dialog A that it needs to be refreshed
                    return true;
                }
            });
            yesNoDialog.show(getSupportFragmentManager());
        }
    }
}

我的对话类

public class EditCalendarsDialogFragment
        extends DialogFragment
{
    private OnEditCalendarsDialogListener mDialogListener;

    public static EditCalendarsDialogFragment newInstance(CalendarSelection calendarSelection) {
        EditCalendarsDialogFragment dialog = new EditCalendarsDialogFragment();
        Bundle arguments = new Bundle();

        if (calendarSelection != null) {
            arguments.putLong(KEY_ID, calendarSelection.getID());
        }
        else {
            arguments.putLong(KEY_ID, 0L);
        }

        dialog.setArguments(arguments);

        return dialog;
    }

    ...

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            mDialogListener = (OnEditCalendarsDialogListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString() + " must implement OnCalendarSelectionDialogListener");
        }
    }

    ...

    private View getLayoutView() {
        View rootView = getActivity().getLayoutInflater().inflate(R.layout.calendar_list, null, false);

        if (rootView != null) {
            mCalendars = (ListView) rootView.findViewById(R.id.calendars);
            if (mCalendars != null) {
                //Create adaptor
                mCalendarAdapter = new ArrayAdapter<Calendar>(
                        getContext(),
                        android.R.layout.simple_list_item_2,
                        android.R.id.text1,
                        new ArrayList<Calendar>()
                ) {
                    @NonNull
                    @Override
                    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
                        View view = super.getView(position, convertView, parent);

                        final Calendar calendar = getItem(position);

                        if (calendar != null && calendar.hasID()) {
                            ...
                            view.setOnLongClickListener(new View.OnLongClickListener() {
                                @Override
                                public boolean onLongClick(View v) {
                                    if (mDialogListener != null) {
                                        //That's where I request delete from calling activity
                                        mDialogListener.onEditCalendarsDialogDelete(calendar.getID());
                                    }
                                    return true;
                                }
                            });
                        }

                        return view;
                    }
                };
                mCalendars.setAdapter(mCalendarAdapter);
                refreshCalendarList();
            }
        }

        return rootView;
    }

}

【问题讨论】:

    标签: android dialog dialogfragment


    【解决方案1】:

    使用EventBus

    注册你的对话 A 来监听事件。当您关闭对话框 B 时,发布一个事件并传递列表项的适配器位置或您想用来识别要删除哪个项目的任何数据。在您的对话框 A 中编写一个函数来接收此事件,您可以在其中删除项目。

    【讨论】:

    • 因为是学校作业,所以我一直在寻找不涉及第三方图书馆的解决方案。但是对于未来的项目,发布-订阅者设计模式的实现可能会被证明是有用的。我把它保存在我的书签里以备将来参考。谢谢!
    • 还有其他方法,比如你说的界面。或者在打开对话框 b 时,您可以传递对话框 a 的引用,并在您删除项目并关闭它时从对话框 b 调用对话框 a 的 deleteitem 方法。但是记得在调用方法之前检查对话框a的实例是否不为空以避免NPE。
    【解决方案2】:

    好的,所以我终于使用了“过度滥用回调”的方法。

    我创建了如下界面:

    public interface OnDeletedListener {
        void onDeleted();
    }
    

    更新了 OnEditCalendarsDialogListener 接口,使回调也有对该接口的回调:

    public interface OnEditCalendarsDialogListener {
        void onEditCalendarsDialogDelete(long calendarID, OnDeletedListener onDeletedListener);
    }
    

    在“Dialog A”类中实现了 OnDeletedListener 接口:

    public class EditCalendarsDialogFragment
            extends DialogFragment
            implements OnDeletedListener
    {
        ...
    
        //OnDeletedListener interface implementation
    
        @Override
        public void onDeleted() {
            //That's where I'm called back after item is deleted
            refreshCalendarList();
        }
    
        ...
    
        private View getLayoutView() {
            ...
            view.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View v) {
                    if (mDialogListener != null) {
                        //That's where I request delete from calling activity, asking to call me back once deleted
                        mDialogListener.onEditCalendarsDialogDelete(calendar.getID(), EditCalendarsDialogFragment.this);
                    }
                    return true;
                }
            });
            ...
        }
    }
    

    最后,在接受并执行删除时调用回调:

    public class MonthActivity
            extends AppCompatActivity
            implements OnEditCalendarsDialogListener
    {
        //OnEditCalendarsDialogListener interface implementation
    
        //That's where Dialog B is shown over Dialog A
        @Override
        public void onEditCalendarsDialogDelete(long calendarID, final OnDeletedListener onDeletedListener) {
            final Repository repository = Repository.getInstance(this);
            final Calendar calendar = repository.fetchOneByID(Calendar.class, calendarID);
    
            if (calendar != null) {
                YesNoDialog yesNoDialog = YesNoDialog.newInstance(this, R.string.yes_no_dialog_confirmation, R.string.yes_no_dialog_calendar_delete);
                setCurrentOnDecisionClickListener(new OnPositiveClickListener() {
                    @Override
                    public boolean onPositiveClick(DialogInterface dialog) {
                        //Delete calendar
                        repository.delete(calendar);
                        //That's where I notify Dialog A that it needs to be refreshed
                        if (onDeletedListener != null) {
                            onDeletedListener.onDeleted();
                        }
                        return true;
                    }
                });
                yesNoDialog.show(getSupportFragmentManager());
            }
        }
    }
    

    工作顺利!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-28
      • 2020-11-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多