Search code examples
androidandroid-spinnerandroid-alertdialogandroid-textwatcheronitemselectedlistener

Enable Button when Spinner and EditText are not empty in Dialog


In my AlertDialog, I have a Spinner and an EditText. I am trying to disable the positive button of the dialog if

  1. selected item at Spinner is "Select currency" ("Select currency" is the first item in my Array and Spinner is set to return String currencyName as "") or
  2. EditText is empty.

In the code below, if I have input in EditText before selecting item in Spinner, the positive button remains disabled. I have no idea how to make these two work together.

Any help will be much appreciated. Thanks.

private void openDialog(){
    LayoutInflater inflater = LayoutInflater.from(MainActivity.this);
    View subView = inflater.inflate(R.layout.dialog_layout, null);
    final EditText subEditTextExchangeRate = subView.findViewById(R.id.textInputExchangeRate);
    final Spinner subSpinner = subView.findViewById(R.id.spinner);

    ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, R.array.currency, android.R.layout.simple_spinner_item);
    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    subSpinner.setAdapter(adapter);
    subSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
            if(parent.getItemAtPosition(position).equals("Select currency")){
                currencyName = "";

            }else {
                currencyName = parent.getItemAtPosition(position).toString();
            }
        }
        @Override
        public void onNothingSelected(AdapterView<?> parent) {

        }
    });

    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setView(subView);

    builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            exchangeRate = subEditTextExchangeRate.getText().toString();
            st2 = exchangeRate;
        }
    });

    builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {

        }
    });


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

    alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
    subEditTextExchangeRate.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) {
            String exchangeRateInput = subEditTextExchangeRate.getText().toString();
            alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(!exchangeRateInput.isEmpty() && !currencyName.isEmpty()); 
        }//This is the logic that I am looking for but the method is watching only EditText

        @Override
        public void afterTextChanged(Editable s) {

        }
    });
}

Solution

  • Please try below code with only one change, put below line in subSpinner.setOnItemSelectedListener and also please declare alertDialog globally.

    alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(!exchangeRateInput.isEmpty() && !currencyName.isEmpty());

    Here is Your Code.

    private void openDialog(){
        LayoutInflater inflater = LayoutInflater.from(MainActivity.this);
        View subView = inflater.inflate(R.layout.dialog_layout, null);
        final EditText subEditTextExchangeRate = subView.findViewById(R.id.textInputExchangeRate);
        final Spinner subSpinner = subView.findViewById(R.id.spinner);
    
        ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, R.array.currency, android.R.layout.simple_spinner_item);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        subSpinner.setAdapter(adapter);
        subSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                if(parent.getItemAtPosition(position).equals("Select currency")){
                    currencyName = "";
    
                }else {
                    currencyName = parent.getItemAtPosition(position).toString();
                }
                alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(!exchangeRateInput.isEmpty() && !currencyName.isEmpty()); 
            }
            @Override
            public void onNothingSelected(AdapterView<?> parent) {
    
            }
        });
    
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setView(subView);
    
        builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                exchangeRate = subEditTextExchangeRate.getText().toString();
                st2 = exchangeRate;
            }
        });
    
        builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
    
            }
        });
    
    
        alertDialog = builder.create();
        alertDialog.show();
    
        alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
        subEditTextExchangeRate.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) {
                String exchangeRateInput = subEditTextExchangeRate.getText().toString();
                alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(!exchangeRateInput.isEmpty() && !currencyName.isEmpty()); 
            }//This is the logic that I am looking for but the method is watching only EditText
    
            @Override
            public void afterTextChanged(Editable s) {
    
            }
        });
    }