AutocompleteTextView dismissDropDown() not working

40 views Asked by At

I have an autocomplete textview that fires a HTTP request when text changes, to search in a remote database. The problem is when I click an item of the dropdown the TextWatcher detects it as a text change, so the dropdown never closes, even using dismissDropdown() method inside setOnItemClickListener. If I dont use the showDropdown() method, the dropdown closes correctly after clicking an item, but it has a weird behavior, in example: if result has 8 items it only shows 2 or never show them.

autocompleteDeposito.addTextChangedListener(new TextWatcher() {
           @Override
           public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
               // No se necesita implementar
           }

           @Override
           public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
               String nombreDeposito = charSequence.toString().trim();

               String url = "http://MY_SERVER_IP/buscarDeposito.php";
               StringRequest stringRequest = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
                   @Override
                   public void onResponse(String response) {
                       try {
                           JSONObject jsonObject = new JSONObject(response);
                           boolean success = jsonObject.getBoolean("success");

                           if (success) {
                               JSONArray data = jsonObject.getJSONArray("data");
                               ArrayList<Deposito> depositoList = new ArrayList<>();

                               for (int i = 0; i < data.length(); i++) {
                                   JSONObject empleado = data.getJSONObject(i);

                                   String idDeposito = empleado.getString("id");
                                   String nombreDeposito = empleado.getString("nombre");
                                   Deposito dep = new Deposito(nombreDeposito, idDeposito);

                                   depositoList.add(dep);
                               }

                               AutoCompleteTextView autocompleteDeposito = findViewById(R.id.autocompleteDeposito);

                               // Configura un adaptador para el AutoCompleteTextView con los nombres de los empleados
                               ArrayAdapter<Deposito> adapter = new ArrayAdapter<>(
                                       RegistroActivity.this,
                                       android.R.layout.simple_dropdown_item_1line,
                                       depositoList);

                               autocompleteDeposito.setThreshold(2);
                               autocompleteDeposito.setAdapter(adapter);
                               autocompleteDeposito.showDropDown();

                               autocompleteDeposito.setOnItemClickListener((parent, view, position, id) -> {
                                   Deposito depositoSeleccionado = (Deposito) parent.getItemAtPosition(position);
                                   depositoSeleccionadoId = depositoSeleccionado.getId();
                                   autocompleteDeposito.dismissDropDown();
                               });

                           } else {
                               Toast.makeText(RegistroActivity.this, "No se encontrĂ³ el empleado", Toast.LENGTH_SHORT).show();
                           }
                       } catch (JSONException e) {
                           e.printStackTrace();
                           Toast.makeText(RegistroActivity.this, "Error al procesar respuesta", Toast.LENGTH_LONG).show();
                       }
                   }
               }, new Response.ErrorListener() {
                   @Override
                   public void onErrorResponse(VolleyError error) {
                       // Errores de la solicitud
                   }
               }) {
                   @Override
                   protected Map<String, String> getParams() {
                       // ParĂ¡metros POST
                       Map<String, String> params = new HashMap<>();
                       params.put("nombre_deposito", nombreDeposito);
                       return params;
                   }
               };

               RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
               requestQueue.add(stringRequest);

           }

           @Override
           public void afterTextChanged(Editable editable) {
               // No se necesita implementar
           }
       }); 

XML:

<AutoCompleteTextView
    android:id="@+id/autocompleteDeposito"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginStart="44dp"
    android:layout_marginTop="180dp"
    android:layout_marginEnd="44dp"
    android:hint="@string/deposito_autocomplete"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintHorizontal_bias="0.0"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="@+id/toolbar" />
1

There are 1 answers

0
pmpato On

Solved by adding the next condition (not the best but the simplest).

This way if depositoSeleccionadoNombre (selected item) and paramDeposito (search parameter) are equal, it means the user has already selected an option so the dropdown should not be shown:

// Declare depositoSeleccionadoNombre before protected void onCreate(Bundle savedInstanceState)
String depositoSeleccionadoNombre = "";

autocompleteDeposito.addTextChangedListener(new TextWatcher() {
    @Override
    public void beforeTextChanged(CharSequence sec, int start, int count, int after) {

    }

    @Override
    public void onTextChanged(CharSequence sec, int start, int before, int count) {
        String paramBusqueda = sec.toString().trim();

        if (paramBusqueda.length() > 1) {
            buscarDeposito(paramBusqueda);
        }
    }

    @Override
    public void afterTextChanged(Editable sec) {

    }
});

private void buscarDeposito(String paramDeposito) {
    // Rest of the code...

    if (!depositoSeleccionadoNombre.equals(paramDeposito)) {
        autocompleteDeposito.showDropDown();
    }

    autocompleteDeposito.setOnItemClickListener((parent, view, position, id) -> {
        Deposito depositoSeleccionado = (Deposito) parent.getItemAtPosition(position);
        depositoSeleccionadoId = depositoSeleccionado.getId();
        depositoSeleccionadoNombre = depositoSeleccionado.getNombre();
    });
}