android 在activity上的悬浮框、利用WindowManager和PopupWindow实现

来源:互联网 发布:双色球参选数据2017年 编辑:程序博客网 时间:2024/05/29 11:20

实现像九游游戏一样的悬浮窗、在按下HOME键的时候不会显示悬浮窗、并随着Activity的销毁而销毁,如果想在桌面也显示悬浮窗的话可以稍微的修改一下,如果不点击的话3秒后变淡

效果图


调用悬浮窗的管理接口

import android.app.Activity;/** * 管理悬浮窗的接口 */public abstract class FloatButtonManager {    private static FloatButtonManager sManager;    public abstract void destroyFloatButton();    public abstract void createFloatButton();    public static FloatButtonManager getFloatButtonManager(Activity activity){        if(sManager == null){            sManager = creatInstance(activity);        }        return sManager;    }    public static void destoryManager(){        if (sManager != null)            sManager = null;    }    private static synchronized FloatButtonManager creatInstance(Activity activity){        return new FloatButtonManagerImpl(activity);    }}

悬浮窗按钮管理的具体实现
import android.app.Activity;import android.view.View;import android.view.animation.AnimationSet;import android.view.animation.AnticipateOvershootInterpolator;import android.view.animation.BounceInterpolator;import android.view.animation.ScaleAnimation;import android.widget.Button;import sdk.game.lx.com.gameSDK.floatButton.view.FloatView;import sdk.game.lx.com.gameSDK.util.LXGameSDKUtil;/** * 悬浮按钮管理的具体实现 */class FloatButtonManagerImpl extends FloatButtonManager {    private Activity mActivity;    FloatView myFloat ;    private Button hideFloatBtn;    public FloatButtonManagerImpl(Activity activity){        mActivity = activity;    }    @Override    public void destroyFloatButton() {        if (myFloat != null){            myFloat.removeAllWindow();            myFloat = null;        }    }    /**     * 在此添加悬浮窗的功能按钮     */    @Override    public void createFloatButton() {        if (myFloat == null){            myFloat = new FloatView(mActivity);            myFloat.addFloatBtn(R.drawable.iv_btn1, "论坛");            myFloat.addFloatBtn(<span style="font-family: 宋体;">R.drawanle.iv_btn2</span>, "礼包");            hideFloatBtn = myFloat.addFloatBtn(R.drawable.iv_btn3, "隐藏");            hideFloatBtn.setOnClickListener(new View.OnClickListener() {                @Override                public void onClick(View v) {                    addFloatBtnAnimation(hideFloatBtn);                    myFloat.removeAllWindow();                    myFloat = null;                }            });        }    }    /**     * 增加按钮的动画效果     * @param button  按钮     */    private void addFloatBtnAnimation(Button button) {        AnimationSet set = new AnimationSet(true);        set.addAnimation(new ScaleAnimation(1f, 1.2f, 1f, 1.2f));        set.setDuration(300);        set.setInterpolator(new AnticipateOvershootInterpolator(9f));        set.setInterpolator(new BounceInterpolator());        button.startAnimation(set);    }}
在大悬浮窗上添加按钮是通过addFloatBtn()这个方法的。参数是一是要传入按钮图片的资源ID,参数二是按钮内容
小悬浮窗类
import android.app.Activity;import android.graphics.PixelFormat;import android.graphics.drawable.BitmapDrawable;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.Button;import android.widget.LinearLayout;import android.widget.PopupWindow;import sdk.game.lx.com.gameSDK.util.LXGameSDKUtil;public class FloatView {    /**     * 记录小悬浮窗的宽度     *///    public static int viewWidth;    /**     * 记录小悬浮窗的高度     *///    public static int viewHeight;    /**     * 记录系统状态栏的高度     */    private static int statusBarHeight;    /**     * 记录当前手指位置在屏幕上的横坐标值     */    private float xInScreen;    /**     * 记录当前手指位置在屏幕上的纵坐标值     */    private float yInScreen;    /**     * 记录手指按下时在屏幕上的横坐标的值     */    private float xDownInScreen;    /**     * 记录手指按下时在屏幕上的纵坐标的值     */    private float yDownInScreen;    /**     * 记录手指按下时在小悬浮窗的View上的横坐标的值     */    private float xInView;    /**     * 记录手指按下时在小悬浮窗的View上的纵坐标的值     */    private float yInView;    public static WindowManager wManager;    private Activity mActivity;    private WindowManager.LayoutParams wmParams;    private Button floatBtn;    private int screenWidth;    private int screenHeigth;    private boolean hasChild = false;  //是否有大窗口    private boolean hasItem = false;   //大窗口是否有内容    public PopupWindow mPopupWindow;    private PopupFloat contentView;    int[] location = new int[2];    private static IsHideThread mThread;    private boolean isHide = false;   //是否隐藏了小窗口    private int timer = 0;    public FloatView(Activity activity) {        this.mActivity = activity;        contentView = new PopupFloat(mActivity);        init();    }    private void init() {        initFloatWindowManage();        floatBtn = new Button(mActivity);        floatBtn.setBackgroundDrawable(mActivity.getResources().getDrawable(                R.drawable.iv_smallbtn1));        statusBarHeight = LXGameSDKUtil.getStatusBarHeight(mActivity);  //取得状态栏高度        floatBtnEvent();        wManager.addView(floatBtn, wmParams);        mThread = new IsHideThread();        mThread.start();    }    private void initFloatWindowManage() {        wManager = mActivity.getWindowManager();        screenWidth = wManager.getDefaultDisplay().getWidth();        screenHeigth = wManager.getDefaultDisplay().getHeight();        wmParams = new WindowManager.LayoutParams();        wmParams.format = PixelFormat.RGBA_8888;        wmParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;        wmParams.gravity = Gravity.LEFT | Gravity.TOP;        wmParams.x = screenWidth;        wmParams.y = screenHeigth/2;        wmParams.width = WindowManager.LayoutParams.WRAP_CONTENT;        wmParams.height = WindowManager.LayoutParams.WRAP_CONTENT;    }    private void floatBtnEvent() {        floatBtn.setOnTouchListener(new View.OnTouchListener() {            @Override            public boolean onTouch(View v, MotionEvent event) {                if (isHide) {   //隐藏的时候                    floatBtn.setBackgroundDrawable(mActivity.getResources().getDrawable(                            R.drawable.iv_smallbtn2));                }                switch (event.getAction()) {                    case MotionEvent.ACTION_DOWN:                        xInView = event.getX();                        yInView = event.getY();                        xDownInScreen = event.getRawX();                        yDownInScreen = event.getRawY() - statusBarHeight;                        xInScreen = event.getRawX();                        yInScreen = event.getRawY() - statusBarHeight;                        break;                    case MotionEvent.ACTION_MOVE:                        xInScreen = event.getRawX();                        yInScreen = event.getRawY() - statusBarHeight;                        if (xInScreen != xDownInScreen && yInScreen != yDownInScreen && hasChild) {                            removeBigWindow();                        }                        wmParams.x = (int) (xInScreen - xInView);                        wmParams.y = (int) (yInScreen - yInView);                        updateViewPosition(); // 手指移动的时候更新小悬浮窗的位置                        break;                    case MotionEvent.ACTION_UP:                        if (xInScreen < screenWidth / 2) {   //在左边                            wmParams.x = 0;                        } else {                   //在右边                            wmParams.x = screenWidth;                        }                        updateViewPosition();                        if (xInScreen == xDownInScreen && yInScreen == yDownInScreen) {                            openBigWindow();                            if (mPopupWindow != null && mPopupWindow.isShowing()){  //点击后显示了                                if (mThread != null)                                    mThread.interrupt();                            }else{            //没有显示bigWindow                                if (mThread != null){                                    mThread.interrupt();                                }                                isHide = false;                                mThread= new IsHideThread();                                mThread.start();                            }                        }else{                            if (mThread != null){                                mThread.interrupt();                            }                            isHide = false;                            mThread= new IsHideThread();                            mThread.start();                        }                        break;                }                return false;            }        });    }    /**     * 打开大悬浮窗     */    private void openBigWindow() {        if (xInScreen < screenWidth/2 ){            openRightBigWindow();        }else openLeftBigWindow();        hasChild = true;    }    protected void openLeftBigWindow()    {        if (mPopupWindow == null && contentView != null && hasItem) {            contentView.setBackgroundDrawable(mActivity.getResources().getDrawable(                    R.drawable.left_bg)); //设置左边的大悬浮窗的背景            contentView.setPadding(20, 10, 25, 10);            mPopupWindow = new PopupWindow(contentView, LinearLayout.LayoutParams.WRAP_CONTENT,                    LinearLayout.LayoutParams.WRAP_CONTENT, true);            mPopupWindow.setFocusable(true);            mPopupWindow.setOutsideTouchable(true);            floatBtn.getLocationOnScreen(location);            mPopupWindow.setBackgroundDrawable(new BitmapDrawable());            mPopupWindow.setAnimationStyle(R.style.left_anim);   //设置左边悬浮窗出来时候的动画            mPopupWindow.showAtLocation(contentView, Gravity.RIGHT,/*Gravity.LEFT | Gravity.TOP,*/                    floatBtn.getWidth(), location[1] - screenHeigth / 2 + statusBarHeight);            mPopupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {                @Override                public void onDismiss() {                    if (mThread != null) {                        mThread.interrupt();                    }                    isHide = false;                    mThread = new IsHideThread();                    mThread.start();                }            });        } else            removeBigWindow();    }    protected void openRightBigWindow()    {        if (mPopupWindow == null && contentView != null && hasItem)        {            contentView.setBackgroundDrawable(mActivity.getResources().getDrawable(                    R.drawable.right_bg));        //设置右悬浮窗的背景            contentView.setPadding(50, 10, 10, 10);            mPopupWindow = new PopupWindow(contentView, LinearLayout.LayoutParams.WRAP_CONTENT,                    LinearLayout.LayoutParams.WRAP_CONTENT, true);            mPopupWindow.setFocusable(true);            mPopupWindow.setOutsideTouchable(true);            floatBtn.getLocationOnScreen(location);            mPopupWindow.setBackgroundDrawable(new BitmapDrawable());            mPopupWindow.setAnimationStyle(R.style.right_anim);       //设置右边悬浮窗显示时候的动画            mPopupWindow.showAtLocation(contentView, Gravity.NO_GRAVITY,                    floatBtn.getWidth(), location[1]);        }        else        {            removeBigWindow();        }    }    /**     * 更新小悬浮窗在屏幕中的位置。     */    private void updateViewPosition() {        wManager.updateViewLayout(floatBtn, wmParams);    }    /**     * 移除大悬浮窗     */    protected void removeBigWindow() {        if (mPopupWindow != null) {            mPopupWindow.dismiss();            mPopupWindow = null;            hasChild = false;        }    }    /**     * 移除所有悬浮窗     */    public void removeAllWindow() {        if (mThread != null){            mThread.interrupt();        }        removeBigWindow();        mPopupWindow = null;        wManager.removeView(floatBtn);    }    public Button addFloatBtn(int resID, String name) {        hasItem = true;        return contentView.addFloatBtn(resID, name);    }    class IsHideThread extends Thread{        @Override        public void run() {            Handler mHandler = new Handler(mActivity.getMainLooper()) {                @Override                public void handleMessage(Message msg) {   //设置隐藏 当时间大于等于三秒并且大悬浮窗不存在的时候隐藏                    if (mPopupWindow != null) {                        hasChild = mPopupWindow.isShowing();                    }                    if (!isHide) {                        isHide = true;                        timer = 0;                        floatBtn.setBackgroundDrawable(mActivity.getResources().getDrawable(                                R.drawable.iv_small2));                        if (mThread != null) {                            mThread.currentThread().interrupt();                            mThread = null;                        }                    }                }            };            try {                sleep(3000);                mHandler.sendEmptyMessage(timer);            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }}

大悬浮窗类
import android.content.Context;import android.graphics.Color;import android.view.Gravity;import android.view.View;import android.view.animation.Animation;import android.view.animation.AnimationSet;import android.view.animation.AnticipateOvershootInterpolator;import android.view.animation.BounceInterpolator;import android.view.animation.ScaleAnimation;import android.widget.Button;import android.widget.LinearLayout;import android.widget.TextView;public class PopupFloat extends LinearLayout {    private Context mContext;    private LayoutParams mButtonLayoutParams;    private LayoutParams mTextLayoutParams;    public PopupFloat(Context context) {        super(context);        this.mContext = context;        initView();    }    public Button addFloatBtn(int resBtnIC,String btnText){        final TextView floatText = new TextView(mContext);        final Button floatbBtn = new Button(mContext);        floatText.setText(btnText);        floatText.setTextSize(16);        floatText.setTextColor(Color.WHITE);        floatbBtn.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                AnimationSet set = new AnimationSet(true);                set.addAnimation(new ScaleAnimation(1f, 1.2f, 1f, 1.2f));                set.setDuration(300);                set.setInterpolator(new AnticipateOvershootInterpolator(9f));                set.setInterpolator(new BounceInterpolator());                floatbBtn.startAnimation(set);                floatText.startAnimation(set);            }        });        floatbBtn.setLayoutParams(mButtonLayoutParams);        floatText.setLayoutParams(mTextLayoutParams);        floatbBtn.setBackgroundDrawable(getResources().getDrawable(resBtnIC));        addView(floatbBtn);        addView(floatText);        return floatbBtn;    }    private void initView() {        this.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, 80));        this.setGravity(Gravity.CENTER_VERTICAL);        mButtonLayoutParams = new LayoutParams(40, 40);        mTextLayoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT,                LayoutParams.WRAP_CONTENT);        mTextLayoutParams.setMargins(10, 0, 10, 0);    }    @Override    public void startAnimation(Animation animation)    {        super.startAnimation(animation);        postInvalidate();    }}
左边悬浮窗动画
<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android">    <scale        android:fromXScale="0.0"        android:toXScale="1.0"        android:fromYScale="1.0"        android:toYScale="1.0"        android:pivotX="100%"        android:duration="300" /></set>

右边悬浮窗动画
<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android">    <scale        android:fromXScale="0.0"        android:toXScale="1.0"        android:fromYScale="1.0"        android:toYScale="1.0"        android:pivotY="50%"        android:duration="300" /></set>



调用悬浮窗
 FloatButtonManager floatButtonManager = FloatButtonManager.getFloatButtonManager(activity);      floatButtonManager.createFloatButton();

销毁悬浮窗
FloatButtonManager floatButtonManager = FloatButtonManager.getFloatButtonManager(activity);      floatButtonManager.destroyFloatButton();






0 0
原创粉丝点击