本网站(662p.com)打包出售,且带程序代码数据,662p.com域名,程序内核采用TP框架开发,需要联系扣扣:2360248666 /wx:lianweikj
精品域名一口价出售:1y1m.com(350元) ,6b7b.com(400元) , 5k5j.com(380元) , yayj.com(1800元), jiongzhun.com(1000元) , niuzen.com(2800元) , zennei.com(5000元)
需要联系扣扣:2360248666 /wx:lianweikj
Android 充电气泡动画
追忆似水年华 · 894浏览 · 发布于2019-11-01 +关注

效果图:

1572598333944988.gif


代码部分

BubbleView.java


/**
 * 气泡自定义控件
 * 思路:
 * 1,定义 Bubble 类;
 * 2,随机生成 Bubble 对象,存放于 List 中;
 * 3,刷新 List 中的数据: 边界控制;
 * 4,刷新 UI。
 *
 * @author wangzhichao
 * @date 2019/10/30
 */
public class BubbleView extends View {
    private static final String TAG = BubbleView.class.getSimpleName();
    private HandlerThread handlerThread;
    private WeakHandler weakHandler;
    private static final int MESSAGE_UPDATE = 1;
    private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
    private int bubbleNumLimit;
    private float minBubbleSpeedX;
    private float maxBubbleSpeedX;
    private float minBubbleSpeedY;
    private float maxBubbleSpeedY;
    private float minBubbleRadius;
    private float maxBubbleRadius;
    private float bubbleCreateLatch;
    private int width;
    private int height;
    private int defaultWidth = (int) dp2px(10);
    private int defaultHeight = (int) dp2px(20);

    public BubbleView(Context context) {
        this(context, null);
    }

    public BubbleView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public BubbleView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.BubbleView);
        minBubbleSpeedX = ta.getDimensionPixelSize(R.styleable.BubbleView_bvMinBubbleSpeedX, (int) dp2px(1f));
        maxBubbleSpeedX = ta.getDimensionPixelSize(R.styleable.BubbleView_bvMaxBubbleSpeedX, (int) dp2px(2));
        minBubbleSpeedY = ta.getDimensionPixelSize(R.styleable.BubbleView_bvMinBubbleSpeedY, (int) dp2px(2));
        maxBubbleSpeedY = ta.getDimensionPixelSize(R.styleable.BubbleView_bvMaxBubbleSpeedY, (int) dp2px(4));
        minBubbleRadius = ta.getDimensionPixelSize(R.styleable.BubbleView_bvMinBubbleRadius, (int) dp2px(1));
        maxBubbleRadius = ta.getDimensionPixelSize(R.styleable.BubbleView_bvMaxBubbleRadius, (int) dp2px(4));
        bubbleNumLimit = ta.getInt(R.styleable.BubbleView_bvBubbleNumLimit, 10);
        bubbleCreateLatch = ta.getFloat(R.styleable.BubbleView_bvBubbleCreateLatch, 0.5f);
        int color = ta.getColor(R.styleable.BubbleView_bvBubbleColor, getResources().getColor(R.color.white));
        int alpha = ta.getInt(R.styleable.BubbleView_bvBubbleAlpha, 128);
        ta.recycle();

        handlerThread = new HandlerThread(TAG);

        paint.setColor(color);
        paint.setAlpha(alpha);
        paint.setStyle(Paint.Style.FILL);
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        handlerThread.start();
        Looper looper = handlerThread.getLooper();
        weakHandler = new WeakHandler(looper, msg -> {
            if (msg.what == MESSAGE_UPDATE) {
                tryCreateBubbles();
                updateBubbles();
                postInvalidate();
            }
            return true;
        });
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        weakHandler.removeCallbacksAndMessages(null);
        handlerThread.quit();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        width = getWidth() - getPaddingLeft() - getPaddingRight();
        height = getHeight() - getPaddingTop() - getPaddingBottom();
        drawBubbles(canvas);
        weakHandler.sendEmptyMessage(MESSAGE_UPDATE);
    }

    private void drawBubbles(Canvas canvas) {
        for (Bubble bubble : bubbles) {
            canvas.drawCircle(bubble.getCenterX(), bubble.getCenterY(), bubble.getRadius(), paint);
        }
    }

    private void updateBubbles() {
        Iterator<Bubble> iterator = bubbles.iterator();
        while (iterator.hasNext()) {
            Bubble bubble = iterator.next();
            bubble.setCenterX(bubble.getCenterX() + bubble.getSpeedX());
            bubble.setCenterY(bubble.getCenterY() - bubble.getSpeedY());
            if (isBubbleTouchTop(bubble)) {
                iterator.remove();
            } else if (isBubbleTouchLeft(bubble)) {
                bubble.setSpeedX(-bubble.getSpeedX());
                bubble.setCenterX(bubble.getRadius());
            } else if (isBubbleTouchRight(bubble)) {
                bubble.setSpeedX(-bubble.getSpeedX());
                bubble.setCenterX(width - bubble.getRadius());
            }
        }
    }

    private boolean isBubbleTouchLeft(Bubble bubble) {
        return bubble.getCenterX() - bubble.getRadius() <= 0;
    }

    private boolean isBubbleTouchRight(Bubble bubble) {
        return bubble.getCenterX() + bubble.getRadius() >= width;
    }

    private boolean isBubbleTouchTop(Bubble bubble) {
        return bubble.getCenterY() - bubble.getRadius() <= 0;
    }

    private List<Bubble> bubbles = new ArrayList<>();

    private void tryCreateBubbles() {
        if (bubbles.size() >= bubbleNumLimit) {
            return;
        }
        if (random.nextFloat() < bubbleCreateLatch) {
            return;
        }
        bubbles.add(createBubble());
    }

    private Bubble createBubble() {
        Bubble bubble = new Bubble();
        bubble.setRadius(getRandomRadius());
        bubble.setSpeedX(getRandomSpeedX());
        bubble.setSpeedY(getRandomSpeedY());
        bubble.setCenterX(width / 2f);
        bubble.setCenterY(height + bubble.getRadius());
        return bubble;
    }

    private Random random = new Random();

    private float getRandomSpeedX() {
        float value = minBubbleSpeedX + random.nextFloat() * (maxBubbleSpeedX - minBubbleSpeedX);
        if (random.nextBoolean()) {
            return value;
        } else {
            return -value;
        }
    }

    private float getRandomSpeedY() {
        return minBubbleSpeedY + random.nextFloat() * (maxBubbleSpeedY - minBubbleSpeedY);
    }

    private float getRandomRadius() {
        return minBubbleRadius + random.nextFloat() * (maxBubbleRadius - minBubbleRadius);
    }

    private int measureWidth(int widthMeasureSpec) {
        int mode = MeasureSpec.getMode(widthMeasureSpec);
        int size = MeasureSpec.getSize(widthMeasureSpec);
        int result;
        if (mode == MeasureSpec.EXACTLY) {
            result = size;
        } else {
            result = defaultWidth;
            if (mode == MeasureSpec.AT_MOST) {
                result = Math.min(result, size);
            }
        }
        return result;
    }

    private int measureHeight(int heightMeasureSpec) {
        int mode = MeasureSpec.getMode(heightMeasureSpec);
        int size = MeasureSpec.getSize(heightMeasureSpec);
        int result;
        if (mode == MeasureSpec.EXACTLY) {
            result = size;
        } else {
            result = defaultHeight;
            if (mode == MeasureSpec.AT_MOST) {
                result = Math.min(result, size);
            }
        }
        return result;
    }

    /**
     * 气泡
     */
    class Bubble {
        /**
         * 气泡的半径
         */
        private float radius;
        /**
         * 气泡 x 向的移动速度
         */
        private float speedX;
        /**
         * 气泡 y 向的移动速度
         */
        private float speedY;
        /**
         * 气泡的中心 x 坐标
         */
        private float centerX;
        /**
         * 气泡的中心 y 坐标
         */
        private float centerY;

        public float getRadius() {
            return radius;
        }

        public void setRadius(float radius) {
            this.radius = radius;
        }

        public float getSpeedX() {
            return speedX;
        }

        public void setSpeedX(float speedX) {
            this.speedX = speedX;
        }

        public float getSpeedY() {
            return speedY;
        }

        public void setSpeedY(float speedY) {
            this.speedY = speedY;
        }

        public float getCenterX() {
            return centerX;
        }

        public void setCenterX(float centerX) {
            this.centerX = centerX;
        }

        public float getCenterY() {
            return centerY;
        }

        public void setCenterY(float centerY) {
            this.centerY = centerY;
        }
    }

    private float dp2px(float dp) {
        return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, Resources.getSystem().getDisplayMetrics());
    }
}


自定义属性:

<declare-styleable name="BubbleView">
        <attr name="bvMinBubbleSpeedX" format="dimension" />
        <attr name="bvMaxBubbleSpeedX" format="dimension" />
        <attr name="bvMinBubbleSpeedY" format="dimension" />
        <attr name="bvMaxBubbleSpeedY" format="dimension" />
        <attr name="bvMinBubbleRadius" format="dimension" />
        <attr name="bvMaxBubbleRadius" format="dimension" />
        <attr name="bvBubbleNumLimit" format="integer" />
        <attr name="bvBubbleColor" format="color" />
        <attr name="bvBubbleAlpha" format="integer" />
        <attr name="bvBubbleCreateLatch" format="float" />
    </declare-styleable>


 最后

代码还是有一些不足,大家多提宝贵意见。

相关推荐

android下vulkan与opengles纹理互通

talkchan · 1176浏览 · 2020-11-23 10:37:39
Android 使用RecyclerView实现轮播图

奔跑的男人 · 2175浏览 · 2019-05-09 17:11:13
微软发布新命令行工具 Windows Terminal

吴振华 · 869浏览 · 2019-05-09 17:15:04
Facebook 停止屏蔽部分区块链广告

· 754浏览 · 2019-05-09 17:20:08
加载中

0评论

评论
分类专栏
小鸟云服务器
扫码进入手机网页