android自动悬浮窗代码,Android实现桌面悬浮窗、蒙板效果实例代码

android自动悬浮窗代码,Android实现桌面悬浮窗、蒙板效果实例代码

2023年7月15日发(作者:)

android⾃动悬浮窗代码,Android实现桌⾯悬浮窗、蒙板效果实例代码现在很多安全类的软件,⽐如360⼿机助⼿,百度⼿机助⼿等等,都有⼀个悬浮窗,可以飘浮在桌⾯上,⽅便⽤户使⽤⼀些常⽤的操作。今天这篇⽂章,就是介绍如何实现桌⾯悬浮窗效果的。⾸先,看⼀下效果图。悬浮窗⼀共分为两个部分,⼀个是平常显⽰的⼩窗⼝,另外⼀个是点击⼩窗⼝显⽰出来的⼆级悬浮窗⼝。⾸先,先看⼀下这个项⽬的⽬录结构。最关键的就是红框内的四个类。⾸先,FloatWindowService是⼀个后台的服务类,主要负责在后台不断的刷新桌⾯上的⼩悬浮窗⼝,否则会导致更换界⾯之后,悬浮窗⼝也会随之消失,因此需要不断的刷新。下⾯是实现代码。package indow;import ;import ask;import e;import t;import ;import r;import r;/*** 悬浮窗后台服务** @author zhaokaiqiang**/public class FloatWindowService extends Service {public static final String LAYOUT_RES_ID = "layoutResId";public static final String ROOT_LAYOUT_ID = "rootLayoutId";// ⽤于在线程中创建/移除/更新悬浮窗private Handler handler = new Handler();private Context context;private Timer timer;// ⼩窗⼝布局资源idprivate int layoutResId;// 布局根布局idprivate int rootLayoutId;@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {context = this;layoutResId = Extra(LAYOUT_RES_ID, 0);rootLayoutId = Extra(ROOT_LAYOUT_ID, 0);if (layoutResId == 0 || rootLayoutId == 0) {throw new IllegalArgumentException("layoutResId or rootLayoutId is illegal");}if (timer == null) {timer = new Timer();// 每500毫秒就执⾏⼀次刷新任务leAtFixedRate(new RefreshTask(), 0, 500);}return tCommand(intent, flags, startId);}@Overridepublic void onDestroy() {roy();// Service被终⽌的同时也停⽌定时器继续运⾏();timer = null;}private class RefreshTask extends TimerTask {@Overridepublic void run() {// 当前界⾯没有悬浮窗显⽰,则创建悬浮if (!tance(context).isWindowShowing()) {(new Runnable() {@Overridepublic void run() {tance(context).createSmallWindow(context, layoutResId,rootLayoutId);}});}}}@Overridepublic IBinder onBind(Intent intent) {return null;}}除了后台服务之外,我们还需要两个⾃定义的布局,分别是FloatWindowSmallView和FloatWindowBigView,这两个⾃定义的布局,主要负责悬浮窗的前台显⽰,我们分别看⼀下代码实现。⾸先是FloatWindowSmallView类的实现。package indow;import ;import ssLint;import t;import ormat;import y;import Inflater;import Event;import ;import Manager;import Layout;import ew;import Utils;import ngwindow.R;/*** ⼩悬浮窗,⽤于初始显⽰** @author zhaokaiqiang**/public class FloatWindowSmallView extends LinearLayout {// ⼩悬浮窗的宽public int viewWidth;// ⼩悬浮窗的⾼public int viewHeight;// 系统状态栏的⾼度private static int statusBarHeight;// ⽤于更新⼩悬浮窗的位置private WindowManager windowManager;// ⼩悬浮窗的布局参数public Params smallWindowParams;// 记录当前⼿指位置在屏幕上的横坐标private float xInScreen;// 记录当前⼿指位置在屏幕上的纵坐标private float yInScreen;// 记录⼿指按下时在屏幕上的横坐标,⽤来判断单击事件private float xDownInScreen;// 记录⼿指按下时在屏幕上的纵坐标,⽤来判断单击事件private float yDownInScreen;// 记录⼿指按下时在⼩悬浮窗的View上的横坐标private float xInView;// 记录⼿指按下时在⼩悬浮窗的View上的纵坐标private float yInView;// 单击接⼝private OnClickListener listener;/*** 构造函数** @param context* 上下⽂对象* @param layoutResId* 布局资源id* @param rootLayoutId* 根布局id*/public FloatWindowSmallView(Context context, int layoutResId,int rootLayoutId) {super(context);windowManager = (WindowManager) temService(_SERVICE);(context).inflate(layoutResId, this);View view = findViewById(rootLayoutId);viewWidth = outParams().width;viewHeight = outParams().height;statusBarHeight = getStatusBarHeight();TextView percentView = (TextView) findViewById(t);t("悬浮窗");smallWindowParams = new Params();// 设置显⽰类型为 = _PHONE;// 显⽰图⽚格式 = _8888;// 设置交互模式 = _NOT_TOUCH_MODAL| _NOT_FOCUSABLE;// 设置对齐⽅式为左上y = | ; = viewWidth; = viewHeight;smallWindowParams.x = eenWidth(context);smallWindowParams.y = eenHeight(context) / 2;}@SuppressLint("ClickableViewAccessibility")@Overridepublic boolean onTouchEvent(MotionEvent event) {switch (ion()) {// ⼿指按下时记录必要的数据,纵坐标的值都减去状态栏的⾼度case _DOWN:// 获取相对与⼩悬浮窗的坐标xInView = ();yInView = ();// 按下时的坐标位置,只记录⼀次xDownInScreen = X();yDownInScreen = Y() - statusBarHeight;break;case _MOVE:// 时时的更新当前⼿指在屏幕上的位置xInScreen = X();yInScreen = Y() - statusBarHeight;// ⼿指移动的时候更新⼩悬浮窗的位置updateViewPosition();break;case _UP:// 如果⼿指离开屏幕时,按下坐标与当前坐标相等,则视为触发了单击事件if (xDownInScreen == X()&& yDownInScreen == (Y() - getStatusBarHeight())) {if (listener != null) {();}}break;}return true;}/*** 设置单击事件的回调接⼝*/public void setOnClickListener(OnClickListener listener) {er = listener;}/*** 更新⼩悬浮窗在屏幕中的位置*/private void updateViewPosition() {smallWindowParams.x = (int) (xInScreen - xInView);smallWindowParams.y = (int) (yInScreen - yInView);ViewLayout(this, smallWindowParams);}/*** 获取状态栏的⾼度** @return*/private int getStatusBarHeight() {try {Class> c = e("al.R$dimen");Object o = tance();Field field = ld("status_bar_height");int x = (Integer) (o);return getResources().getDimensionPixelSize(x);} catch (Exception e) {tackTrace();}return 0;}/*** 单击接⼝** @author zhaokaiqiang**/public interface OnClickListener {public void click();}}在这个类⾥⾯,主要的⼯作是实现悬浮窗⼝在桌⾯前端的实现,还有就是位置的移动和单击事件的判断以及处理。这⾥使⽤的是主要是WindowManager类的⼀些⽅法和属性,下⼀篇会详细说明,这篇只说实现。除了⼩悬浮窗之外,点击之后弹出的⼆级悬浮窗也是类似的⽅式添加到桌⾯上,下⾯是⼆级悬浮窗的代码。package indow;import t;import ormat;import y;import Inflater;import ;import Manager;import Layout;import ew;import Utils;import ngwindow.R;public class FloatWindowBigView extends LinearLayout {// 记录⼤悬浮窗的宽public int viewWidth;// 记录⼤悬浮窗的⾼public int viewHeight;public Params bigWindowParams;private Context context;public FloatWindowBigView(Context context) {super(context);t = context;(context).inflate(_window_big, this);View view = findViewById(_window_layout);viewWidth = outParams().width;viewHeight = outParams().height;bigWindowParams = new Params();// 设置显⽰的位置,默认的是屏幕中⼼bigWindowParams.x = eenWidth(context) / 2 - viewWidth/ 2;bigWindowParams.y = eenHeight(context) / 2- viewHeight / 2; = _PHONE; = _8888;// 设置交互模式 = _NOT_TOUCH_MODAL| _NOT_FOCUSABLE;y = | ; = viewWidth; = viewHeight;initView();}private void initView() {TextView tv_back = (TextView) findViewById(_back);tv_lickListener(new OnClickListener() {@Overridepublic void onClick(View v) {tance(context).removeBigWindow();}});}}这些基本的类建⽴起来之后,剩下的就是最重要的类FloatWindowManager的实现。这个类实现的就是对悬浮窗的操作。package indow;import t;import ;import Manager;/*** 悬浮窗管理器** @author zhaokaiqiang**/public class FloatWindowManager {// ⼩悬浮窗对象private FloatWindowSmallView smallWindow;// ⼤悬浮窗对象private FloatWindowBigView bigWindow;// ⽤于控制在屏幕上添加或移除悬浮窗private WindowManager mWindowManager;// FloatWindowManager的单例private static FloatWindowManager floatWindowManager;// 上下⽂对象private Context context;private FloatWindowManager(Context context) {t = context;}public static FloatWindowManager getInstance(Context context) {if (floatWindowManager == null) {floatWindowManager = new FloatWindowManager(context);}return floatWindowManager;}/*** 创建⼩悬浮窗** @param context* 必须为应⽤程序的Context.*/public void createSmallWindow(Context context, int layoutResId,int rootLayoutId) {WindowManager windowManager = getWindowManager();if (smallWindow == null) {smallWindow = new FloatWindowSmallView(context, layoutResId,rootLayoutId);w(smallWindow, indowParams);}}/*** 将⼩悬浮窗从屏幕上移除** @param context*/public void removeSmallWindow() {if (smallWindow != null) {WindowManager windowManager = getWindowManager();View(smallWindow);smallWindow = null;}}public void setOnClickListener(kListener listener) {if (smallWindow != null) {lickListener(listener);}}/*** 创建⼤悬浮窗** @param context* 必须为应⽤程序的Context.*/public void createBigWindow(Context context) {WindowManager windowManager = getWindowManager();if (bigWindow == null) {bigWindow = new FloatWindowBigView(context);w(bigWindow, dowParams);}}/*** 将⼤悬浮窗从屏幕上移除** @param context*/public void removeBigWindow() {if (bigWindow != null) {WindowManager windowManager = getWindowManager();View(bigWindow);bigWindow = null;}}public void removeAll() {rvice(new Intent(context, ));removeSmallWindow();removeBigWindow();}/*** 是否有悬浮窗显⽰(包括⼩悬浮窗和⼤悬浮)** @return 有悬浮窗显⽰在桌⾯上返回true,没有的话返回false*/public boolean isWindowShowing() {return smallWindow != null || bigWindow != null;}/*** 如果WindowManager还未创建,则创建新的WindowManager返回。否则返回当前已创建的WindowManager** @param context* @return*/private WindowManager getWindowManager() {if (mWindowManager == null) {mWindowManager = (WindowManager) temService(_SERVICE);}return mWindowManager;}}还有个获取屏幕宽⾼的帮助类。package ;import t;import Manager;/*** 屏幕帮助类** @author zhaokaiqiang**/public class ScreenUtils {/*** 获取屏幕宽度** @return*/@SuppressWarnings("deprecation")public static int getScreenWidth(Context context) {return ((WindowManager) temService(_SERVICE)).getDefaultDisplay().getWidth();}/*** 获取屏幕宽度** @return*/@SuppressWarnings("deprecation")public static int getScreenHeight(Context context) {return ((WindowManager) temService(_SERVICE)).getDefaultDisplay().getHeight();}}完成这些,我们就可以直接⽤了。package ;import ty;import t;import ;import ;import nt;import ;import ngwindow.R;import indowManager;import indowService;import kListener;/*** ⽰例** @ClassName: tivity* @Description:* @author zhaokaiqiang* @date 2014-10-23 下午11:30:13**/public class MainActivity extends Activity {private FloatWindowManager floatWindowManager;private Context context;@Overrideprotected void onCreate(Bundle savedInstanceState) {te(savedInstanceState);setContentView(ty_main);context = this;floatWindowManager = tance(context);}/*** 显⽰⼩窗⼝** @param view*/public void show(View view) {// 需要传递⼩悬浮窗布局,以及根布局的id,启动后台服务Intent intent = new Intent(context, );ra(_RES_ID,_window_small);ra(_LAYOUT_ID,_window_layout);startService(intent);}/*** 显⽰⼆级悬浮窗** @param view*/public void showBig(View view) {// 设置⼩悬浮窗的单击事件lickListener(new OnClickListener() {@Overridepublic void click() {BigWindow(context);}});}/*** 移除所有的悬浮窗** @param view*/public void remove(View view) {All();}@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {// 返回键移除⼆级悬浮窗if (keyCode == E_BACK&& ion() == _DOWN) {BigWindow();return true;}return own(keyCode, event);}}在上⾯⽂章中,我们介绍了如何实现桌⾯悬浮窗⼝,在这个效果的实现过程中,最重要的⼀个类就是WindowManager,今天这篇⽂章,将对WindowManager的使⽤进⾏介绍,并且实现⼀个使⽤WindowManager来实现⽤户打开APP,显⽰⾸次使⽤教学蒙板的效果。WindowManager类实现了ViewManager接⼝,ViewManager接⼝允许我们在Activity上添加或者是移除view,因此WindowManager也允许我们在Activity上进⾏View的添加和移除操作。我们可以通过下⾯的⽅法获取⼀个WindowManager对象temService(_SERVICE)在Activity之中,我们可以直接通过getWindowManager()获取到⼀个WindowManager对象。每⼀个WindowManager实例都被绑定到⼀个独有的Display对象上⾯,如果我们想获取不同Display的WindowManager对象,我们可以通过createDisplayContext(Display)获取到这个Display的Context对象,然后使⽤上⾯的⽅法,也可以获取到⼀个WindowManager对象。我们在使⽤WindowManager类的时候,通常使⽤下⾯的⼏个⽅法:w(View,Param);View();aultDisplay();w()⽅法⽤来向当前的窗⼝上添加View对象,需要接受两个参数,View是要添加到窗⼝的View对象,⽽Param则是添加的窗⼝的参数,在上⼀篇添加悬浮窗的操作的时候,需要对LayoutParam设置很多参数,下⾯我们看⼀下常⽤的设置// 设置LayoutParams参数LayoutParams params = new Params();//设置显⽰的类型,TYPE_PHONE指的是来电话的时候会被覆盖,其他时候会在最前端,显⽰位置在stateBar下⾯,其他更多的值请查阅⽂档 = _PHONE;//设置显⽰格式 = _8888;//设置对齐⽅式y = | ;//设置宽⾼ = eenWidth(this); = eenHeight(this);//设置显⽰的位置params.x;params.y;设置好LayoutParam之后,我们就可以通过w(View,Param)将View添加到窗⼝之上,不过,我们需要申明权限添加完成之后,我们就可以在窗⼝上看到我们添加的View对象了。如果我们想将添加的View移除,我们只需要调⽤View()即可,参数就是我们前⾯使⽤的View对象,使⽤很简单。除了这个⽅法,还有个ViewImmediate(),也可以将View移除,但是⽂档中说,这个⽅法并不是给⼀般程序调⽤的,因此需要⼩⼼使⽤,我们开发的都属于⼀般程序,建议不要使⽤这个⽅法。除了这两个⽅法之外,我们最常⽤的另外⼀个⽅法就是aultDisplay(),通过这个⽅法,我们可以获取到当前界⾯的Display的⼀个对象,然后我们就可以获取到当前屏幕的⼀些参数,⽐如说宽⾼。下⾯是我常⽤的⼀个⼯具类。package ask;import t;import Manager;/*** 屏幕帮助类** @author zhaokaiqiang**/public class ScreenUtils {/*** 获取屏幕宽度** @return*/@SuppressWarnings("deprecation")public static int getScreenWidth(Context context) {return ((WindowManager) temService(_SERVICE)).getDefaultDisplay().getWidth();}/*** 获取屏幕宽度** @return*/@SuppressWarnings("deprecation")public static int getScreenHeight(Context context) {return ((WindowManager) temService(_SERVICE)).getDefaultDisplay().getHeight();}}知道上⾯这些之后,我们就可以实现教学模板效果了,⾸先看效果图。下⾯是代码实现package ask;import ty;import ormat;import ;import y;import ;import kListener;import Manager;import Params;import iew;import ype;public class MainActivity extends Activity {private ImageView img;private WindowManager windowManager;@Overrideprotected void onCreate(Bundle savedInstanceState) {te(savedInstanceState);setContentView(ty_main);windowManager = getWindowManager();// 动态初始化图层img = new ImageView(this);outParams(new LayoutParams(_PARENT,_PARENT));leType(_XY);geResource();// 设置LayoutParams参数LayoutParams params = new Params();// 设置显⽰的类型,TYPE_PHONE指的是来电话的时候会被覆盖,其他时候会在最前端,显⽰位置在stateBar下⾯,其他更多的值请查阅⽂档 = _PHONE;// 设置显⽰格式 = _8888;// 设置对齐⽅式y = | ;// 设置宽⾼ = eenWidth(this); = eenHeight(this);// 添加到当前的窗⼝上w(img, params);// 点击图层之后,将图层移除lickListener(new OnClickListener() {@Overridepublic void onClick(View arg0) {View(img);}});}}以上所述是⼩编给⼤家介绍的Android实现桌⾯悬浮窗、蒙板效果实例代码,希望对⼤家有所帮助!

发布者:admin,转转请注明出处:http://www.yc00.com/xiaochengxu/1689425861a246235.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信