Android 索引的实现

在刚学习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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值