欢迎光临
我们一直在努力

如何制作Android平台上类似QQ的圆形头像个性化名片?

Android仿QQ圆形头像个性名片

如何制作Android平台上类似QQ的圆形头像个性化名片?

一、引言

在移动应用开发中,用户界面(UI)设计是吸引用户和提升用户体验的关键因素之一,圆形头像作为一种简洁且具有视觉吸引力的设计元素,被广泛应用于各类社交应用中,如QQ,本文将详细介绍如何在Android平台上实现仿QQ的圆形头像个性名片,包括圆形头像的绘制、光环波形的设计以及气泡布局的定制。

二、圆形头像的实现

使用BitmapShader类

在Android中,可以使用BitmapShader类来创建圆形图片。BitmapShader允许我们将位图应用于画笔,然后通过设置Shader的模式为SHADER_TYPE_CIRCLE(即Shader.TileMode.CLAMP),可以将位图的边缘平滑地扩展到圆形,我们需要使用Paint对象来绘制这个圆形图片,并确保Paint的抗锯齿属性开启。

示例代码:

如何制作Android平台上类似QQ的圆形头像个性化名片?

public class CircleClipView extends ImageView {
    private Paint backgroundPaint = null;
    private Paint maskPaint = null;
    private int backgroundColor = 1;
    public CircleClipView(Context context) {
        super(context);
        init();
    }
    public CircleClipView(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.circleview);
        backgroundColor = a.getColor(R.styleable.circleview_backgroundcolor, Color.WHITE);
        a.recycle();
        init();
    }
    private void init() {
        maskPaint = new Paint();
        PorterDuffXfermode porterDuffXfermode = new PorterDuffXfermode(PorterDuff.Mode.SRC_IN);
        maskPaint.setXfermode(porterDuffXfermode);
        maskPaint.setColor(Color.TRANSPARENT);
        maskPaint.setAntiAlias(true);
        backgroundPaint = new Paint();
        backgroundPaint.setColor(backgroundColor);
        backgroundPaint.setAntiAlias(true);
    }
    private Bitmap getMask() {
        Bitmap b = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(b);
        RectF rectF = new RectF(0, 0, getWidth(), getHeight());
        canvas.drawRect(rectF, backgroundPaint);
        canvas.drawOval(rectF, maskPaint);
        return b;
    }
    @Override
    protected void onDraw(Canvas canvas) {
        Bitmap sourceBitmap = scaleDrawable(getDrawable());
        if (sourceBitmap != null) canvas.drawBitmap(sourceBitmap, 0, 0, null);
        canvas.drawBitmap(getMask(), 0, 0, null);
    }
    private Bitmap scaleDrawable(Drawable drawable) {
        Bitmap b = ((BitmapDrawable) drawable).getBitmap();
        Matrix matrix = new Matrix();
        float scaleWidth = ((float) getWidth()) / b.getWidth();
        float scaleHeight = ((float) getHeight()) / b.getHeight();
        matrix.postScale(scaleWidth, scaleHeight);
        Bitmap bitmap = Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(), matrix, true);
        return bitmap;
    }
}

2. 自定义ViewGroup实现气泡布局

为了实现类似QQ的个性名片效果,我们可以自定义一个RatioLayout继承自ViewGroup,它允许开发者根据特定的比例关系来布局子视图,在计算每个气泡的位置时,需要知道圆环的半径,然后根据气泡的总数计算它们之间的角度间隔,如果有12个气泡,那么每个气泡之间相差30°,利用三角函数计算出每个气泡相对于圆心的坐标,然后调用view.layout()方法设置它们的位置。

示例代码:

private void calculateRatioFrame(List<TextView> textViews) {
    if (textViews.size() == 0) return;
    mRatioFrameList.clear();
    double angle = 0; // 记录每个气泡的角度,正上方的为0°
    double grad = Math.PI * 2 / textViews.size(); // 梯度,每个TextView之间的角度 (Math.PI 是数学中的90°)
    double rightAngle = Math.PI / 2; // 一圈为360°,一共四个方向,每个方向90°,我们按照小于等于90°来计算,然后再放到相应的方向上
    // cx,cy是容器的中心点,也是圆形头像的中心点,计算气泡的位置就是已cx,cy为基准来计算的
    int cx = mWidth / 2; // 容器中心x坐标
    int cy = mHeight / 2; // 容器中心y坐标
    int radius = mMinSize / 2 / 2 / 2 + mMinSize / 2 / 2; // 动态气泡的组成圆的半径
    int left = 0;
    int top = 0;
    int right = 0;
    int bottom = 0;
    int a = 0, b = 0; // a是基于cx的偏移量,b是基于cy的偏移量,
    for (int i = 0; i < textViews.size(); i++) {
        int r = textViews.get(i).getMeasuredWidth() / 2; // 计算得来 //固定死的mMinSize / 6 / 2; //气泡半径
        if (angle >= 0 && angle < rightAngle) { // 0  90度是计算偏移量
            // 保持角度在 0  90
            a = (int) (radius * Math.sin(Math.abs(angle % rightAngle)));
            b = (int) (radius * Math.cos(Math.abs(angle % rightAngle)));
            left = cx + a  r; // cx + a为气泡的中心点,要想得到left,还需减去半径r
            top = cy  b  r;
            right = left + 2 * r;
            bottom = top + 2 * r;
        } else if (angle >= rightAngle && angle < rightAngle * 2) { // 90  180
            a = (int) (radius * Math.sin(Math.abs(angle % rightAngle)));
            b = (int) (radius * Math.cos(Math.abs(angle % rightAngle)));
            left = cx + b  r;
            top = cy + a  r;
            right = left + 2 * r;
            bottom = top + 2 * r;
        } else if (angle >= rightAngle * 2 && angle < rightAngle * 3) { // 180  270
            a = (int) (radius * Math.sin(Math.abs(angle % rightAngle)));
            b = (int) (radius * Math.cos(Math.abs(angle % rightAngle)));
            left = cx  a  r;
            top = cy + b  r;
            right = left + 2 * r;
            bottom = top + 2 * r;
        } else if (angle >= rightAngle * 3 && angle < rightAngle * 4) { //270  360
            a = (int) (radius * Math.sin(Math.abs(angle % rightAngle)));
            b = (int) (radius * Math.cos(Math.abs(angle % rightAngle)));
            left = cx  b  r;
            top = cy  a  r;
            right = left + 2 * r;
            bottom = top + 2 * r;
        }
        // 将计算好的left, top, right,bottom,angle保存起来
        mRatioFrameList.add(new RatioFrame(left, top, right, bottom, angle));
        // 角度再加一个梯度值
        angle += grad;
    }
}

三、光环波形设计

光环波形通常涉及到自定义视图和动画效果,我们可以创建一个自定义的View,在其onDraw()方法中绘制光环,可以使用Path对象描绘波形路径,然后利用PaintsetShader()方法结合LinearGradientRadialGradient来实现颜色过渡效果,为了创建动态的光环波形,可以使用ValueAnimatorObjectAnimator来改变Path的形状参数,从而实现波形的流动效果。

如何制作Android平台上类似QQ的圆形头像个性化名片?

四、归纳与展望

通过上述步骤,我们可以在Android应用中实现一个仿QQ风格的圆形头像个性名片,这不仅提升了应用的视觉效果,也增强了用户的交互体验,随着技术的发展和用户需求的变化,我们可以进一步优化这一功能,例如增加更多的个性化选项、支持更复杂的动画效果等。

小伙伴们,上文介绍了“Android仿QQ圆形头像个性名片”的内容,你了解清楚吗?希望对你有所帮助,任何问题可以给我留言,让我们下期再见吧。

赞(0)
版权声明:本文采用知识共享 署名4.0国际许可协议 [BY-NC-SA] 进行授权
文章名称:《如何制作Android平台上类似QQ的圆形头像个性化名片?》
文章链接:https://yuyunkj.com/article/10826.html
本站资源仅供个人学习交流,请于下载后24小时内删除,不允许用于商业用途,否则法律问题自行承担。

评论 抢沙发