likes
comments
collection
share

【Android自定义View实战01】仿微信读书APP滑动指示条

作者站长头像
站长
· 阅读数 11

先看一下读书APP的效果:

【Android自定义View实战01】仿微信读书APP滑动指示条

弹窗往下滑动时,顶部的指示条也会跟着向下弯曲变成箭头形状。

分析

话不多说,先来给指示条做个X光检查看看:

【Android自定义View实战01】仿微信读书APP滑动指示条

  1. 未滑动时指示条就是一个普通的圆角矩形
  2. 滑动时是一个箭头,箭头的两端是两个圆

指示条从点S滑动到点T过程中,圆L圆K的切线相交形成箭头。箭头通过Path圆心L点T圆心K连接起来,拐角处还需要处理为圆角,可以使用PaintsetStrokeJoin()方法,该方法设置线段连接处的样式,取值有三个:

Paint.Join.MITER //锐角  
Paint.Join.Round //圆弧  
Paint.Join.BEVEL //直线

这里取Round,该值的处理方式是以点T为圆心、指示条高度的一半为半径画圆弧,连接拐角,如图:

【Android自定义View实战01】仿微信读书APP滑动指示条 【Android自定义View实战01】仿微信读书APP滑动指示条 至此,指示条的整体高度就确定了,就是QH的长度,即ST+指示条高度

实现

首先给指示条指定一个最大可弯曲的高度值bendingHeight,当前弯曲的比例为bendingRatio

  • onMeasure()测量宽高:
  1. 当弯曲比例等于0时,测量高度就是指示条高度
  2. 当弯曲比例大于0时,测量高度就是指示条高度+弯曲高度
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int width = MeasureSpec.getSize(widthMeasureSpec);
    int hMode = MeasureSpec.getMode(heightMeasureSpec);
    int hSize = MeasureSpec.getSize(heightMeasureSpec);
    int height;
    if (hMode == MeasureSpec.EXACTLY) {
        height = hSize;
    } else {
        if (bendingRatio <= 0) {
            height = barHeight + getPaddingTop() + getPaddingBottom();
        } else {
            int h = (int) (barHeight + bendingHeight * bendingRatio);
            height = Math.min(h + getPaddingTop() + getPaddingBottom(), hSize);
        }
    }
    setMeasuredDimension(width, height);
}
  • onDraw()绘制,
  1. 当弯曲比例等于0时,绘制圆角矩形即可
  2. 当弯曲比例大于0时,先使用Path绘制箭头,再绘制两端的圆
@Override
protected void onDraw(Canvas canvas) {
    float radius = barHeight / 2f;
    if (bendingRatio <= 0) {
        rectF.set(getPaddingLeft(), getPaddingTop(),
                getWidth() - getPaddingRight(), getPaddingTop() + barHeight);
        barPaint.setStyle(Paint.Style.FILL);
        canvas.drawRoundRect(rectF, radius, radius, barPaint);
    } else {
        path.reset();
        path.moveTo(getPaddingLeft() + radius, getPaddingTop() + radius);
        float x = getPaddingLeft() + (getWidth() - getPaddingLeft() - getPaddingRight()) / 2f;
        float y = getPaddingTop() + barHeight / 2f + bendingHeight * bendingRatio;
        path.lineTo(x, y);
        path.lineTo(getWidth() - getPaddingRight() - radius, getPaddingTop() + radius);
        barPaint.setStyle(Paint.Style.STROKE);
        canvas.drawPath(path, barPaint);
        canvas.drawCircle(getPaddingLeft() + radius, getPaddingTop() + radius,
                radius, circlePaint);
        canvas.drawCircle(getWidth() - getPaddingRight() - radius, getPaddingTop() + radius,
                radius, circlePaint);
    }
}

最后只需要调用setBendingRatio()方法实时更改弯曲比例即可。

效果

【Android自定义View实战01】仿微信读书APP滑动指示条

到这里文章就水完了,有写的不好的地方还请指出。 参考连接:SlidingIndicatorBar-项目地址

转载自:https://juejin.cn/post/7232571353122701370
评论
请登录