日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

Android浮動(dòng)窗口實(shí)現(xiàn)原理及代碼實(shí)例

瀏覽:26日期:2022-09-23 09:12:38

1.浮動(dòng)窗口的實(shí)現(xiàn)原理

看到上圖的那個(gè)小Android圖標(biāo)了吧,它不會(huì)被其他組建遮擋,也可以響應(yīng)用戶的點(diǎn)擊和拖動(dòng)事件,它的顯示和消失由WindowManager直接管理,它就是Android浮動(dòng)窗口。Android浮動(dòng)窗口的實(shí)現(xiàn)主要是靠WindowManager這個(gè)類。通過WindowManager類的addView(),updateViewLayout(),removeView()這幾個(gè)方法,我們可以直接在Window中添加,更新,移除View。

2.浮動(dòng)窗口實(shí)現(xiàn)的具體步驟

1)既然浮動(dòng)窗口的實(shí)現(xiàn)依賴與WindowManager,那么毫無(wú)疑問,我們得先拿到WindowManger對(duì)象。考慮到浮動(dòng)窗口通常在應(yīng)用程序退出后依然顯示,所以我們需要在Service中實(shí)現(xiàn)浮動(dòng)窗口的添加和更新,當(dāng)然別忘了提供給用戶一個(gè)取消浮動(dòng)窗口的功能。

2)定義你要顯示的View。可以在布局文件中定義,也可以自定義視圖。

3)設(shè)置必要的參數(shù),其中有幾個(gè)比較重要的參數(shù)需要設(shè)置,具體請(qǐng)參考下面的代碼。

4)將View添加到Window中,接收并處理事件,更新View。

5)在Manifest中加入對(duì)應(yīng)的權(quán)限。<uses-permission android:name='android.permission.SYSTEM_ALERT_WINDOW'/>

3.浮動(dòng)窗口實(shí)現(xiàn)代碼

package com.spreadst.floatwindow; import android.app.Service; import android.content.Context; import android.content.Intent; import android.graphics.PixelFormat; import android.os.IBinder; import android.util.Log; import android.view.Gravity; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.WindowManager; public class FloatWindowService extends Service { private static final TAG = 'FloatWindowService'; private WindowManager mWindowManager; private WindowManager.LayoutParams mLayoutParams; private LayoutInflater mLayoutInflater; private View mFloatView; private int mCurrentX; private int mCurrentY; private static int mFloatViewWidth = 50; private static int mFloatViewHeight = 80; @Override public void onCreate() { // TODO Auto-generated method stub super.onCreate(); //初始化WindowManager對(duì)象和LayoutInflater對(duì)象 mWindowManager = (WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE); mLayoutInflater = LayoutInflater.from(this); } @Override public void onStart(Intent intent, int startId) { // TODO Auto-generated method stub super.onStart(intent, startId); Log.i(TAG, 'onStart()'); createView(); } private void createView() { // TODO Auto-generated method stub //加載布局文件 mFloatView = mLayoutInflater.inflate(R.layout.main, null); //為View設(shè)置監(jiān)聽,以便處理用戶的點(diǎn)擊和拖動(dòng) mFloatView.setOnTouchListener(new OnFloatViewTouchListener()); /*為View設(shè)置參數(shù)*/ mLayoutParams = new WindowManager.LayoutParams(); //設(shè)置View默認(rèn)的擺放位置 mLayoutParams.gravity = Gravity.LEFT | Gravity.TOP; //設(shè)置window type mLayoutParams.type = WindowManager.LayoutParams.TYPE_PHONE; //設(shè)置背景為透明 mLayoutParams.format = PixelFormat.RGBA_8888; //注意該屬性的設(shè)置很重要,F(xiàn)LAG_NOT_FOCUSABLE使浮動(dòng)窗口不獲取焦點(diǎn),若不設(shè)置該屬性,屏幕的其它位置點(diǎn)擊無(wú)效,應(yīng)為它們無(wú)法獲取焦點(diǎn) mLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; //設(shè)置視圖的顯示位置,通過WindowManager更新視圖的位置其實(shí)就是改變(x,y)的值 mCurrentX = mLayoutParams.x = 50; mCurrentY = mLayoutParams.y = 50; //設(shè)置視圖的寬、高 mLayoutParams.width = 100; mLayoutParams.height = 100; //將視圖添加到Window中 mWindowManager.addView(mFloatView, mLayoutParams); } /*由于直接startService(),因此該方法沒用*/ @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub return null; } /*該方法用來更新視圖的位置,其實(shí)就是改變(LayoutParams.x,LayoutParams.y)的值*/ private void updateFloatView() { mLayoutParams.x = mCurrentX; mLayoutParams.y = mCurrentY; mWindowManager.updateViewLayout(mFloatView, mLayoutParams); } /*處理視圖的拖動(dòng),這里只對(duì)Move事件做了處理,用戶也可以對(duì)點(diǎn)擊事件做處理,例如:點(diǎn)擊浮動(dòng)窗口時(shí),啟動(dòng)應(yīng)用的主Activity*/ private class OnFloatViewTouchListener implements View.OnTouchListener { @Override public boolean onTouch(View v, MotionEvent event) { // TODO Auto-generated method stub Log.i(TAG, 'mCurrentX: ' + mCurrentX + ',mCurrentY: ' + mCurrentY + ',mFloatViewWidth: ' + mFloatViewWidth + ',mFloatViewHeight: ' + mFloatViewHeight); /* * getRawX(),getRawY()這兩個(gè)方法很重要。通常情況下,我們使用的是getX(),getY()來獲得事件的觸發(fā)點(diǎn)坐標(biāo), * 但getX(),getY()獲得的是事件觸發(fā)點(diǎn)相對(duì)與視圖左上角的坐標(biāo);而getRawX(),getRawY()獲得的是事件觸發(fā)點(diǎn) * 相對(duì)與屏幕左上角的坐標(biāo)。由于LayoutParams中的x,y是相對(duì)與屏幕的,所以需要使用getRawX(),getRawY()。 */ mCurrentX = (int) event.getRawX() - mFloatViewWidth; mCurrentY = (int) event.getRawY() - mFloatViewHeight; int action = event.getAction(); switch (action) { case MotionEvent.ACTION_DOWN:break; case MotionEvent.ACTION_MOVE:updateFloatView();break; case MotionEvent.ACTION_UP:break; } return true; } } }

4.如何只在Launcher界面顯示浮動(dòng)窗口

大家應(yīng)該都熟悉360安全衛(wèi)士的浮動(dòng)窗口,它的浮動(dòng)窗口只會(huì)在Launcher界面顯示,當(dāng)用戶切到其它界面,浮動(dòng)窗口自動(dòng)被移除了。

要實(shí)現(xiàn)該功能,我們就必須知道當(dāng)前所在的界面,如果只去監(jiān)聽Activity的category,那么我們只能知道什么時(shí)候進(jìn)入Launcher界面了,卻無(wú)法知道是否離開了Launcher界面。那么360是如何實(shí)現(xiàn)該功能呢?大家可以反編譯一下它的代碼。這里提供一種可行的方法,我們的目前其實(shí)很簡(jiǎn)單,就是要知道當(dāng)前的Activity是否是Launcher界面的Activity。由于Activity是以堆棧的形式被管理的,因此,只要我們查看棧頂?shù)腁ctivity是否是Launcher的Activity即可。要獲取Activity的Task信息,需要在Manifest中添加對(duì)應(yīng)權(quán)限,<uses-permission android:name = “android.permission.GET_TASKS”/>。

private String getTopActivity(Context context) { //獲取ActivityManager對(duì)象 ActivityManager manager = (ActivityManager)getSystemService(ACTIVITY_SERVICE) ; /* * 拿到當(dāng)前正在運(yùn)行的Task列表,該列表按照最近使用的時(shí)間順序排列,其中的參數(shù)表示需要返回的最大列表項(xiàng)數(shù)目。 * 這里我們只需要拿到處于onResume狀態(tài)的Activity所在的Task。 */ List<RunningTaskInfo> runningTaskInfos = manager.getRunningTasks(1) ; if(runningTaskInfos != null) { //拿到該task中的棧頂Activity return (runningTaskInfos.get(0).topActivity).toString() ; } else { return null; } }

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持好吧啦網(wǎng)。

標(biāo)簽: Android
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
五月国产精品| 国产精品一区二区三区av麻| 欧美激情视频一区二区三区免费 | 亚洲91精品| 女人av一区| 女人av一区| 亚洲成人三区| 日韩影院免费视频| 日本不卡高清| 国产精品xxx| 日韩成人a**站| 日韩精品看片| 国产亚洲亚洲| 欧美日韩黄网站| 国产一区二区三区四区| 久久精品亚洲欧美日韩精品中文字幕| 自拍日韩欧美| 日本在线成人| 另类小说一区二区三区| 日韩在线观看| 另类国产ts人妖高潮视频| 日本在线不卡视频一二三区| 嫩呦国产一区二区三区av| 欧美三区四区| 91国语精品自产拍| 日本在线不卡视频| 国内精品伊人| 免费观看不卡av| 视频一区日韩精品| 国产在线不卡一区二区三区| 美女少妇全过程你懂的久久| 深夜日韩欧美| 水蜜桃久久夜色精品一区| 99国产精品| 欧美日韩亚洲一区三区| 丝袜美腿诱惑一区二区三区 | 美国三级日本三级久久99| 天堂精品久久久久| 免费看久久久| 激情综合网址| 亚洲毛片在线| 精品五月天堂| 在线亚洲成人| 国产精品调教视频| 蜜臀91精品国产高清在线观看| 亚洲精品免费观看| 亚洲最新无码中文字幕久久| 蜜臀国产一区二区三区在线播放 | 九色porny丨国产首页在线| 久久久久蜜桃| 欧美日韩一区二区三区视频播放| 久久亚洲精品伦理| 不卡av一区二区| 日本成人精品| 日韩理论视频| 久久最新视频| 中文字幕在线视频网站| 首页国产欧美日韩丝袜| 国产一区精品福利| 综合一区av| 亚洲成人va| 免费精品视频| 日韩久久视频| 欧美一级网站| 欧美日韩国产欧| 精品无人区麻豆乱码久久久| 国产精品婷婷| 精品一区二区三区免费看| 亚洲欧美日韩高清在线| 久久精品 人人爱| 伊人久久大香线蕉av超碰演员| 国产精品99久久免费| 丝袜美腿一区二区三区| 亚洲91视频| 麻豆91小视频| 日韩午夜视频在线| 欧美一区二区三区高清视频| 久久中文精品| 亚洲综合小说| 亚洲一级少妇| 老牛国内精品亚洲成av人片| 亚洲18在线| 欧美久久精品一级c片| 福利视频一区| 国产剧情在线观看一区| 精品五月天堂| 国产欧美日韩在线观看视频| 亚洲天堂av影院| 国产乱码精品一区二区三区亚洲人| 视频一区在线视频| 日韩在线二区| 久久av综合| 91精品美女| 久久亚洲欧美| 亚洲精华国产欧美| 黑丝美女一区二区| 久久久精品网| 日韩国产综合| 涩涩av在线| 蜜桃av.网站在线观看| 国产一区二区三区黄网站| 国产另类在线| 欧美日一区二区在线观看| 婷婷综合福利| 一区二区三区国产在线| 欧美午夜不卡影院在线观看完整版免费| 美女精品久久| 久久精品国产久精国产爱| 国产精品久久久久久久久久白浆| 天海翼亚洲一区二区三区| 亚洲一区二区日韩| 免费不卡在线视频| 日韩在线视频一区二区三区| 麻豆一区二区三区| 精品一区二区三区四区五区| 国产精品99久久免费观看| 国产精品成人国产| 国产欧美69| 美女尤物国产一区| **爰片久久毛片| 91欧美日韩在线| 69堂精品视频在线播放| 国产麻豆一区二区三区精品视频| 国产日韩免费| 久久香蕉网站| 美女av在线免费看| 日韩欧美一区二区三区免费观看| 日本黄色精品| 日本精品影院| 欧美在线亚洲| 老色鬼久久亚洲一区二区| 蜜桃av一区二区三区电影| 亚洲精品亚洲人成在线观看| 日韩一区中文| 久久不见久久见国语| 高清日韩欧美| 日韩欧美看国产| 影音先锋久久| 日本91福利区| 精品国产三区在线| 欧美日一区二区| 亚洲一区日本| 日韩高清不卡在线| 国产精品sm| 九九精品调教| 久久高清免费观看| 国产色噜噜噜91在线精品| 老司机精品在线| 久久影院午夜精品| 中文欧美日韩| 国产精品一区二区av交换| 久久久91麻豆精品国产一区| 日韩欧美国产精品综合嫩v| 99精品99| 国产免费播放一区二区| 亚洲天堂av影院| 玖玖玖国产精品| 美女毛片一区二区三区四区最新中文字幕亚洲 | 日韩精品欧美| 一区二区亚洲视频| 国产精品宾馆| 欧美一区二区性| 婷婷成人av| 国产成人精品三级高清久久91| 香蕉精品视频在线观看| 日韩欧美三区| 国内精品美女在线观看| 免费观看久久av| 91欧美日韩在线| 国产精品成久久久久| 亚洲深夜福利| 免费一区二区三区在线视频| 国产精品99一区二区| 日韩欧美2区| 色婷婷狠狠五月综合天色拍| 亚洲欧美久久精品| 亚洲一级少妇| 最新国产精品视频| 成人国产精品久久| 免费人成精品欧美精品| 美女视频一区在线观看| 午夜精品亚洲| 国产精品中文| 亚洲日本国产| 色偷偷偷在线视频播放| 日韩久久一区| 激情欧美国产欧美| 麻豆精品视频在线观看| 在线免费观看亚洲| 日韩影院二区| 国产精品久久| 黑丝一区二区三区| 久久av免费| 亚洲深深色噜噜狠狠爱网站 | 精品资源在线| 免费在线视频一区| 日韩大片在线观看| 国产麻豆一区二区三区| 日韩中文欧美在线| 国产96在线亚洲|