美文网首页
8.实现包含快速检索的ListView

8.实现包含快速检索的ListView

作者: BusyBunny | 来源:发表于2019-08-01 21:17 被阅读0次

    实现包含快速检索的ListView

    • 1.案例演示:


      案例演示.gif
    • 2.实现逻辑:

    • 1.界面分为ListView和自定义QuickIndexBar;
    • 2.右边自定义QuickIndexBar,并获取到被点击的字母,点击字母变色;


      x和y坐标演示图.png
        绘制文本X坐标:设置为以底部为中心点后,x坐标为控件宽度的一半;
        绘制文本Y坐标:格子高度的一半+文本高度的一半+索引*格子高度;
        计算触摸点对应的字母:根据触摸点的y坐标除以格子高度,得到的值就是字母对应的索引值;
        点击字母变色:每一次点击颜色会改变,因此每一次点击都要重绘文本,并设置paint.setColor();
    
     Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); //参数效果为:抗锯齿
     mPaint.setTextSize(18);
     mPaint.setColor(Color.WHITE);
     //以底部中心为起点:
     mPaint.setTextAlign(Paint.Align.CENTER);
    
     @Override
     protected void onDraw(Canvas canvas) {
         super.onDraw(canvas);
         float width=mWidth/2;
         for (int i=0;i<indexArr.length;i++){
             //格子高度的一半+文本高度的一半+索引*格子高度
             float height=cellHeight/2+getTextHeight(indexArr[i])/2+i*cellHeight;
             canvas.drawText(indexArr[i],width,height,mPaint);
         }
     }
    
     //平均每个格子的高度:
     cellHeight=getMeasuredHeight()*1f/indexArr.length;
    
     //获取文本高度:
     private int getTextHeight(String text){
         //第二个参数:start:text起始数量
         //第三个参数:end:text的最终数量
         Rect rect=new Rect();
         mPaint.getTextBounds(text,0,text.length(),rect);
         return rect.height();
     }
    
    • 3.左边为ListView或者RecyclerView,根据当前的被触摸的字母去找与自己列表相同的首字母的那个item,然后放到顶部setSelection(int i);
        mQuickIndexBar.setQuickIndexBarListener(new QuickIndexBar.QuickIndexBarListener() {
                @Override
                public void getLetter(String letter) {
                    Log.d(TAG, "getLetter: "+letter);
                    for (int i=0;i<friends.size();i++){
                       String firstLetter=friends.get(i).getPinyin().charAt(0)+"";
                       Log.d(TAG, "getLetter: "+firstLetter);
                       if (letter.equals(firstLetter)){
                           mListView.setSelection(i);
                           break;
                       }
                   }
                }
            });
    
    • 4.需要用到获取的汉字的拼音
    public class PinYinUtils {
        public static String getPinYin(String chinese){
            String pinyin ="";
            if (TextUtils.isEmpty(chinese)) return null;
            HanyuPinyinOutputFormat hanyuPinyinOutputFormat=new HanyuPinyinOutputFormat();
            //设置转换为大写
            hanyuPinyinOutputFormat.setCaseType(HanyuPinyinCaseType.UPPERCASE);
            //设置音调为无音调
            hanyuPinyinOutputFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
    
            //由于只能单个转换,因此将字符串转换为字符数组
            char[] charArray = chinese.toCharArray();
            for (int i=0;i<charArray.length;i++){
                //过滤空格
                if (Character.isWhitespace(charArray[i])) continue;
                //需要判断是否是汉字:
                //一个汉字占2个字节,一个字节范围是-127~127,只要该字符大于127就认为可能是汉字;
                if (charArray[i]>127){
                    //可能是汉字
                    try {
                        String[] pinyinStringArray = PinyinHelper.toHanyuPinyinStringArray(charArray[i], hanyuPinyinOutputFormat);
                        if (pinyinStringArray!=null){
                            pinyin+=pinyinStringArray[i];
                        }else {
                            //说明未获取到
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }else{
                    //一定不是汉字,可能是符号之类的,因此将此字符拼接
                    pinyin+=charArray[i];
                }
            }
            return pinyin;
        }
    }
    
    • 5.ListView根据拼音首字母合并:比较上一个item的letter和本次item的letter如果一样则隐藏本次的item的letter
            String currentLetter=friend.getPinyin().charAt(0)+"";
                if (position>0){
                    String lastLetter=getItem(position-1).getPinyin().charAt(0)+"";
                    if (lastLetter.equals(friend.getPinyin().charAt(0)+"")){
                        //上一个item的letter和本次item的letter一样,则隐藏本次的item的letter:
                        viewHolder.letter.setVisibility(View.GONE);
                    }else {
                        //由于复用,要将所需要的显示出
                        viewHolder.letter.setVisibility(View.VISIBLE);
                    }
                }else{
                    viewHolder.letter.setVisibility(View.VISIBLE);
                }
                viewHolder.letter.setText(currentLetter);
                viewHolder.name.setText(friend.getName());
    

    相关文章

      网友评论

          本文标题:8.实现包含快速检索的ListView

          本文链接:https://www.haomeiwen.com/subject/mlqhdctx.html