自定义View:按字母索引排序

本文介绍了Android开发中按照汉字首字母排序的需求,详细讲解如何创建一个自定义View,包括计算字母空间高度、绘制字母和圆圈、处理触摸事件,以及与RecyclerView联动的方法。
摘要由CSDN通过智能技术生成

Android开发常见的需求: 按拼音排序

Android常见需求,按照汉字首字母排序,从A~Z,右侧自定义一个字母列表,手指可以滑动选择,并和RecyclerView联动的效果。
如图:
在这里插入图片描述
左侧RecyclerView建议使用多布局类型,以后好做头部悬停效果。右侧要自定义View来实现,触摸滑动刷新界面了。

首先,计算View的宽高和字母所占的空间高度;

1、计算View的宽度

  @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
   
        //取出宽高的MeasureSpec  Mode 和Size
        int wMode = MeasureSpec.getMode(widthMeasureSpec);
        int wSize = MeasureSpec.getSize(widthMeasureSpec);
        int hMode = MeasureSpec.getMode(heightMeasureSpec);
        int hSize = MeasureSpec.getSize(heightMeasureSpec);
        int measureWidth = 0, measureHeight = 0;//最终测量出来的宽高
        //得到合适宽度:
        Rect indexBounds = new Rect();//存放每个绘制的index的Rect区域
        String index;//每个要绘制的index内容
        for (int i = 0; i < firstLetters.size(); i++) {
   
            index = firstLetters.get(i);
            mPaint.getTextBounds(index, 0, index.length(), indexBounds);//测量计算文字所在矩形,可以得到宽高
            measureWidth = Math.max(indexBounds.width(), measureWidth);//循环结束后,得到index的最大宽度
        }
  
        //得到合适的宽度:
        switch (wMode) {
   
            case MeasureSpec.EXACTLY:
                measureWidth = wSize;
                break;
            case MeasureSpec.AT_MOST:
            //wrap_content
                measureWidth = Math.min(measureWidth, wSize);//wSize此时是父控件能给子View分配的最大空间
                break;
            case MeasureSpec.UNSPECIFIED:
                break;
        }
    }

2、先算出整个View的高度,再除以字母个数,就是每个字母所用的平均空间高度,

 @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
   
        //取出宽高的MeasureSpec  Mode 和Size
        int wMode = MeasureSpec.getMode(widthMeasureSpec);
        int wSize = MeasureSpec.getSize(widthMeasureSpec);
        int hMode = MeasureSpec.getMode(heightMeasureSpec);
        int hSize = MeasureSpec.getSize(heightMeasureSpec);
        int measureWidth = 0, measureHeight = 0;//最终测量出来的宽高
        //得到合适宽度:
        Rect indexBounds = new Rect();//存放每个绘制的index的Rect区域
        String index;//每个要绘制的index内容
        for (int i = 0; i < firstLetters.size(); i++) {
   
            index = firstLetters.get(i);
            mPaint.getTextBounds(index, 0, index.length(), indexBounds);//测量计算文字所在矩形,可以得到宽高
            measureWidth = Math.max(indexBounds.width(), measureWidth);//循环结束后,得到index的最大宽度
            measureHeight = Math.max(indexBounds.height(), measureHeight);//循环结束后,得到index的最大高度,然后*size
        }
        measureHeight *= firstLetters.size();
        measureHeight += (getPaddingBottom() + getPaddingTop());
       

        //得到合适的高度:
        switch (hMode) {
   
            case MeasureSpec.EXACTLY:
                measureHeight = hSize;
                break;
            case MeasureSpec.AT_MOST:
            	//wrap_content
                measureHeight = Math.min(measureHeight, hSize);//wSize此时是父控件能给子View分配的最大空间
                break;
            case MeasureSpec.UNSPECIFIED:
                break;
        }
    }

高度算出来后,可以在 onSizeChanged() 方法里面获取;

  @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
   
        super.onSizeChanged(w, h, oldw, oldh);
        mWidth = w;
        mHeight = h;
        if (mIsHalfWidth){
   
            mCircleRadius = mWidth / 2F;
        }

        if (null == firstLetters || firstLetters.isEmpty()) {
   
            return;
        }
        //计算每个字母平均占据空间高度
        computeGapHeight();
    }

获取高度后,除去字母个数可得每个字母所占平均高度:

 private void computeGapHeight() {
   
 		//高度减去padding,除以字母个数
        mCellHeight = (mHeight - getPaddingTop() - getPaddingBottom()) / firstLetters.size();
    }
绘制字母和小圆圈

onDraw() 方法里吗进行绘制。

    @Override
    protected void onDraw(Canvas canvas) {
   
        super.onDraw(canvas);

        int paddingTop = getPaddingTop();
        String letter;
        for (int i = 0; i < firstLetters.size(); i++) {
   
        	//选中的字母
            if (choosePos == i) {
   
            //如果有字体大小变化需求的话
//                mPaint.setTextSize();
                mPaint.setColor(mSelectTextColor);
                //计算圆圈圆心坐标,x,y,和半径
                //x坐标位于View中间,宽度的一半
                //y坐标是每个字母的中心位置,字母所占高度的一半,再加上边几个字母的距离,paddingTop+mCellHeight * i
                canvas.drawCircle(mWidth / 2F, paddingTop + mCellHeight 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值