重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
仿微信联系人列表字母侧滑控件, 侧滑控件参考了以下博客:
我们提供的服务有:成都网站制作、网站建设、外贸网站建设、微信公众号开发、网站优化、网站认证、新华ssl等。为上千企事业单位解决了网站和推广的问题。提供周到的售前咨询和贴心的售后服务,是有科学管理、有技术的新华网站制作公司
Android实现ListView的A-Z字母排序和过滤搜索功能
首先分析一下字母侧滑控件应该如何实现,根据侧滑控件的高度和字母的数量来平均计算每个字母应该占据的高度。
在View的onDraw()方法下绘制每一个字母
protected void onDraw(Canvas canvas) { super.onDraw(canvas); int height = getHeight();// 获取对应高度 int width = getWidth(); // 获取对应宽度 int singleHeight = height / getData().size();// 获取每一个字母的高度 for (int i = 0; i < getData().size(); i++) { mPaint.setColor(getLetterColor());//绘制字母的颜色 mPaint.setTypeface(Typeface.DEFAULT); mPaint.setAntiAlias(true); mPaint.setTextSize(singleHeight); // 如果是选中的状态 if (i == mPosition) { mPaint.setColor(getLetterPressedColor()); mPaint.setFakeBoldText(true); } // x坐标等于总体宽度中间的位置减去字符串宽度的一半. float xPos = width / 2 - mPaint.measureText(getData().get(i)) / 2; float yPos = singleHeight * i + singleHeight; canvas.drawText(getData().get(i), xPos, yPos, mPaint); mPaint.reset();// 重置画笔 } }
然后再看一下触控事件的拦截处理
@Override public boolean dispatchTouchEvent(MotionEvent event) { final int action = event.getAction(); final float y = event.getY();// 点击y坐标 final int lastPosition = mPosition;//记录上一次选中字母的位置 final int position = (int) (y / getHeight() * getData().size());// 点击y坐标所占总高度的比例*b数组的长度就等于点击b中的个数. switch (action) { //当手指离开 case MotionEvent.ACTION_UP: //设置侧滑控件的背景色 setBackgroundColor(getBackgroundNormalColor()); mPosition = -1; invalidate(); if (getOnTouchLetterListener() != null) { //回调事件,告知当前手指已经离开当前区域 getOnTouchLetterListener().onTouchOutside(); } break; default: //更改当字母为选中状态时控件的背景色 setBackgroundColor(getBackgroundPressedColor()); //如果选中字母的位置不等于上一次选中的位置 if (lastPosition != position) { if (position >= 0 && position < getData().size()) { if (getOnTouchLetterListener() != null) { //回调事件,返回当前选中的字母 getOnTouchLetterListener().onTouchLetter(getData().get(position)); } mPosition = position; invalidate(); } } break; } return true; } public interface OnTouchLetterListener { /** * 当接触到某个key的时候会调用; * @param s */ void onTouchLetter(String s); /** * 当离开控件可触摸区域时会调用; */ void onTouchOutside(); }
侧滑控件完成后, 再分析一下分组界面是怎么实现的,不同分组由不同的字母作为标题,用ListView就可以实现,ListView里使用的Adapter里面有一个方法getItemViewType()方法用于区分返回多种类型的View,这里我们就两种, 一个是标题,一个是联系人信息;顶部里那些新的朋友、群聊等可以用ListView的addHeaderView()实现。但是用最SDK自带的BaseAdapter实现分组的话也不方便,实际上我们可以进一步包装;
首先看一下最基本的Adapter封装:
public abstract class SimpleAdapterextends BaseAdapter { protected Context mContext; protected List mData; public SimpleAdapter(){} public SimpleAdapter(Context context, List data){ init(context, data); } public void init(Context context, List data){ this.mContext = context; this.mData = data; } @Override public int getCount() { return mData.size(); } @Override public T getItem(int position) { if(checkPositionIsOutOfRange(position)){ return null; } return mData.get(position); } @Override public long getItemId(int position) { return position; } @Override public abstract View getView(int position, View convertView, ViewGroup parent); public void refresh(List data){ if(data == null){ this.mData.clear(); }else{ this.mData = data; } notifyDataSetChanged(); } public boolean checkPositionIsOutOfRange(int position){ if(0 <= position && position < mData.size()){ return false; } return true; } public Context getContext(){ return mContext; } public List getData(){ return mData; } }
这个SimpleAdapter实现了数据基于List的最基本方法的实现,使得每次继承BaseAdapter不用再实现一些基本的方法,接下来再看一下用于更好实现分组的Adapter的进一步封装:
public abstract class SortAdapterextends SimpleAdapter
本项目Github地址(基于AndroidStudio构建):
https://github.com/yuhengye/LetterSort
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持创新互联。