Search code examples
androidandroid-alertdialogaddtextchangedlistener

reference to custom AlertDialog button returns null when onTextChanged


I am working on an application that uses a custom view for an AlertDialog. I want to make it so that the submit button is disabled if the edit text field is empty. I found a few examples online but my in my implementation keeps returning null on the reference to the submit button. as soon as I enter any text into the edittext the app crashes. here is alertdialog class with my failing attempt at grabbing the button commented out:

public class FileNameDialogFragment extends DialogFragment {
private static final String TAG = "dialogFragment";

private EditText namefield;
private Button submit;

@Override
public Dialog onCreateDialog(Bundle savedInstanceState){

    LayoutInflater inflater = LayoutInflater.from(getActivity());
    View v = inflater.inflate(R.layout.file_prompt_dialog, null, false);
    namefield = (EditText) v.findViewById(R.id.nameField);

    AlertDialog dialog = new AlertDialog.Builder(getActivity())
            .setTitle(R.string.dialog_title)
            .setView(v)
            .setIcon(R.drawable.icon)
            .setPositiveButton(R.string.btnOK, new DialogInterface.OnClickListener(){

                @Override
                public void onClick(DialogInterface dialog, int which) {
                    MainActivity.setFileName(namefield.getText().toString());
                    String fileName = namefield.getText().toString();
                    Toast.makeText(getActivity(), MainActivity.getUrl().toString(), Toast.LENGTH_SHORT).show();
                    MainActivity.download(MainActivity.getUrl(), getActivity(), MainActivity.getPath(), fileName);
                }
            })
            .setNegativeButton(R.string.btnCancel, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dismiss();
                }
            })
            .create();

            //I have also tried to place the code that is below here. neither works

    dialog.show();
    /*
     *  this is the section of code that i am having trouble with
     *
    submit = ((AlertDialog)dialog).getButton(AlertDialog.BUTTON_POSITIVE);
    namefield.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            //left intentionally blank
        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            if (count == 0){
                submit.setEnabled(false);
            }else{
                submit.setEnabled(true);<--NullPointerException
            }
        }

        @Override
        public void afterTextChanged(Editable s) {
            //left intentionally blank
        }
    });*/
    return dialog;
}
}

I am hoping to find out how to make this work as a way to validate input. i don't want the user to be able to leave this field blank because the input is used to name a file that is downloaded from the internet.


Solution

  • You can try the code below, I have specified how you can disable custom button as well as dialog's positive/negative button depending on your editText value

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        LayoutInflater inflater = LayoutInflater.from(getActivity());
        View v = inflater.inflate(R.layout.file_prompt_dialog, null, false);
        namefield = v.findViewById(R.id.nameField);
    
        //To get custom button of dialog
        submit = v.findViewById(R.id.submitBtn);
    
        final AlertDialog dialog = new AlertDialog.Builder(getActivity())
                .setTitle(R.string.dialog_title)
                .setView(v)
                .setIcon(R.mipmap.ic_launcher)
                .setPositiveButton(R.string.btnOK, new DialogInterface.OnClickListener(){
    
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        MainActivity.setFileName(namefield.getText().toString());
                        String fileName = namefield.getText().toString();
                        Toast.makeText(getActivity(), "Positive Button", Toast.LENGTH_SHORT).show();
                        MainActivity.download(MainActivity.getUrl(), getActivity(), MainActivity.getPath(), fileName);
                    }
                })
                .setNegativeButton(R.string.btnCancel, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dismiss();
                    }
                })
                .create();
    
        dialog.show();
    
        //Dialog's positive button
        dialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
    
        //Custom button
        submit.setEnabled(false);
    
        namefield.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                //left intentionally blank
            }
    
            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                if (count == 0){
    
                    //To disable dialog's positive button
                    dialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
    
                    //To disable custom button
                    submit.setEnabled(false);
                }else{
    
                    //To enable dialog/s positive button
                    dialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(true);
    
                    //To enable custom button
                    submit.setEnabled(true);
                }
            }
    
            @Override
            public void afterTextChanged(Editable s) {
                //left intentionally blank
            }
        });
    
        return dialog;
    }