工具类-添加悬浮窗(View)

前言:

这是一个用来用户体验的工具类, 可以根据一个参照View的位置,来决定悬浮窗(View)的位置。一次触摸事件以后,悬浮窗消失。悬浮窗用于提示用户如何操作某些功能。
以下为粗略版




import android.app.Activity;
import android.content.Context;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.os.Handler;
import android.os.Message;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageView;


/**
 * Created by yj on 2016/8/26.
 * 描述:提示用户操作
 * 悬浮窗
 * 作用:根据参照View的位置大小来决定一个提示悬浮窗的位置。
 * 提高用户体验
 */
public class PromptUtil {
    // targetView出现在referenceView的什么位置
    public enum ENUM {
       TOP, BOTTOM
    }

    private static Context mContext;
    // 悬浮窗
    private static ImageView mTargetView;
    // 参照View ,悬浮窗根据参照View的位置大小来决定其位置
    private static View mReferenceView;
    private static ENUM mAnEnum;


    public static void show(Context context, int res, View referenceView, ENUM anEnum) {
        mContext = context;
        mTargetView = new ImageView(context);
        mTargetView.setImageResource(res);
        mReferenceView = referenceView;
        mAnEnum = anEnum;
        waitViewMeasure(mReferenceView);
    }

    static Handler mHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            startShow();
        }
    };

    private static void startShow() {
        final WindowManager wm = (WindowManager) mContext.getSystemService(mContext.WINDOW_SERVICE);
        WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();
        layoutParams.format = PixelFormat.TRANSLUCENT; // 图片之外的其他地方透明

        // 大小
        layoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
        layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
        // 位置
        layoutParams.gravity = Gravity.TOP | Gravity.LEFT;
        // 参照View的x坐标
        float referenceX = mReferenceView.getLeft();
        // 参照项View的Y坐标
        float referenceY = mReferenceView.getTop();
        // 参照项View的长
        int referenceW = mReferenceView.getMeasuredWidth();
        // 参照项View的宽
        int referenceH = mReferenceView.getMeasuredHeight();



        switch (mAnEnum) {
            case TOP:
                layoutParams.x = (int) referenceX;
                layoutParams.y = (int) referenceY - mTargetView.getDrawable().getIntrinsicHeight();
                break;
            case BOTTOM:
                layoutParams.x = (int) referenceX;
                layoutParams.y = (int) referenceY + referenceH;
                break;
        }

        //  适应状态栏高度
        layoutParams.y -= getStatusHeight(mContext);

        // 透明背景
        WindowManager.LayoutParams lp = ((Activity)mContext).getWindow().getAttributes();
        lp.alpha = 0.9f;
        ((Activity)mContext).getWindow().setAttributes(lp);

        // 设置触摸监听,移除悬浮窗和内存.恢复背景透明度
        mTargetView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                // 移除悬浮窗
                wm.removeView(mTargetView);
                // 恢复背景
                WindowManager.LayoutParams lp = ((Activity) mContext).getWindow().getAttributes();
                lp.alpha = 1.0f;
                ((Activity) mContext).getWindow().setAttributes(lp);
                // 移除内存
                mContext = null;
                mTargetView = null;
                mReferenceView = null;
                mAnEnum = null;

                return false;
            }
        });
        // 添加悬浮窗
        wm.addView(mTargetView, layoutParams);
    }

    // 参照View在一段时间后才能获取x,y,width和height
    private static void waitViewMeasure(final View referenceView) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                while(referenceView.getMeasuredWidth() == 0) {
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                mHandler.sendEmptyMessage(101);

            }
        }).start();
    }

    /**
     * 获取状态栏的高度
     *
     * @param context
     * @return
     */
    private static int getStatusHeight(Context context) {
        int statusHeight = 0;
        Rect localRect = new Rect();
        ((Activity) context).getWindow().getDecorView().getWindowVisibleDisplayFrame(localRect);
        statusHeight = localRect.top;
        if (0 == statusHeight) {
            Class<?> localClass;
            try {
                localClass = Class.forName("com.android.internal.R$dimen");
                Object localObject = localClass.newInstance();
                int i5 = Integer.parseInt(localClass.getField("status_bar_height").get(localObject).toString());
                statusHeight = context.getResources().getDimensionPixelSize(i5);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return statusHeight;
    }


}

用法

参数说明:
1.context
2.资源图片 R.drawable.xxxx
3.参照View
4.位置

        PromptUtil.show(context, res, View, PromptUtil.ENUM.BOTTOM);

to do :以后补个图~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值