#android #android-arrayadapter
#Android #android-arrayadapter
Вопрос:
Я хочу показать имя пользователя списка и его номер телефона с сервера в качестве предложения ниже AutoCompleteTextView. Мне не нужен фильтр, потому что я уже получаю результат фильтрации с сервера. Я добавил TextWatcher в AutoCompleteTextView при каждом изменении текста он будет вызывать API. Я создал пользовательский адаптер, но он ничего не показывает.
ArrayList объявлен как глобальный
ArrayList<NameModel> nameList = new ArrayList<>();
AutoCompleteAdapter autoCompleteAdapter;
onCreate
autoCompleteAdapter = new AutoCompleteAdapter(this,nameList);
txtNumber.setAdapter(autoCompleteAdapter);
txtNumber.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 number = s.toString();
if (number.matches("^[0-9]*$") amp;amp; number.length() == 10){
btnAdd.setVisibility(View.VISIBLE);
}else {
btnAdd.setVisibility(View.GONE);
GetNames(s);
}
}
@Override
public void afterTextChanged(Editable s) {
}
});
GetNames()
nameList.clear();
autoCompleteAdapter.notifyDataSetChanged();
String params = inst_id "/?name=" text;
StringRequest stringRequest = new StringRequest(Request.Method.GET, getResources().getString(R.string.ipmain) GET_NAME_URL params, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
try {
JSONArray jsonArray = new JSONArray(response);
for (int i=0;i<jsonArray.length();i ){
JSONObject jsonObject = jsonArray.getJSONObject(i);
String name = jsonObject.getString("first_name") " " jsonObject.getString("last_name");
String role = jsonObject.getString("role");
String number = jsonObject.getString("phone_number");
NameModel nameModel = new NameModel(name,role,number);
nameList.add(nameModel);
}
autoCompleteAdapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
}
Адаптер — который является подклассом родительского
private class AutoCompleteAdapter extends ArrayAdapter<NameModel> {
Context cntx;
ArrayList<NameModel> listGlobal;
AutoCompleteAdapter(@NonNull Context context, ArrayList<NameModel> list) {
super(context,R.layout.item_attendance,list);
cntx = context;
listGlobal = list;
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
if (convertView == null){
convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_attendance, parent, false);
}
TextView txtName = convertView.findViewById(R.id.txtName);
TextView txtRole = convertView.findViewById(R.id.txtGender);
TextView txtPhone = convertView.findViewById(R.id.txtPhone);
txtName.setText(listGlobal.get(position).getName());
txtRole.setText(listGlobal.get(position).getRole());
txtPhone.setText(listGlobal.get(position).getNumber());
return convertView;
}
@Override
public int getCount() {
Log.d("Adpter List:",String.valueOf(listGlobal.size()));
Log.d("Main List:",String.valueOf(nameList.size()));
return listGlobal.size();
}
}
сбой при вводе второй буквы (ничего не отображается при вводе первой буквы)
java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.get(ArrayList.java:411)
at android.widget.ArrayAdapter.getItem(ArrayAdapter.java:349)
at android.widget.AutoCompleteTextView.buildImeCompletions(AutoCompleteTextView.java:1241)
at android.widget.AutoCompleteTextView.showDropDown(AutoCompleteTextView.java:1201)
at android.widget.AutoCompleteTextView.updateDropDownForFilter(AutoCompleteTextView.java:1084)
at android.widget.AutoCompleteTextView.-wrap2(AutoCompleteTextView.java)
at android.widget.AutoCompleteTextView$PopupDataSetObserver$1.run(AutoCompleteTextView.java:1409)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)
Ответ №1:
Я думаю, вам нужно пересмотреть следующее
1. После выполнения удаленного строкового запроса убедитесь, что вы обновили AutoCompleteAdapter новым списком имен.
2. убедитесь, что в списке массивов есть значения, прежде чем вызывать autoCompleteAdapter = new AutoCompleteAdapter(this,nameList);
Комментарии:
1. Уже добавляю данные в nameList и после этого notifyingDataSetChanged();
2. ну, я не вижу, где вы обновляете свой адаптер, я предполагаю, что у вас либо есть метод внутри адаптера public void updateList(List<String> newlist) { nameList.clear(); nameList.addAll(newlist); this.notifyDataSetChanged(); }, либо вы выполняете вызов удаленного серверавнутри самого адаптера?
3. где определен метод GetNames() ?
4. внутри родительского класса
5. итак, вы предполагаете, что список имен будет обновляться внутри адаптера, потому что это глобальная переменная? если нет штрафа, если да, это не сработает, потому что Java передается по значению, а не передается по ссылке
Ответ №2:
попробуйте аннулировать и перезапустить Android studio.
или
удалите файлы .gradle, .iml, .idea и перестройте свой проект
Комментарии:
1. нет, что-то не так в коде. Я попробовал решение ur, но не сработало.
Ответ №3:
У вас возникли проблемы, потому что вы используете ArrayAdapter. ArrayAdapter сохраняет свой собственный список и работает с ним, поэтому, когда вы предоставляете список в конструкторе, адаптер создает копию и использует ее для заполнения представлений. Когда вы обновляете свой объект list, копия адаптера не обновляется, но поскольку вы переопределяете метод getCount и возвращаете ненулевое значение, адаптер пытается извлечь элемент из пустого списка.
Решение: вместо этого вы должны использовать BaseAdapter. Или, если вы хотите использовать ArrayAdapter, вам следует изменить список адаптеров, используя вместо этого ArrayAdapter.add(), ArrayAdapter.clear() и т. Д.