自动完成文本视图强制显示所有项目

20

我的应用中有一个场景,需要强制显示建议列表中的所有条目,无论用户键入了什么。我该如何做到这一点?

我尝试使用过滤器来实现,但对于我这样的初学者来说,过滤器太过复杂了。我尝试搜索过滤器的入门教程,但没有找到任何有用的内容。也许有一种更简单的方法可以强制显示所有建议项吗?

编辑: 基本上我的想法是,当用户输入不在列表中的内容时,显示所有可用选项。

我已经找到了检查ACTV是否正在显示的最佳方法,但在TextChangeEvent中,我将用户键入的文本与我的列表进行比较,如果没有找到任何元素,则显示完整列表。

public void onTextChanged(CharSequence s, int start, int before, int count)
         {                
           final EditText editText = (EditText) findViewById(R.id.vardsUserInput);
            String strValue = editText.getText().toString().toUpperCase();
            String temp;
            int Cc=0; //my count variable
            for(int i=0; i<vardi.length; i++)
            {
                temp = vardi[i].toUpperCase();
                if(temp.startsWith(strValue.toUpperCase()))
                {
                    Log.d("testing",vardi[i]);
                    Cc++;                                                   
                }
            }               
        if(Cc == 0)
        {
        //Show all the available options
    textView.showDropDown();                    
         }                  
}
12个回答

15

你没有定义想要显示所有结果的“时刻”,所以我希望这个方法适用。但是尝试一些类似于这样的东西:

AutoCompleteTextView autoComplete;
String savedText;

public void showAll() {
    savedText = autoComplete.getText().toString();
    autoComplete.setText("");
    autoComplete.showDropDown();
}

public void restore() {
    autoComplete.setText(savedText);
}

1
当我尝试这个时,我立即收到了“很遗憾,此应用程序已停止”的消息。但我并不真正理解在哪里应该使用恢复功能。 - XCoder
好的,那么我需要一些关于你问题的上下文。请在你的问题中发布相关的代码,并描述你想要显示所有内容的时刻。 - Sam
@XCoder 很好的描述!您是否正在使用FilterQueryProvider和数据库来更新您的AutoCompleteTextView? - Sam
不,我不是。我会看一下的。如果我无法弄清楚,我会喊一声的,因为ACTV中的过滤器很令人困惑。 - XCoder

15

这对我来说完美地起作用了,这是解决问题的简单方法:

final ArrayAdapter<String> adapter = new ArrayAdapter<>(getContext(), android.R.layout.simple_dropdown_item_1line, usernameLists);
    etUsername.setThreshold(1);
    etUsername.setAdapter(adapter);
    etUsername.setOnTouchListener(new View.OnTouchListener() {

        @SuppressLint("ClickableViewAccessibility")
        @Override
        public boolean onTouch(View paramView, MotionEvent paramMotionEvent) {
            if (usernameLists.size() > 0) {
                // show all suggestions
                if (!etUsername.getText().toString().equals(""))
                    adapter.getFilter().filter(null);
                etUsername.showDropDown();
            }
            return false;
        }
    });

这个解决方案比其他的要简短和简单得多,使用AutoCompleteTextView代替那个该死的Spinner完成工作,我可以设置提示和错误,再也不用使用那个Spinner了,谢谢 :) - user3718908x100
我使用了 OnClickListener,同时将 focusable 属性设置为 false。 - user3718908x100
挽救了情况。谢谢! - Dhaval Patel
这种方法可以工作,但是当您再次单击该字段时,它不会关闭下拉菜单,而是重新打开它!! - G. Ciardini

15

要阻止适配器过滤您的内容,您可以在TextView上设置足够高的阈值:

autoCompleteTextView.setThreshold(100);

希望对您有所帮助。


1
对我有用。新的Material暴露下拉框给我带来了问题。用户选择项目后,它不再显示适配器项,所以这是完美的解决方案!谢谢。 - Izak
非常感谢,我已经面临这个问题好几天了,只有这个解决了我的问题。 - Andrain

9

基本上,在经过5-6小时的实验来了解这个该死的过滤器是如何工作之后,我编写了自己的适配器,它完全符合我的要求:

    public class burtuAdapteris extends ArrayAdapter<String> implements Filterable {

       ArrayList<String> _items = new ArrayList<String>();
       ArrayList<String> orig = new ArrayList<String>();

       public burtuAdapteris(Context context, int resource, ArrayList<String> items) {
           super(context, resource, items);    

           for (int i = 0; i < items.size(); i++) {
                orig.add(items.get(i));
            }
       }

       @Override
       public int getCount() {
           if (_items != null)
               return _items.size();
           else
               return 0;
       }

       @Override
       public String getItem(int arg0) {
           return _items.get(arg0);
       }


      @Override

      public Filter getFilter() {
          Filter filter = new Filter() {
              @Override
              protected FilterResults performFiltering(CharSequence constraint) {

                  if(constraint != null)
                      Log.d("Constraints", constraint.toString());
                  FilterResults oReturn = new FilterResults();

                /*  if (orig == null){
                    for (int i = 0; i < items.size(); i++) {
                        orig.add(items.get(i));
                    }
                  }*/
                  String temp;  
                  int counters = 0;
                  if (constraint != null){

                      _items.clear();
                      if (orig != null && orig.size() > 0) {
                          for(int i=0; i<orig.size(); i++)
                            {                           
                                temp = orig.get(i).toUpperCase();

                                if(temp.startsWith(constraint.toString().toUpperCase()))
                                {

                                     _items.add(orig.get(i));               
counters++;

                                }
                            }
                      }
                      Log.d("REsult size:" , String.valueOf(_items.size()));
                          if(!counters)
                          {
                             _items.clear();
                             _items = orig;
                          }
                      oReturn.values = _items;
                      oReturn.count = _items.size();
                  }
                  return oReturn;
              }


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

              }

            };

          return filter;

      }


 }

它很容易使用,只需将原始适配器替换为此适配器:

final burtuAdapteris fAdapter = new burtuAdapteris(this, android.R.layout.simple_dropdown_item_1line, liste);

在我的情况下,列表是:ArrayList<String> liste = new ArrayList<String>();

2
我正在复制粘贴,但是为了向您的工作致敬,我保留了BurtuAdapter这个名称。 :) - brainmurphy1
1
一个更简洁的解决方案和源代码。 - lasec0203
实现可过滤性是解决方案! - G. Ciardini

3

强制显示下拉列表的方法。

在调用requestFocus()以显示键盘之前,需要先调用它,否则键盘不会弹出。

autocomptv.setOnTouchListener(new OnTouchListener() {

        @SuppressLint("ClickableViewAccessibility")
        @Override
        public boolean onTouch(View paramView, MotionEvent paramMotionEvent) {
            // TODO Auto-generated method stub
            autocomptv.showDropDown();
            autocomptv.requestFocus();
            return false;
        }
    });

3
如“ArtOfWarfare”所建议的,您可以只需子类化并覆盖performFiltering()方法:
public class My_AutoCompleteTextView extends AutoCompleteTextView {
    public My_AutoCompleteTextView(Context context) {
        super(context);
    }
    public My_AutoCompleteTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    public My_AutoCompleteTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void performFiltering(CharSequence text, int keyCode) {
        super.performFiltering("", 0);
    }
}

我已经成功使用了它。


2
这是对我有效的方法:
    public class CustomAutoCompleteTextView extends AutoCompleteTextView {
    public CustomAutoCompleteTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean enoughToFilter() {
        return true;
    }

    @Override
    protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
        super.onFocusChanged(focused, direction, previouslyFocusedRect);
        if (focused) {
            performFiltering(getText(), 0);
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        this.showDropDown();
        return super.onTouchEvent(event);
    }
}

如果适配器为nil,它将会导致崩溃。 - famfamfam

2
简单易懂的答案是:在autoCompleteTextView.setText("")之后,只需像这样从适配器中删除过滤器:autoCompleteTextView.adapter.filter.filter(null)。这就是全部了,过滤就消失了,整个下拉列表都会显示出来。

2
如果您想即时显示建议,则必须重写enoughToFilter()使其始终返回true。要忽略输入的文本,请使用performFiltering("", 0)和空过滤模式。然后,AutoCompleteTextView会显示所有建议。
这是我从其他StackOverflow帖子中结合的解决方案:
public class InstantAutoComplete extends android.support.v7.widget.AppCompatAutoCompleteTextView {
    public InstantAutoComplete(Context context) {
        super(context);
    }

    public InstantAutoComplete(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public InstantAutoComplete(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public boolean enoughToFilter() {
        return true;
    }

    @Override
    protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
        super.onFocusChanged(focused, direction, previouslyFocusedRect);

        if (focused && getAdapter() != null) {
            performFiltering("", 0);
        }
    }
}

这将显示下拉菜单,即使我没有按@键。 - famfamfam

0
  1. autoComplete.setText(" ")
  2. filter { it.contains(constraint.trim(), true) } }

注意:您需要将自动完成文本设置为空格文本,并在过滤器中修剪约束文本输入,这将显示所有下拉列表。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接