提前祝大家元旦快乐,恭喜发财!
深夜来一发,2015年最后一篇博客。
差不多一个月没写博客了,最近开始实习了,空闲时间少了,人也变懒了^_^
今天来个比较简单的,先看效果图。
下面简单说下实现原理。
源码不长,先贴上来
package me.wcy.express.widget;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import java.util.List;
import me.wcy.express.R;
/**
* 快速定位侧边栏
* Created by hzwangchenyan on 2015/12/31.
*/
public class IndexBar extends LinearLayout implements View.OnTouchListener {
private ListView lvData;
private TextView tvIndicator;
private List mTitles;
private String[] mIndexes;
private int mHeight;
public IndexBar(Context context) {
this(context, null);
}
public IndexBar(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public IndexBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(attrs);
}
private void init(AttributeSet attrs) {
TypedArray ta = getContext().obtainStyledAttributes(attrs, R.styleable.IndexBar);
float indexTextSize = ta.getDimension(R.styleable.IndexBar_indexTextSize, 36.0f);
int indexTextColor = ta.getColor(R.styleable.IndexBar_indexTextColor, 0xFF616161);
ta.recycle();
mIndexes = new String[]{"☆", "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", "#"};
setOrientation(VERTICAL);
setOnTouchListener(this);
for (String index : mIndexes) {
TextView text = new TextView(getContext());
text.setText(index);
text.setTextSize(TypedValue.COMPLEX_UNIT_PX, indexTextSize);
text.setTextColor(indexTextColor);
text.setGravity(Gravity.CENTER);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 0, 1);
text.setLayoutParams(params);
addView(text);
}
}
public void setData(List titles, ListView lvData, TextView tvIndicator) {
this.mTitles = titles;
this.lvData = lvData;
this.tvIndicator = tvIndicator;
}
@Override
public boolean onTouch(View v, MotionEvent event) {
int y;
int i;
int position;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
setBackgroundColor(0x40000000);
tvIndicator.setVisibility(View.VISIBLE);
y = (int) event.getY();
mHeight = v.getHeight();
i = mIndexes.length * y / mHeight;
if (i < 0) {// 防止数组越界
i = 0;
} else if (i >= mIndexes.length) {
i = mIndexes.length - 1;
}
position = mTitles.indexOf(mIndexes[i]);
tvIndicator.setText(mIndexes[i]);
if (position != -1) {
lvData.setSelection(position);
}
break;
case MotionEvent.ACTION_MOVE:
y = (int) event.getY();
i = mIndexes.length * y / mHeight;
if (i < 0) {
i = 0;
} else if (i >= mIndexes.length) {
i = mIndexes.length - 1;
}
position = mTitles.indexOf(mIndexes[i]);
tvIndicator.setText(mIndexes[i]);
if (position != -1) {
lvData.setSelection(position);
}
break;
case MotionEvent.ACTION_UP:
setBackgroundColor(0x00000000);
tvIndicator.setVisibility(View.GONE);
y = (int) event.getY();
i = mIndexes.length * y / mHeight;
if (i < 0) {
i = 0;
} else if (i >= mIndexes.length) {
i = mIndexes.length - 1;
}
position = mTitles.indexOf(mIndexes[i]);
tvIndicator.setText(mIndexes[i]);
if (position != -1) {
lvData.setSelection(position);
}
break;
}
return true;
}
}
继承自LinearLayout,添加了26个字母索引TextView,需要传进来展示数据的ListView、数据源List、滑动时显示当前索引的TextView,就可以愉快的滑滑滑了~
核心是OnTouchListener,手指滑动的时候根据当前Y坐标计算出手指所在的索引位置,然后将ListView滑动到索引的位置,要注意临界值。