亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 系統 > Android > 正文

android實現可自由移動、監聽點擊事件的懸浮窗

2019-10-21 21:34:02
字體:
來源:轉載
供稿:網友

最近因為項目需要,自己實現了個可以自由移動,并且長按可以跳出一個控制播放的,大的懸浮窗。

好,開始吧。首先我們先聊權限,懸浮窗需要在manifest中聲明一個權限:

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

然后呢,嗯,我們來講講關于懸浮窗實現的原理。

在Andriod中,所有的界面元素都要通過windowmanger來實現,像Activity、Fragment等等這些也是在其上實現。因此,我們的懸浮窗自然要通過這個實現。

這個項目中,我們自定義了兩個懸浮窗view。我們以其中一個比較簡單的為例: 

我們自定義一個管理可以統一管理懸浮窗的類MyWindowManager,負責創建,刪除懸浮窗

/** * Created by shiwe on 2017/3/7. * 懸浮窗管理 * 創建,移除 * 單例模式 */public class MyWindowManager { private FloatNormalView normalView; private FloatControlView controlView; private static MyWindowManager instance; private MyWindowManager() { } public static MyWindowManager getInstance() {  if (instance == null)   instance = new MyWindowManager();  return instance; } /**  * 創建小型懸浮窗  */ public void createNormalView(Context context) {  if (normalView == null)   normalView = new FloatNormalView(context); } /**  * 移除懸浮窗  *  * @param context  */ public void removeNormalView(Context context) {  if (normalView != null) {   WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);   windowManager.removeView(normalView);   normalView = null;  } } /**  * 創建小型懸浮窗  */ public void createControlView(Context context) {  if (controlView == null)   controlView = new FloatControlView(context); } /**  * 移除懸浮窗  *  * @param context  */ public void removeControlView(Context context) {  if (controlView != null) {   WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);   windowManager.removeView(controlView);   controlView = null;  } }}

然后看看我們自定義的一個view,其繼承自LinearLayout,我們在initLayoutParams初始化這個控件的位置等其他參數;在initEvent方法中定義隨手指移動的監聽事件以及長按的監聽事件。

public class FloatNormalView extends LinearLayout { private Context context = null; private View view = null; private ImageView ivShowControlView = null; private WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); private static WindowManager windowManager; private float mTouchStartX; private float mTouchStartY; private float x; private float y; private boolean initViewPlace = false; private MyWindowManager myWindowManager; private boolean isControlViewShowing = false; public FloatNormalView(Context context) {  super(context);  this.context = context;  myWindowManager = MyWindowManager.getInstance();  LayoutInflater.from(context).inflate(R.layout.float_normal_view, this);  view = findViewById(R.id.ll_float_normal);  ivShowControlView = (ImageView) findViewById(R.id.iv_show_control_view);  windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);  initLayoutParams();  initEvent(); } /**  * 初始化參數  */ private void initLayoutParams() {  //屏幕寬高  int screenWidth = windowManager.getDefaultDisplay().getWidth();  int screenHeight = windowManager.getDefaultDisplay().getHeight();  //總是出現在應用程序窗口之上。  lp.type = WindowManager.LayoutParams.TYPE_PHONE;  // FLAG_NOT_TOUCH_MODAL不阻塞事件傳遞到后面的窗口  // FLAG_NOT_FOCUSABLE 懸浮窗口較小時,后面的應用圖標由不可長按變為可長按,不設置這個flag的話,home頁的劃屏會有問題  lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE    | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;  //懸浮窗默認顯示的位置  lp.gravity = Gravity.START | Gravity.TOP;  //指定位置  lp.x = screenWidth - view.getLayoutParams().width * 2;  lp.y = screenHeight / 2 + view.getLayoutParams().height * 2;  //懸浮窗的寬高  lp.width = WindowManager.LayoutParams.WRAP_CONTENT;  lp.height = WindowManager.LayoutParams.WRAP_CONTENT;  lp.format = PixelFormat.TRANSPARENT;  windowManager.addView(this, lp); } /**  * 設置懸浮窗監聽事件  */ private void initEvent() {  ivShowControlView.setOnLongClickListener(new OnLongClickListener() {   @Override   public boolean onLongClick(View view) {    if (!isControlViewShowing) {     myWindowManager.createControlView(context);     isControlViewShowing = true;    } else {     myWindowManager.removeControlView(context);     isControlViewShowing = false;    }    return true;   }  });  view.setOnTouchListener(new OnTouchListener() {   @Override   public boolean onTouch(View v, MotionEvent event) {    switch (event.getAction()) {     case MotionEvent.ACTION_DOWN:      if (!initViewPlace) {       initViewPlace = true;       //獲取初始位置       mTouchStartX += (event.getRawX() - lp.x);       mTouchStartY += (event.getRawY() - lp.y);      } else {       //根據上次手指離開的位置與此次點擊的位置進行初始位置微調       mTouchStartX += (event.getRawX() - x);       mTouchStartY += (event.getRawY() - y);      }      break;     case MotionEvent.ACTION_MOVE:      // 獲取相對屏幕的坐標,以屏幕左上角為原點      x = event.getRawX();      y = event.getRawY();      updateViewPosition();      break;     case MotionEvent.ACTION_UP:      break;    }    return true;   }  }); } /**  * 更新浮動窗口位置  */ private void updateViewPosition() {  lp.x = (int) (x - mTouchStartX);  lp.y = (int) (y - mTouchStartY);  windowManager.updateViewLayout(this, lp); }

最后,只需要在Activity中調用mywindowManager中調用createxxx方法就可以。

public class MainActivity extends AppCompatActivity { MyWindowManager myWindowManager; @Override protected void onCreate(@Nullable Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.activity_main);  myWindowManager = MyWindowManager.getInstance();  myWindowManager.createNormalView(this.getApplicationContext()); }}

最后,附上demo項目的下載地址: android實現懸浮窗

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日本精品性网站在线观看| 精品国产区一区二区三区在线观看| 国产精品一区久久| 亚洲国产精品系列| 欧美日韩中文字幕在线视频| 国产aⅴ夜夜欢一区二区三区| www欧美日韩| 欧美在线免费看| 久久久久久久网站| 欧美裸体xxxx极品少妇软件| 亚洲精品视频久久| 日韩欧美黄色动漫| 一区二区亚洲精品国产| 亚洲视频一区二区三区| 91禁外国网站| 91久久久久久久一区二区| 最新69国产成人精品视频免费| 久久久精品在线观看| 欧美性受xxxx白人性爽| 日韩亚洲精品视频| 欧美极品少妇xxxxⅹ喷水| 成人字幕网zmw| 日韩在线播放一区| 日韩精品视频在线| 亚洲一级黄色av| 亚洲黄页网在线观看| 亚洲xxxxx| 热草久综合在线| 亚洲第一免费播放区| 久久99国产精品久久久久久久久| 久久精品青青大伊人av| 久久综合国产精品台湾中文娱乐网| 久久精品久久久久久国产 免费| 亚洲精品v天堂中文字幕| 这里精品视频免费| 在线免费看av不卡| 欧美精品福利在线| 91在线观看免费高清| 欧美日韩第一页| 亚洲精品国产免费| 成人羞羞国产免费| 成人午夜两性视频| 成人疯狂猛交xxx| 成人羞羞国产免费| 日韩中文在线视频| 久久精品国产电影| 久久精品成人一区二区三区| 亚洲精品理论电影| 日韩欧美一区二区三区| 欧美性猛交xxxx| 91精品久久久久久久久久另类| 日韩免费观看av| 亚洲网站在线播放| 亚洲欧美国产精品久久久久久久| 国产精品女人久久久久久| 91国语精品自产拍在线观看性色| 国产女同一区二区| 亚洲精品免费在线视频| 国产精品pans私拍| 欧美成人激情在线| 亚洲久久久久久久久久| 91精品国产91久久久久久最新| 黄色91在线观看| 国产极品精品在线观看| 成人久久18免费网站图片| 亚洲综合日韩在线| 久久躁狠狠躁夜夜爽| 久久精品国产2020观看福利| 亚洲性生活视频在线观看| 96精品久久久久中文字幕| 国产一区二区动漫| 欧美国产中文字幕| 久久久久久亚洲精品不卡| 在线免费观看羞羞视频一区二区| 久久久精品一区二区三区| 久久精品在线视频| 午夜精品福利在线观看| 国产午夜精品免费一区二区三区| 91精品视频播放| 高清日韩电视剧大全免费播放在线观看| 欧美一级大片在线观看| 欧美精品情趣视频| 日韩亚洲欧美中文高清在线| 国产欧美日韩综合精品| 欧美天堂在线观看| 欧美在线视频一区二区| 日韩成人在线视频网站| 久久九九有精品国产23| 亚洲偷熟乱区亚洲香蕉av| 欧美激情第99页| 亚洲国产精品久久久久秋霞蜜臀| 亚洲国产成人精品女人久久久| 精品国产91乱高清在线观看| 视频一区视频二区国产精品| 欧美最猛性xxxxx(亚洲精品)| 日韩欧美亚洲国产一区| 国产一区二区成人| 欧美一级成年大片在线观看| 一区二区欧美久久| 久久国产精彩视频| 日韩中文字幕在线视频| 日韩黄在线观看| 日韩av在线免费观看| 国产精品91视频| 精品在线观看国产| 狠狠躁夜夜躁久久躁别揉| 3344国产精品免费看| 国产97色在线|日韩| 91亚洲国产成人久久精品网站| 久久久久久久国产精品| 成人www视频在线观看| 国产精品揄拍500视频| 欧美理论电影在线播放| 亚洲精品一区在线观看香蕉| 国产91精品高潮白浆喷水| 国产精品视频男人的天堂| 精品日本高清在线播放| 性欧美xxxx视频在线观看| 91国内精品久久| 亚洲欧洲高清在线| 亚洲欧美国产一本综合首页| 久久精品国产电影| 26uuu国产精品视频| 久久久久久美女| 国产精品久久久久久av福利软件| 亚洲精品成人网| 美女久久久久久久| 欧美主播福利视频| 久久全国免费视频| 欧美色欧美亚洲高清在线视频| 久久久免费电影| 亚洲成人免费网站| 欧美一区在线直播| 国产成人在线一区二区| 久久视频在线播放| 粉嫩老牛aⅴ一区二区三区| 久久久久久国产精品三级玉女聊斋| 久久久日本电影| 欧美成aaa人片在线观看蜜臀| 国产精品久久一区主播| 日韩在线视频二区| 亚洲在线观看视频网站| 精品亚洲国产成av人片传媒| 51色欧美片视频在线观看| 蜜臀久久99精品久久久久久宅男| 亚洲激情 国产| 国产日韩av在线播放| 97精品国产97久久久久久免费| 国产精品精品视频一区二区三区| 亚洲黄色免费三级| 5566成人精品视频免费| 中文字幕av一区中文字幕天堂| 欧美国产日韩xxxxx| 欧美成人午夜视频| 久久久女女女女999久久| 国产ts一区二区| 久久亚洲私人国产精品va| 国产精品一区二区三区久久久| 欧美在线观看一区二区三区| 性日韩欧美在线视频| 国产区精品在线观看| 日韩在线观看精品| 久久天天躁狠狠躁夜夜躁| 欧美精品久久久久久久久|