Android漂浮移动自定义View,类似于网站上的小广告

最近需求做个漂浮移动的点击广告,就这玩意,看图。

对代码有好的优化建议请留言。

源码地址https://github.com/weixx/FloatingWidget

可以自由设置漂浮移动的范围,为了演示所以范围设置的200*200



一、代码:
public class FloatingWidget extends TextView {

    private int mWidth;
    private int mHeight;

    private int windowWidth;
    private int windowHeight;
    private Handler handler = new Handler(Looper.getMainLooper());

    private boolean xIsReduce;
    private boolean yIsReduce;

    private boolean isStop;

    private int speed = 10;
    private int stepping = 1;//步进,每次移动1px,这是最小的值了,因为不支持float类型
    private ThreadPoolExecutor threadPoolExecutor;

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

    public FloatingWidget(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public FloatingWidget(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        threadPoolExecutor = new ThreadPoolExecutor(1, 1, 0, TimeUnit.MILLISECONDS, new SynchronousQueue<Runnable>());
        setVisibility(GONE);
        setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                setVisibility(GONE);
                isStop = true;
            }
        });
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);


        if (widthMode == MeasureSpec.EXACTLY) {
            mWidth = widthSize;
        } else {
            mWidth = dp2px(100);
        }

        if (heightMode == MeasureSpec.EXACTLY) {
            mHeight = heightSize;
        } else {
            mHeight = dp2px(30);
        }
        setMeasuredDimension(mWidth,mHeight);
    }

    public int dp2px(int dp){
        return (int) TypedValue.applyDimension(
                TypedValue.COMPLEX_UNIT_DIP,
                dp,
                getResources().getDisplayMetrics());
    }
    public int sp2px(int sp){
        return (int)TypedValue.applyDimension(
                TypedValue.COMPLEX_UNIT_SP,
                sp,
                getResources().getDisplayMetrics());
    }

    public void start() {
        if(isStop) return;
        setVisibility(VISIBLE);

        if (windowHeight == 0 || windowWidth == 0) {
            layout(0, 0, mWidth, mHeight);
        } else {
            int l;
            int t;
            int r;
            int b;
            int right = getRight();
            int bottom = getBottom();
            if (xIsReduce) {
                if (right - stepping < mWidth) {
                    r = mWidth;
                    xIsReduce = false;
                } else {
                    r = right - stepping;
                }
            } else {
                if (right + stepping > windowWidth) {
                    r = windowWidth;
                    xIsReduce = true;
                } else {
                    r = right + stepping;
                }
            }

            if (yIsReduce) {
                if (bottom - stepping < mHeight) {
                    b = mHeight;
                    yIsReduce = false;
                } else {
                    b = bottom - stepping;
                }
            } else {
                if (bottom + stepping > windowHeight) {
                    b = windowHeight;
                    yIsReduce = true;
                } else {
                    b = bottom + stepping;
                }
            }

            l = r - mWidth;
            t = b - mHeight;
            layout(l,t,r,b);
        }
        threadPoolExecutor.execute(new Runnable() {
            @Override
            public void run() {
                Log.e("TAG", Thread.currentThread().getName());
                try {
                    Thread.sleep(speed);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        FloatingWidget.this.start();
                    }
                });
            }
        });
    }

    /**
     * 以屏幕分辨率为漂浮范围
     * @param activity 漂浮在的页面,用于获取屏幕分辨率
     */
    public FloatingWidget setActivity(Activity activity) {
        DisplayMetrics metrics = new DisplayMetrics();
        activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
        windowWidth = metrics.widthPixels;
        windowHeight = metrics.heightPixels;
        return this;
    }

    /**
     * 设置漂浮范围,范围为一个矩形
     * @param widthPixels 矩形的宽度,单位px
     * @param heightPixels 矩形的高度,单位px
     */
    public FloatingWidget setMovingRange(int widthPixels, int heightPixels) {
        windowWidth = widthPixels;
        windowHeight = heightPixels;
        return this;
    }

    /**
     * 设置漂浮移动的速度
     * @param speed 参数范围(1 - 10),数值越大移动速度越快,
     *              建议不要低于5,值过小时,会出现抖动视感
     */
    public FloatingWidget setSpeed(int speed) {
        this.speed *= (11 - speed);
        return this;
    }

    /**
     * 停止
     */
    public void stop(){
        isStop = true;
    }
}
二、使用:

    1、xml中

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.xinxin.floatingwidget.MainActivity">

    <com.xinxin.floatingwidget.FloatingWidget
        android:id="@+id/mFloatingWidget"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="代码大法好"
        android:textColor="#FFFFFF"
        android:gravity="center"
        android:background="@color/colorPrimary"/>
</RelativeLayout>

    2、activity中

public class MainActivity extends AppCompatActivity {

    private FloatingWidget mFloatingWidget;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mFloatingWidget = (FloatingWidget) findViewById(R.id.mFloatingWidget);
        mFloatingWidget.setMovingRange(200,200).setSpeed(10).start();
    }

    @Override
    protected void onDestroy() {
        mFloatingWidget.stop();
        super.onDestroy();
    }
}

    也可以将漂浮移动范围设置为整个屏幕,代码替换即可

mFloatingWidget.setActivity(this).setSpeed(10).start();
具体使用,类中的方法都有注释。


  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值