按照项目要求我们做的类似通讯录效果是这样的:
然后根据这样来开发,当时找了好多代码,看到的只是一个版本的代码。自己就在其基础上修改了代码。正好这边记录一下。直接贴代码
public class SideBar extends View {
private OnTouchingLetterChangedListener onTouchingLetterChangedListener;
public static String[] b ;
private int choose = -1;
private Paint paint = new Paint();
private TextView mTextDialog;
private Context context;
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,String[] b) {
super(context);
this.b= b;//传过来的数组
this.context = context;
}
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int height = b.length*40;//获取总长度,设定每个字母高度为40px
int topOffset = (getHeight()-(b.length*40))/2;//获取父控件的高度减去字母总长度/2;目的是让字母在屏幕中间
int width = getWidth();
for (int i = 0; i < b.length; i++) {
paint.setColor(Color.parseColor("#007aff"));
// paint.setColor(Color.WHITE);
paint.setTypeface(Typeface.DEFAULT_BOLD);
paint.setAntiAlias(true);
paint.setTextSize(24);//设置文字大小
if (i == choose) {
paint.setColor(Color.parseColor("#3399ff"));
paint.setFakeBoldText(true);
}
float xPos = width / 2 - paint.measureText(b[i]) / 2;
float yPos = i *40+ topOffset;//画每一个字符
canvas.drawText(b[i], xPos, yPos, paint);
paint.reset();
}
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
String Tag = "Hight";
final int action = event.getAction();
int topOffset = (getHeight()-(b.length*40))/2;
final float y = event.getY();
final int oldChoose = choose;
final OnTouchingLetterChangedListener listener = onTouchingLetterChangedListener;
final int c = (int) ((y - topOffset) /40); //点击的时候获取点击时 //画每个字符的y坐标是 字母的位置i * 40+topOffset,现在要根据y来得到i,逆运算即可
Log.e(Tag, c+"=getHeight()="+getHeight()+"=y="+y);
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;
}
public void setOnTouchingLetterChangedListener(
OnTouchingLetterChangedListener onTouchingLetterChangedListener) {
this.onTouchingLetterChangedListener = onTouchingLetterChangedListener;
}
public interface OnTouchingLetterChangedListener {
public void onTouchingLetterChanged(String s);
}
在activity中,在拼音排完序之后,根据获取的list的长度来定义一个数组(长度一致)。在对拼音排序时,数组不断添加元素。对数组去重,然后排序就可以使用了。
下边是去重:
public void quchong(String[] array) {
List<String> list = new ArrayList<String>();
for (int i = 0; i < array.length; i++) {
list.add(array[i]);
}
Set<String> numSet = new HashSet<String>();
numSet.addAll(list);
Log.e("==00==", numSet + "");
bb = new String[numSet.size()];
Iterator<String> iterator = numSet.iterator();
for (int i = 0; i < numSet.size(); i++) {
bb[i] = iterator.next();
}
Arrays.sort(bb);
}
注意:要在获取完数据之后通过handler来动态添加SideBar
Handler handler = new Handler() {
public void handleMessage(Message msg) {
setSidBar();
}
};
setSidBar();方法如下:
private void setSidBar() {
quchong(b);// 获取的数组需要去重,排列
// 添加sideBar
sidebar = new SideBar(this, bb);
LayoutParams lypParams = new LayoutParams(50, LayoutParams.WRAP_CONTENT,5);//三个参数的最后一个是 gravity(5表示右边)
frameLayout.addView(sidebar, lypParams);
// SideBar.b = listuse.get(location)
// 设置右侧触摸监听
sidebar.setOnTouchingLetterChangedListener(new OnTouchingLetterChangedListener() {
@Override
public void onTouchingLetterChanged(String s) {
// 该字母首次出现的位置
int position = adapter.getPositionForSection(s.charAt(0));
if (position != -1) {
lv_contactsa.setSelection(position);
}
}
});
sidebar.setTextView(tv_contactsac_center_dialog);
}
核心的都在这里,其他的相信大家都能找到木有经过改造的代码。