自定义容器实现类似Windows屏保功能

菜鸟进场,方圆十里,寸草不生

写得很详细啦,本来是用RxJava来写的延时,不过考虑到有点门槛就放弃了

import android.animation.ObjectAnimator;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.ViewGroup;
import android.widget.ImageView;

import com.xhs.backupforcesmarthome.R;

import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;


/**
 * @author zx
 * @date 2018/3/29 17:09
 * description
 */
public class BubbleBackgroundView extends ViewGroup {
    private Context context;
    private Bitmap bitmap;
    private ScheduledExecutorService scheduledThreadPool;
    private Thread myThread;
    private boolean flag = false;

    public BubbleBackgroundView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        //初始化泡泡
        bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.bubble);
        //初始化线程池
        scheduledThreadPool = Executors.newScheduledThreadPool(1);
        //初始化线程
        myThread = new MyThread();
    }

    /**
     * 设置父控件宽高
     * @param widthMeasureSpec
     * @param heightMeasureSpec
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    /**
     * 设置子控件位置
     * @param b
     * @param i
     * @param i1
     * @param i2
     * @param i3
     */
    @Override
    protected void onLayout(boolean b, int i, int i1, int i2, int i3) {
        scheduledThreadPool.schedule(myThread, 2000, TimeUnit.MILLISECONDS);
    }

    /**
     * 线程回调到主线程
     */
    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (msg.what == 1) {
                if (getChildCount() >= 20) {
                    removeView(getChildAt(0));
                }
                if (getChildCount() < 20) {
                    ImageView imageView = new ImageView(context);
                    imageView.setImageBitmap(bitmap);
                    imageView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
                    addView(imageView);
                    setChildLayout(imageView);
                }
            }
        }
    };


    /**
     * 子线程,在线程中进行泡泡生成与添加
     */
    private class MyThread extends Thread{
        @Override
        public void run() {
            super.run();
            handler.sendEmptyMessage(1);
        }
    }

    /**
     * 设置子控件的位置
     * @param imageView 子控件
     */
    private void setChildLayout(ImageView imageView) {
        //随机距离左面的距离,控制从控件上面出来还是下面出来
        int left = new Random().nextInt(getWidth() - bitmap.getWidth()) + bitmap.getWidth();
        //随机距离顶部的距离,控制从左面和右面出来
        int top = new Random().nextInt(getHeight() - bitmap.getHeight()) + bitmap.getHeight();
        //随机四个方位
        int direction = new Random().nextInt(4);
        //随机泡泡x、y轴的运动时间
        long a = new Random().nextInt(8000) + 15000;
        long b1 = new Random().nextInt(8000) + 15000;
        //随机参数控制是往左飘还是往右飘
        int c = new Random().nextInt(2);
        //随机参数控制是往上飘还是往下飘
        int f = new Random().nextInt(2);
        int d = 1;
        int e = 1;
        if (c == 0) {
            d = -1;
        }
        if (f == 0) {
            e = -1;
        }
        //方位设置
        switch (direction) {
            case 0:
                //从上面出来的泡泡
                imageView.layout(left, 0, left + bitmap.getWidth(), bitmap.getHeight());
                //控制在y轴上只能往下飘
                e = 1;
                break;
            case 1:
                //从下面出来的泡泡
                imageView.layout(left, getHeight() - bitmap.getHeight(), left + bitmap.getWidth(), getHeight());
                //控制在y轴上只能往上飘
                e = -1;
                break;
            case 2:
                //从左面出来的泡泡
                imageView.layout(0, top, bitmap.getWidth(), bitmap.getHeight() + top);
                //控制在x轴上只能往右飘
                d = 1;
                break;
            case 3:
                //从右面出来的泡泡
                imageView.layout(getWidth() - bitmap.getWidth(), top, getWidth(), bitmap.getHeight() + top);
                //控制在x轴上只能往左飘
                d = -1;
                break;
            default:
        }
        //设置动画
        ObjectAnimator animator = ObjectAnimator.ofFloat(imageView, "translationX", 0, d * (getWidth() + bitmap.getWidth()));
        animator.setDuration(a);
        ObjectAnimator animator1 = ObjectAnimator.ofFloat(imageView, "translationY", 0, e * (getHeight() + bitmap.getHeight()));
        animator1.setDuration(b1);
        animator.start();
        animator1.start();
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值