android-仿手机通讯录(支持索引导航和搜索功能)

来源:互联网 发布:华中科技大学软件下载 编辑:程序博客网 时间:2024/06/04 21:08

最近公司需要实现类似于手机通讯录的功能,并支持搜索功能,今天便简单写了一下。基本功能已经实现。我们先看一下效果。联系QQ878586063。以下晒出来的代码,是全部代码。代码不多,大家感受一下。
这里写图片描述这里写图片描述这里写图片描述

首页我们看下索引导航View,特别简单一看就懂,这个类已经用模拟器试过除了手表所有的机型,都是可以的。

 @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        for (int i = 0; i < codes.length; i++) {            if (codes[i].equals("#")) {                canvas.drawBitmap(mBitmap, 8 * displayMetrics.density, lineHeight * (i + 1), paint);            } else {                canvas.drawText(codes[i], 10 * displayMetrics.density, 7 * displayMetrics.density + lineHeight * (i + 1), paint);            }        }    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        setMeasuredDimension((int) (viewHeight * displayMetrics.density), (int) (lineHeight * codes.length + 13 * displayMetrics.density));    }    @Override    public boolean onTouchEvent(MotionEvent event) {        switch (event.getAction()) {            case MotionEvent.ACTION_DOWN:                setAlpha(0.5f);                setBackgroundColor(Color.GRAY);                float y = event.getY();                int v = (int) ((y - 6.5 * displayMetrics.density) / lineHeight);                if (v >= 0 && v <= codes.length - 1) {                    if (moveEvent != null)                        moveEvent.move(codes[v]);                }                break;            case MotionEvent.ACTION_MOVE:                y = event.getY();                v = (int) ((y - 6.5 * displayMetrics.density) / lineHeight);                if (v >= 0 && v <= codes.length - 1) {                    if (moveEvent != null)                        moveEvent.move(codes[v]);                }                break;            case MotionEvent.ACTION_UP:                setBackgroundColor(Color.WHITE);                setAlpha(1f);                break;        }        return super.onTouchEvent(event);    }

接下来我们看下怎么处理的:

//数据类 * * Created by yang pengtao on 2017/9/19. */public class SelectCountryCodeBean implements Serializable {    private List<CodesBean> codes;    public List<CodesBean> getCodes() {        return codes;    }    public void setCodes(List<CodesBean> codes) {        this.codes = codes;    }    public static class CodesBean {        /**         * cname : 福克兰群岛(马尔维纳斯)         * ename : Falkland Islands (Islas Malvinas)         * code : +500         */        private String cname;        private String ename;        private String code;        private String first_letter;        private int type = 1;        public String getCname() {            return cname;        }        public void setCname(String cname) {            this.cname = cname;        }        public String getEname() {            return ename;        }        public void setEname(String ename) {            this.ename = ename;        }        public String getCode() {            return code;        }        public void setCode(String code) {            this.code = code;        }        public String getFirst_letter() {            return first_letter;        }        public void setFirst_letter(String first_letter) {            this.first_letter = first_letter;        }        public int getType() {            return type;        }        public void setType(int type) {            this.type = type;        }    }}

我们得到数据后先要处理一下,用pinyin4j.jar得到汉字拼音首字母,还要得到字母显示在列表中的下标,用于我们列表滚动。如果大家需要pinyin4j.jar。戳这里。

/**     * 重置数据成自己想要的数据     *     * @param data 要被重置的数据     */    private void resetData(List<SelectCountryCodeBean.CodesBean> data) {        for (int i = 0; i < data.size(); i++) {            String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(data.get(i).getCname().charAt(0));            if (pinyinArray != null) {                String s = pinyinArray[0].substring(0, 1).toUpperCase();                data.get(i).setFirst_letter(s);                if (!positions.containsKey(s)) {                    positions.put(s, i);                }            }        }    }

有了数据我们就可以把数据显示到我们的列表上了,我用到了我写的上一篇封装的适配器,用起来非常方便,不用编写adapter和view holder,看下面代码,感受一下。希望大家赶快用起来吧。想学习的可以直接看暴力封装Adapter

 /**     * 设置adapter     */    private void setAdapter() {        listview.setAdapter(new BaseAdapter<SelectCountryCodeBean.CodesBean>(R.layout.layout_select_country_code, codes) {            @Override            public void onBindViewHolder(BaseViewHolder holder, List<SelectCountryCodeBean.CodesBean> data, int position) {                if (position != 0 && data.get(position).getFirst_letter().equals(data.get(position - 1).getFirst_letter())) {                    holder.getView(R.id.code).setVisibility(View.GONE);                } else {                    holder.getView(R.id.code).setVisibility(View.VISIBLE);                }                holder.setText(R.id.code, data.get(position).getFirst_letter());                holder.setText(R.id.country, data.get(position).getCname() + "(" + data.get(position).getEname() + ")").setText(R.id.country_code, data.get(position).getCode());            }        });    }

实现索引导航的代码也只不过仅仅几行,来感受虾:

 /**     * 索引导航     */    private void indexNavigae() {        ((ZoomImageView) findViewById(R.id.leftView)).setMoveEvent(new ZoomImageView.MoveEvent() {            @Override            public void move(String code) {                if (positions.get(code) != null) {                    linearLayoutManager.scrollToPositionWithOffset(positions.get(code), 0);                }            }        });    }

最后就只有我们的搜索功能,闲话不多说,直接感受:

/**     * 搜索数据     *     * @param s 搜索字符     */    public void searchResetData(String s) {        serachData.clear();        //如果为null,直接使用全部数据        if (s.equals("")) {            serachData.addAll(codes);        } else {            //否则,匹配相应的数据            for (int i = 0; i < codes.size(); i++) {                if (codes.get(i).getCname().indexOf(s) >= 0 || codes.get(i).getEname().indexOf(s) >= 0) {//这里可拓展自己想要的,甚至可以拆分搜索汉字来匹配                    serachData.add(codes.get(i));                }            }        }        //绑定索引        positions.clear();        resetData(serachData);        //刷新数据        ((BaseAdapter<SelectCountryCodeBean.CodesBean>) listview.getAdapter()).setmData(serachData);    }

最后有一点非常重要:给IndexNavigateView加一个click事件,否则触摸事件回合recyclerView冲突。

到这就结束了,是不是特别简单,欢迎评论反馈。大家支持一下。

阅读全文
0 0
原创粉丝点击