Android 索引的实现

来源:互联网 发布:简约博客网站源码 编辑:程序博客网 时间:2024/05/17 07:01

在刚学习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;    }}

数据排序的实现

  1. 新建一个map用来存储索引开头字母和姓名类似:map<字母 姓名>
  2. 我们遍历数据集合并且取出姓名首字母,然后新建集合放入字母对应的名字map
  3. 按字母排序Collections.sort(keys);,让后按照字母遍历分组排序。这样就搞定了

怎么获取的姓名首字母的呢?

我们使用了一个jar包,pinyin4j-2.5.0.jar就是它。有兴趣的可以看下。 需要源码@我

0 0