Android:限制用户选择自动完成建议以外的其他内容?

时间:2012-11-15 08:49:44

标签: android autocompletetextview

我已提供AutoCompleteTextView向用户显示建议。根据用户选择的项目,我获取项目的ID并在数据库中使用它。现在我的问题是强迫用户仅从AutoCompleteTextView进行选择(即用户不应该输入他自己的文本)。这是客户要求。怎么做?

9 个答案:

答案 0 :(得分:27)

这是一个非常直接的解决方案:

您可以通过在setOnItemClickListener中设置AutoCompleteTextView来创建存储所选值的变量。然后,只要用户通过向其添加null键入字段,您就可以TextWatcher该值。最后,您可以在继续之前验证您的变量是否为空。

String my_var; //keep track!
AutoCompleteTextView tv = (AutoCompleteTextView) layout.findViewById(R.id.tv);
tv.setAdapter(my_adapter);  
tv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        my_var = my_adapter.getItem(position).toString();
    }
});
/**
 * Unset the var whenever the user types. Validation will
 * then fail. This is how we enforce selecting from the list.
 */
tv.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) {
        my_var = null;
    }
    @Override
    public void afterTextChanged(Editable s) {}
});

答案 1 :(得分:15)

我碰巧需要对我正在进行的项目提出这样的要求,而且我会按照我实施所需的方式与您分享。

我为自动完成文本视图添加了焦点更改侦听器,并在用户将焦点从自动完成时更改焦点时进行检查,并直接处理了该情况。

autoTextViewCountry.setOnFocusChangeListener(new View.OnFocusChangeListener() {
        @Override
        public void onFocusChange(View view, boolean b) {
            if(!b) {
                // on focus off
                String str = autoTextViewCountry.getText().toString();

                ListAdapter listAdapter = autoTextViewCountry.getAdapter();
                for(int i = 0; i < listAdapter.getCount(); i++) {
                    String temp = listAdapter.getItem(i).toString();
                    if(str.compareTo(temp) == 0) {
                        return;
                    }
                }

                autoTextViewCountry.setText("");

            }
        }
    });

所以我的实现是:如果类型化的文本不存在于数组适配器中,则焦点更改为空文本视图,稍后在继续下一阶段的注册时,检查此文本视图是否为空或不。

希望这种方法有助于某人。

快乐的编码。

答案 2 :(得分:3)

NiceAutoCompleteTextView可让您通过调用isSelectionFromPopup()

来检查是否通过下拉弹出窗口进行了选择

答案 3 :(得分:2)

只需将此属性添加到您的 AutoCompleteTextView。

<块引用>

android:focusable="false"

我的代码如下:

        <com.google.android.material.textfield.TextInputLayout
        android:id="@+id/menu"
        style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Mode">

        <AutoCompleteTextView
            android:id="@+id/mode"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:focusable="false"
            />

    </com.google.android.material.textfield.TextInputLayout>

Java 端:

AutoCompleteTextView mode = findViewById(R.id.mode);
   final List<String> modeList = new ArrayList();
    modeList.add("YEARLY");
    modeList.add("HALF-YEARLY");
    modeList.add("QUARTER-YEARLY");
    modeList.add("MONTHLY");
    mode.setAdapter(new ArrayAdapter(getApplicationContext(),R.layout.list_item,modeList));

获取 AutoCompleteTextView 的文本:

mode.getText().toString()

答案 4 :(得分:1)

好的,我假设您希望将用户的输入限制为建议框中列出的项目列表中包含的文本。

例如,如果你有:

  • 两个

然后用户只能键入第一个字符“O”和“T”。 等等根据之前输入的文字。

要实现此目的,您可以使用 TextView setFilters 方法:

editBox = (TextView) findViewById(R.id.editBox);
editBox.setFilters(getFilters());
editBox.addTextChangedListener(this);
editBox.setOnFocusChangeListener(this);

此外,您可能需要文本更改侦听器焦点侦听器以在输入新字符时响应并更新已过滤的列表...以及更新过滤器

以下是我在项目中使用的十进制数过滤器的示例:

protected InputFilter[] getFilters()
    {
        InputFilter[] filters = new InputFilter[1];

        filters[0] = new InputFilter()
        {
            public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend)
            {
                // limit input to digits and decimal / thousand separator only
                // in case thousand separator is pressed, change it to decimal
                // separator instead
                String output = "";

                if (number.isFocused())
                {
                    for (int i = start; i < end; i++)
                    {
                        char c = source.charAt(i);

                        if (isDecimalOrThousandSeparator(c))
                        {
                            output = output + Character.toString(decimalSeparator);
                        }
                        else if (Character.isDigit(c))
                        {
                            output = output + Character.toString(c);
                        }
                    }

                    return output == "" ? null : output;
                }

                return null;
            }
        };

        return filters;
    }

答案 5 :(得分:1)

一个简单的解决方案是仅检查当前输入是否是适配器中的一项。您可以这样做:

val AutoCompleteTextView.isValid: Boolean
    get() {
        for (i in 0 until adapter.count) {
            if (adapter.getItem(i) == text.toString()) {
                return true
            }
        }

        return false
    }

答案 6 :(得分:1)

这是此pro AutoCompleteTextView.Validator的另一种解决方案,可确保有效值。当编辑文本失去焦点时,将调用验证程序。

autoCompleteTextView.validator = object : AutoCompleteTextView.Validator {
        override fun isValid(text: CharSequence?): Boolean {
            return optionsList.contains(text.toString())
        }

        override fun fixText(invalidText: CharSequence?): CharSequence {
            return ""
        }
    }

optionsList是有效值的列表。

答案 7 :(得分:0)

我有相同的要求,所以这是我的实现:

autoCompleteTextView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                autoCompleteTextView.showDropDown();
            }
        });

在xml中设置focusable=falsefocusableInTouchMode=false

快乐编码

答案 8 :(得分:0)

为了使AutoCompleteTextView的版本不可编辑,您应该在AutoCompleteTextView中禁用用户输入。可以通过在AutoCompleteTextView上设置android:inputType =“ none”来实现。