在做一个电台类的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() {
@Override
public 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) {
@Override
public void onTick(long millisUntilFinished) {
// TODO Auto-generated method stub
}
@Override
public 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()
如有帮助,看完记得点赞