【www.bbyears.com--微信】
先给大家展示下效果图:
实现代码如下:
下面简单说下实现原理。
代码如下
publicclassIndexBarextendsLinearLayoutimplementsView.OnTouchListener {
privatestaticfinalString[] INDEXES =newString[]{"#","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"};
privatestaticfinalintTOUCHED_BACKGROUND_COLOR =0x40000000;
privateOnIndexChangedListener mListener;
publicvoidsetOnIndexChangedListener(OnIndexChangedListener listener) {
mListener = listener;
}
publicIndexBar(Context context) {
this(context,null);
}
publicIndexBar(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
publicIndexBar(Context context, AttributeSet attrs,intdefStyleAttr) {
super(context, attrs, defStyleAttr);
init(attrs);
}
privatevoidinit(AttributeSet attrs) {
TypedArray ta = getContext().obtainStyledAttributes(attrs, R.styleable.IndexBar);
floatindexTextSize = ta.getDimension(R.styleable.IndexBar_indexTextSize, Utils.sp2px(getContext(),12));
intindexTextColor = ta.getColor(R.styleable.IndexBar_indexTextColor,0xFF616161);
ta.recycle();
setOrientation(VERTICAL);
setOnTouchListener(this);
for(String index : INDEXES) {
TextView text =newTextView(getContext());
text.setText(index);
text.setTextSize(TypedValue.COMPLEX_UNIT_PX, indexTextSize);
text.setTextColor(indexTextColor);
text.setGravity(Gravity.CENTER);
LinearLayout.LayoutParams params =newLinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,0,1);
text.setLayoutParams(params);
addView(text);
}
}
@Override
publicbooleanonTouch(View v, MotionEvent event) {
switch(event.getAction()) {
caseMotionEvent.ACTION_DOWN:
setBackgroundColor(TOUCHED_BACKGROUND_COLOR);
handle(v, event);
returntrue;
caseMotionEvent.ACTION_MOVE:
handle(v, event);
returntrue;
caseMotionEvent.ACTION_UP:
setBackgroundColor(Color.TRANSPARENT);
handle(v, event);
returntrue;
}
returnsuper.onTouchEvent(event);
}
privatevoidhandle(View v, MotionEvent event) {
inty = (int) event.getY();
intheight = v.getHeight();
intposition = INDEXES.length * y / height;
if(position<0) {
position =0;
}elseif(position >= INDEXES.length) {
position = INDEXES.length -1;
}
String index = INDEXES[position];
booleanshowIndicator = event.getAction() != MotionEvent.ACTION_UP;
if(mListener !=null) {
mListener.onIndexChanged(index, showIndicator);
}
}
publicinterfaceOnIndexChangedListener {
voidonIndexChanged(String index,booleanshowIndicator);
}
}
使用
代码如下
publicclassCompanyActivityextendsBaseActivityimplementsIndexBar.OnIndexChangedListener {
@Bind(R.id.lv_company)
ListView lvCompany;
@Bind(R.id.ib_indicator)
IndexBar ibIndicator;
@Bind(R.id.tv_indicator)
TextView tvIndicator;
privateList
@Override
protectedvoidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_company);
// ...
}
@Override
publicvoidonIndexChanged(String index,booleanshowIndicator) {
intposition = -1;
for(CompanyEntity company : mCompanyList) {
if(TextUtils.equals(company.getName(), index)) {
position = mCompanyList.indexOf(company);
break;
}
}
if(position != -1) {
lvCompany.setSelection(position);
}
tvIndicator.setText(index);
tvIndicator.setVisibility(showIndicator ? View.VISIBLE : View.GONE);
}
}
继承自LinearLayout,添加了26个字母索引TextView,当手指滑动时通知Activity更新界面。
核心是OnTouchListener,手指滑动的时候根据当前Y坐标计算出手指所在的索引位置,要注意临界值。