欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android自定义Spinner

程序员文章站 2022-07-04 18:50:32
...

项目中用到Spinner,什么都好,就是内含的popup无法限制高度。当我展示的数据较多时,
spinner会自动计算屏高,尽可能多的展示,导致item列表时高时矮,不甚美观。耗费了很多时间和精力
在网上查找解决方法,并仔细看了Spinner源码,发现真的没有提供限制高度这一方法。无奈只能尝试自己写一个类似功能的
MySpinner。
我们知道Spinner有DropdownPopup,DialogPopup两种展示模式,这里只用到DropDown模式,所以MySpinner中只用到了
TextView,PopupWindow和ListView。思路是点击TextView,显示包含ListView的PopupWindow和ListView,
然后设置 一系列点击事件和监听,满足需求。特点就在于可灵活设置PopupWindow宽高和Spinner常见功能。但因为只用到了基本的ArrayAdapter,所以功能有点受限。

代码如下:

public class MySpinner extends AppCompatTextView {

    private PopupWindow popupWindow;
    private int popupWindowWidth = 50;
    private int popupWindowHeight = 50;
    private int listviewDividerHeight = 0;
    private int selectedItemPosition = 0;
    private ListView listView;
    private ListAdapter adapter;
    private MySpinnerListener listener;//可监听listview Item点击,回调结果

    public MySpinner(Context context) {
        super(context);
        initView(context);
        initListener();
    }

    public MySpinner(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initView(context);
        initListener();
    }

    public MySpinner(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView(context);
        initListener();
    }

    private void initView(Context context) {
        popupWindow = new PopupWindow(this);
        listView = new ListView(context);
    }

    private void initListener() {
        setOnItemClickListener();
        popupWindowShowAsDropDown(MySpinner.this);
    }

    public void setPopupWindowParams(int windowWidth,int windowHeight) {
        this.popupWindowWidth = windowWidth;
        this.popupWindowHeight = windowHeight;
    }

    public void setPopupWindowWidth(int windowWidth) {
        this.popupWindowWidth = windowWidth;
    }

    public void setPopupWindowHeight(int windowHeight) {
        this.popupWindowHeight = windowHeight;
    }

    public void setListviewDividerHeight(int listviewDividerHeight) {
        this.listviewDividerHeight = listviewDividerHeight;
    }

    public void setAdapter(ListAdapter adapter) {
        this.adapter = adapter;
    }

    //listview 点击事件
    private void setOnItemClickListener() {
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                selectedItemPosition = position;
                String itemselect = (String) parent.getItemAtPosition(position);
                MySpinner.this.setText(itemselect);
                popupWindow.dismiss();
                //回调
                if (listener != null)
                    listener.onItemSelected(itemselect, position);
            }
        });
    }

    //作用同 listview setOnItemSelectedListener
    public void setMySpinnerOnItemSelectedListener(MySpinnerListener listener) {
        this.listener = listener;
    }

    public void popupWindowShowAsDropDown(View anchor) {
        popupWindowShowAsDropDown(anchor, 0, 0);
    }

    public void popupWindowShowAsDropDown(View anchor, int xoff, int yoff) {
        popupWindowShowAsDropDown(anchor, xoff, yoff, Gravity.TOP | Gravity.START);
    }

    public void popupWindowShowAsDropDown(final View anchor, final int xoff, final int yoff, final int gravity) {
        //popupwindow显示事件
        this.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                popupWindow.showAsDropDown(anchor, xoff, yoff, gravity);
            }
        });
    }

    public void show() {
        listView.setBackgroundResource(R.drawable.shape_bg_test);
        listView.setDividerHeight(listviewDividerHeight);
        listView.setAdapter(adapter);

        popupWindow.setWidth(popupWindowWidth);
        popupWindow.setHeight(popupWindowHeight);
        popupWindow.setContentView(listView);
        popupWindow.setBackgroundDrawable(new ColorDrawable(0x00000000));
        popupWindow.setOutsideTouchable(false);
        popupWindow.setFocusable(true);

        setSelection(0);
    }

    public void setSelection(int i) {
        if (adapter != null && adapter.getCount() > i) {
            selectedItemPosition = i;
            listView.setSelection(i);
            MySpinner.this.setText((String) adapter.getItem(i));
        }
    }

    public String getSelectedItem() {
        return (String) listView.getItemAtPosition(selectedItemPosition);
    }

    public int getSelectedItemPosition() {
        return selectedItemPosition;
    }
}
public interface MySpinnerListener {
    public void onItemSelected(String item,int position);
}

调用如下:

    myspinner.setPopupWindowParams(dip2px(getActivity(), 70), dip2px(getActivity(), 26*7));
    myspinner.setAdapter(new ArrayAdapter<String>(getActivity(), R.layout.simple_spinner_dropdown_item, getDays()));
    myspinner.show();
相关标签: Spinner