단추를 클릭할 때 대화 상자가 닫히지 않도록 방지하는 방법
와 대화가 있습니다.EditText
한 다음 .대화 상자에서 "예" 버튼을 클릭하면 입력 내용을 확인한 다음 대화 상자를 닫습니다.그러나 입력이 잘못되었다면 같은 대화 상자에 남아 있기를 원합니다.입력 내용에 관계없이 "아니오" 버튼을 클릭하면 대화 상자가 자동으로 닫힙니다.이 기능을 해제하려면 어떻게 해야 합니까?참고로, 저는 대화상자의 버튼에 포지티브 버튼과 네거티브 버튼을 사용했습니다.
편집: 일부 의견에서 언급한 대로 API 8+에서만 작동합니다.
이것은 늦은 답변이지만 경고 대화 상자에 onShowListener를 추가할 수 있습니다. 여기서 버튼의 onClickListener를 재정의할 수 있습니다.
final AlertDialog dialog = new AlertDialog.Builder(context)
.setView(v)
.setTitle(R.string.my_title)
.setPositiveButton(android.R.string.ok, null) //Set to null. We override the onclick
.setNegativeButton(android.R.string.cancel, null)
.create();
dialog.setOnShowListener(new DialogInterface.OnShowListener() {
@Override
public void onShow(DialogInterface dialogInterface) {
Button button = ((AlertDialog) dialog).getButton(AlertDialog.BUTTON_POSITIVE);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// TODO Do something
//Dismiss once everything is OK.
dialog.dismiss();
}
});
}
});
dialog.show();
다음은 AlertDialog 솔루션을 포함한 모든 유형의 대화 상자에 대한 몇 가지 솔루션입니다.모든 API 레벨에서 작동하는 빌더(여기의 다른 답변은 그렇지 않은 API 8 이하에서 작동함).AlertDialog를 사용하는 AlertDialog에 대한 솔루션이 있습니다.Builder, DialogFragment 및 DialogPreference를 선택합니다.
다음은 기본 공통 단추 처리기를 재정의하고 이러한 다양한 형식의 대화 상자에 대해 대화 상자를 닫지 않도록 하는 방법을 보여주는 코드 예제입니다.모든 예에서는 양수 버튼이 대화 상자를 닫지 않도록 방지하는 방법을 보여 줍니다.
참고: 기본 안드로이드 클래스의 후드 아래에서 대화 상자 닫기가 작동하는 방식과 더 자세한 정보를 원하는 사용자를 위해 예제 다음에 다음과 같은 접근 방식을 선택하는 이유에 대한 설명입니다.
알림 대화 상자.Builder - show() 직후 기본 단추 처리기 변경
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setMessage("Test for preventing dialog close");
builder.setPositiveButton("Test",
new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
//Do nothing here because we override this button later to change the close behaviour.
//However, we still need this because on older versions of Android unless we
//pass a handler the button doesn't get instantiated
}
});
final AlertDialog dialog = builder.create();
dialog.show();
//Overriding the handler immediately after show is probably a better approach than OnShowListener as described below
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
Boolean wantToCloseDialog = false;
//Do stuff, possibly set wantToCloseDialog to true then...
if(wantToCloseDialog)
dialog.dismiss();
//else dialog stays open. Make sure you have an obvious way to close the dialog especially if you set cancellable to false.
}
});
DialogFragment - Resume()에서 재정의합니다.
@Override
public Dialog onCreateDialog(Bundle savedInstanceState)
{
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setMessage("Test for preventing dialog close");
builder.setPositiveButton("Test",
new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
//Do nothing here because we override this button later to change the close behaviour.
//However, we still need this because on older versions of Android unless we
//pass a handler the button doesn't get instantiated
}
});
return builder.create();
}
//onStart() is where dialog.show() is actually called on
//the underlying dialog, so we have to do it there or
//later in the lifecycle.
//Doing it in onResume() makes sure that even if there is a config change
//environment that skips onStart then the dialog will still be functioning
//properly after a rotation.
@Override
public void onResume()
{
super.onResume();
final AlertDialog d = (AlertDialog)getDialog();
if(d != null)
{
Button positiveButton = (Button) d.getButton(Dialog.BUTTON_POSITIVE);
positiveButton.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
Boolean wantToCloseDialog = false;
//Do stuff, possibly set wantToCloseDialog to true then...
if(wantToCloseDialog)
d.dismiss();
//else dialog stays open. Make sure you have an obvious way to close the dialog especially if you set cancellable to false.
}
});
}
}
대화 상자 기본 설정 - showDialog() 재정의
@Override
protected void onPrepareDialogBuilder(Builder builder)
{
super.onPrepareDialogBuilder(builder);
builder.setPositiveButton("Test", this); //Set the button here so it gets created
}
@Override
protected void showDialog(Bundle state)
{
super.showDialog(state); //Call show on default first so we can override the handlers
final AlertDialog d = (AlertDialog) getDialog();
d.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
Boolean wantToCloseDialog = false;
//Do stuff, possibly set wantToCloseDialog to true then...
if(wantToCloseDialog)
d.dismiss();
//else dialog stays open. Make sure you have an obvious way to close the dialog especially if you set cancellable to false.
}
});
}
접근 방식 설명:
Android 소스 코드를 통해 AlertDialog 기본 구현은 OnCreate()의 모든 실제 버튼에 공통 버튼 핸들러를 등록함으로써 작동합니다.버튼을 클릭하면 공통 버튼 핸들러가 클릭 이벤트를 setButton()에서 전달한 핸들러로 전달한 다음 호출이 대화 상자를 해제합니다.
이러한 버튼 중 하나를 눌렀을 때 대화 상자가 닫히지 않도록 하려면 버튼의 실제 보기를 위해 공통 버튼 핸들러를 교체해야 합니다.OnCreate()에서 할당되므로 기본 OnCreate() 구현이 호출된 후 이를 교체해야 합니다.OnCreate는 show() 메서드의 프로세스에서 호출됩니다.사용자 정의 Dialog 클래스를 만들고 OnCreate()를 재정의하여 슈퍼를 호출할 수 있습니다.Create()에서 버튼 핸들러를 재정의하지만 사용자 지정 대화 상자를 만들면 Builder를 무료로 얻을 수 없습니다. 이 경우 무엇이 중요합니까?
따라서 설계된 방식으로 대화상자를 사용할 때 대화상자를 무시할 때 제어할 수 있는 한 가지 방법은 대화상자를 호출하는 것입니다.먼저 표시()한 다음 dialog.getButton()을 사용하여 버튼에 대한 참조를 가져와 클릭 핸들러를 재정의합니다.또 다른 접근 방식은 setOnShowListener()를 사용하여 버튼 보기를 찾고 OnShowListener에서 처리기를 교체하는 것입니다.원래 대화 상자 인스턴스를 생성하는 스레드에 따라 둘 사이의 기능 차이는 '거의' nill입니다.소스 코드를 살펴보면 onShowListener는 해당 대화 상자를 만든 스레드에서 실행 중인 처리기에 게시된 메시지에 의해 호출됩니다.따라서 OnShowListener는 메시지 대기열에 게시된 메시지에 의해 호출되므로, 기술적으로 쇼가 완료된 후에 청취자 호출이 지연될 수 있습니다.
그러므로, 저는 가장 안전한 접근법이 첫 번째라고 생각합니다: 콜 쇼입니다.대화상자()를 누른 후 동일한 실행 경로에서 즉시 단추 처리기를 바꿉니다.show()를 호출하는 코드는 메인 GUI 스레드에서 작동하므로, 이는 OnShowListener 메서드의 타이밍이 메시지 큐에 따라 결정되는 반면 show()를 따르는 코드는 해당 스레드의 다른 코드보다 먼저 실행된다는 것을 의미합니다.
대체 솔루션
UX 관점에서 대안을 제시하고자 합니다.
단추를 클릭할 때 대화 상자가 닫히지 않도록 하려는 이유는 무엇입니까?아마도 사용자가 선택하지 않았거나 아직 모든 내용을 완전히 작성하지 않은 사용자 지정 대화 상자가 있기 때문일 것입니다.그리고 그것들이 완료되지 않았다면, 당신은 그들이 긍정적인 버튼을 클릭하도록 허용하지 말아야 합니다.모든 것이 준비될 때까지 비활성화하기만 하면 됩니다.
여기에 있는 다른 답변은 긍정적인 버튼 클릭을 무시하는 많은 요령을 제공합니다.그게 중요했다면 안드로이드가 편리한 방법을 만들었을 것 아닙니까?안 했어요.
대신 Dialogs 설계 안내서에 이러한 상황의 예가 나와 있습니다.OK(확인) 버튼은 사용자가 선택할 때까지 비활성화됩니다.우선적인 속임수는 전혀 필요하지 않습니다.사용자는 작업을 계속하기 전에 여전히 무언가를 수행해야 한다는 것을 분명히 알 수 있습니다.
양의 버튼을 비활성화하는 방법
사용자 지정 대화 상자 레이아웃을 만드는 방법은 Android 설명서를 참조하십시오.다음을 배치할 것을 권장합니다.AlertDialog
富士山의 DialogFragment
그런 다음 레이아웃 요소에서 수신기를 설정하여 양수 단추를 사용하거나 사용하지 않도록 설정하기만 하면 됩니다.
- 사용자 지정 대화 상자에 라디오 단추가 있는 경우 라디오 그룹을 사용합니다.Checked Change Listener.
- 사용자 정의 대화 상자에 확인란이 있는 경우 CompoundButton을 사용합니다.Checked Change Listener.
- 사용자 지정 대화 상자에 다음이 있는 경우
EditText
그런 다음 TextWatcher를 사용합니다.
다음과 같이 양극 버튼을 비활성화할 수 있습니다.
AlertDialog dialog = (AlertDialog) getDialog();
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
내용이 .DialogFragment
위의 이미지에서 사용할 수 있는 양의 버튼을 사용하지 않습니다.
import android.support.v4.app.DialogFragment;
import android.support.v7.app.AlertDialog;
public class MyDialogFragment extends DialogFragment {
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// inflate the custom dialog layout
LayoutInflater inflater = getActivity().getLayoutInflater();
View view = inflater.inflate(R.layout.my_dialog_layout, null);
// add a listener to the radio buttons
RadioGroup radioGroup = (RadioGroup) view.findViewById(R.id.radio_group);
radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup radioGroup, int i) {
// enable the positive button after a choice has been made
AlertDialog dialog = (AlertDialog) getDialog();
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(true);
}
});
// build the alert dialog
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setView(view)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
// TODO: use an interface to pass the user choice back to the activity
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
MyDialogFragment.this.getDialog().cancel();
}
});
return builder.create();
}
@Override
public void onResume() {
super.onResume();
// disable positive button by default
AlertDialog dialog = (AlertDialog) getDialog();
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
}
}
사용자 지정 대화 상자는 다음과 같은 활동에서 실행할 수 있습니다.
MyDialogFragment dialog = new MyDialogFragment();
dialog.show(getFragmentManager(), "MyTag");
메모들
- 간결함을 위해 사용자 선택 정보를 활동에 다시 전달하기 위해 통신 인터페이스를 생략했습니다.그러나 문서는 이 작업이 어떻게 수행되는지 보여줍니다.
버튼이 정지해 있습니다.
null
onCreateDialog
그래서 저는 그것을 비활성화했습니다.onResume
이는 사용자가 다른 앱으로 전환한 후 대화 상자를 해제하지 않고 다시 돌아올 경우 다시 비활성화하는 바람직하지 않은 효과를 가져옵니다.이 문제는 사용자 선택을 취소하거나 전화를 걸어 해결할 수도 있습니다.Runnable
onCreateDialog
다음 실행 루프에서 버튼을 비활성화합니다.view.post(new Runnable() { @Override public void run() { AlertDialog dialog = (AlertDialog) getDialog(); dialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false); } });
관련된
대화 상자의 버튼을 누를 때 자동 해제 기능을 비활성화하는 데 사용할 수 있는 간단한 클래스(AlertDialogBuilder)를 작성했습니다.
Android 1.6과도 호환되므로 OnShowListener(API > = 8만 사용 가능)를 사용하지 않습니다.
따라서 AlertDialog를 사용하는 대신에작성자 이 사용자 정의를 사용할 수 있습니다.경보 대화 상자 작성기입니다.가장 중요한 부분은 create()를 호출하지 말고 show() 메서드만 호출해야 한다는 것입니다.setCancelledOn과 같은 메서드를 추가했습니다.Outside()를 누르고 OnDismiss Listener를 설정하면 작성기에서 직접 설정할 수 있습니다.
안드로이드 1.6, 2.x, 3.x, 4.x에서 테스트를 해봤기 때문에 잘 작동할 것입니다.문제가 발견되면 여기에 댓글을 달아주시기 바랍니다.
package com.droidahead.lib.utils;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.view.View;
import android.view.View.OnClickListener;
public class CustomAlertDialogBuilder extends AlertDialog.Builder {
/**
* Click listeners
*/
private DialogInterface.OnClickListener mPositiveButtonListener = null;
private DialogInterface.OnClickListener mNegativeButtonListener = null;
private DialogInterface.OnClickListener mNeutralButtonListener = null;
/**
* Buttons text
*/
private CharSequence mPositiveButtonText = null;
private CharSequence mNegativeButtonText = null;
private CharSequence mNeutralButtonText = null;
private DialogInterface.OnDismissListener mOnDismissListener = null;
private Boolean mCancelOnTouchOutside = null;
public CustomAlertDialogBuilder(Context context) {
super(context);
}
public CustomAlertDialogBuilder setOnDismissListener (DialogInterface.OnDismissListener listener) {
mOnDismissListener = listener;
return this;
}
@Override
public CustomAlertDialogBuilder setNegativeButton(CharSequence text, DialogInterface.OnClickListener listener) {
mNegativeButtonListener = listener;
mNegativeButtonText = text;
return this;
}
@Override
public CustomAlertDialogBuilder setNeutralButton(CharSequence text, DialogInterface.OnClickListener listener) {
mNeutralButtonListener = listener;
mNeutralButtonText = text;
return this;
}
@Override
public CustomAlertDialogBuilder setPositiveButton(CharSequence text, DialogInterface.OnClickListener listener) {
mPositiveButtonListener = listener;
mPositiveButtonText = text;
return this;
}
@Override
public CustomAlertDialogBuilder setNegativeButton(int textId, DialogInterface.OnClickListener listener) {
setNegativeButton(getContext().getString(textId), listener);
return this;
}
@Override
public CustomAlertDialogBuilder setNeutralButton(int textId, DialogInterface.OnClickListener listener) {
setNeutralButton(getContext().getString(textId), listener);
return this;
}
@Override
public CustomAlertDialogBuilder setPositiveButton(int textId, DialogInterface.OnClickListener listener) {
setPositiveButton(getContext().getString(textId), listener);
return this;
}
public CustomAlertDialogBuilder setCanceledOnTouchOutside (boolean cancelOnTouchOutside) {
mCancelOnTouchOutside = cancelOnTouchOutside;
return this;
}
@Override
public AlertDialog create() {
throw new UnsupportedOperationException("CustomAlertDialogBuilder.create(): use show() instead..");
}
@Override
public AlertDialog show() {
final AlertDialog alertDialog = super.create();
DialogInterface.OnClickListener emptyOnClickListener = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) { }
};
// Enable buttons (needed for Android 1.6) - otherwise later getButton() returns null
if (mPositiveButtonText != null) {
alertDialog.setButton(AlertDialog.BUTTON_POSITIVE, mPositiveButtonText, emptyOnClickListener);
}
if (mNegativeButtonText != null) {
alertDialog.setButton(AlertDialog.BUTTON_NEGATIVE, mNegativeButtonText, emptyOnClickListener);
}
if (mNeutralButtonText != null) {
alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, mNeutralButtonText, emptyOnClickListener);
}
// Set OnDismissListener if available
if (mOnDismissListener != null) {
alertDialog.setOnDismissListener(mOnDismissListener);
}
if (mCancelOnTouchOutside != null) {
alertDialog.setCanceledOnTouchOutside(mCancelOnTouchOutside);
}
alertDialog.show();
// Set the OnClickListener directly on the Button object, avoiding the auto-dismiss feature
// IMPORTANT: this must be after alert.show(), otherwise the button doesn't exist..
// If the listeners are null don't do anything so that they will still dismiss the dialog when clicked
if (mPositiveButtonListener != null) {
alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mPositiveButtonListener.onClick(alertDialog, AlertDialog.BUTTON_POSITIVE);
}
});
}
if (mNegativeButtonListener != null) {
alertDialog.getButton(AlertDialog.BUTTON_NEGATIVE).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mNegativeButtonListener.onClick(alertDialog, AlertDialog.BUTTON_NEGATIVE);
}
});
}
if (mNeutralButtonListener != null) {
alertDialog.getButton(AlertDialog.BUTTON_NEUTRAL).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mNeutralButtonListener.onClick(alertDialog, AlertDialog.BUTTON_NEUTRAL);
}
});
}
return alertDialog;
}
}
편집 사용자 정의 사용 방법에 대한 작은 예는 다음과 같습니다.경고 대화 상자 작성기:
// Create the CustomAlertDialogBuilder
CustomAlertDialogBuilder dialogBuilder = new CustomAlertDialogBuilder(context);
// Set the usual data, as you would do with AlertDialog.Builder
dialogBuilder.setIcon(R.drawable.icon);
dialogBuilder.setTitle("Dialog title");
dialogBuilder.setMessage("Some text..");
// Set your buttons OnClickListeners
dialogBuilder.setPositiveButton ("Button 1", new DialogInterface.OnClickListener() {
public void onClick (DialogInterface dialog, int which) {
// Do something...
// Dialog will not dismiss when the button is clicked
// call dialog.dismiss() to actually dismiss it.
}
});
// By passing null as the OnClickListener the dialog will dismiss when the button is clicked.
dialogBuilder.setNegativeButton ("Close", null);
// Set the OnDismissListener (if you need it)
dialogBuilder.setOnDismissListener(new DialogInterface.OnDismissListener() {
public void onDismiss(DialogInterface dialog) {
// dialog was just dismissed..
}
});
// (optional) set whether to dismiss dialog when touching outside
dialogBuilder.setCanceledOnTouchOutside(false);
// Show the dialog
dialogBuilder.show();
건배.
유비
사용 중인 경우 다음과 같은 사항이 있습니다.DialogFragment
대화 상자를 처리하는 데 권장되는 방법입니다.
AlertDialog에서 하는 작업setButton()
방법 (그리고 나는 같은 것을 상상합니다.AlertDialogBuilder
의setPositiveButton()
그리고.setNegativeButton()
설정한 버튼입니다(예:AlertDialog.BUTTON_POSITIVE
Different )를 .OnClickListener
개체를 누릅니다.
첫 번째는 Dialog Interface입니다.ClickListener(클릭 리스너) - 다음에 대한 매개 변수입니다.setButton()
,setPositiveButton()
,그리고.setNegativeButton()
.
다른 하나는 View입니다.OnClickListener(클릭 리스너) - 자동으로 해제하도록 설정됩니다.AlertDialog
중 때 - 를 - 를 누르면 됩니다.AlertDialog
그 자체로
당신이 할 수 있는 것은 사용하는 것입니다.setButton()
와 함께null
▁the로서DialogInterface.OnClickListener
단추를 만든 다음 내부에서 사용자 정의 수행 방법을 호출합니다.View.OnClickListener
를 들어, .를들면예,
@Override
public Dialog onCreateDialog(Bundle savedInstanceState)
{
AlertDialog alertDialog = new AlertDialog(getActivity());
// set more items...
alertDialog.setButton(AlertDialog.BUTTON_POSITIVE, "OK", null);
return alertDialog;
}
그런 다음 기본값을 재정의할 수 있습니다.AlertDialog
buttons' 's buttons'View.OnClickListener
.)DialogFragment
의onResume()
방법:
@Override
public void onResume()
{
super.onResume();
AlertDialog alertDialog = (AlertDialog) getDialog();
Button okButton = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
okButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v)
{
performOkButtonAction();
}
});
}
private void performOkButtonAction() {
// Do your stuff here
}
은 이것을 은설정다설합니에 해야 할 것입니다.onResume()
이유는 은왜하면냐법방▁because면.getButton()
돌아올 것입니다null
대화 상자가 표시될 때까지!
이렇게 하면 사용자 지정 작업 방법이 한 번만 호출되고 대화 상자가 기본적으로 해제되지 않습니다.
Tom의 대답에 영감을 받아, 저는 여기서 아이디어가 다음과 같다고 생각합니다.
- 을 합니다.
onClickListener
대화 상자를 만드는 동안null
- 다음 럼그 세트 를 설정합니다.
onClickListener
대화 상자가 표시된 후에 표시됩니다.
다음을 재정의할 수 있습니다.onShowListener
톰처럼또는 다음과 같은 작업을 수행할 수 있습니다.
- AlertDialog AlertDialog를 한 후 을 얻습니다.
show()
- 단를추채 다우▁the를 설정합니다.
onClickListener
다음과 같이 (조금 더 읽기 쉬운 것 같습니다).
드코:
AlertDialog.Builder builder = new AlertDialog.Builder(context);
// ...
final AlertDialog dialog = builder.create();
dialog.show();
// now you can override the default onClickListener
Button b = dialog.getButton(AlertDialog.BUTTON_POSITIVE);
b.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.i(TAG, "ok button is clicked");
handleClick(dialog);
}
});
초간단 코틀린 접근법
with(AlertDialog.Builder(this)) {
setTitle("Title")
setView(R.layout.dialog_name)
setPositiveButton("Ok", null)
setNegativeButton("Cancel") { _, _ -> }
create().apply {
setOnShowListener {
getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener {
//Validate and dismiss
dismiss()
}
}
}
}.show()
API 8 이전 버전의 경우 부울 플래그, 수신기 해제 및 호출 대화를 사용하여 문제를 해결했습니다.editText의 내용이 올바르지 않은 경우 다시 표시합니다.다음과 같이:
case ADD_CLIENT:
LayoutInflater factoryClient = LayoutInflater.from(this);
final View EntryViewClient = factoryClient.inflate(
R.layout.alert_dialog_add_client, null);
EditText ClientText = (EditText) EntryViewClient
.findViewById(R.id.client_edit);
AlertDialog.Builder builderClient = new AlertDialog.Builder(this);
builderClient
.setTitle(R.string.alert_dialog_client)
.setCancelable(false)
.setView(EntryViewClient)
.setPositiveButton("Save",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int whichButton) {
EditText newClient = (EditText) EntryViewClient
.findViewById(R.id.client_edit);
String newClientString = newClient
.getText().toString();
if (checkForEmptyFields(newClientString)) {
//If field is empty show toast and set error flag to true;
Toast.makeText(getApplicationContext(),
"Fields cant be empty",
Toast.LENGTH_SHORT).show();
add_client_error = true;
} else {
//Here save the info and set the error flag to false
add_client_error = false;
}
}
})
.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int id) {
add_client_error = false;
dialog.cancel();
}
});
final AlertDialog alertClient = builderClient.create();
alertClient.show();
alertClient
.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
//If the error flag was set to true then show the dialog again
if (add_client_error == true) {
alertClient.show();
} else {
return;
}
}
});
return true;
이 링크의 답은 API 3과 바로 호환되는 간단한 솔루션입니다.Tom Bollwitt의 솔루션과 매우 유사하지만 호환성이 떨어지는 OnShowListener를 사용하지 않습니다.
네, 가능합니다.기본적으로 다음을 수행해야 합니다.
- Dialog Builder를 사용하여 대화 상자 만들기
- 대화상자를 표시합니다.
- 표시된 대화 상자에서 버튼을 찾아 onClickListener를 재정의합니다.
텍스트 환경설정 편집을 확장할 때부터 Kamen의 코드를 약간 수정했습니다.
@Override
protected void showDialog(Bundle state) {
super.showDialog(state);
class mocl implements OnClickListener{
private final AlertDialog dialog;
public mocl(AlertDialog dialog) {
this.dialog = dialog;
}
@Override
public void onClick(View v) {
//checks if EditText is empty, and if so tells the user via Toast
//otherwise it closes dialog and calls the EditTextPreference's onClick
//method to let it know that the button has been pressed
if (!IntPreference.this.getEditText().getText().toString().equals("")){
dialog.dismiss();
IntPreference.this.onClick(dialog,DialogInterface.BUTTON_POSITIVE);
}
else {
Toast t = Toast.makeText(getContext(), "Enter a number!", Toast.LENGTH_SHORT);
t.show();
}
}
}
AlertDialog d = (AlertDialog) getDialog();
Button b = d.getButton(DialogInterface.BUTTON_POSITIVE);
b.setOnClickListener(new mocl((d)));
}
정말 재미있습니다!
이 코드는 당신에게 효과가 있을 것입니다. 왜냐하면 저는 비슷한 문제가 있었고 이것은 저에게 효과가 있었기 때문입니다.:)
1 - fragment-dialog 클래스에서 Onstart() 메서드를 재정의합니다.
@Override
public void onStart() {
super.onStart();
final AlertDialog D = (AlertDialog) getDialog();
if (D != null) {
Button positive = (Button) D.getButton(Dialog.BUTTON_POSITIVE);
positive.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
if (edittext.equals("")) {
Toast.makeText(getActivity(), "EditText empty",Toast.LENGTH_SHORT).show();
} else {
D.dismiss(); //dissmiss dialog
}
}
});
}
}
인터넷을 사용할 수 있을 때만 닫아야 하는 대화 상자를 닫지 않으려면
인터넷이 연결될 때까지 또는 연결되지 않은 경우 대화 상자를 닫지 않기 때문에 동일한 작업을 수행하려고 합니다.
내 코드는 다음과 같습니다.
AlertDialog.Builder builder=new AlertDialog.Builder(MainActivity.this); builder.setTitle("Internet Not Connected");
if(ifConnected()){
Toast.makeText(this, "Connected or not", Toast.LENGTH_LONG).show();
}
else{
builder.setPositiveButton("Retry", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
if(!ifConnected())
{
builder.show();
}
}
}).setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
finish();
}
});
builder.show();
}
다음은 연결 관리자 코드입니다.
private boolean ifConnected()
{
ConnectivityManager connectivityManager= (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo=connectivityManager.getActiveNetworkInfo();
return networkInfo!=null && networkInfo.isConnected();
}
진행률 대화 상자
대화 상자가 자동으로 해제되지 않도록 하려면 다음을 설정해야 합니다.OnClickListener
에 ProgressDialog
다음과 같이 표시됩니다.
connectingDialog = new ProgressDialog(this);
connectingDialog.setCancelable(false);
connectingDialog.setCanceledOnTouchOutside(false);
// Create the button but set the listener to a null object.
connectingDialog.setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel",
(DialogInterface.OnClickListener) null )
// Show the dialog so we can then get the button from the view.
connectingDialog.show();
// Get the button from the view.
Button dialogButton = connectingDialog.getButton( DialogInterface.BUTTON_NEGATIVE);
// Set the onClickListener here, in the view.
dialogButton.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick ( View v ) {
// Dialog will not get dismissed until you call dismiss() explicitly.
}
});
public class ComentarDialog extends DialogFragment{
private EditText comentario;
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
LayoutInflater inflater = LayoutInflater.from(getActivity());
View v = inflater.inflate(R.layout.dialog_comentar, null);
comentario = (EditText)v.findViewById(R.id.etxt_comentar_dialog);
builder.setTitle("Comentar")
.setView(v)
.setPositiveButton("OK", null)
.setNegativeButton("CANCELAR", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
});
return builder.create();
}
@Override
public void onStart() {
super.onStart();
//Obtenemos el AlertDialog
AlertDialog dialog = (AlertDialog)getDialog();
dialog.setCanceledOnTouchOutside(false);
dialog.setCancelable(false);//Al presionar atras no desaparece
//Implementamos el listener del boton OK para mostrar el toast
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(TextUtils.isEmpty(comentario.getText())){
Toast.makeText(getActivity(), "Ingrese un comentario", Toast.LENGTH_SHORT).show();
return;
}
else{
((AlertDialog)getDialog()).dismiss();
}
}
});
//Personalizamos
Resources res = getResources();
//Buttons
Button positive_button = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
positive_button.setBackground(res.getDrawable(R.drawable.btn_selector_dialog));
Button negative_button = dialog.getButton(DialogInterface.BUTTON_NEGATIVE);
negative_button.setBackground(res.getDrawable(R.drawable.btn_selector_dialog));
int color = Color.parseColor("#304f5a");
//Title
int titleId = res.getIdentifier("alertTitle", "id", "android");
View title = dialog.findViewById(titleId);
if (title != null) {
((TextView) title).setTextColor(color);
}
//Title divider
int titleDividerId = res.getIdentifier("titleDivider", "id", "android");
View titleDivider = dialog.findViewById(titleDividerId);
if (titleDivider != null) {
titleDivider.setBackgroundColor(res.getColor(R.color.list_menu_divider));
}
}
}
builder.show()를 추가할 수 있습니다. 반환 전에 유효성 확인 메시지가 표시된 후;
이것처럼.
public void login()
{
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setView(R.layout.login_layout);
builder.setTitle("Login");
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int id)
{
dialog.cancel();
}
});// put the negative button before the positive button, so it will appear
builder.setPositiveButton("Ok", new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int id)
{
Dialog d = (Dialog) dialog;
final EditText etUserName = (EditText) d.findViewById(R.id.etLoginName);
final EditText etPassword = (EditText) d.findViewById(R.id.etLoginPassword);
String userName = etUserName.getText().toString().trim();
String password = etPassword.getText().toString().trim();
if (userName.isEmpty() || password.isEmpty())
{
Toast.makeText(getApplicationContext(),
"Please Fill all fields", Toast.LENGTH_SHORT).show();
builder.show();// here after validation message before retrun
// it will reopen the dialog
// till the user enter the right condition
return;
}
user = Manager.get(getApplicationContext()).getUserByName(userName);
if (user == null)
{
Toast.makeText(getApplicationContext(),
"Error ethier username or password are wrong", Toast.LENGTH_SHORT).show();
builder.show();
return;
}
if (password.equals(user.getPassword()))
{
etPassword.setText("");
etUserName.setText("");
setLogged(1);
setLoggedId(user.getUserId());
Toast.makeText(getApplicationContext(),
"Successfully logged in", Toast.LENGTH_SHORT).show();
dialog.dismiss();// if every thing is ok then dismiss the dialog
}
else
{
Toast.makeText(getApplicationContext(),
"Error ethier username or password are wrong", Toast.LENGTH_SHORT).show();
builder.show();
return;
}
}
});
builder.show();
}
이 코드를 사용하면 긍정 버튼을 클릭할 때 대화 상자가 닫히지 않도록 할 수 있습니다.또한 네거티브 버튼으로도 동일하게 구현할 수 있습니다.
final AlertDialog alertDialog = alertDialogBuilder
.setCancelable(false)
.setTitle("TITLE");
.setPositiveButton("OK", null)
.setNegativeButton("CANCEL",
(dialog, id) -> {
dialog.cancel();
})
.show();
Button positiveButton = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
positiveButton.setOnClickListener(v -> {
// check whatever you want
if(checkMyCondition())
dialog.cancel();
})
사중인경우를 .material design
저는 자료 대화를 확인하는 것을 제안합니다.현재 열려 있는 안드로이드 버그(78088 참조)와 관련된 몇 가지 문제를 해결했지만, 가장 중요한 것은 이 티켓에 대한 것입니다.autoDismiss
설수있플그래는할을 할 때 할 수 Builder
.
사용자 지정 레이아웃 사용DialogFragment
그리고 a를 추가LinearLayout
Google Material Design과 일치하도록 테두리 없는 것으로 스타일링할 수 있는 콘텐츠 아래에 있습니다. 다음 해당 버튼을 .OnClickListener
.
예:
public class AddTopicFragment extends DialogFragment {
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
// Get the layout inflater
LayoutInflater inflater = getActivity().getLayoutInflater();
final View dialogView = inflater.inflate(R.layout.dialog_add_topic, null);
Button saveTopicDialogButton = (Button) dialogView.findViewById(R.id.saveTopicDialogButton);
Button cancelSaveTopicDialogButton = (Button) dialogView.findViewById(R.id.cancelSaveTopicDialogButton);
final AppCompatEditText addTopicNameET = (AppCompatEditText) dialogView.findViewById(R.id.addTopicNameET);
final AppCompatEditText addTopicCreatedByET = (AppCompatEditText) dialogView.findViewById(R.id.addTopicCreatedByET);
saveTopicDialogButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// validate inputs
if(addTopicNameET.getText().toString().trim().isEmpty()){
addTopicNameET.setError("Topic name can't be empty");
addTopicNameET.requestFocus();
}else if(addTopicCreatedByET.getText().toString().trim().isEmpty()){
addTopicCreatedByET.setError("Topic created by can't be empty");
addTopicCreatedByET.requestFocus();
}else {
// save topic to database
Topic topic = new Topic();
topic.name = addTopicNameET.getText().toString().trim();
topic.createdBy = addTopicCreatedByET.getText().toString().trim();
topic.createdDate = new Date().getTime();
topic.save();
AddTopicFragment.this.dismiss();
}
}
});
cancelSaveTopicDialogButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
AddTopicFragment.this.dismiss();
}
});
// Inflate and set the layout for the dialog
// Pass null as the parent view because its going in the dialog layout
builder.setView(dialogView)
.setMessage(getString(R.string.add_topic_message));
return builder.create();
}
}
dialog_add_details.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:padding="@dimen/activity_horizontal_margin"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:errorEnabled="true">
<android.support.v7.widget.AppCompatEditText
android:id="@+id/addTopicNameET"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Topic Name"
android:inputType="textPersonName"
android:maxLines="1" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:errorEnabled="true">
<android.support.v7.widget.AppCompatEditText
android:id="@+id/addTopicCreatedByET"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Created By"
android:inputType="textPersonName"
android:maxLines="1" />
</android.support.design.widget.TextInputLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:text="@string/cancel"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/cancelSaveTopicDialogButton"
style="@style/Widget.AppCompat.Button.ButtonBar.AlertDialog" />
<Button
android:text="@string/save"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/saveTopicDialogButton"
style="@style/Widget.AppCompat.Button.ButtonBar.AlertDialog" />
</LinearLayout>
</LinearLayout>
코틀린
val dialogView = LayoutInflater.from(requireContext()).inflate(R.layout.dialog_userinput, null)
val dialogBuilder = MaterialAlertDialogBuilder(requireContext(), R.style.AlertDialogTheme)
dialogBuilder.setView(dialogView)
dialogBuilder.setCancelable(false)
dialogBuilder.setPositiveButton("send",null)
dialogBuilder.setNegativeButton("cancel") { dialog,_ ->
dialog.dismiss()
}
val alertDialog = dialogBuilder.create()
alertDialog.show()
val positiveButton = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE)
positiveButton.setOnClickListener {
val myInputText = dialogView.etxt_userinput.text.toString().trim()
if(myInputText.isNotEmpty()){
//Do something
}else{
//Prompt error
dialogView.etxt_userinput.error = "Please fill this"
}
}
우리는 단지 그것을 만들 뿐입니다.AlertDialog
dialogBuilder
대로 .
가장 쉬운 방법으로 제작할 수 있습니다.
사용자 정의 보기와 두 개의 버튼(양 및 음)이 있는 경보 대화 상자.
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()).setTitle(getString(R.string.select_period));
builder.setPositiveButton(getString(R.string.ok), null);
builder.setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// Click of Cancel Button
}
});
LayoutInflater li = LayoutInflater.from(getActivity());
View promptsView = li.inflate(R.layout.dialog_date_picker, null, false);
builder.setView(promptsView);
DatePicker startDatePicker = (DatePicker)promptsView.findViewById(R.id.startDatePicker);
DatePicker endDatePicker = (DatePicker)promptsView.findViewById(R.id.endDatePicker);
final AlertDialog alertDialog = builder.create();
alertDialog.show();
Button theButton = alertDialog.getButton(DialogInterface.BUTTON_POSITIVE);
theButton.setOnClickListener(new CustomListener(alertDialog, startDatePicker, endDatePicker));
사용자 지정 알림 대화 상자의 긍정 버튼 목록:
private class CustomListener implements View.OnClickListener {
private final Dialog dialog;
private DatePicker mStartDp, mEndDp;
public CustomListener(Dialog dialog, DatePicker dS, DatePicker dE) {
this.dialog = dialog;
mStartDp = dS;
mEndDp = dE;
}
@Override
public void onClick(View v) {
int day1 = mStartDp.getDayOfMonth();
int month1= mStartDp.getMonth();
int year1 = mStartDp.getYear();
Calendar cal1 = Calendar.getInstance();
cal1.set(Calendar.YEAR, year1);
cal1.set(Calendar.MONTH, month1);
cal1.set(Calendar.DAY_OF_MONTH, day1);
int day2 = mEndDp.getDayOfMonth();
int month2= mEndDp.getMonth();
int year2 = mEndDp.getYear();
Calendar cal2 = Calendar.getInstance();
cal2.set(Calendar.YEAR, year2);
cal2.set(Calendar.MONTH, month2);
cal2.set(Calendar.DAY_OF_MONTH, day2);
if(cal2.getTimeInMillis()>=cal1.getTimeInMillis()){
dialog.dismiss();
Log.i("Dialog", "Dismiss");
// Condition is satisfied so do dialog dismiss
}else {
Log.i("Dialog", "Do not Dismiss");
// Condition is not satisfied so do not dialog dismiss
}
}
}
다 했어요.
다른 방법을 찾아냈어요
1단계: 메소드(또는 C의 함수)에 대화 상자 열기 코드를 넣습니다.
of 2(온클릭 시): onClick(온클릭 시)yes
(긍정 버튼), 조건이 충족되지 않는 경우 이 대화 상자 열기 방법을 재귀적으로 호출합니다(if...else... 사용).아래와 같이:
private void openSave() {
final AlertDialog.Builder builder=new AlertDialog.Builder(Phase2Activity.this);
builder.setTitle("SAVE")
.setIcon(R.drawable.ic_save_icon)
.setPositiveButton("Save", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
if((!editText.getText().toString().isEmpty() && !editText1.getText().toString().isEmpty())){
createPdf(fileName,title,file);
}else {
openSave();
Toast.makeText(Phase2Activity.this, "Some fields are empty.", Toast.LENGTH_SHORT).show();
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();
}
})
.setCancelable(false)
.create()
.show();
}
그러나 이 경우 대화 상자가 잠시 사라지면 즉시 다시 나타납니다.:)
이것은 아마도 매우 늦은 답장일 것이지만, setCancelable을 사용하면 효과가 있을 것입니다.
alertDial.setCancelable(false);
언급URL : https://stackoverflow.com/questions/2620444/how-to-prevent-a-dialog-from-closing-when-a-button-is-clicked
'programing' 카테고리의 다른 글
값을 전환하는 방법? (0) | 2023.07.16 |
---|---|
Firebase용 Cloud Functions(multer, busboy)에서 Express를 사용하여 HTTP 파일 업로드를 수행하는 방법 (0) | 2023.07.06 |
ID가 Next 페이지 매개 변수에 없을 때 ID별 API 리소스를 가져오는 방법 (0) | 2023.07.06 |
SQL Server 2008에서 SQL Profiler는 어디에 있습니까? (0) | 2023.07.06 |
스크립트 열거형에 문자열 값을 할당할 수 없습니다(Initializer 유형 문자열을 변수 유형에 할당할 수 없음). (0) | 2023.07.06 |