android 标题栏下拉选择控件(下拉菜单宽度全屏显示spinner)
16lz
2021-01-23
android下拉菜单spinner,虽然很方便,但有些需求是下拉框是固定大小,下拉菜单栏则是宽度全屏,据我所知android自带的spinner是不好处理的,所以就自己动手吧,自己动手有饭吃。废话少说,先上图再说
这里的实现方案是TextView加PopupWindow,并对其进行了封装。
照惯例,我们仍然从简单的说起,首先是适配器,因为我们的下拉列表其实就是一个listView,所以该适配器直接继承BaseAdapter,在这里我们只增加一个抽象方法getItemText(int position),用于TextView获取显示的文本,代码如下:
public abstract class BaseSpinnerAdapter extends BaseAdapter { public abstract String getItemText(int position);}
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); } } }); }
------------------------------------------------@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); }------------------------------------------------
----------------------------------------------//设置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
更多相关文章
- Android的事件处理模式
- 源码角度分析Android的事件输入系统(input system)及ANR原理分析
- Android开发之基本控件和详解四种布局方式
- android 上实现 控件平滑移动(smooth move) 研究
- Android 利用控件显示HTML样式
- Android 使用Vitamio打造自己的万能播放器(6)――在线播放(播放列表
- android获取控件宽高和屏幕宽高
- Android android控件动态使用
- 【Android】利用Java代码布局,按钮添加点击事件