android android-arrayadapter baseadapter autocompletetextview

android - Cómo crear BaseAdapter personalizado para AutoCompleteTextView



android-arrayadapter (2)

Clase BaseAdapter personalizada

public class ObjectAdapter extends BaseAdapter implements Filterable { private Context context; private ArrayList<Object> originalList; private ArrayList<Object> suggestions = new ArrayList<>(); private Filter filter = new CustomFilter(); /** * @param context Context * @param originalList Original list used to compare in constraints. */ public ObjectAdapter(Context context, ArrayList<Object> originalList) { this.context = context; this.originalList = originalList; } @Override public int getCount() { return suggestions.size(); // Return the size of the suggestions list. } @Override public Object getItem(int position) { return suggestions.get(position).getCountryName(); } @Override public long getItemId(int position) { return 0; } /** * This is where you inflate the layout and also where you set what you want to display. * Here we also implement a View Holder in order to recycle the views. */ @Override public View getView(int position, View convertView, ViewGroup parent) { LayoutInflater inflater = LayoutInflater.from(context); ViewHolder holder; if (convertView == null) { convertView = inflater.inflate(R.layout.adapter_autotext, parent, false); holder = new ViewHolder(); holder.autoText = (TextView) convertView.findViewById(R.id.autoText); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } holder.autoText.setText(suggestions.get(position).getCountryName()); return convertView; } @Override public Filter getFilter() { return filter; } private static class ViewHolder { TextView autoText; } /** * Our Custom Filter Class. */ private class CustomFilter extends Filter { @Override protected FilterResults performFiltering(CharSequence constraint) { suggestions.clear(); if (originalList != null && constraint != null) { // Check if the Original List and Constraint aren''t null. for (int i = 0; i < originalList.size(); i++) { if (originalList.get(i).getCountryName().toLowerCase().contains(constraint)) { // Compare item in original list if it contains constraints. suggestions.add(originalList.get(i)); // If TRUE add item in Suggestions. } } } FilterResults results = new FilterResults(); // Create new Filter Results and return this to publishResults; results.values = suggestions; results.count = suggestions.size(); return results; } @Override protected void publishResults(CharSequence constraint, FilterResults results) { if (results.count > 0) { notifyDataSetChanged(); } else { notifyDataSetInvalidated(); } } } }

Clase de actividad principal

public class MainActivity extends AppCompatActivity{ private SGetCountryListAdapter countryAdapter; private ArrayList<SGetCountryList> countryList; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); country = (AutoCompleteTextView) findViewById(R.id.country); countryAdapter = new SGetCountryListAdapter(getApplicationContext(), ConnectionParser.SGetCountryList); country.setAdapter(countryAdapter); country.setThreshold(1); } }

Diseño desplegable

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:id="@+id/autoText" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="8dp" android:layout_marginEnd="16dp" android:layout_marginLeft="16dp" android:layout_marginRight="16dp" android:layout_marginStart="16dp" android:layout_marginTop="8dp" android:textColor="@color/black" /> </LinearLayout>

Mi lista original tiene datos tomados del servicio web, así que supongamos que ya tiene datos. Por supuesto, puede personalizar aún más el menú desplegable agregando más vistas, solo no olvide actualizar el adaptador para incorporar las nuevas vistas.

He tenido dificultades para crear un ArrayAdapter personalizado para AutoCompleteTextView, tales errores que aparecerían a pesar de que el siguiente código encontrado en Internet sería:

  • El menú desplegable no aparecerá.
  • Los objetos personalizados y sus detalles no aparecerían.

Entonces, para aquellos que tienen o tuvieron el mismo problema que yo, recomiendo usar BaseAdapter para AutoCompleteTextView en su lugar.


El siguiente es mi código de trabajo usando ArrayAdapter .

Supongamos que los datos de respuesta del servicio web tienen el siguiente aspecto:

[ { "id": "1", "name": "Information Technology" }, { "id": "2", "name": "Human Resources" }, { "id": "3", "name": "Marketing and PR" }, { "id": "4", "name": "Research and Developement" } ]

Luego en tu cliente Android:

Clase de departamento:

public class Department { public int id; public String name; }

Clase de adaptador personalizado:

public class DepartmentArrayAdapter extends ArrayAdapter<Department> { private final Context mContext; private final List<Department> mDepartments; private final List<Department> mDepartmentsAll; private final int mLayoutResourceId; public DepartmentArrayAdapter(Context context, int resource, List<Department> departments) { super(context, resource, departments); this.mContext = context; this.mLayoutResourceId = resource; this.mDepartments = new ArrayList<>(departments); this.mDepartmentsAll = new ArrayList<>(departments); } public int getCount() { return mDepartments.size(); } public Department getItem(int position) { return mDepartments.get(position); } public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { try { if (convertView == null) { LayoutInflater inflater = ((Activity) mContext).getLayoutInflater(); convertView = inflater.inflate(mLayoutResourceId, parent, false); } Department department = getItem(position); TextView name = (TextView) convertView.findViewById(R.id.textView); name.setText(department.name); } catch (Exception e) { e.printStackTrace(); } return convertView; } @Override public Filter getFilter() { return new Filter() { @Override public String convertResultToString(Object resultValue) { return ((Department) resultValue).name; } @Override protected FilterResults performFiltering(CharSequence constraint) { FilterResults filterResults = new FilterResults(); List<Department> departmentsSuggestion = new ArrayList<>(); if (constraint != null) { for (Department department : mDepartmentsAll) { if (department.name.toLowerCase().startsWith(constraint.toString().toLowerCase())) { departmentsSuggestion.add(department); } } filterResults.values = departmentsSuggestion; filterResults.count = departmentsSuggestion.size(); } return filterResults; } @Override protected void publishResults(CharSequence constraint, FilterResults results) { mDepartments.clear(); if (results != null && results.count > 0) { // avoids unchecked cast warning when using mDepartments.addAll((ArrayList<Department>) results.values); for (Object object : (List<?>) results.values) { if (object instanceof Department) { mDepartments.add((Department) object); } } notifyDataSetChanged(); } else if (constraint == null) { // no filter, add entire original list back in mDepartments.addAll(mDepartmentsAll); notifyDataSetInvalidated(); } } }; } }

Actividad principal:

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mAutoCompleteTextView = (AutoCompleteTextView) findViewById(R.id.autoCompleteTextView); mAutoCompleteTextView.setThreshold(1); new DepartmentRequest().execute(); } private class DepartmentRequest extends AsyncTask<Void, Void, JSONArray> { @Override protected JSONArray doInBackground(Void... voids) { OkHttpJsonArrayRequest request = new OkHttpJsonArrayRequest(); try { return request.get("http://..."); } catch (IOException | JSONException e) { e.printStackTrace(); } return null; } @Override protected void onPostExecute(JSONArray jsonArray) { super.onPostExecute(jsonArray); if (jsonArray != null && jsonArray.length() > 0) { Gson gson = new Gson(); Department[] departments = gson.fromJson(jsonArray.toString(), Department[].class); mDepartmentList = Arrays.asList(departments); mDepartmentArrayAdapter = new DepartmentArrayAdapter(mContext, R.layout.simple_text_view, mDepartmentList); mAutoCompleteTextView.setAdapter(mDepartmentArrayAdapter); } } } private class OkHttpJsonArrayRequest { OkHttpClient client = new OkHttpClient(); // HTTP GET REQUEST JSONArray get(String url) throws IOException, JSONException { Request request = new Request.Builder() .url(url) .build(); Response response = client.newCall(request).execute(); return new JSONArray(response.body().string()); } }

Aquí está la captura de pantalla:

¡Espero que esto ayude!