您的位置:首页 > 移动开发 > Android开发

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

2017-09-20 12:31 591 查看
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()
a655
) {
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: