android 标题栏下拉选择控件(下拉菜单宽度全屏显示spinner)

来源:互联网 发布:网络语qc是什么意思 编辑:程序博客网 时间:2024/06/05 20:09

android下拉菜单spinner,虽然很方便,但有些需求是下拉框是固定大小,下拉菜单栏则是宽度全屏,据我所知android自带的spinner是不好处理的,所以就自己动手吧,自己动手有饭吃。废话少说,先上图再说


这里的实现方案是TextView加PopupWindow,并对其进行了封装。

照惯例,我们仍然从简单的说起,首先是适配器,因为我们的下拉列表其实就是一个listView,所以该适配器直接继承BaseAdapter,在这里我们只增加一个抽象方法getItemText(int position),用于TextView获取显示的文本,代码如下:

public abstract class BaseSpinnerAdapter extends BaseAdapter {    public abstract String getItemText(int position);}


这次的控件会比较简单,只是TextView和PopupWindow的组合控件,所以理所当然的该控件直接继承TextView,然后分一下几步

1、在构造方法中创建一个PopWindow,代码如下:

 /**     * 初始化列表PopupWindow     */    public void init(Context context) {        setGravity(Gravity.CENTER);        LinearLayout layout = new LinearLayout(context);        layout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,                LinearLayout.LayoutParams.MATCH_PARENT));        layout.setBackgroundColor(0xaa000000);        layout.setOrientation(LinearLayout.VERTICAL);        mPopWindow = new PopupWindow(layout, WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT, true);        mPopWindow.setAnimationStyle(animationId);        line = new View(context);//添加一条分割线,不需要可将其设置为透明色        float scale = context.getResources().getDisplayMetrics().density;        line.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,                (int) (1 * scale + 0.5f)));        line.setBackgroundColor(lineColor);        listView = new ListView(context);        listView.setDivider(new ColorDrawable(0xffd6d6d6));        listView.setDividerHeight(1);        listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);//设置为单选模式,方便获取最新的点击item的下标        if (adapter != null) {            listView.setAdapter(adapter);        }        layout.addView(line);        layout.addView(listView);        layout.setFocusableInTouchMode(true);        mPopWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {//向外部暴露popWindow消失时的通知接口            @Override            public void onDismiss() {                if (statusListener != null) {                    statusListener.onDismiss(PopSpinner.this);                }            }        });//点击空白处时,关闭PopWindows        layout.setOnTouchListener(new OnTouchListener() {            @Override            public boolean onTouch(View v, MotionEvent event) {                closeWindow();                return false;            }        });        layout.setOnKeyListener(new OnKeyListener() {            @Override            public boolean onKey(View v, int keyCode, KeyEvent event) {                closeWindow();                return true;            }        });        setOnClickListener(this);        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {            @Override            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {                if (adapter != null) {                    PopSpinner.this.setText(adapter.getItemText(position));                }                closeWindow();                if (mOnSpinnerItemClickListener != null) {                    mOnSpinnerItemClickListener.onItemClick(parent, view, position, id);                }            }        });    }


2、修改setOnClickListener方法,使点击该控件时弹出下拉菜单,再调用外部设置的点击事件,代码如下:


------------------------------------------------@Override    public void setOnClickListener(OnClickListener l) {        if (l instanceof PopSpinner) {            super.setOnClickListener(l);        } else {            this.onClickListener = l;        }    }    @Override    public void onClick(View view) {        if (mPopWindow.isShowing()) {            closeWindow();        } else {            showWindow();        }        if (onClickListener != null) {            onClickListener.onClick(view);        }    }------------------------------------------------

3、定义外部响应接口

------------------------------------------------//下拉列表的item点击事件,即listView的item点击事件 public interface OnSpinnerItemClickListener {        void onItemClick(AdapterView<?> parent, View view, int position, long id);    }    //下拉列表显示与隐藏事件    public interface WindowStatusListener {        //下拉列表显示        void onShow(View view);        // 下拉列表隐藏        void onDismiss(View view);    }------------------------------------------------


4、丰富特色设置

----------------------------------------------//设置adapter  public void setAdapter(BaseSpinnerAdapter adapter) {        this.adapter = adapter;        if (listView != null) {            listView.setAdapter(adapter);        }        if (adapter.getCount() > 0) {            setSelectedItemPosition(0);        }    }    //方便外部获取下拉列表的listView    public ListView getListView() {        return listView;    }   // 设置PopWindows显示隐藏动画    public void setAnimationStyle(int animationId) {        if (mPopWindow != null) {            mPopWindow.setAnimationStyle(animationId);        }        this.animationId = animationId;    }    /**     * 获取当前选中的item     *     * @return     */    public int getSelectedItemPosition() {        if (listView != null) {            return listView.getCheckedItemPosition();        }        return 0;    }   //获取选中的对象    public Object getSelectItemObject() {        if (adapter != null && adapter.getCount() > 0) {            return adapter.getItem(getSelectedItemPosition());        }        return null;    }   //设置选中第几个    public void setSelectedItemPosition(int position) {        if (listView != null && listView.getCount() > 0) {            listView.setItemChecked(listView.getCount() > position ? position : listView.getCount() - 1, true);        }        if (adapter != null && adapter.getCount() > 0) {            setText(adapter.getItemText(adapter.getCount() > position ? position : adapter.getCount() - 1));        }    }   //设置顶部分割线的颜色    public void setLineColor(int lineColor) {        if (line != null) {            line.setBackgroundColor(lineColor);        }        this.lineColor = lineColor;    }------------------------------------------------


到此我们的下拉控件就完成了,使用上数据源和item的设置跟listView几乎差不多,控件中的样式的配置则跟TextView一样(因为本身就是继承TextView的),比如上图中的样式

------------------------------------------------        popSpinner = new PopSpinner(this);        ActionBar.LayoutParams lp = new ActionBar.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT                , ViewGroup.LayoutParams.MATCH_PARENT);        lp.gravity = Gravity.CENTER;        popSpinner.setLayoutParams(lp);        popSpinner.setTextSize(16);        Drawable drawable = getResources().getDrawable(R.mipmap.arrow_down);        drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight());        popSpinner.setCompoundDrawables(null, null, drawable, null);        popSpinner.setCompoundDrawablePadding(15);------------------------------------------------

至于下拉列表中打勾的显示方式,可以在你继承的adapter中做个标记位,选中的item显示个勾。实现方案有很多种,我这里又是使用自己定义的控件,思路是TextView+RadioButton,比较简单,我查了下,网上也有不少,这里就不讲了。


本文地址:http://blog.csdn.net/lanqi_x/article/details/78039435