¿Cómo deshabilitar / habilitar los botones positivos negativos de diálogo?

111

Consulte el cuadro de diálogo personalizado a continuación. Tengo un campo de texto de edición en el diálogo y si el campo de texto está vacío, me gustaría deshabilitar el archivo positiveButton. Puedo obtener un charListener para el campo de texto, pero no estoy seguro de cómo voy a configurar positivebuttonpara deshabilitar o habilitar desde ese oyente. ¿Cuál es la referencia para los botones positivos y negativos?

 case DIALOG_TEXT_ENTRY:
    // This example shows how to add a custom layout to an AlertDialog
    LayoutInflater factory = LayoutInflater.from(this);
    final View textEntryView = factory.inflate(R.layout.alert_dialog_text_entry, null);
    return new AlertDialog.Builder(AlertDialogSamples.this)
        .setIconAttribute(android.R.attr.alertDialogIcon)
        .setTitle(R.string.alert_dialog_text_entry)
        .setView(textEntryView)
        .setPositiveButton(R.string.alert_dialog_ok, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int whichButton) {
                /* User clicked OK so do some stuff */
            }
        })
        .setNegativeButton(R.string.alert_dialog_cancel, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int whichButton) {
                /* User clicked cancel so do some stuff */
            }
        })
        .create();
}
akd
fuente
Creo que esta respuesta responde a su pregunta [ stackoverflow.com/questions/4291548/… [1]: stackoverflow.com/questions/4291548/…
Alexander Kulyakhtin
gracias pero esta no es la respuesta. aunque podría ayudar. porque deshabilita el botón después de hacer clic en sí mismo. que no es lo que quiero. Me gustaría mostrarlo deshabilitado depende del campo de texto.
akd
1
if (editTextEmailAddress.getText (). toString (). length () == 0)
SALMAN
Básicamente, está creando un objeto con referencia anónima una vez creado, no puede volver a hacer referencia a él. Gracias.
SALMAN

Respuestas:

207

Editar para una solución completa ...

AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setIcon(android.R.drawable.ic_dialog_info);
builder.setTitle("Alert dialog title");
builder.setMessage("This is the example code snippet to disable button if edittext attached to dialog is empty.");
builder.setPositiveButton("PositiveButton",
        new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface arg0, int arg1) {
                // DO TASK
            }
        });
builder.setNegativeButton("NegativeButton",
        new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface arg0, int arg1) {
                // DO TASK
            }
        });

// Set `EditText` to `dialog`. You can add `EditText` from `xml` too.
final EditText input = new EditText(MainActivity.this);

LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
        LinearLayout.LayoutParams.MATCH_PARENT,
        LinearLayout.LayoutParams.MATCH_PARENT
);
input.setLayoutParams(lp);


builder.setView(input);

final AlertDialog dialog = builder.create();
dialog.show();

// Initially disable the button
((AlertDialog) dialog).getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);

// OR you can use here setOnShowListener to disable button at first time.

// Now set the textchange listener for edittext
input.addTextChangedListener(new TextWatcher() {

    @Override
    public void onTextChanged(CharSequence s, int start, int before,
            int count) {
    }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count,
            int after) {
    }

    @Override
    public void afterTextChanged(Editable s) {

        // Check if edittext is empty
        if (TextUtils.isEmpty(s)) {
            // Disable ok button
            ((AlertDialog) dialog).getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);

        } else {
            // Something into edit text. Enable the button.
            ((AlertDialog) dialog).getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(true);
        }

    }
});

A continuación se muestra el historial editado, que se puede consultar como algunos detalles más

Aquí hay un código de muestra, intente esto

AlertDialog.Builder builder = new AlertDialog.Builder(AddSchedule.this);
builder.setIcon(android.R.drawable.ic_dialog_info);
builder.setTitle("Alert dialog title");
builder.setMessage("Dialog message");
builder.setPositiveButton("Button1", new DialogInterface.OnClickListener() {
    public void onClick(DialogInterface arg0, int arg1) {
        //DO TASK
    }
});
builder.setNegativeButton("Button2", new DialogInterface.OnClickListener() {
    public void onClick(DialogInterface arg0, int arg1) {
        //DO TASK
    }
});

AlertDialog dialog = builder.create();
dialog.show();

// After calling show method, you need to check your condition and enable/disable the dialog buttons 
if (your_condition_true) {
    // BUTTON1 is the positive button
    dialog.getButton(AlertDialog.BUTTON1).setEnabled(false);
}

Para botón negativo

dialog.getButton(AlertDialog.BUTTON2).setEnabled(false); //BUTTON2 is negative button

Para la identificación de los botones : referencia alert_dialog.xml

Editado:

Y el setOnShowListener desde el nivel 8 API (FroYo), hace lo mismo,

AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setPositiveButton(android.R.string.ok, null);

AlertDialog dialog = builder.create();
dialog.setOnShowListener(new OnShowListener() {

    @Override
    public void onShow(DialogInterface dialog) {
        if (condition) {
            ((AlertDialog)dialog).getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
        }
    }
});

dialog.show();

Editado

new AlertDialog.Builder(this)
    .setMessage("This may take a while")
    .setPositiveButton("OK", new android.content.DialogInterface.OnClickListener() {

        @Override
        public void onClick(DialogInterface dialog, int which) {
            ((AlertDialog)dialog).getButton(which).setVisibility(View.INVISIBLE);
            // the rest of your stuff
        }

    }).show();

Pankaj Kumar
fuente
corríjame si me equivoco, pero cuando volvió a llamar a AlertDialog, ¿volvió a llamar a su objeto o aún lo usa? No conozco este método. ¿Debería explicarlo brevemente? Gracias :)
NovusMobile
Para los skimmers, me gustaría agregar que dialog.getButton () solo funciona para AlertDialogs, por lo que es posible que tenga que lanzar el diálogo a AlertDialog como lo hace más abajo en la publicación.
Noumenon
no funciona, también leo el código al menos 5x, y todavía no tiene sentido por qué debería funcionar :) La respuesta correcta está a continuación de Nick Palmer
qkx
@qkx ¿Puede explicar lo que está tratando de hacer? ¿Puede mostrar el código relevante? Y no seas irónico y no votes en contra.
Pankaj Kumar
1
No quería ser irónico, grosero. También intenté anular el voto, pero no es posible ... Sin embargo, una vez más, el problema: ¿dónde tiene un oyente de texto en su código, puede decirme? No importa cuál sea la condición, si se llama solo una vez. Si no tiene un escucha de texto como Nick a continuación, es simplemente imposible que su solución funcione ... O me perdí algo. O envíeme un proyecto de Android simple para demostrar que está funcionando;)
qkx
25

Ninguna de estas respuestas realmente resuelve el problema.

Lo logro usando un diseño personalizado con un EditText y un TextWatcher en esa vista.

final LinearLayout layout = (LinearLayout) inflator.inflate(R.layout.text_dialog, null);
final EditText text = (EditText) layout.findViewById(R.id.text_edit);
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setView(layout);
// Now add the buttons...
builder.setPositiveButton(R.string.ok, new AlertDialog.OnClickListener() {
    // Left out for brevity...
}
builder.setNegativeButton(R.string.cancel, new AlertDialog.OnClickListener() {
    // Left out for brevity...
}

// Create the dialog
final AlertDialog d = builder.create();

// Now add a TextWatcher that will handle enable/disable of save button
text.addTextChangedListener(new TextWatcher() {
    private void handleText() {
        // Grab the button
        final Button okButton = d.getButton(AlertDialog.BUTTON_POSITIVE);
        if(text.getText().length() == 0) {
            okButton.setEnabled(false);
        } else {
            okButton.setEnabled(true);
        }
    }
    @Override
    public void afterTextChanged(Editable arg0) {
        handleText();
    }
    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        // Nothing to do
    }
    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
       // Nothing to do
    }
});

// show the dialog
d.show();
// and disable the button to start with
d.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
Nick Palmer
fuente
Esta respuesta está incompleta, no hay declaración ded
androidguy
Editado para agregar la construcción de d.
Nick Palmer
4

Aquí está el código completo para habilitar y deshabilitar el botón positivo del diálogo:

AlertDialog.Builder builder = new AlertDialog.Builder(this);
LayoutInflater layoutInflater = MainActivity.this.getLayoutInflater();
View view = layoutInflater.inflate(R.layout.dialog,null);

builder.setView(view);
builder.setTitle("Test");
builder.setPositiveButton("ok", new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
        Toast.makeText(MainActivity.this, "Ok clicked", Toast.LENGTH_SHORT).show();
        dialog.dismiss();
    }
});
builder.setNegativeButton("cancel", null);

final AlertDialog alertDialog = builder.create();

alertDialog.show();

EditText editText = (EditText)view.findViewById(R.id.mobile_number);
alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
editText.addTextChangedListener(new TextWatcher() {
    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {}

    @Override
    public void afterTextChanged(Editable s) {
        if (s.length() >= 1) {
            alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(true);
        } else {
            alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);

        }
    }
});
Kalpesh Kumawat
fuente
1

Puede escribir un oyente en el cuadro de texto de edición e intentar habilitar o deshabilitar botones. Este es un código de muestra para xamarin.

var dialog = builder.Create();

dialog.Show();

var btnOk = dialog.GetButton((int)DialogButtonType.Positive).Enabled = false;

_enterTextDialogEditText.AfterTextChanged += (sender, e) => {
  if (!string.IsNullOrEmpty(_enterTextDialogEditText.Text)) {
    dialog.GetButton((int)DialogButtonType.Positive).Enabled = true;
  } else {
    dialog.GetButton((int)DialogButtonType.Positive).Enabled = false;
  }
};
Ravi Kiran
fuente
0

Para eliminar el registro de la vista de lista de la base de datos usando el titular de la vista, usó este código en su método getview ().

viewHolder.btn.setOnClickListener (nuevo OnClickListener () {

                @Override
                public void onClick(View arg0) {
                    // TODO Auto-generated method stub
                    AlertDialog.Builder alertDialog2 = new AlertDialog.Builder(
                            Favorate.this.getParent());

                    // Setting Dialog Title
                    alertDialog2.setTitle("Confirm Delete...");

                    // Setting Dialog Message
                    alertDialog2
                            .setMessage("Are you sure you want delete ?");

                    // Setting Icon to Dialog
                    alertDialog2.setIcon(R.drawable.delete);

                    // Setting Positive "Yes" Btn
                    alertDialog2.setPositiveButton("YES",
                            new DialogInterface.OnClickListener() {
                                public void onClick(DialogInterface dialog,
                                        int which) {
                                    // Write your code here to execute after
                                    // dialog

                                    int id = _items.get(position).id;
                                    db.deleterecord(id);

                                    db.close();
                                }
                            });
                    // Setting Negative "NO" Btn
                    alertDialog2.setNegativeButton("NO",
                            new DialogInterface.OnClickListener() {
                                public void onClick(DialogInterface dialog,
                                        int which) {
                                    // Write your code here to execute after
                                    // dialog

                                    dialog.cancel();
                                }
                            });

                    // Showing Alert Dialog
                    alertDialog2.show();

                }
            });

Lee mas

Roadies
fuente
0

Este dialogFragment hará el trabajo por usted. Tenga en cuenta que el cuadro de diálogo permanecerá abierto después de la rotación de la pantalla conservando cualquier texto que el usuario ya haya escrito. Si no desea que eso suceda, debe descartar el fragmento en el onStop de su actividad. La firma del método newInstance se puede cambiar a lo que necesite.

import android.app.Activity;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AlertDialog;
import android.text.Editable;
import android.text.TextWatcher;
import android.widget.EditText;

public class TextViewDialogFragment extends DialogFragment implements DialogInterface.OnClickListener, DialogInterface.OnShowListener, TextWatcher
{
    final static private String TITLE = "title", MESSAGE = "message", IDENTIFIER = "identifier", INPUT_TYPE = "inputType", POSITIVE_TEXT = "pText", NEGATIVE_TEXT = "nText", CANCELABLE = "cancelable";

    public TextViewDialogFragment()
    {
        super();
    }

    static public TextViewDialogFragment newInstance(int title, @Nullable String message, int identifier, int inputType, int positiveText, int negativeText, boolean cancelable)
    {
        TextViewDialogFragment fragement = new TextViewDialogFragment();
        Bundle args = new Bundle();
        args.putInt(TITLE, title);
        args.putString(MESSAGE, message);
        args.putInt(IDENTIFIER, identifier);
        args.putInt(INPUT_TYPE, inputType);
        args.putInt(POSITIVE_TEXT, positiveText);
        args.putInt(NEGATIVE_TEXT, negativeText);
        args.putBoolean(CANCELABLE, cancelable);
        fragement.setArguments(args);
        return fragement;
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState)
    {
        Activity activity =  getActivity();
        Bundle args = getArguments();
        EditText input = new EditText(activity);
        input.setInputType(args.getInt(INPUT_TYPE));
        input.setId(R.id.dialog_edit_text);
        input.addTextChangedListener(this);
        AlertDialog.Builder alert = new AlertDialog.Builder(activity);
        alert.setCancelable(args.getBoolean(CANCELABLE)).setTitle(args.getInt(TITLE)).setMessage(args.getString(MESSAGE)).setView(input).setPositiveButton(args.getInt(POSITIVE_TEXT), this);
        int negativeText = args.getInt(NEGATIVE_TEXT);
        if (negativeText != 0)
        {
            alert.setNegativeButton(negativeText, this);
        }
        AlertDialog dialog = alert.create();
        dialog.setOnShowListener(this);
        return dialog;
    }

    @Override
    public void onShow(DialogInterface dialog)
    {
        // After device rotation there may be some text present.
        if (((EditText)((AlertDialog) dialog).findViewById(R.id.dialog_edit_text)).length() == 0)
        {
            ((AlertDialog) dialog).getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
        }
    }

    @Override
    public void onClick(DialogInterface dialog, int which)
    {
        String text = ((EditText)((AlertDialog) dialog).findViewById(R.id.dialog_edit_text)).getText().toString();
        ((Callbacks) getActivity()).onTextViewDialogResult(which, getArguments().getInt(IDENTIFIER), text);
    }

    @Override
    public void onCancel(DialogInterface dialog)
    {
        ((Callbacks) getActivity()).onTextViewDialogActivityCancelled(getArguments().getInt(IDENTIFIER));
        super.onCancel(dialog);
    }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after)
    {
    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count)
    {
    }

    @Override
    public void afterTextChanged(Editable s)
    {
        ((AlertDialog) getDialog()).getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(s.length() > 0);
    }

    void setMessage(String message)
    {
        Bundle args = getArguments();
        args.putString(MESSAGE, message);
        setArguments(args);
    }

    interface Callbacks
    {
        void onTextViewDialogResult(int which, int identity, String text);
        void onTextViewDialogActivityCancelled(int identity);
    }
}

Agregue implementos a su actividad (cualquier tipo de actividad está bien):

public class Myctivity extends AppCompatActivity implements TextViewDialogFragment.Callbacks
{
...
}

Cree el diaglogFragment en su actividad de esta manera:

final static int SOMETHING = 1;
myDF = TextViewDialogFragment.newInstance(R.string.my_title, "my message", SOMETHING, InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_CAP_WORDS | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES, /* Whatever is best for your user. */    R.string.yay, android.R.string.cancel, true);

Maneje el resultado en su actividad de esta manera:

@Override
public void onTextViewDialogResult(int which, int identity, String text)
{
    if (which == AlertDialog.BUTTON_NEGATIVE)
    {
        // User did not want to do anything.
        return;
    }
    // text now holds the users answer.
    // Identity can be used if you use the same fragment for more than one type of question.
}
@Override
public void onTextViewDialogActivityCancelled(int identity)
{
    // This is invoked if you set cancelable to true and the user pressed the back button.
}

Necesita crear el identificador de recursos, así que agregue este recurso en algún lugar debajo de res / valores

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <item name="dialog_edit_text" type="id"/>
</resources> 
Steve Waring
fuente
-1
if (editTextEmailAddress.getText().toString().length() == 0) {
    btnCancelCross.setEnabled(false);
} else {
    btnCancelCross.setEnabled(true);
}

Eso podría ayudarte, gracias.

SALMAN
fuente
gracias pero esto no es lo que estoy buscando. Puedo hacerlo usando un cuadro de diálogo personalizado y crear un diseño con el botón y habilitarlo para desactivarlo. Lo que estoy buscando es que haya una forma de deshabilitar o habilitar los botones de diálogo positivos y negativos integrados. Si miras el código que compartí, verás lo que estoy buscando. Pero gracias de nuevo por el código.
akd
2
Por favor, publique una respuesta completa sobre el tema (solo edite su respuesta existente, no siga publicando respuestas adicionales).
Tim Post