<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                ### 8.1 Window和WindowManager 為了分析Window的工作機制,我們需要先了解如何使用WindowManager添加一個Window。下面的代碼演示了通過WindowManager添加Window的過程,是不是很簡單呢? mFloatingButton = new Button(this); mFloatingButton.setText("button"); mLayoutParams = new WindowManager.LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 0, 0, PixelFormat.TRANSPARENT); mLayoutParams.flags = LayoutParams.FLAG_NOT_TOUCH_MODAL | LayoutParams.FLAG_NOT_FOCUSABLE | LayoutParams. FLAG_SHOW_WHEN_LOCKED mLayoutParams.gravity = Gravity.LEFT | Gravity.TOP; mLayoutParams.x = 100; mLayoutParams.y = 300; mWindowManager.addView(mFloatingButton, mLayoutParams); 上述代碼可以將一個Button添加到屏幕坐標為(100,300)的位置上。WindowManager. LayoutParams中的flags和type這兩個參數比較重要,下面對其進行說明。 Flags參數表示Window的屬性,它有很多選項,通過這些選項可以控制Window的顯示特性,這里主要介紹幾個比較常用的選項,剩下的請查看官方文檔。 * FLAG_NOT_FOCUSABLE 表示Window不需要獲取焦點,也不需要接收各種輸入事件,此標記會同時啟用FLAG_NOT_TOUCH_MODAL,最終事件會直接傳遞給下層的具有焦點的Window。 * FLAG_NOT_TOUCH_MODAL 在此模式下,系統會將當前Window區域以外的單擊事件傳遞給底層的Window,當前Window區域以內的單擊事件則自己處理。這個標記很重要,一般來說都需要開啟此標記,否則其他Window將無法收到單擊事件。 * FLAG_SHOW_WHEN_LOCKED 開啟此模式可以讓Window顯示在鎖屏的界面上。 Type參數表示Window的類型,Window有三種類型,分別是應用Window、子Window和系統Window。應用類Window對應著一個Activity。子Window不能單獨存在,它需要附屬在特定的父Window之中,比如常見的一些Dialog就是一個子Window。系統Window是需要聲明權限在能創建的Window,比如Toast和系統狀態欄這些都是系統Window。 Window是分層的,每個Window都有對應的z-ordered,層級大的會覆蓋在層級小的Window的上面,這和HTML中的z-index的概念是完全一致的。在三類Window中,應用Window的層級范圍是1~99,子Window的層級范圍是1000~1999,系統Window的層級范圍是2000~2999,這些層級范圍對應著WindowManager.LayoutParams的type參數。如果想要Window位于所有Window的最頂層,那么采用較大的層級即可。很顯然系統Window的層級是最大的,而且系統層級有很多值,一般我們可以選用TYPE_SYSTEM_OVERLAY或者TYPE_SYSTEM_ERROR,如果采用TYPE_SYSTEM_ERROR,只需要為type參數指定這個層級即可:`mLayoutParams.type = LayoutParams.TYPE_SYSTEM_ERROR;`同時聲明權限:`<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />`。因為系統類型的Window是需要檢查權限的,如果不在AndroidManifest中使用相應的權限,那么創建Window的時候就會報錯,錯誤如下所示。 E/AndroidRuntime(8071): Caused by: android.view.WindowManager$BadToken- Exception: Unable to add window android.view.ViewRootImpl$W@42882fe8 -- permission denied for this window type E/AndroidRuntime(8071): at android.view.ViewRootImpl.setView(ViewRootImpl. java:677) E/AndroidRuntime(8071): at android.view.WindowManagerImpl.addView(Window- ManagerImpl.java:326) E/AndroidRuntime(8071): at android.view.WindowManagerImpl.addView(Window- ManagerImpl.java:224) E/AndroidRuntime(8071): at android.view.WindowManagerImpl$CompatMode- Wrapper.addView(WindowManagerImpl.java:149) E/AndroidRuntime(8071): at android.view.Window$LocalWindowManager.addView (Window.java:558) E/AndroidRuntime(8071): at com.ryg.chapter_8.TestActivity.onButtonClick (TestActivity.java:60) E/AndroidRuntime(8071): ... 14 more W/ActivityManager( 514): Force finishing activity com.ryg.chapter_8/. TestActivity WindowManager所提供的功能很簡單,常用的只有三個方法,即添加View、更新View和刪除View,這三個方法定義在ViewManager中,而WindowManager繼承了ViewManager。 public interface ViewManager { public void addView(View view, ViewGroup.LayoutParams params); public void updateViewLayout(View view, ViewGroup.LayoutParams params); public void removeView(View view); } 對開發者來說,WindowManager常用的就只有這三個功能而已,但是這三個功能已經足夠我們使用了。它可以創建一個Window并向其添加View,還可以更新Window中的View,另外如果想要刪除一個Window,那么只需要刪除它里面的View即可。由此來看,WindowManager操作Window的過程更像是在操作Window中的View。我們時常見到那種可以拖動的Window效果,其實是很好實現的,只需要根據手指的位置來設定LayoutParams中的x和y的值即可改變Window的位置。首先給View設置onTouchListener:mFloatingButton.setOnTouchListener(this)。然后在onTouch方法中不斷更新View的位置即可: public boolean onTouch(View v, MotionEvent event) { int rawX = (int) event.getRawX(); int rawY = (int) event.getRawY(); switch (event.getAction()) { case MotionEvent.ACTION_MOVE: { mLayoutParams.x = rawX; mLayoutParams.y = rawY; mWindowManager.updateViewLayout(mFloatingButton, mLayoutParams); break; } default: break; } return false; }
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看