SideBar就是在ListView右边出现的一个竖条,有A到Z字母索引,通过字母索引可以快速定位到ListView的位置。
先上图 动图就不放了,只放个静态图
唔....大致说下思路,我这边sidebar和字母提示框是分开的,SideBar只是右边那一列,中间的字母提示只是一个单独的TextView,两个控件通过接口实现绑定。
另外该篇只讲控件的实现和方法使用,具体的ListView定位position逻辑不讲 有时间会写-。-
attrs属性
严格来讲,SideBar的属性应该包含字母字体前景色、背景色、触摸时背景色、字体大小这些。这里我只暴露了字体的颜色大小两个属性,背景色固定为透明色,触摸时加了蒙版遮罩层。
<declare-styleable name="SideBar">
<attr name="letterColor" format="color" />
<attr name="letterSize" format="dimension" />
</declare-styleable>
View实现
- 上面说过,索引和提示框是分开的,所以需要提供一个方法做绑定
- 其次是触摸事件响应,由于控件本身并不知道具体要做什么处理,所以需要把接口暴露出去
public class SideBar extends View {
public final String[] index = { "#",
"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 Paint paint = new Paint();
/**
* 索引字体颜色
*/
private int mLetterColor;
/**
* 索引字体大小
*/
private int mLetterSize;
/**
* 中间显示文字
*/
private TextView mTextDialog;
/**
* 触摸事件接口
*/
private OnTouchListener onTouchListener;
public SideBar(Context context) {
super(context);
}
public SideBar(Context context, AttributeSet attrs) {
super(context, attrs);
initAttrs(context, attrs);
}
public SideBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initAttrs(context, attrs);
}
/**
* 初始化属性
* @param context 上下文
* @param attrs 属性
*/
private void initAttrs(Context context, AttributeSet attrs){
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.SideBar);
mLetterColor = array.getColor(R.styleable.SideBar_letterColor, Color.alpha(R.color.blue_light));
mLetterSize = array.getDimensionPixelSize(R.styleable.SideBar_letterSize, 30);
array.recycle();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int singleHeight = getMeasuredHeight() / index.length;
for (int i = 0; i < index.length; i++) {
paint.setTypeface(Typeface.DEFAULT_BOLD);
paint.setAntiAlias(true); // 抗锯齿
paint.setColor(mLetterColor);
paint.setTextSize(mLetterSize);
float xPos = getWidth() / 2 - paint.measureText(index[i]) / 2;
float yPos = singleHeight * i + singleHeight * 0.6f;
canvas.drawText(index[i], xPos, yPos, paint);
paint.reset();// 重置画笔
}
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
final int action = event.getAction();
final float y = event.getY();// 点击y坐标
// 点击y坐标所占总高度的比例*b数组的长度就等于点击b中的个数.
final int c = (int) (y / getHeight() * index.length);
switch (action) {
case MotionEvent.ACTION_DOWN: // 摁下
case MotionEvent.ACTION_MOVE: // 移动
setBackgroundColor(Color.parseColor("#40000000")); // 遮罩层
if (c >= 0 && c < index.length) {
if (onTouchListener != null) {
onTouchListener.onTouching(index[c].charAt(0)); // 触摸事件接口
}
if (mTextDialog != null) { // 显示字母文本提示框
mTextDialog.setText(index[c]);
mTextDialog.setVisibility(View.VISIBLE);
}
invalidate(); //请求重新draw()
}
break;
case MotionEvent.ACTION_UP: // 抬起
setBackgroundColor(Color.TRANSPARENT);
invalidate();
if (mTextDialog != null) {
mTextDialog.setVisibility(View.GONE);
}
break;
default:
break;
}
return true;
}
/**
* 绑定LetterDialog
* @param mTextDialog 文本控件
*/
public void setTextView(TextView mTextDialog) {
this.mTextDialog = mTextDialog;
}
/**
* 绑定触摸事件接口
* @param onTouchListener 触摸事件接口
*/
public void setOnTouchListener(OnTouchListener onTouchListener) {
this.onTouchListener = onTouchListener;
}
/**
* 触摸事件
*/
public interface OnTouchListener {
void onTouching(char c);
}
}
使用
布局
<com.xtao.tlib.view.SideBar
android:id="@+id/sidebar"
app:letterColor="@color/blue_light"
android:layout_width="22dp"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_alignParentEnd="true"/>
Activity
public class SideBarActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView textView = (TextView) findViewById(R.id.textView);
SideBar sidebar = (SideBar) findViewById(R.id.sidebar);
sidebar.setTextView(textView);
sidebar.setOnTouchListener(new SideBar.OnTouchListener() {
@Override
public void onTouching(char c) {
// TODO: 2017/8/4 根据letter定位ListView
Log.i("SideBar Touching", String.valueOf(c));
}
});
}
}
网友评论