Spinner就像edittext一样

时间:2017-05-15 00:20:43

标签: android android-spinner

我有一个带有TextInputLayout + TextInputEditText和微调器的表单。我想要微调器高度换行文本,但在下拉列表中有大项目。问题是微调器的高度取决于下拉项高度(simple_spinner_dropdown_item)。 我设置了style =" @ style / Base.Widget.AppCompat.Spinner.Underlined"为了在微调器下面添加一行。

任何解决方案?

5 个答案:

答案 0 :(得分:7)

  

Spinner喜欢edittext

如果您想要像edittext一样的微调器,它就像 AutoCompleteTextView 。您可以像这样定制AppCompatAutoCompleteTextView

public class AutoCompleteDropDown extends AppCompatAutoCompleteTextView {
    //    implements AdapterView.OnItemClickListener
    private static final int MAX_CLICK_DURATION = 200;
    private long startClickTime;
    private boolean isPopup;
    private int mPosition = ListView.INVALID_POSITION;

    public AutoCompleteDropDown(Context context) {
        super(context);
//        setOnItemClickListener(this);
    }

    public AutoCompleteDropDown(Context arg0, AttributeSet arg1) {
        super(arg0, arg1);
//        setOnItemClickListener(this);
    }

    public AutoCompleteDropDown(Context arg0, AttributeSet arg1, int arg2) {
        super(arg0, arg1, arg2);
//        setOnItemClickListener(this);
    }

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

    @Override
    protected void onFocusChanged(boolean focused, int direction,
                                  Rect previouslyFocusedRect) {
        super.onFocusChanged(focused, direction, previouslyFocusedRect);
        if (focused) {
            performFiltering("", 0);
            InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(getWindowToken(), 0);
            setKeyListener(null);
            dismissDropDown();
        } else {
            isPopup = false;
        }
    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {

        switch (event.getAction()) {
            case MotionEvent.ACTION_UP: {
                if (isPopup) {
                    dismissDropDown();
                } else {
                    requestFocus();
                    showDropDown();
                }
                break;
            }
        }

        return super.onTouchEvent(event);
    }

    @Override
    public void showDropDown() {
        super.showDropDown();
        isPopup = true;
    }

    @Override
    public void dismissDropDown() {
        super.dismissDropDown();
        isPopup = false;
    }



    @Override
    public void setCompoundDrawablesWithIntrinsicBounds(Drawable left, Drawable top, Drawable right, Drawable bottom) {
        Drawable dropdownIcon = ContextCompat.getDrawable(getContext(), R.drawable.ic_expand_more_black_18dp);
        if (dropdownIcon != null) {
            right = dropdownIcon;
            right.mutate().setAlpha(66);
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            super.setCompoundDrawablesRelativeWithIntrinsicBounds(left, top, right, bottom);
        } else {
            super.setCompoundDrawablesWithIntrinsicBounds(left, top, right, bottom);
        }

    }



    public int getPosition() {
        return mPosition;
    }
}

ic_expand_more_black_18dp.png是这样的图像:

布局:

<android.support.design.widget.TextInputLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:textColorHint="@color/gray_text_hint"
        app:hintTextAppearance="@style/TextAppearance.App.TextInputLayout.Dark">

        <yourpackage.AutoCompleteDropDown
            android:id="@+id/edtBloodType"
            style="@style/edt_dark"
            android:hint="Blood Type"
            android:inputType="textNoSuggestions" />
    </android.support.design.widget.TextInputLayout>

结果(您可以为AutoCompleteTextView设置适配器)

enter image description here

答案 1 :(得分:1)

以下是解决方法:

Spinner spinner = (Spinner) findViewById(R.id.spinner);
ArrayAdapter<String> adapter = new ArrayAdapter<>(context, R.layout.custom_spinner_item, values);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);

此处布局android.R.layout.simple_spinner_dropdown_item用于dropdown商品,自定义布局custom_spinner_item用于微调器view仅显示TextView

<强> custom_spinner_item.xml:

<TextView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@android:id/text1"
    android:maxLines="1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:ellipsize="marquee" />

仅供参考,您可以根据需要自定义此TextView

希望这会有所帮助〜

答案 2 :(得分:0)

我正在使用支持库(AppCompat)和下面的布局。更多信息here

<!-- editText -->
<android.support.design.widget.TextInputLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_weight="1"
    android:hint="Hint">

    <android.support.design.widget.TextInputEditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:maxLines="1"
        android:singleLine="true" />

</android.support.design.widget.TextInputLayout>

<!-- spinner with label -->
<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <TextView
        style="@style/TextAppearance.AppCompat.Caption"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Label"></TextView>

    <android.support.v7.widget.AppCompatSpinner
        style="@style/Widget.AppCompat.Spinner.Underlined"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:spinnerMode="dialog" />
</LinearLayout>

<强>更新

微调项目布局:

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/text1"
    style="?android:attr/spinnerItemStyle"
    android:paddingStart="0dp"
    android:paddingLeft="0dp"
    android:textSize="18sp"
    android:singleLine="true"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:ellipsize="marquee"
    android:textAlignment="inherit"/>

下拉视图:android.R.layout.simple_spinner_dropdown_item

答案 3 :(得分:0)

我想花点时间来扩展RoShan Shan's answer,因为花了将近2个小时才使他的代码真正起作用。

该做什么

您将需要创建一个扩展AppCompatAutoCompleteTextView的新类:

public class ComboBox extends AppCompatAutoCompleteTextView implements AdapterView.OnItemClickListener {

    private boolean isPopup;
    private int mPosition = -1;

    public ComboBox(Context context){
        super(context);
        setAdapter(new ArrayAdapter<>(context, android.R.layout.simple_expandable_list_item_1, new String[0]));
        setOnItemClickListener(this);
        setKeyListener(null);
    }

    public ComboBox(Context context, AttributeSet attributes){
        super(context, attributes);
        setAdapter(new ComboBoxAdapter(context, attributes.getAttributeListValue("http://schemas.android.com/apk/res/android", "entries", new String[0], R.array.default_empty_list)));
        setOnItemClickListener(this);
        setKeyListener(null);
    }

    public ComboBox(Context context, AttributeSet attributes, int arg2){
        super(context, attributes, arg2);
        setAdapter(new ComboBoxAdapter(context, attributes.getAttributeListValue("http://schemas.android.com/apk/res/android", "entries", new String[0], R.array.default_empty_list)));
        setOnItemClickListener(this);
        setKeyListener(null);
    }

    public static class ComboBoxAdapter extends ArrayAdapter<String> {

        private final String[] list;

        public ComboBoxAdapter(Context context, @ArrayRes int array){
            super(context, android.R.layout.simple_expandable_list_item_1, context.getResources().getStringArray(array));
            list = context.getResources().getStringArray(array);
        }

        @Override
        public Filter getFilter(){
            return new Filter(){
                @Override
                protected FilterResults performFiltering(CharSequence constraint){
                    FilterResults out = new FilterResults();
                    out.values = list;
                    out.count = list.length;
                    return out;
                }

                @Override
                protected void publishResults(CharSequence constraint, FilterResults results){
                    notifyDataSetChanged();
                }
            };
        }

    }

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

    @Override
    protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect){
        super.onFocusChanged(focused, direction, previouslyFocusedRect);
        if (focused){
            InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(getWindowToken(), 0);
            showDropDown();
        }
    }

    @Override
    public boolean performClick(){
        if (isPopup){
            dismissDropDown();
        }
        else {
            showDropDown();
        }
        return super.performClick();
    }

    @Override
    public void showDropDown(){
        super.showDropDown();
        isPopup = true;
    }

    @Override
    public void dismissDropDown(){
        super.dismissDropDown();
        isPopup = false;
    }

    @Override
    public void setCompoundDrawablesWithIntrinsicBounds(Drawable left, Drawable top, Drawable right, Drawable bottom){
        Drawable dropdownIcon = ContextCompat.getDrawable(getContext(), R.drawable.ic_chevron_down);
        if (dropdownIcon != null){
            right = dropdownIcon;
            right.mutate().setAlpha(66);
        }
        super.setCompoundDrawablesRelativeWithIntrinsicBounds(left, top, right, bottom);
    }

    public int getPosition(){
        return mPosition;
    }

    public String getCurrentText(){
        if (mPosition == -1){
            return "";
        }
        else {
            return getText().toString();
        }
    }

    public void registerDataSetObserver(DataSetObserver observer){
        getAdapter().registerDataSetObserver(observer);
    }

    public void unregisterDataSetObserver(DataSetObserver observer){
        getAdapter().unregisterDataSetObserver(observer);
    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id){
        setText(parent.getItemAtPosition(position).toString());
        mPosition = position;
    }

}

您将需要定义一个空列表以用作默认设置:

<string-array name="default_empty_list"/>

并为下拉菜单添加一个图标。我建议从剪贴画(File > New > Vector Assest > Clip Art)中导入ic_expand_more矢量资产。

为什么这样更好

此组合框为您提供了一些原始答案之外的东西:

  1. 开箱即用。创建上面的三个项目,一切都将正常工作。

  2. 您可以在xml的任何视图或布局中包含ComboBox(请参阅原始答案,它没有改变),但是现在您还可以通过向android:entries提供数组资源来定义列表

  3. 使用registerDataSetObserver()添加更改侦听器。

  4. 使用getPosition()(索引)或getCurrentText()(字符串)检索ComboBox的当前值。

祝你好运

答案 4 :(得分:-1)

答案:我只是设置了适配器布局(尝试了两种布局),但是有特定的下拉布局。

ArrayAdapter<String> typeAdapter = new ArrayAdapter<>(getActivity(), android.R.layout.spinner_item, types);
typeAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

spinner_item是一个删除左边距的自定义布局:

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
style="?android:attr/spinnerItemStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:paddingEnd="0dp"
android:paddingLeft="0dp"
android:paddingStart="0dp"
android:singleLine="true"
android:textAlignment="inherit" />

另外,将此样式添加到微调器:

style="@style/Widget.AppCompat.Spinner.Underlined"

并且