【问题标题】:Android AutoCompleteTextView with custom Adapter带有自定义适配器的 Android AutoCompleteTextView
【发布时间】:2018-07-11 17:57:13
【问题描述】:

我陷入了与此非常相似的情况:Android: Using item selected in AutoCompleteTextView to populate another field

在 SO 阅读了这么多帖子和答案数小时后,我设法达到了 AutoCompleteTextView 正在使用自定义 XML 布局填充客户列表(我需要的自定义对象/ POJO)的地步,但我得到了这个错误似乎是由于索引逻辑而发生的:

java.lang.IndexOutOfBoundsException:索引:2,大小:2 在 java.util.ArrayList.get(ArrayList.java:437) 在 irisdesigns.studio.jewellery.Model.CustomerAutoAdapter.getView(CustomerAutoAdapter.java:76) 在 android.widget.AbsListView.obtainView(AbsListView.java:2365) 在 android.widget.DropDownListView.obtainView(DropDownListView.java:305) 在 android.widget.ListView.measureHeightOfChildren(ListView.java:1408) 在 android.widget.ListPopupWindow.buildDropDown(ListPopupWindow.java:1257) 在 android.widget.ListPopupWindow.show(ListPopupWindow.java:613) 在 android.widget.AutoCompleteTextView.showDropDown(AutoCompleteTextView.java:1217) 在 android.widget.AutoCompleteTextView.updateDropDownForFilter(AutoCompleteTextView.java:1086) 在 android.widget.AutoCompleteTextView.onFilterComplete(AutoCompleteTextView.java:1068) 在 android.widget.Filter$ResultsHandler.handleMessage(Filter.java:285) 在 android.os.Handler.dispatchMessage(Handler.java:106) 在 android.os.Looper.loop(Looper.java:164) 在 android.app.ActivityThread.main(ActivityThread.java:6494) 在 java.lang.reflect.Method.invoke(本机方法) 在 com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)

有人可以帮忙吗? 适配器代码

public class CustomerAutoAdapter extends ArrayAdapter implements Filterable {

    private ArrayList<CustomerSuggestion> customerSuggestions, filteredList;


    public CustomerAutoAdapter(Context context, ArrayList<CustomerSuggestion> customerSuggestions) {
        super(context, 0, customerSuggestions);
        this.customerSuggestions = customerSuggestions;
        this.filteredList = customerSuggestions;
    }



    @Nullable
    @Override
    public CustomerSuggestion getItem(int position) {
        return customerSuggestions.get(position);
    }


    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View view = convertView;
        if (convertView == null) {
            view = LayoutInflater.from(parent.getContext()).inflate(R.layout.litem_customer_autocomplete, parent, false);
        }
        CustomerSuggestion customerSuggestion = filteredList.get(position);
        if (customerSuggestion != null) {
            ((TextView) view.findViewById(R.id.tv_cust_auto_name)).setText(customerSuggestion.getCustomer().getName());
            ((TextView) view.findViewById(R.id.tv_cust_auto_ph)).setText(customerSuggestion.getCustomer().getPh1());
            ((TextView) view.findViewById(R.id.tv_cust_auto_email)).setText(customerSuggestion.getCustomer().getEmail());
        }
        return view;
    }


    @Override
    public Filter getFilter() {
        return filter;
    }


    // Custom Filter implementation for custom suggestions we provide.
    private Filter filter = new Filter() {
        @Override
        public CharSequence convertResultToString(Object resultValue) {
            return ((CustomerSuggestion) resultValue).getCustomer().getName();
        }


        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            if (constraint != null && constraint.length()>1) {
                ArrayList<CustomerSuggestion> filteredList = new ArrayList<>();
                for (CustomerSuggestion customerSuggestion : customerSuggestions)
                    if (customerSuggestion.getCustomer().getName().toLowerCase().contains(constraint.toString().toLowerCase()))
                        filteredList.add(customerSuggestion);

                FilterResults filterResults = new FilterResults();
                filterResults.values = filteredList;
                filterResults.count = filteredList.size();
                return filterResults;
            } else
                return new FilterResults();
        }


        @SuppressWarnings("unchecked")
        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            if (results != null && results.count > 0) {
                filteredList = (ArrayList<CustomerSuggestion>) results.values;
                notifyDataSetChanged();
            }
            else
                filteredList = customerSuggestions;
        }
    };
}

MainActivity 代码: Text Watched 和 setAdapter

final CustomerAutoAdapter customerAutoAdapter = new CustomerAutoAdapter(getApplicationContext(),customerSuggestions);
            et_customer_name.setAdapter(customerAutoAdapter);

            et_customer_name.addTextChangedListener(new TextWatcher() {
                @Override
                public void onTextChanged(CharSequence s, int start, int before, int count) {
                }

                @Override
                public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                }

                @Override
                public void afterTextChanged(Editable s) {
                    // you can use runnable postDelayed like 500 ms to delay search text
                    cust_key = "";
                    if (userExists) {
                        et_phone1.setText("");
                        et_cc_phone1.setText("+91");
                        et_phone2.setText("");
                        et_cc_phone2.setText("");
                        et_email.setText("");
                        tv_btn_od_create_phone.setText("+ Phone");

                        et_phone1.setEnabled(true);
                        et_cc_phone1.setEnabled(true);
                        et_phone2.setEnabled(true);
                        et_cc_phone2.setEnabled(true);
                        et_email.setEnabled(true);
                        tv_btn_od_create_phone.setEnabled(true);

                        tv_btn_od_create_phone.setVisibility(View.VISIBLE);
                        et_phone2.setVisibility(View.GONE);
                        et_cc_phone2.setVisibility(View.GONE);
                    }
                    userExists = false;
                    // customerAutoAdapter.filter(et_customer_name.getText().toString());
                }
            });

AutoCompleteTextView setOnClickListener:

et_customer_name.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
                    cust_key = customerSuggestions.get(position).getCust_key();
                    autoFillData(position);
                    userExists = true;
                }
            });

【问题讨论】:

    标签: java android adapter android-arrayadapter


    【解决方案1】:

    在这一行 CustomerSuggestion customerSuggestion = filteredList.get(position); 尝试使用原始列表而不是过滤后的列表,如下所示。

    CustomerSuggestion customerSuggestion = customerSuggestions.get(position);
    

    经过一番搜索,我认为这是因为这种适配器的主列表是原始列表而不是过滤后的列表,因此引用原始列表调用get view方法!

    【讨论】:

    • 我想它会起作用,因为我遇到过这个问题
    • 感谢@Giulio Pettenuzzo,这似乎已经解决了。不过,在确认之前,我会再次对其进行彻底检查。但是我仍然不明白,为什么使用/显示原始列表(customerSuggestions)而不是过滤列表?适配器将如何/将如何显示过滤结果?
    • @viditkothari 我编辑答案给你一个解释,记得点赞并接受答案,这样你也会获得一些积分
    • 嗨@GiulioPettenuzzo 感谢您的更新。正如我所说,这部分代码现在没有错误,但它没有过滤结果。每次我开始输入时,都会弹出完整列表,但我没有看到过滤结果?我想我需要了解 getfilter 和其他 Filterable 实现如何以及何时工作,因为有了这种理解,我将能够修复我的代码。您是否有资源/文章显示适配器的流程图或生命周期之类的内容?
    猜你喜欢
    • 2023-03-19
    • 2013-10-07
    • 1970-01-01
    • 1970-01-01
    • 2021-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多