带有侦听器的通用DialogFragment

时间:2018-06-05 07:38:51

标签: android android-fragments android-dialogfragment dialogfragment

我想创建一个DialogFragment子类,可以在我的应用程序中重复使用。因此,当Activity想要创建DialogFragment时,它可以设置自己的文本并为正面和负面按钮附加自己的侦听器。对于DialogFragment内的文本,我使用参数bundle将它们传递给片段,以确保在配置更改时它们是持久的。但是,按钮的侦听器无法使用这些参数传递给片段。

将这些侦听器附加到DialogFragment的最佳做法是什么,而不会在配置更改时丢失它们?

3 个答案:

答案 0 :(得分:2)

BaseDialogFragment.java

public abstract class BaseDialogFragment extends AppCompatDialogFragment {
public AppCompatDialog dialog;

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(getLayoutResource(), null);
    ButterKnife.bind(this, view);
    return view;
}


@Override
public void onStart() {
    super.onStart();
    dialog = (AppCompatDialog) getDialog();
    if (dialog != null) {
        WindowManager windowManager =
                (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
        Display display = windowManager.getDefaultDisplay();
        Point size = new Point();
        display.getSize(size);
        int width = size.x;

        dialog.getWindow().setLayout(width - 75, ViewGroup.LayoutParams.WRAP_CONTENT);
        WindowManager.LayoutParams params = dialog.getWindow().getAttributes();
        dialog.getWindow().setAttributes(params);
        dialog.getWindow().setBackgroundDrawable(ContextCompat.getDrawable(getContext(), R.drawable.dialog_rounded_back));
    }

}

protected abstract int getLayoutResource();

@Override
public void show(FragmentManager manager, String tag) {

    try {
        FragmentTransaction ft = manager.beginTransaction();
        ft.add(this, tag);
        ft.commitAllowingStateLoss();
    } catch (IllegalStateException e) {

    }
}

}

子片段对话框:

public class InvitationAcceptRejectDialog extends BaseDialogFragment {
public InvitationAcceptRejectDialog() {

}

@Override
protected int getLayoutResource() {
    return R.layout.invite_accept_reject_dialog;
}

protected OnDialogClickListener alertListener;


@BindView(R.id.tvDialogTitle)
AppCompatTextView tvDialogTitle;
@BindView(R.id.tvDialogMessage)
AppCompatTextView tvDialogMessage;
int requestCode;
public String dialogTitle;
public String dialogMessage;
public Bundle bundle;

@OnClick({R.id.imgCloseDialog, R.id.btnYes, R.id.btnNo})
public void dialgClick(View view) {
    switch (view.getId()) {
        case R.id.imgCloseDialog:
            break;
        case R.id.btnYes:
            alertListener.onPositiveClick(dialog, requestCode, bundle);
            break;
        case R.id.btnNo:
            alertListener.onNegativeClick(dialog, requestCode, bundle);
            break;
    }
    dialog.dismiss();
}

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    tvDialogTitle.setText(dialogTitle);
    tvDialogMessage.setText(dialogMessage);
}

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    return super.onCreateView(inflater, container, savedInstanceState);

}

public static class Builder {

    InvitationAcceptRejectDialog alertDialogFragment;

    public Builder() {
        alertDialogFragment = new InvitationAcceptRejectDialog();
    }

    public Builder setTitle(String title) {
        alertDialogFragment.dialogTitle = title;
        return this;
    }

    public Builder setMessage(String message) {
        alertDialogFragment.dialogMessage = message;
        return this;
    }

    public Builder setBundel(Bundle bundel) {
        alertDialogFragment.bundle = bundel;
        return this;
    }

    public Builder setCallback(OnDialogClickListener mListener, int code) {
        alertDialogFragment.alertListener = mListener;
        alertDialogFragment.requestCode = code;
        return this;
    }

    public InvitationAcceptRejectDialog build() {
        return alertDialogFragment;
    }
}
}

活动 fragmnet 中的实施:

  InvitationAcceptRejectDialog build = new InvitationAcceptRejectDialog.Builder()
            .setCallback(this, Constant.DialogConstant.ACCEPET_INVITE)
            .setTitle(getString(R.string.logout))
            .setMessage(getString(R.string.logout_message))
            .build();
    build.show(getSupportFragmentManager(), "TAG");

手柄正负按钮点击界面:

public interface OnDialogClickListener {

void onPositiveClick(DialogInterface dialog, int id, Bundle bundle);

void onNegativeClick(DialogInterface dialog, int id, Bundle bundle);

}

答案 1 :(得分:1)

关于传递侦听器,您可以创建一个具有两个函数的接口,每个函数用于DialogFragment中的正按钮和负按钮。在正面和负面按钮的内部点击监听器中,您可以相应地调用这些接口方法。在DialogFragment中创建一个方法来设置此接口。

答案 2 :(得分:0)

我会做这样的事情,使用按钮作为接口,你可以在你的项目中任何你想要的地方调用这个类。并且您也可以在配置更改时保存它的实例:

public class MyDialogFragment extends DialogFragment  {

// the fragment initialization parameters,
private static final String DIALOG_TITLE = "DIALOG_TITLE";
private static final String DIALOG_MESSAGE = "DIALOG_MESSAGE";
private static final String DIALOG_BUTTON_POSITIVE = "DIALOG_BUTTON_POSITIVE";
private static final String DIALOG_BUTTON_NEGATIVE = "DIALOG_BUTTON_NEGATIVE";

private String Title;
private String Message;
private String btnPositive;
private String btnNegative;

public interface DialogFragmentButtonPressedListener {
    void onPositiveButtonClick();

    void onNegativeButtonClick();

}


public static MyDialogFragment newInstance(String title, String message, String btnPositiveText, String btnNegativeText) {
    MyDialogFragment fragment = new MyDialogFragment();
    Bundle args = new Bundle();
    args.putString(DIALOG_TITLE, title);
    args.putString(DIALOG_MESSAGE, message);
    args.putString(DIALOG_BUTTON_POSITIVE, btnPositiveText);
    args.putString(DIALOG_BUTTON_NEGATIVE, btnNegativeText);

    fragment.setArguments(args);
    return fragment;
}

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (getArguments() != null) {
        Title = getArguments().getString(DIALOG_TITLE);
        Message = getArguments().getString(DIALOG_MESSAGE);
        btnPositive = getArguments().getString(DIALOG_BUTTON_POSITIVE);
        btnNegative = getArguments().getString(DIALOG_BUTTON_NEGATIVE);

    }

}

// updated this method. before update it was onAttach(Activity activity)
@Override
public void onAttach(Context context) {
    super.onAttach(context);
    if (!(context instanceof DialogFragmentButtonPressedListener)) {
        throw new ClassCastException(context.toString() + " must implement DialogFragmentButtonPressedListener");
    }
}

static Handler handler = new Handler(Looper.getMainLooper());

final Runnable runnable = new Runnable( ) {
    @Override
    public void run() {
        if (mAlertDialog.isShowing()) {
            mAlertDialog.dismiss();

        }
    }
};

AlertDialog mAlertDialog = null;
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {

//        return new AlertDialog.Builder(getActivity())
//                .setTitle(Title)
//                .setMessage(Message)
//                .setPositiveButton(btnPositive, new DialogInterface.OnClickListener() {
//
//                    @Override
//                    public void onClick(DialogInterface dialog, int which) {
//                        ((DialogFragmentButtonPressedListener) getActivity()).onPositiveButtonClick();
//                    }
//                })
//                .setNegativeButton(btnNegative, new DialogInterface.OnClickListener() {
//
//                    @Override
//                    public void onClick(DialogInterface dialog, int which) {
//                        ((DialogFragmentButtonPressedListener) getActivity()).onNegativeButtonClick();
//                    }
//                })
//                .create();


    return mAlertDialog;
}
 }

在我的通话活动中,我会这样做:

 new MyDialogFragment();
 myDialogFragment = MyDialogFragment.newInstance("successfull", "Please follow the instructions", " OK ", "negativeButtonText");
  myDialogFragment.show(getSupportFragmentManager(), "MyDialogFragment");