星空发现图(仿蜗牛梦话圈)

栏目: Android · 发布时间: 7年前

  • 背景类水波纹的扩散效果

    • 初始化

    初始化没啥好说的,就是一些画笔设置,点位初始化,因为部分初始化与控件大小相关,因此要讲初始化放在尺寸确认后,了解一下View的关键生命周期 构造函数() --> onFinishInflate() --> onAttachedToWindow() --> onMeasure() --> onSizeChanged() --> onLayout() --> onDraw() --> onDetackedFromWindow() 当onSizeChanged之后,布局大小确定下来,因此在此处初始化.

    • 环形渐变效果 使用RadialGradient
    //圆心为画布中心,半径为 mRadiusMax,半径80%处向外渐变为白色
        RadialGradient gradient =
                new RadialGradient(width / 2, height / 2, mRadiusMax,
                        new int[]{centerColor, centerColor, edgeColor}, new float[]{0f, .8f, 1.0f}, Shader.TileMode.MIRROR);
        mLayoutPaint.setShader(gradient);
    复制代码
    • 使用handler 定时,更新圆直径,模拟水波纹效果

    初始化三个大小不等的圆,每次放大2%,超出最大值,重新开始,模拟水波纹效果

    • 绘制图形,使用画布缩放绘制不同大小的圆环;

    原本直接想用 drawCircle() 绘制不同大小的圆,出现一个问题,需要为不同大小的圆重新 设置环形渐变,而 onDraw() 是一个频繁操作,不建议创建对象,因此想到通过缩放画布的方式来实现绘制不同大小的渐变圆环.

    // scale 描述图片放大比例;
        // 将画布放大scale 比例后,绘制同样大小的圆,还原画布,即可得放大scale倍的圆
        canvas.save();
        canvas.scale(scale, scale, width / 2, height / 2);
        canvas.drawCircle(width / 2, height / 2, mRadiusMax, mLayoutPaint);
        canvas.restore();
    复制代码
  • 随机显示位置的子控件

    • 随机点位:保证不重叠;

    对于圆形图,不重叠即保证生成的新点与已存在的点距离大于两者半径和 随机生成点,计算其与已存在在的控件比较,不符合条件,重新生成,超出重试次数即认为无足够空间.

    /**
     * 获取随机点,根据父子空间半径判断随机点是否有足够空间可用
     * @param rad 子控件半径
     * @param radMax 父布局半径
     * @param centerX 父布局中点 x
     * @param centerY 父布局中点 y
     * @return 一个可用的随机点位
     */
    private Point getRandomPoint(int rad, int radMax, int centerX, int centerY) {
        int x = 0;
        int y = 0;
        int counter = 0;
        boolean conflict;
        Random random = new Random();
        while (counter < 100000) {
            counter++;
            x = (int) (getMeasuredWidth() / 2 - radMax + rad + random.nextInt( 2 * radMax - 2 * rad));
            y = (int) (getMeasuredHeight() / 2 - radMax + rad + random.nextInt( 2 * radMax - 2 * rad));
            conflict = false;
            // 判断与其他子控件是否冲突
            for (Point p : mChildrenPoints) {
                int dis = (int) Math.sqrt(Math.pow(p.x - x, 2) + Math.pow(p.y - y, 2));
                if (dis < 2 * rad * (1 + mBlankPer)) {//子控件大小一致,设置两个子控件中点距离最小为 半径和的(1+mBlankPer)倍
                    conflict = true;
                    break;
                }
            }
            if (!conflict) {// 判断与中心点冲突
                int dis = (int) Math.sqrt(Math.pow(centerX - x, 2) + Math.pow(centerY - y, 2));
                if (dis < (rad + mCenterRadius) * ((1 + mBlankPer))) conflict = true;
            }
            if (!conflict) return new Point(x, y);
        }
        Log.e(TAG, "getRandomPoint: 无剩余空间");
        return new Point(0, 0);
    }
    复制代码
    • 测量大小:交给子控件自己测量,保证最大值不超过布局的宽高较小值即可
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int contentWidth = MeasureSpec.getSize(widthMeasureSpec);
        int contentHeight = MeasureSpec.getSize(heightMeasureSpec);
        int len = Math.min(contentWidth, contentHeight);
        measureChildren(MeasureSpec.makeMeasureSpec(len, MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(len, MeasureSpec.AT_MOST));
    }
    复制代码
    • 布局 onLayout()
    for (int i = 1; i < getChildCount(); i++) {
            View view = getChildAt(i);
            int rad = Math.max(view.getMeasuredWidth(), view.getMeasuredHeight()) / 2;
            
            Point position;
    		// 数据只支持末尾插入,可直接通过列表长度判断是否是新增点
            if (i > mChildrenPoints.size()) {// 新增的控件,设置随机点
                position = getRandomPoint(rad, mRadiusMax, getMeasuredWidth() / 2, getMeasuredHeight() / 2);
                mChildrenPoints.add(position);
            } else {//已存在控件,直接从列表取
                position = mChildrenPoints.get(i - 1);
            }
            int x = position.x;
            int y = position.y;
            view.layout(x - rad, y - rad, x + rad, y + rad);
        }
    复制代码

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

How to Build a Billion Dollar App

How to Build a Billion Dollar App

George Berkowski / Little, Brown Book Group / 2015-4-1 / USD 24.95

Apps have changed the way we communicate, shop, play, interact and travel and their phenomenal popularity has presented possibly the biggest business opportunity in history. In How to Build a Billi......一起来看看 《How to Build a Billion Dollar App》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

SHA 加密
SHA 加密

SHA 加密工具