首页 文章

带有异步建议的AutocompleteTextView不会显示下拉列表

提问于
浏览
8

我将 TextChangedListener 添加到 AutocompleteTextView . 在 TextChangedListenerafterTextChanged() 中,我调用了 AsyncTask ,它从web加载数据(在活动开始时加载所有数据不是一个选项,因为列表可能非常大,所以它只是浪费流量) . AsyncTaskonPostExecute() 看起来像那样(我使用 ArrayAdapter ):

@Override
    protected void onPostExecute(ArrayList<Subregion> result)
    {
        super.onPostExecute(result);
        if (result != null)
        {
            adapter.clear();
            for (Iterator<Subregion> iterator = result.iterator(); iterator.hasNext();)
            {
                Subregion subregion = iterator.next();
                adapter.add(subregion);
            }
            adapter.notifyDataSetChanged();
            autocompleteTextView.showDropDown();
        }
    }

Subregion 是我的自定义对象,覆盖 toString() . 我希望我的程序在用户开始输入时开始加载数据,并在收到和解析它们时立即显示结果 .

我的问题:

autocompleteTextView.showDropDown() 无效 . onPostExecute() 收到正确的数据列表,它们被添加到适配器,但 showDropDown() 不是't show the dropdown. What'的事情?

3 回答

  • 6

    我正在做同样的事情,我刚刚实现了这个功能 . 不是清除适配器并单独构建它,而是将适配器设置如下(我在onPostExecute中调用的函数中执行此操作);

    //suggestions is a string array of suggestions.
    suggestAdapter = new ArrayAdapter<String>(this, R.layout.suggestions, suggestions);
    //The autocomplete view 
    suggestions.setAdapter(this.suggestAdapter);
    suggestAdapter.notifyDataSetChanged();
    

    您不需要显式调用showdropdown,当适配器通知它数据已更改时,自动完成视图会自动更新 .

    你也可以打电话

    adapter.setNotifyOnChange(true)
    

    这使得无需打电话

    adapter.notifyDatasetChanged()
    

    setNotifyOnChange希望我能提供帮助 .

  • 18

    我也遇到过这个问题 . 我的完成阈值是2.当输入2个字符时,我从服务器获取数据并填充了数组适配器,但 autoRailwayFrom.showDropDown(); 没有显示下拉...

    我只是写在线,它的工作原理......

    autoRailwayFrom.setText(autoRailwayFrom.getText());
    adapterFrom.notifyDataSetChanged();
    autoRailwayFrom.showDropDown();
    
  • 1

    这个问题已得到解答,但我认为这不是一个好方法 - 关键是所有人都是可过滤的界面 . 这里有适配器的工作示例,基于BaseAdapter . 缺少这里的部分是沟通(我使用了Retrofit):

    public class UsersAutoAdapter extends BaseAdapter implements Filterable
    {
        {
            DaggerGraphManager.INSTANCE.inject(this);
        }
    
        @Inject
        CommunicationManager mCommunicationManager;
    
        private FindUserResponse mFindUserResponse;
    
        @Override
        public int getCount()
        {
            if (mFindUserResponse != null && mFindUserResponse.mUsers != null)
            {
                return mFindUserResponse.mUsers.size();
            }
    
            return 0;
        }
    
        @Override
        public Object getItem(int i)
        {
            return mFindUserResponse.mUsers.get(i);
        }
    
        @Override
        public long getItemId(int i)
        {
            return i;
        }
    
        @Override
        public View getView(int i, View pView, ViewGroup pViewGroup)
        {
            if (pView == null)
            {
                LayoutInflater inflater = LayoutInflater.from(pViewGroup.getContext());
                pView = inflater.inflate(R.layout.ac_item_user, pViewGroup, false);
            }
            TextView textViewUserName = (TextView) pView.findViewById(R.id.text_view_user_name);
            textViewUserName.setText(mFindUserResponse.mUsers.get(i).mUserName);
    
    
            return pView;
        }
    
        @Override
        public Filter getFilter()
        {
            return new Filter()
            {
                //this method is called async (not from UI thread!) so making network request is possible here
                @Override
                protected FilterResults performFiltering(CharSequence pCharSequence)
                {
    
                    if (pCharSequence != null && pCharSequence.length() >= 3)
                    {
                        FindUserResponse users = mCommunicationManager.findUsersSync(pCharSequence.toString());
    
                        FilterResults results = new FilterResults();
    
                        results.values = users;
                        results.count = users.mUsers.size();
    
                        return results;
                    }
                    return null;
                }
    
                //this is UI thread called method (just after performFiltering returns it's results
                @Override
                protected void publishResults(CharSequence pCharSequence, FilterResults pFilterResults)
                {
                    if (pFilterResults != null)
                    {
                        mFindUserResponse = (FindUserResponse) pFilterResults.values;
                        notifyDataSetInvalidated();
                    }
                }
            };
        }
    }
    

相关问题