Android 城市选择万能控件
Android 城市选择万能控件,选择城市,选择汽车品牌等等,支持按照a-z、# 排序等的选择控件,废话不多说直接上效果图:
(开的Android模拟器录得gif,有点糙,凑合看吧,程序猿不是艺术家!!!)
github Demo下载地址 如果觉得好,欢迎start、fork
具体可实现功能:
本选择模块支持泛型的省份等(按照a-z、# 排序的实体及自定义headview的展示等)
泛型ObjectModle
String sortLetters;//显示数据拼音的首字母
Object object;//显示的实体
像某大型汽车app的汽车品牌,城市定位,学生排名等效果都能实现,只需要稍作修改
接下来讲解一下右边的支持a-z、# 排序及支持自定义的选择控件
package com.selectmodule.select;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.graphics.drawable.ColorDrawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.TextView;
import com.selectmodule.R;
/**
* Created by Administrator on 2016/11/14.
*
* @todo A-Z、# 选择控件
* 支持设置默认字母显示颜色及选中显示颜色
* 支持字体的大小
* @auther madreain
*/
public class SideBar extends View {
// 触摸事件
private OnTouchingLetterChangedListener onTouchingLetterChangedListener;
// 26个字母
public static String[] b = {"A", "B", "C", "D", "E", "F", "G", "H", "I",
"J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",
"W", "X", "Y", "Z", "#"};
private int choose = -1;// 选中
private Paint paint = new Paint();
private TextView mTextDialog;
//设置选中的颜色
private String selectColor;
//设置默认的颜色
private String defaultColor;
//设置字体的大小
private int textSize;
public void setTextView(TextView mTextDialog) {
this.mTextDialog = mTextDialog;
}
public SideBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public SideBar(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SideBar(Context context) {
super(context);
}
public void setDefaultColor(String defaultColor) {
this.defaultColor = defaultColor;
}
public void setSelectColor(String selectColor) {
this.selectColor = selectColor;
}
public void setTextSize(int textSize) {
this.textSize = textSize;
}
//设置显示的刷选内容
public void setB(String[] b) {
this.b = b;
}
/**
* 重写这个方法
*/
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 获取焦点改变背景颜色.
int height = getHeight();// 获取对应高度
int width = getWidth(); // 获取对应宽度
int singleHeight = height / b.length;// 获取每一个字母的高度
for (int i = 0; i < b.length; i++) {
if (defaultColor != null) {
paint.setColor(Color.parseColor(defaultColor));
} else {
paint.setColor(Color.rgb(67, 196, 148));
}
// paint.setColor(Color.WHITE);
paint.setTypeface(Typeface.DEFAULT_BOLD);
paint.setAntiAlias(true);
if (textSize > 0) {
paint.setTextSize(textSize);
} else {
paint.setTextSize(40);
}
// 选中的状态
if (i == choose) {
if (selectColor != null) {
paint.setColor(Color.parseColor(selectColor));
} else {
paint.setColor(Color.parseColor("#ffffffff"));
}
paint.setFakeBoldText(true);
}
// x坐标等于中间-字符串宽度的一半.
float xPos = width / 2 - paint.measureText(b[i]) / 2;
float yPos = singleHeight * i + singleHeight;
canvas.drawText(b[i], xPos, yPos, paint);
paint.reset();// 重置画笔
}
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
final int action = event.getAction();
final float y = event.getY();// 点击y坐标
final int oldChoose = choose;
final OnTouchingLetterChangedListener listener = onTouchingLetterChangedListener;
final int c = (int) (y / getHeight() * b.length);// 点击y坐标所占总高度的比例*b数组的长度就等于点击b中的个数.
switch (action) {
case MotionEvent.ACTION_UP:
setBackgroundDrawable(new ColorDrawable(0x00000000));
choose = -1;//
invalidate();
if (mTextDialog != null) {
mTextDialog.setVisibility(View.INVISIBLE);
}
break;
default:
setBackgroundResource(R.drawable.sidebar_background);
if (oldChoose != c) {
if (c >= 0 && c < b.length) {
if (listener != null) {
listener.onTouchingLetterChanged(b[c]);
}
if (mTextDialog != null) {
mTextDialog.setText(b[c]);
mTextDialog.setVisibility(View.VISIBLE);
}
choose = c;
invalidate();
}
}
break;
}
return true;
}
/**
* 向外公开的方法
*
* @param onTouchingLetterChangedListener
*/
public void setOnTouchingLetterChangedListener(
OnTouchingLetterChangedListener onTouchingLetterChangedListener) {
this.onTouchingLetterChangedListener = onTouchingLetterChangedListener;
}
/**
* 接口
*
* @author madreain
*/
public interface OnTouchingLetterChangedListener {
public void onTouchingLetterChanged(String s);
}
}
为了支持泛型数据,采用了ObjectModle 传入String sortLetters;(显示数据拼音的首字母) 及需要传入的实体Object object;(传入需要显示的实体),通过按照首字母来进行数据的排序及展示
package com.selectmodule.select;
/**
* Created by Administrator on 2016/11/14.
*
* @auther madreain
*/
public class ObjectModle {
private String sortLetters; //显示数据拼音的首字母
private Object object;//传入需要显示的实体
public ObjectModle(String sortLetters, Object object) {
this.sortLetters = sortLetters;
this.object = object;
}
public ObjectModle() {
}
public String getSortLetters() {
return sortLetters;
}
public void setSortLetters(String sortLetters) {
this.sortLetters = sortLetters;
}
public Object getObject() {
return object;
}
public void setObject(Object object) {
this.object = object;
}
}
数据的传入及排序代码块
/**
* 为ListView填充数据
*
* @param date
* @return
*/
private List<ObjectModle> filledData(MBUserModel[] date) {
List<ObjectModle> mSortList = new ArrayList<ObjectModle>();
for (int i = 0; i < date.length; i++) {
ObjectModle sortModel = new ObjectModle();
//汉字转换成拼音
String sortString = date[i].getRemarkpinyinstart();
sortModel.setObject(date[i]);
// TODO: 2016/11/15
// if (sortString.matches("位")) {
// sortModel.setSortLetters(sortString.toUpperCase());
// } else if (sortString.matches("[A-Z]")) {
// sortModel.setSortLetters(sortString.toUpperCase());
// } else {
// sortModel.setSortLetters("#");
// }
// 正则表达式,判断首字母是否是英文字母
if (sortString.matches("[A-Z]")) {
sortModel.setSortLetters(sortString.toUpperCase());
} else {
sortModel.setSortLetters("#");
}
mSortList.add(sortModel);
}
return mSortList;
}