在刚学习Android的时候就想自己手写一个索引,但是当时还是彩笔,就一直没做,昨天写了一个索引,今天贴出来,以备后用,先上图:
由于列表是我自己封装的,可能必看到展示页面的时候会有陌生感,但是并不复杂,很好理解,好了不废话了,操起键盘就是干。
自定义索引栏:
注释加的已经很清楚了,还是不理解的@我
package app.project.view;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import app.project.R;
/**
* @author qly
*/
public class MySlideBar extends View {
// 是否点击
private boolean showBkg = false;
// 监听面板是否点击接口
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" };
// 选择的值
int choose = -1;
private Context context;
// 画笔
Paint paint = new Paint();
public MySlideBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.context = context;
}
public MySlideBar(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
}
public MySlideBar(Context context) {
super(context);
this.context = context;
}
/**
* 重写这个方法
*/
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//背景色绘制为灰色
if (showBkg) {
canvas.drawColor(Color.parseColor("#40000000"));
}
int height = getHeight();
int width = getWidth();
int singleHeight = height / b.length;
for (int i = 0; i < b.length; i++) {
paint.setAntiAlias(true);
paint.setTextSize(context.getResources().getDimensionPixelSize(
R.dimen.sidebar_textsize));
// 点击的字体和26个字母中的任意一个相等就
if (i == choose) {
paint.setColor(Color.parseColor("#3399ff"));
paint.setFakeBoldText(true);
}
// 字体的X坐标
float xPos = width / 2 - paint.measureText(b[i]) / 2;
// 字体的Y坐标
float yPos = singleHeight * i + singleHeight;
canvas.drawText(b[i], xPos, yPos, paint);
// 还原画布
paint.reset();
}
}
/**
* 点击事件
*/
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
// 点击的Y坐标
final float y = event.getY();
final int oldChoose = choose;
// 得到当前的值(当前点击坐标/控件高度*27)
final int c = (int) (y / getHeight() * b.length);
// 根据点击的状态不同做出不同的处理
switch (event.getAction()) {
// 按下已经开始
case MotionEvent.ACTION_DOWN:
// 将开关设置为true
showBkg = true;
if (oldChoose != c && onTouchingLetterChangedListener != null) {
if (c >= 0 && c < b.length) {
// 当当前点击的值绑定监听
// 这个监听在本页面中做的是接口。实际调用是在MainActiv中。也就是说我们调用这个接口会执行MainActivtiy的方法
onTouchingLetterChangedListener.onTouchingLetterChanged(b[c]);
choose = c;
// 刷新界面
invalidate();
}
}
break;
// 松开为完成点击
case MotionEvent.ACTION_MOVE:
if (oldChoose != c && onTouchingLetterChangedListener != null) {
if (c >= 0 && c < b.length) {
onTouchingLetterChangedListener.onTouchingLetterChanged(b[c]);
choose = c;
invalidate();
}
}
break;
// 完成松开 还原数据 并刷新界面
case MotionEvent.ACTION_UP:
showBkg = false;
choose = -1;
invalidate();
break;
}
return true;
}
/**
* 向外公开的方法
*/
public void setOnTouchingLetterChangedListener(
OnTouchingLetterChangedListener onTouchingLetterChangedListener) {
this.onTouchingLetterChangedListener = onTouchingLetterChangedListener;
}
/**
* 接口
*/
public interface OnTouchingLetterChangedListener {
void onTouchingLetterChanged(String s);
}
}
列表展示页面
package app.project;
import android.graphics.Color;
import android.os.Bundle;
import android.support.annotation.LayoutRes;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import app.project.recycler.DevBaseRecyclerViewActivity;
import app.project.recycler.ListBaseRecyclerAdapter;
import app.project.utils.BaseStickyBean;
import app.project.model.ContactHeader;
import app.project.model.ItemsEntity;
import app.project.view.MySlideBar;
public class IndexActivity extends DevBaseRecyclerViewActivity<BaseStickyBean> {
List<ItemsEntity> list=new ArrayList<>();
@Override
public void setContentView(@LayoutRes int layoutResID) {
super.setContentView(R.layout.activity_index);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MySlideBar mySideBar= (MySlideBar) findViewById(R.id.my_side_bar);
mySideBar.setOnTouchingLetterChangedListener(new MySlideBar.OnTouchingLetterChangedListener() {
@Override
public void onTouchingLetterChanged(String s) {
for (int i = 1; i < mList.size(); i++) {
if (mList.get(i).getStickItem().equalsIgnoreCase(s)) {
mRecyclerView.scrollToPosition(i);
}
}
}
});
}
@Override
public void loadData() {
enableSwipeRefresh(false);
list.add(new ItemsEntity("阿文"));
list.add(new ItemsEntity("Andy"));
list.add(new ItemsEntity("梁朝伟"));
list.add(new ItemsEntity("周杰伦"));
list.add(new ItemsEntity("蔡依林"));
list.add(new ItemsEntity("陈慧琳"));
list.add(new ItemsEntity("房祖名"));
list.add(new ItemsEntity("罗启新"));
list.add(new ItemsEntity("陈浩民"));
list.add(new ItemsEntity("苏友朋"));
list.add(new ItemsEntity("胡彦斌"));
list.add(new ItemsEntity("叶德娴"));
list.add(new ItemsEntity("孙燕姿"));
list.add(new ItemsEntity("欧阳震华"));
list.add(new ItemsEntity("郭富城"));
list.add(new ItemsEntity("麦兆辉"));
list.add(new ItemsEntity("向海岚 "));
sortList(list);
}
public void sortList(List<ItemsEntity> list) {
Map<String, List<ItemsEntity>> map = new HashMap<>();
for (int i = 0; i < list.size(); i++) {
ItemsEntity myContact = list.get(i);
List<ItemsEntity> temp = map.get(myContact.getStickItem());
if (temp == null) {
temp = new ArrayList<>();
map.put(myContact.getStickItem(), temp);
}
temp.add(myContact);
}
List<BaseStickyBean> finalList = new ArrayList<>();
List<String> keys = new ArrayList<>(map.keySet());
Collections.sort(keys);
for (int i = 0; i < keys.size(); i++) {
finalList.add(new ContactHeader(keys.get(i)));
finalList.addAll(map.get(keys.get(i)));
}
mList.addAll(finalList);
setListAdapter();
}
@Override
public void onItemClick(ListBaseRecyclerAdapter.YFViewHolder holder, BaseStickyBean o, int position, long id) {
}
@Override
public View getView(ViewGroup parent, int viewType) {
View view=LayoutInflater.from(this).inflate(R.layout.item,parent,false);
if(viewType==0){
return view;
}else if(viewType==1){
view.setBackgroundColor(Color.parseColor("#CDD7E2"));
return view;
}
return null;
}
@Override
public void convertObject2View(ListBaseRecyclerAdapter.YFViewHolder holder, int position) {
if(holder.getItemViewType()==1){
holder.setText(R.id.tv, mList.get(position).getStickItem());
}else if(holder.getItemViewType()==0){
ItemsEntity item= (ItemsEntity) mList.get(position);
holder.setText(R.id.tv,item.getName() );
}
}
@Override
public int getItemViewType(int position) {
BaseStickyBean bean = mList.get(position);
if (bean instanceof ContactHeader) {
return 1;
}
return 0;
}
}
数据排序的实现
- 新建一个map用来存储索引开头字母和姓名类似:map<字母 姓名>
- 我们遍历数据集合并且取出姓名首字母,然后新建集合放入字母对应的名字map
- 按字母排序Collections.sort(keys);,让后按照字母遍历分组排序。这样就搞定了
怎么获取的姓名首字母的呢?
我们使用了一个jar包,pinyin4j-2.5.0.jar就是它。有兴趣的可以看下。 需要源码@我