Spinner like edittext

笑着哭i 提交于 2019-12-21 05:56:08

问题


I have a form with TextInputLayout+TextInputEditText and spinners. I want the spinner height wrap text but have large items in the dropdown. The problem is that the spinner's height depends on the dropdown items height (simple_spinner_dropdown_item). I set style="@style/Base.Widget.AppCompat.Spinner.Underlined" in order to add line below spinner.

Any solution?


回答1:


Spinner like edittext

If you want spinner like edittext, it's like AutoCompleteTextView .You can custom your AppCompatAutoCompleteTextView like that:

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;
    }
}

And ic_expand_more_black_18dp.png is a image like that:

Layout:

<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>

Result (You can set adapter for your AutoCompleteTextView)




回答2:


Here is an workaround:

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);

Here layout android.R.layout.simple_spinner_dropdown_item is used for dropdown item and custom layout custom_spinner_item is used for spinner view to show only 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" />

FYI, You can customize this TextView as per your needs.

Hope this will help~




回答3:


I'm using Support Libraries (AppCompat) and layouts like below. More info 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>

Update

spinner item layout:

<?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"/>

for dropdown view: android.R.layout.simple_spinner_dropdown_item




回答4:


I wanted to take a moment and expand on RoShan Shan's answer, having just spent nearly 2 hours getting his code actually working.

What to do

You will need to create a new class which extends 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;
    }

}

You will need to define an empty list to use as default:

<string-array name="default_empty_list"/>

And add an icon for the drop down. I recommend importing the ic_expand_more vector asset from clip art (File > New > Vector Assest > Clip Art).

Why this is better

This ComboBox buys you a few things over the original answer:

  1. Works out of the box. Create the three items above and everything will just work.

  2. You can include the ComboBox in any View or layout from the xml (see original answer, it hasn't changed) but now you can also define the list there by supplying android:entries with an array resource.

  3. Use registerDataSetObserver() to add a change listener.

  4. Retrieve the current value of the ComboBox using getPosition() (index) or getCurrentText() (string).

Good luck




回答5:


ANSWER: I was just setting adapter layout (tried both layouts) but there is specific dropdown layout.

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

spinner_item is a custom layout that removes left padding:

<?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" />

Also, add this style to spinner:

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

And



来源:https://stackoverflow.com/questions/43970038/spinner-like-edittext

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!