本文实例为大家分享了android实现全局悬浮框的具体代码,供大家参考,具体内容如下
效果图:
代码实现:
androidmanifest.xml添加弹框权限
自定义悬浮窗类floatwindow.java
public class floatwindow implements view.ontouchlistener {
private context mcontext;
private windowmanager.layoutparams mwindowparams;
private windowmanager mwindowmanager;
private view mfloatlayout;
private float minviewx;
private float minviewy;
private float mdowninscreenx;
private float mdowninscreeny;
private float minscreenx;
private float minscreeny;
private textview infotext;
public floatwindow(context context) {
this.mcontext = context;
initfloatwindow();
}
private void initfloatwindow() {
layoutinflater inflater = layoutinflater.from(mcontext);
if(inflater == null)
return;
mfloatlayout = (view) inflater.inflate(r.layout.layout_float, null);
infotext = mfloatlayout.findviewbyid(r.id.textview);
mfloatlayout.setontouchlistener(this);
mwindowparams = new windowmanager.layoutparams();
mwindowmanager = (windowmanager) mcontext.getsystemservice(context.window_service);
if (build.version.sdk_int >= 26) {//8.0新特性
mwindowparams.type = windowmanager.layoutparams.type_application_overlay;
}else{
mwindowparams.type = windowmanager.layoutparams.type_system_alert;
}
mwindowparams.format = pixelformat.rgba_8888;
mwindowparams.flags = windowmanager.layoutparams.flag_not_focusable;
mwindowparams.gravity = gravity.start | gravity.top;
mwindowparams.width = windowmanager.layoutparams.wrap_content;
mwindowparams.height = windowmanager.layoutparams.wrap_content;
}
@override
public boolean ontouch(view view, motionevent motionevent) {
return floatlayouttouch(motionevent);
}
private boolean floatlayouttouch(motionevent motionevent) {
switch (motionevent.getaction()) {
case motionevent.action_down:
// 获取相对view的坐标,即以此view左上角为原点
minviewx = motionevent.getx();
minviewy = motionevent.gety();
// 获取相对屏幕的坐标,即以屏幕左上角为原点
mdowninscreenx = motionevent.getrawx();
mdowninscreeny = motionevent.getrawy() - getsysbarheight(mcontext);
minscreenx = motionevent.getrawx();
minscreeny = motionevent.getrawy() - getsysbarheight(mcontext);
break;
case motionevent.action_move:
// 更新浮动窗口位置参数
minscreenx = motionevent.getrawx();
minscreeny = motionevent.getrawy() - getsysbarheight(mcontext);
mwindowparams.x = (int) (minscreenx- minviewx);
mwindowparams.y = (int) (minscreeny - minviewy);
// 手指移动的时候更新小悬浮窗的位置
mwindowmanager.updateviewlayout(mfloatlayout, mwindowparams);
break;
case motionevent.action_up:
// 如果手指离开屏幕时,xdowninscreen和xinscreen相等,且ydowninscreen和yinscreen相等,则视为触发了单击事件。
if (mdowninscreenx == minscreenx && mdowninscreeny == minscreeny){
}
break;
}
return true;
}
public void showfloatwindow(){
if (mfloatlayout.getparent() == null){
displaymetrics metrics = new displaymetrics();
// 默认固定位置,靠屏幕右边缘的中间
mwindowmanager.getdefaultdisplay().getmetrics(metrics);
mwindowparams.x = metrics.widthpixels;
mwindowparams.y = metrics.heightpixels/2 - getsysbarheight(mcontext);
mwindowmanager.addview(mfloatlayout, mwindowparams);
}
}
public void updatetext(final string s) {
infotext.settext(s);
}
public void hidefloatwindow(){
if (mfloatlayout.getparent() != null)
mwindowmanager.removeview(mfloatlayout);
}
public void setfloatlayoutalpha(boolean alpha){
if (alpha)
mfloatlayout.setalpha((float) 0.5);
else
mfloatlayout.setalpha(1);
}
// 获取系统状态栏高度
public static int getsysbarheight(context contex) {
class> c;
object obj;
field field;
int x;
int sbar = 0;
try {
c = class.forname("com.android.internal.r$dimen");
obj = c.newinstance();
field = c.getfield("status_bar_height");
x = integer.parseint(field.get(obj).tostring());
sbar = contex.getresources().getdimensionpixelsize(x);
} catch (exception e1) {
e1.printstacktrace();
}
return sbar;
}
}
自定义悬浮窗界面布局文件layout_float.xml
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
android:id="@+id/imageview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/float_win"
app:layout_constraintstart_tostartof="parent"
app:layout_constrainttop_totopof="parent"/>
android:id="@+id/textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#00ffffff"
android:text="hello"
android:textsize="12sp"
app:layout_constraintleft_toleftof="@id/imageview"
app:layout_constraintright_torightof="@id/imageview"
app:layout_constrainttop_tobottomof="@id/imageview"/>
在activity中使用悬浮窗。
public class mainactivity extends appcompatactivity {
private button btnshow;
floatwindow floatwindow;
@override
protected void oncreate(bundle savedinstancestate) {
super.oncreate(savedinstancestate);
// 权限判断
if (build.version.sdk_int >= 23) {
if(!settings.candrawoverlays(getapplicationcontext())) {
// 启动activity让用户授权
intent intent = new intent(settings.action_manage_overlay_permission,uri.parse("package:" + getpackagename()));
startactivityforresult(intent,10);
} else {
// 执行6.0以上绘制代码
initview();
}
} else {
// 执行6.0以下绘制代码
initview();
}
}
@override
protected void onresume() {
super.onresume();
// 权限判断
if (build.version.sdk_int >= 23) {
if(settings.candrawoverlays(getapplicationcontext())) {
initview();
}
} else {
//执行6.0以下绘制代码
initview();
}
}
private void initview() {
setcontentview(r.layout.activity_main);
floatwindow = new floatwindow(getapplicationcontext());
btnshow = findviewbyid(r.id.btn_show);
btnshow.setonclicklistener(new view.onclicklistener() {
@override
public void onclick(view view) {
if (null != floatwindow) {
floatwindow.showfloatwindow();
}
}
});
button btnrefresh = findviewbyid(r.id.btn_refresh);
btnrefresh.setonclicklistener(new view.onclicklistener() {
@override
public void onclick(view view) {
int random = (int) (math.random() * 10);
if (null != floatwindow) {
floatwindow.updatetext(string.valueof(random));
}
}
});
}
@override
protected void ondestroy() {
super.ondestroy();
if (null != floatwindow) {
floatwindow.hidefloatwindow();
}
}
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持萬仟网。