android通讯录(任意层级树形列表和字母列表切换)
参考文章Android使用RecycleView实现魅族手机通讯录界面Android微信通讯录滑动快速定位实现其中recyclerview部分参考第一篇文章,侧边栏参考第二篇文章关键点:判断是否分组的开始ItemDecorationgetItemOffsets为绘制分组头部字母和分割线预留空间onDraw绘制分组头部字母onDrawOver绘制悬停字母侧边...
·
参考文章
- Android使用RecycleView实现魅族手机通讯录界面
- Android微信通讯录滑动快速定位实现
- 更快实现Android多级树形选择列表
- 其中recyclerview部分参考第一篇文章,侧边栏参考第二篇文章
关键点:
-
判断是否分组的开始
-
ItemDecoration
- getItemOffsets为绘制分组头部字母和分割线预留空间
- onDraw绘制分组头部字母
- onDrawOver绘制悬停字母
-
侧边栏的实现
- 侧边栏的事件
效果如下
关键代码
-
关键点1代码
/** * 是否是分组头部 当前位置和上一个位置的首字母不一样,则是分组的头部 * @param position 位置 * @return */ private boolean isSectionHeader(int position){ if (position == 0){ return true; }else{ if (!modelList.get(position).getIndexTag().equals(modelList.get(position - 1).getIndexTag())){ return true; }else { return false; } } }
-
关键点2代码
@Override public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) { //parent.getChildLayoutPosition(view); 区别 int position = parent.getChildAdapterPosition(view); if (modelList == null || modelList.size() == 0 || modelList.size() <= position || position < 0) { super.getItemOffsets(outRect, view, parent, state); return; } if (isSectionHeader(position)){ outRect.top = dividerHeight; }else { outRect.top = 1; } } @Override public void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) { int count = parent.getChildCount(); for (int i = 0; i < count; i++) { View view = parent.getChildAt(i); int position = parent.getChildAdapterPosition(view); //考虑到recyclerview的内边距 int left = parent.getPaddingLeft(); int right = parent.getWidth() - parent.getPaddingRight();//?parent.getRight - parent.getPaddingRight() if (isSectionHeader(position)){//分组头部 //1.先画矩形 // c.drawRect(0,view.getTop() - dividerHeight,right,view.getTop(),mPaint); //2.画圆 //改变画笔的颜色 // ColorUtil.setPaintColor(mPaint,tagsStr.indexOf(modelList.get(position).getIndexTag())); // c.drawCircle(QMUIDisplayHelper.dp2px(mContext, 42), view.getTop() - dividerHeight / 2, 35, mPaint); //3.画字 mPaint.setTextSize(40); mPaint.setColor(Color.parseColor("#909090")); c.drawText(modelList.get(position).getFirstLetter(),QMUIDisplayHelper.dp2px(mContext,42),view.getTop()-dividerHeight/3,mPaint); }else {//普通item // c.drawRect(0,view.getTop() - 1,right,view.getTop(),linePaint); // c.drawLine(0,view.getTop() - 1,right,view.getTop(),linePaint);//画分割线,宽度不会撑满 } } } @Override public void onDrawOver(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) { //第一个可见的item的position int position = ((LinearLayoutManager) (parent.getLayoutManager())).findFirstVisibleItemPosition(); if (modelList == null || modelList.size() == 0 || modelList.size() <= position || position < 0){ return; } int bottom = parent.getPaddingTop() + dividerHeight; mPaint.setColor(Color.parseColor("#ffffff")); c.drawRect(parent.getLeft(), parent.getPaddingTop(), parent.getRight() - parent.getPaddingRight(), parent.getPaddingTop() + dividerHeight, mPaint); // ColorUtil.setPaintColor(mPaint, tagsStr.indexOf(modelList.get(position).getIndexTag())); // c.drawCircle(QMUIDisplayHelper.dp2px(mContext, 42), bottom - dividerHeight / 2, 35, mPaint); mPaint.setTextSize(40); mPaint.setColor(Color.parseColor("#007aff")); c.drawText(modelList.get(position).getFirstLetter(), QMUIDisplayHelper.dp2px(mContext, 42), bottom - dividerHeight / 3, mPaint); }
-
关键点3代码
@Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: setBackgroundColor(TOUCHED_BACKGROUND_COLOR); handle(event); return true; case MotionEvent.ACTION_MOVE: handle(event); return true; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: setBackgroundColor(Color.TRANSPARENT); handle(event); return true; } return super.onTouchEvent(event); } private void handle(MotionEvent event) { int color = downTextColor; if (event.getAction() == MotionEvent.ACTION_UP){ color = indexTextColor; } for (int i = 0; i < getChildCount(); i++) { View vi = getChildAt(i); if (vi instanceof TextView){ ((TextView) vi).setTextColor(color); } } int y = (int) event.getY(); int height = getHeight(); //触摸点的距离除以每个字母的高度(控件高度除以字母的个数) int position = y / (height/INDEXES.length); if (position < 0){ position = 0; }else if (position >= INDEXES.length){ position = INDEXES.length - 1; } String tag = INDEXES[position]; boolean showInicator = event.getAction() != MotionEvent.ACTION_UP && event.getAction() != MotionEvent.ACTION_CANCEL; if (listener != null){ listener.onIndexChanged(tag,position, showInicator); } }
完整代码github
更多推荐
已为社区贡献7条内容
所有评论(0)