欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

android實(shí)現(xiàn)可自由移動、監(jiān)聽點(diǎn)擊事件的懸浮窗

最近因?yàn)轫?xiàng)目需要,自己實(shí)現(xiàn)了個可以自由移動,并且長按可以跳出一個控制播放的,大的懸浮窗。

創(chuàng)新互聯(lián)主營改則網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營網(wǎng)站建設(shè)方案,app軟件開發(fā)公司,改則h5小程序定制開發(fā)搭建,改則網(wǎng)站營銷推廣歡迎改則等地區(qū)企業(yè)咨詢

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

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

然后呢,嗯,我們來講講關(guān)于懸浮窗實(shí)現(xiàn)的原理。

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

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

我們自定義一個管理可以統(tǒng)一管理懸浮窗的類MyWindowManager,負(fù)責(zé)創(chuàng)建,刪除懸浮窗

/**
 * Created by shiwe on 2017/3/7.
 * 懸浮窗管理
 * 創(chuàng)建,移除
 * 單例模式
 */

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;
 }


 /**
  * 創(chuàng)建小型懸浮窗
  */
 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;
  }
 }

 /**
  * 創(chuàng)建小型懸浮窗
  */
 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初始化這個控件的位置等其他參數(shù);在initEvent方法中定義隨手指移動的監(jiān)聽事件以及長按的監(jiān)聽事件。

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();
 }


 /**
  * 初始化參數(shù)
  */
 private void initLayoutParams() {
  //屏幕寬高
  int screenWidth = windowManager.getDefaultDisplay().getWidth();
  int screenHeight = windowManager.getDefaultDisplay().getHeight();

  //總是出現(xiàn)在應(yīng)用程序窗口之上。
  lp.type = WindowManager.LayoutParams.TYPE_PHONE;

  // FLAG_NOT_TOUCH_MODAL不阻塞事件傳遞到后面的窗口
  // FLAG_NOT_FOCUSABLE 懸浮窗口較小時,后面的應(yīng)用圖標(biāo)由不可長按變?yōu)榭砷L按,不設(shè)置這個flag的話,home頁的劃屏?xí)袉栴}
  lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
    | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;

  //懸浮窗默認(rèn)顯示的位置
  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);
 }

 /**
  * 設(shè)置懸浮窗監(jiān)聽事件
  */
 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 {
       //根據(jù)上次手指離開的位置與此次點(diǎn)擊的位置進(jìn)行初始位置微調(diào)
       mTouchStartX += (event.getRawX() - x);
       mTouchStartY += (event.getRawY() - y);
      }
      break;
     case MotionEvent.ACTION_MOVE:
      // 獲取相對屏幕的坐標(biāo),以屏幕左上角為原點(diǎn)
      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中調(diào)用mywindowManager中調(diào)用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項(xiàng)目的下載地址: android實(shí)現(xiàn)懸浮窗

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。

當(dāng)前題目:android實(shí)現(xiàn)可自由移動、監(jiān)聽點(diǎn)擊事件的懸浮窗
瀏覽地址:http://aaarwkj.com/article14/peejge.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供移動網(wǎng)站建設(shè)、網(wǎng)站維護(hù)做網(wǎng)站、App設(shè)計網(wǎng)站設(shè)計公司、企業(yè)建站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設(shè)
久久精品国产久精国产爱| 国产黄片自拍视频免费看| 婷婷激情亚洲综合综合久久| 亚洲黄片在线免费播放观看| 亚洲码欧洲码一二三区| 国产亚洲精品美女视频| 男女做爰高清无遮挡免费| 亚洲一区二区精品999| 91超碰这里只有精品国产| 亚洲成人免费电影久久| 全国精品免费视频久久久| 欧美激情中文字幕日韩精品| 日韩高清中文字幕在线| 久久国产精品一区免费观看| 日韩欧美国产精品加勒比| 久久国产精品一区二区三区 | 欧美日韩免费爱爱视频| 免费在线观看成人av| 久久九九精品日本人妻视频| 中文字幕人妻丝袜一区一三区| 日韩成人手机视频在线观看| 国产成人色污在线观看| 日韩视频播放一区二区| 男人的天堂久久精品激情| 免费国产污网站在线观看| 国产福利在线观看网站| 国产一区二区黄色录像| 91在线国产精品视频| 亚洲一区二区三区 日韩精品| 国产婷婷色三区一区二区| 极品女神福利视频久久| 免费看的日韩av毛片| 欧美性生活真实的视频| 日韩毛片免费看美日韩毛片| 久久亚洲精品中文字幕馆| 国产又粗又长又大又长| 中文字幕一区二区不卡顿| 日韩av熟女人妻一区二| 国产精品美女丝袜久久久| 日韩欧美一区亚洲一区| 内射极品美女在线观看|