2017-04-14 78 views
0

我有一个AppCompatActivity,它在某些时候显示DialogFragment。在这个对话框中,有些项目在我删除之前需要确认。该确认通过另一个是/否DialogFragment提出。当用户在第二个对话框中单击“是”时,我想让第一个对话框刷新其ListView(只需更新适配器并调用其notifyDataSetChanged方法)。问题是我不知道什么时候更新列表视图。如何在关闭另一个DialogFragment后刷新DialogFragment

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

因为我不在乎在不必要的情况下刷新ListView,我试图更新onResume事件中的列表,但是在确认一个被解除后返回到第一个对话框时不会调用该事件。

所以我的问题是:我怎么能知道当对话框A显示在对话框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; 
    } 

} 

回答

0

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

我创建了以下接口:

public interface OnDeletedListener { 
    void onDeleted(); 
} 

更新了OnEditCalendarsDialogListener接口,这样的回调有回调到该接口也:

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

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

工作顺利!

1

使用EventBus

注册您的对话A以收听活动。当您解除对话B发布事件并传递listitem的适配器位置或您想要用来识别哪个项目将被删除的任何数据时。在对话框中写一个函数来接收这个事件,在这个事件中你删除了这个项目。

+0

由于这是一个学校作业,我一直在寻找一种不涉及第三方图书馆的解决方案。但是对于未来的项目,发布 - 订阅者设计模式的实现可能是有用的。我将它保存在我的书签中供将来参考。谢谢! – STremblay

+0

还有其他的方式,比如你说的界面。或者在打开对话框b时,您可以传递对话框a的引用,并在删除某个项目并关闭它时调用对话框b中的对话框a的deleteitem方法。但请记得在调用避免NPE的方法之前检查对话a的实例是否为空。 –