当文本更改以在远程数据库中搜索时,我有一个自动完成文本视图会触发 HTTP 请求。问题是,当我单击下拉列表中的某个项目时,TextWatcher 会将其检测为文本更改,因此下拉列表永远不会关闭,即使在 setOnItemClickListener 中使用 dismissDropdown() 方法也是如此。如果我不使用 showDropdown() 方法,下拉菜单在单击某个项目后会正确关闭,但它有一个奇怪的行为,例如:如果结果有 8 个项目,它只显示 2 个或从不显示它们。
@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
}
}); ```
<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" />
通过添加下一个条件来解决(不是最好的,而是最简单的)。
这样,如果 DepositoSeleccionadoNombre (所选项目)和 paramDeposito (搜索参数)相等,则意味着用户已经选择了一个选项,因此不应显示下拉列表:
// 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();
});
}