在做一个电台类的app时,需要一个按钮始终显示在最前端,查找了一些博客,都不尽如人意,选择了其中写的比较好的一篇进行了修改,最终满足了需求。
此方法使用的是系统弹窗,由于我这个项目的特殊性,这个控件是无法移动的,且用户三秒不点就会以动画的形式向上移动一半且半透明化,如果不需要这个功能可以直接删除相关代码,这个类内所有功能都有注释,很好修改,我直接整理成了一个工具类,代码如下:
package com.ijia.customview;import com.ijia.activity.PlayActivity;
import com.ijia.framework.MyApplication;
import com.ijia.util.CommonUtils;
import com.watch.radio.R;import android.app.Activity;
import android.content.Context;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.os.CountDownTimer;
import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
import android.widget.Toast;/*** @author 作者 :WY* @version 创建时间:2017年8月24日 上午11:40:50 类说明:始终显示在上层的按钮*/
public class FloatingFunc {/*** 浮动窗口在屏幕中的x坐标*/private float x = 0;/*** 浮动窗口在屏幕中的y坐标*/private float y = 0;/*** 屏幕触摸状态,暂时未使用*/private float state = 0;/*** 鼠标触摸开始位置*/private float mTouchStartX = 0;/*** 鼠标触摸结束位置*/private float mTouchStartY = 0;/*** windows 窗口管理器*/private WindowManager wm = null;/*** 当前显示状态(全显示还是半显示中) true为全显示*/public boolean isAllDisplay = true;/*** 参数设定类*/public WindowManager.LayoutParams params = new WindowManager.LayoutParams();private int TOOL_BAR_HIGH = 0;/*** 要显示在窗口最前面的对象*/private View view_obj = null;private static class MapUtilsHolder {/** 单例对象 */static final FloatingFunc instance = new FloatingFunc();}public static FloatingFunc getInstance() {return MapUtilsHolder.instance;}/** 防止外部实例化 */private FloatingFunc() {}/** readResolve方法应对单例对象被序列化时候 */private Object readResolve() {return getInstance();}/*** 要显示在窗口最前面的方法* * @param context* 调用对象Context getApplicationContext()* @param window* 调用对象 Window getWindow()* @param floatingViewObj* 要显示的浮动对象 View*/public void show(final Context context, Window window, View floatingViewObj) {// 关闭浮动显示对象然后再显示close(context);view_obj = floatingViewObj;Rect frame = new Rect();// 这一句是关键,让其在top 层显示// getWindow()window.getDecorView().getWindowVisibleDisplayFrame(frame);TOOL_BAR_HIGH = frame.top;wm = (WindowManager) context// getApplicationContext().getSystemService(Activity.WINDOW_SERVICE);params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT | WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;params.flags = LayoutParams.FLAG_NOT_TOUCH_MODAL | LayoutParams.FLAG_NOT_FOCUSABLE;// 设置悬浮窗口长宽数据params.width = WindowManager.LayoutParams.WRAP_CONTENT;params.height = WindowManager.LayoutParams.WRAP_CONTENT;params.format = PixelFormat.RGBA_8888;// 设定透明度// params.alpha = 100;// 设定内部文字对齐方式params.gravity = Gravity.RIGHT | Gravity.TOP;// 以屏幕左上角为原点,设置x、y初始值ֵ
// params.x = (int) MyApplication.mContext.getResources().getDimension(R.dimen.x320);
// params.y = (int) -100;view_obj.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {show(context);}});wm.addView(view_obj, params);timer.start();}/** 全显示(动画) */public void displayAll() {view_obj.animate().y(0).alpha(1).setDuration(700).start();isAllDisplay = true;}/** 半显示(动画) */public void displayHalf() {view_obj.animate().y(-(int) MyApplication.mContext.getResources().getDimension(R.dimen.x40)).alpha(0.5f).setDuration(700).start();isAllDisplay = false;}private void show(Context mContext){view_obj.setVisibility(View.VISIBLE);if (isAllDisplay) {if (!CommonUtils.isExsitMianActivity(mContext, PlayActivity.class)) {Toast.makeText(mContext, "暂无播放", Toast.LENGTH_SHORT).show();return;}displayHalf();CommonUtils.jumpToPage(mContext, PlayActivity.class, null, false, 0);}else {displayAll();timer.start();}}private CountDownTimer timer = new CountDownTimer(3000,1000) {@Overridepublic void onTick(long millisUntilFinished) {// TODO Auto-generated method stub}@Overridepublic void onFinish() {displayHalf();}};/*** 关闭浮动显示对象*/private void close(Context context) {if (view_obj != null && view_obj.isShown()) {WindowManager wm = (WindowManager) context.getSystemService(Activity.WINDOW_SERVICE);wm.removeView(view_obj);}}/*** 隐藏按钮*/public void close() {if (view_obj != null) {view_obj.setVisibility(View.GONE);}}/*** 显示按钮*/public void show(){if (view_obj != null) {view_obj.setVisibility(View.VISIBLE);}}/*** 更新弹出窗口位置*/private void updateViewPosition() {// 更新浮动窗口位置参数params.x = (int) (x - mTouchStartX);params.y = (int) (y - mTouchStartY);wm.updateViewLayout(view_obj, params);}
}
初始化:
FloatingFunc.getInstance().show(mContext, getWindow(), LayoutInflater.from(mContext).inflate(R.layout.floatingfunc_view, null));
里面这个view就是要显示的控件。初始显示位置,还有隐藏显示之类的方法都已写在类里,可以自己看注释找一下,类对象使用单例模式,调用类内的方法都是通过FloatingFunc.getInstance()点出来的,比如:FloatingFunc.getInstance().close()