如何将AutoCompleteTextView用作Spinner的替代品 - 但在焦点流内部

7
我在过去的两天中花费了大部分时间来解决这个问题。实际上,我想要一个像TextInputLayout内EditText一样的Spinner(带有流动提示,如果在前一个EditText中按下下一个/输入键,则被选中/输入)。这似乎是不可能的,所以我想到了以下解决方案:
    <android.support.design.widget.TextInputLayout
        android:id="@+id/newMeasure_layout"
        android:layout_width="0dp"
        android:layout_height="wrap_content"


        app:layout_constraintEnd_toEndOf="@+id/title_layout"
        app:layout_constraintStart_toStartOf="@+id/title_layout"
        app:layout_constraintTop_toBottomOf="@+id/measureSpinner">

        <AutoCompleteTextView
            android:id="@+id/newMeasure"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"

            android:imeOptions="actionNext|flagNoExtractUi"
            android:singleLine="true"
            android:inputType="textNoSuggestions|textVisiblePassword"
            android:cursorVisible="false"


            android:hint="@string/measure"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"

            android:drawableTint="@color/secondaryColor"
            android:drawableEnd="@drawable/ic_arrow_drop_down_black_24dp"
            android:drawableRight="@drawable/ic_arrow_drop_down_black_24dp" />
    </android.support.design.widget.TextInputLayout>

这可以防止键盘显示闪烁的光标,提供建议、更正等功能。
为了防止用户输入内容,但仍然允许通过按Enter/下一步来聚焦到下一个输入框,我在代码中设置了一个过滤器(该过滤器还检查建议光标中是否有文本)。
private AutoCompleteTextView mNewMeasure;
...
    mNewMeasure = root.findViewById(R.id.newMeasure);

    mNewMeasure.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View view, MotionEvent motionEvent) {
            ((AutoCompleteTextView)view).showDropDown();
            return false;
        }
    });
    mNewMeasure.setOnFocusChangeListener(new View.OnFocusChangeListener() {
        @Override
        public void onFocusChange(View view, boolean b) {
            AutoCompleteTextView v = ((AutoCompleteTextView)view);
            if(b && v.getText().length() == 0) {
                v.showDropDown();
            }
        }
    });

//inside the cursor loaded method (data == the loaded cursor)

    String[] madapterCols = new String[]{1}; //0 contains the id, 1 the textfield
            int[] madapterRowViews = new int[]{android.R.id.text1};
            SimpleCursorAdapter msca = new SimpleCursorAdapter(
                    getContext(),
                    R.layout.support_simple_spinner_dropdown_item,
                    data,
                    madapterCols,
                    madapterRowViews,
                    SimpleCursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);

             msca.setDropDownViewResource(R.layout.support_simple_spinner_dropdown_item);
            msca.setStringConversionColumn(1);
            mNewMeasure.setAdapter(msca);
            //NOTE: its onItemClick for the suggestions, instead of onItemSelected as the spinner requires 
            // https://dev59.com/O2kw5IYBdhLWcg3w1eC7
            mNewMeasure.setOnItemClickListener(new AdapterView.OnItemClickListener() {...});


    InputFilter infil = new InputFilter() {
                //based on https://stackoverflow.com/questions/37152413/allowing-space-and-enter-key-in-android-keyboard

                @Override
                public CharSequence filter(CharSequence charSequence, int i, int i1, Spanned spanned, int i2, int i3) {
                    Pattern ps = Pattern.compile("^[\n]+$");
                    if(!charSequence.equals("")
                            && !cursorContains(data, charSequence)
                            && !ps.matcher(charSequence).matches()) {
                        //not allowed
                        return "";
                    }
                    return null;
                }

                private boolean cursorContains(Cursor c, CharSequence cs) {
                    c.moveToFirst();
                    int textColIdx = 1; //  c.getColumnIndex(PoetcomContract.)
                    for(int i = 0; i < c.getCount(); i++) {
                        String currentCursorStringval =  c.getString(textColIdx);
                         if(currentCursorStringval.equalsIgnoreCase(cs.toString())) {
                            return true;
                        }
                        c.moveToNext();
                    }

                    return false;
                }
            };

            mNewMeasure.setFilters(new InputFilter[] {infil});

结果如下:

并且结果为: 表现为旋转器的字段,EditText混合

另一种方法-具有类似意图和结果的方法,它使用EditText作为连接的适配器的过滤器:https://stackoverflow.com/a/43971008

1个回答

0

这也可以正常工作

 <com.google.android.material.textfield.TextInputLayout
        android:id="@+id/orderStatus"
     style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
        android:layout_width="wrap_content"
        android:layout_height="60dp"
        android:layout_alignParentStart="true"
        android:layout_alignParentBottom="true"
        android:layout_marginStart="15dp"
        android:layout_marginTop="5dp"
        android:layout_marginBottom="6dp"
        android:layout_toStartOf="@+id/textview"
        app:startIconDrawable="@drawable/ic_org">

        <AutoCompleteTextView
            android:id="@+id/status"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:hint="Drop down"
            android:inputType="none" />
    </com.google.android.material.textfield.TextInputLayout>

还有Java代码

ArrayAdapter<String> adapter = new ArrayAdapter<>(this, R.layout.support_simple_spinner_dropdown_item, {your string array});
        autocompletetextview.setAdapter(adapter);

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