HowTo:AutoCompleteTextView作为微调器替换 - 但在焦点流内

时间:2018-03-16 12:24:41

标签: android android-edittext spinner autocompletetextview

过去两天我花了最多的时间来解决这个问题。 实际上我想要一个微调器,其行为类似于TextInputLayout中的EditText(花哨的提示,如果在前一个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 / next来聚焦下一个输入,我在代码中设置了一个过滤器(它还会检查建议中的文本是否可用)

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://stackoverflow.com/questions/9616812/how-to-add-listener-to-autocompletetextview-android
            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});

结果: field behaving like a spinner, edittext mixture

一种不同的方法 - 具有相似的意图和结果,使用EditText作为附加适配器的过滤器:https://stackoverflow.com/a/43971008

1 个答案:

答案 0 :(得分: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);