DialogFragment和onDismiss

时间:2014-05-21 14:22:38

标签: android android-dialogfragment

我正在使用DialogFragment,我在Activity显示这样的内容:

DialogFragmentImage dialog = DialogFragmentImage.newInstance(createBitmap());
dialog.onDismiss(dialog);.onDismiss(this);          
dialog.show(getFragmentManager(), "DialogFragmentImage");

我想检查DialogFragment被解雇的时间(例如按下后退按钮时),但是在Activity中。我怎样才能做到这一点?如何“告诉”我的activity DialogFragment已被解雇?

8 个答案:

答案 0 :(得分:85)

让您的活动实施OnDismissListener

public final class YourActivity extends Activity implements DialogInterface.OnDismissListener {

    @Override
    public void onDismiss(final DialogInterface dialog) {
        //Fragment dialog had been dismissed
    }

}

DialogFragment已实现OnDismissListener,只需覆盖该方法并调用Activity。

public final class DialogFragmentImage extends DialogFragment {

    ///blah blah

    @Override
    public void onDismiss(final DialogInterface dialog) {
        super.onDismiss(dialog);
        final Activity activity = getActivity();
        if (activity instanceof DialogInterface.OnDismissListener) {
            ((DialogInterface.OnDismissListener) activity).onDismiss(dialog);
        }
    }

}

如果您使用childFragment管理器(API&gt; = 17)从片段启动对话框,则可以使用getParentFragment与父片段上的onDismissListener进行通信。:< / p>

public final class DialogFragmentImage extends DialogFragment {

    ///blah blah

    @Override
    public void onDismiss(final DialogInterface dialog) {
        super.onDismiss(dialog);
        Fragment parentFragment = getParentFragment();
        if (parentFragment instanceof DialogInterface.OnDismissListener) {
            ((DialogInterface.OnDismissListener) parentFragment).onDismiss(dialog);
        } 
    }

}

答案 1 :(得分:15)

这是我的答案。这有点晚了,但也许有人会路过。

FragmentManager fm = getFragmentManager();

YourDialogFragment dialog = new YourDialogFragment();
dialog.show(fm,"MyDialog");

fm.executePendingTransactions();
dialog.getDialog().setOnDismissListener(new DialogInterface.OnDismissListener() {
                    @Override
                    public void onDismiss(DialogInterface dialogInterface) {
                       //do whatever you want when dialog is dismissed
                    }
                });

我们需要致电

fm.executePendingTransactions(); 

确保已执行FragmentTransaction工作。否则,在调用NullPointerException时会出现setOnDismissListener()

对不起,如果有任何错误。希望这有帮助。

答案 2 :(得分:5)

这是一个老问题,但我找不到任何我满意的解决方案。我不想将任何监听器传递给我的DialogFragment或设置TargetFragment,因为这可能会在方向更改时中断。你怎么看待这件事?

SELECT `a.count` + `b.count`
FROM ( 
 SELECT count(1) as `count`
 FROM tableA
 WHERE NOT EXISTS
  (SELECT bookID FROM tableB WHERE bookID = tableA.bookID)
 ) a,
(
 SELECT count(1) as `count`
 FROM tableB
 WHERE NOT EXISTS
  (SELECT bookID FROM tableA WHERE bookID = tableB.bookID);
) b;

答案 3 :(得分:4)

备选答案,如果您无法访问onDismiss of activity的方法。

//DIALOGFRAGMENT
//Create interface in your DialogFragment (or a new file)
public interface OnDismissListener {
   void onDismiss(MyDialogFragment myDialogFragment);
}
//create Pointer and setter to it
private OnDismissListener onDismissListener;
public void setDissmissListener(DissmissListener dissmissListener) {
   this.dissmissListener = dissmissListener;
}
//Call it on the dialogFragment onDissmiss
@Override
public void onDismiss(DialogInterface dialog) {
   super.onDismiss(dialog);

   if (onDismissListener != null) {
      onDismissListener.onDismiss(this);
   }
}

//OTHER CLASS, start fragment where you want
MyDialogFragment df = new MyDialogFragment();
df.setOnDismissListener(new MyDialogFragment.OnDismissListener() {
   @Override
   public void onDismiss(MyDialogFragment myDialogFragment) {
      //Call when MyDialogFragment close
   }
});
df.show(activity.getFragmentManager(), "myDialogFragment");

编辑:如果系统需要重新创建DialogFragment: 你可以用

找到它
MyDialogFragment myDialogFragment = getFragmentManager().findFragmentByTag("MyDialogFragment"); 
if(myDialogFragment != null) { 
   myDialogFragment.setOnDismissListener(...); 
}

答案 4 :(得分:1)

MyButton

通话中

public class OpcoesProdutoDialogo extends DialogFragment{
    private DialogInterface.OnDismissListener onDismissOuvinte;
.
.
.

@Override
    public void onDismiss(DialogInterface dialog) {
        super.onDismiss(dialog);
        if(onDismissOuvinte!=null)
            onDismissOuvinte.onDismiss(dialog);
    }

    public void setOnDismissListener(@Nullable DialogInterface.OnDismissListener listener) {
        this.onDismissOuvinte = listener;
    }
}

答案 5 :(得分:0)

如果您不喜欢@ yaroslav-mytkalyk的解决方案,其中片段需要转换活动/父片段,那么这是另一个:

这是主意:

  1. 在片段DialogFragmentImage中暴露一个侦听器。
  2. 在您的活动中实现侦听器,并在创建它时将其传递给片段。确保还使用标签,以便以后可以找到该片段(请参阅下文)。
  3. onStop()中,删除侦听器,以免在活动被破坏时不泄漏活动。旋转屏幕时会发生这种情况,因为将重新创建活动。
  4. onResume()中,检查片段是否存在,如果存在,请重新添加侦听器。

暴露片段中的一个侦听器:

class MyFragment extends DialogFragment {

    public interface OnDismissListener {
        void dismissed();
    }

    @Nullable
    private OnDismissListener onDismissListener;

    public void setOnDismissListener(@Nullable OnDismissListener onDismissListener) {
        this.onDismissListener = onDismissListener;
    }

    /*
    If you are calling dismiss() or dismissAllowingStateLoss() manually,
    don't forget to call:
    if (onDismissListener != null) {
        onDismissListener.dismissed();
    }

    Otherwise, override them and call it there.
    */
}

这是您的活动的样子:

class MyActivity extends AppCompatActivity {

    private static final String MY_FRAGMENT_TAG = "my_fragment";

    private MyFragment.OnDismissListener myFragmentListener = () -> {

        // ...
    };

    /**
     * Shows the fragment. Note that:
     * 1. We pass a tag to `show()`.
     * 2. We set the listener on the fragment.
     */
    private void showFragment() {

        MyFragment fragment = new MyFragment();
        fragment.show(getSupportFragmentManager(), MY_FRAGMENT_TAG);
        fragment.setOnDismissListener(myFragmentListener);
    }

    @Override
    protected void onStart() {

        super.onStart();

        // Restore the listener that we may have removed in `onStop()`.
        @Nullable MyFragment myFragment =  (MyFragment) getSupportFragmentManager().findFragmentByTag(MY_FRAGMENT_TAG);
        if (myFragment != null) {
            myFragment.setOnDismissListener(myFragmentListener);
        }
    }

    @Override
    protected void onStop() {

        // If the fragment is currently shown, remove the listener so that the activity is not leaked when e.g. the screen is rotated and it's re-created.
        @Nullable MyFragment myFragment =  (MyFragment) getSupportFragmentManager().findFragmentByTag(MY_FRAGMENT_TAG);
        if (myFragment != null) {
            myFragment.setOnDismissListener(null);
        }

        super.onStop();
    }
}

答案 6 :(得分:0)

注意:所有示例都不正确,因为您的片段应具有no-arg构造函数!

片段中带有后退手势和关闭按钮的工作代码。我删除了无用的代码内容,例如在onCreate中获取arg等。

重要提示:更改方向时也会调用onDismiss,因此,您应检查回调中的上下文是否不为空(或使用其他内容)。

public class MyDialogFragment extends DialogFragment {

    public static String TAG = "MyFragment";

    public interface ConfirmDialogCompliant {
        void doOkConfirmClick();
    }


    public MyFragment(){
        super();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View rootView = inflater.inflate(R.layout.fragment_layout, container, false);

        ((ImageButton) rootView.findViewById(R.id.btn_close)).setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                // close fragment
                dismiss();
            }
        });
        return rootView;
    }

    @Override
    public void onDismiss(@NonNull DialogInterface dialog) {
        super.onDismiss(dialog);
        // notify
        if(caller != null)
           caller.doOkConfirmClick();
        }
    }

  public void setCallback(ConfirmDialogCompliant caller) {
    this.caller = caller;
  }

 public static MyDialogFragment newInstance(String id) {
    MyDialogFragment f = new MyDialogFragment();

    // Supply num input as an argument.
    Bundle args = new Bundle();
    args.putString("YOU_KEY", id);
    f.setArguments(args);

    return f;
}

}

现在如何从父级调用它。

MyDialogFragment.ConfirmDialogCompliant callback = new MyDialogFragment.ConfirmDialogCompliant() {

            @Override
            public void doOkConfirmClick() {
                // context can be null, avoid NPE
                if(getContext() != null){

                }

            }

        };

    MyDialogFragment fragment = MyDialogFragment.newInstance("item");
    fragment.setCallback(callback);
    fragment.show(ft, MyDialogFragment.TAG);
        new MyDialogFragment(callback, item);

    fragment.show(getActivity().getSupportFragmentManager(), MyDialogFragment.TAG);

其他来源:https://developer.android.com/reference/android/app/DialogFragment

答案 7 :(得分:-1)

你可以继承DialogFragment,并提供你自己的调用,并在onCancel中调用。

var onDismissListener: (() -> Unit)? = null

对于那些不熟悉Kotlin的人来说,这只是一个匿名界面,可以在Java中保存样板表面。在Java中使用字段和setter。

然后在onCancel

    override fun onCancel(dialog: DialogInterface?) {
    super.onCancel(dialog)
    onDismissListener?.invoke()
}

玩得开心!