上次在子線程更新UI時用了一下WindowManager.LayoutParams,當時覺得不太順手。以前都是用空參構造器,這次用了type和flag屬性,出現了意想不到的效果。也看看源碼吧,多鍛煉鍛煉。
public static class WindowManager.LayoutParams extends ViewGroup.LayoutParams implements Parcelable
WindowManager.LayoutParams是WindowManager里的靜態類,源碼兩千多行,不過大部分都是一些常量。
/** * The general type of window. There are three main classes of window主要的type分為三種: * window types: * <ul> * <li> <strong>Application windows</strong> (ranging from 應用窗口(從FIRST_APPLICATION_WINDOW到LAST_APPLICATION_WINDOW)是普通的頂層應用窗口, * {@link #FIRST_APPLICATION_WINDOW} to * {@link #LAST_APPLICATION_WINDOW}) are normal top-level application * windows. For these types of windows, the {@link #token} must be 對這類window而言,它們的token必須設置給它們所屬的activity的token * set to the token of the activity they are a part of (this will * normally be done for you if {@link #token} is null). * <li> <strong>Sub-windows</strong> (ranging from 子窗口從FIRST_SUB_WINDOW到LAST_SUB_WINDOW與另一個頂層的window * {@link #FIRST_SUB_WINDOW} to 關聯。這些window的token必須與它們依附的window的token一致。 * {@link #LAST_SUB_WINDOW}) are associated with another top-level * window. For these types of windows, the {@link #token} must be * the token of the window it is attached to. * <li> <strong>System windows</strong> (ranging from 系統窗口從FIRST_SYSTEM_WINDOW到lAST_SYSTEM_WINDOW是系統出於 * {@link #FIRST_SYSTEM_WINDOW} to 特別的目的使用的一類特殊的窗口。它們不應被應用隨意使用,而且使用時 * {@link #LAST_SYSTEM_WINDOW}) are special types of windows for 需要特殊的權限。
* use by the system for specific purposes. They should not normally
* be used by applications, and a special permission is required
* to use them.
* </ul>
實在太多了,留到后面總結吧。
周一剛好整理一下。WindowManager是個接口。源碼中是這樣介紹的:用Context.geSystemService(Context.WINDOW_SERVICE)得到WindowManager的實例,內部類LayoutParams可以通過getWindow.getAttributes()或者new出來。然后是設置參數的一些變量,例如type,flag,format,x,y等。特意對照源碼做了一個參照表格,此外,還要說一下源碼中的@hide。帶有@hide標識的方法或者接口是Android系統不想讓開發者使用的功能,是那些當前版本尚未穩定的架構。在下一個API,這些帶有@hide的方法屬性等可能得到驗證刪除@hide並予以開發者調用也有可能這些功能不合適被移除掉。因此,這些可以看做是Android下個版本的新功能的趨勢,但也可能胎死腹中,而且一般開發人員都不會用到這些。因此,LayoutParams中帶有@hide、@Deprecated的變量方法不在本文中予以收錄。
![]() |
接下來是flag:
下面是format的說明:
/** * The desired bitmap format. May be one of the constants in * {@link android.graphics.PixelFormat}. Default is OPAQUE. */bitmap格式。PixelFormat的一個常量。默認是OPAQUE public int format;
說明flag的設置決定了window能否接收鍵盤輸入:
/** * Given a particular set of window manager flags, determine whether * such a window may be a target for an input method when it has * focus. In particular, this checks the * {@link #FLAG_NOT_FOCUSABLE} and {@link #FLAG_ALT_FOCUSABLE_IM} * flags and returns true if the combination of the two corresponds * to a window that needs to be behind the input method so that the * user can type into it. * * @param flags The current window manager flags. * * @return Returns true if such a window should be behind/interact * with an input method, false if not. */ public static boolean mayUseInputMethod(int flags) { switch (flags&(FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM)) { case 0: case FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM: return true; } return false; }
softInputMode:輸入法模式,也可以在theme的WindowSoftInputMode設置。
/** * Desired operating mode for any soft input area. May be any combination * of: * * <ul> * <li> One of the visibility states * {@link #SOFT_INPUT_STATE_UNSPECIFIED}, {@link #SOFT_INPUT_STATE_UNCHANGED}, * {@link #SOFT_INPUT_STATE_HIDDEN}, {@link #SOFT_INPUT_STATE_ALWAYS_VISIBLE}, or * {@link #SOFT_INPUT_STATE_VISIBLE}. * <li> One of the adjustment options * {@link #SOFT_INPUT_ADJUST_UNSPECIFIED}, * {@link #SOFT_INPUT_ADJUST_RESIZE}, or * {@link #SOFT_INPUT_ADJUST_PAN}. * </ul> * * * <p>This flag can be controlled in your theme through the * {@link android.R.attr#windowSoftInputMode} attribute.</p> */ public int softInputMode;
Gravity:
/** * Placement of window within the screen as per {@link Gravity}. Both * {@link Gravity#apply(int, int, int, android.graphics.Rect, int, int, * android.graphics.Rect) Gravity.apply} and * {@link Gravity#applyDisplay(int, android.graphics.Rect, android.graphics.Rect) * Gravity.applyDisplay} are used during window layout, with this value * given as the desired gravity. For example you can specify * {@link Gravity#DISPLAY_CLIP_HORIZONTAL Gravity.DISPLAY_CLIP_HORIZONTAL} and * {@link Gravity#DISPLAY_CLIP_VERTICAL Gravity.DISPLAY_CLIP_VERTICAL} here * to control the behavior of * {@link Gravity#applyDisplay(int, android.graphics.Rect, android.graphics.Rect) * Gravity.applyDisplay}. * * @see Gravity */ public int gravity;
horizontalMargin:
/** * The horizontal margin, as a percentage of the container's width, * between the container and the widget. See * {@link Gravity#apply(int, int, int, android.graphics.Rect, int, int, * android.graphics.Rect) Gravity.apply} for how this is used. This * field is added with {@link #x} to supply the <var>xAdj</var> parameter. */ public float horizontalMargin;
verticalMargin:
/** * The vertical margin, as a percentage of the container's height, * between the container and the widget. See * {@link Gravity#apply(int, int, int, android.graphics.Rect, int, int, * android.graphics.Rect) Gravity.apply} for how this is used. This * field is added with {@link #y} to supply the <var>yAdj</var> parameter. */ public float verticalMargin;
動畫:必須使用系統資源,不能使用應用內自定義的動畫。
/** * A style resource defining the animations to use for this window. * This must be a system resource; it can not be an application resource * because the window manager does not have access to applications. */ public int windowAnimations;
還有一些window屬性不再一一列舉:
/** * An alpha value to apply to this entire window. * An alpha of 1.0 means fully opaque and 0.0 means fully transparent */ public float alpha = 1.0f; /** * When {@link #FLAG_DIM_BEHIND} is set, this is the amount of dimming * to apply. Range is from 1.0 for completely opaque to 0.0 for no * dim. */ public float dimAmount = 1.0f;
當然,還發現了一個屬性,systemUiVisibility:
/** * Control the visibility of the status bar. * * @see View#STATUS_BAR_VISIBLE * @see View#STATUS_BAR_HIDDEN */ public int systemUiVisibility;
源碼中介紹這個變量可以控制狀態欄的visibility,接着跳到View.STATUS_BAR_HIDDEN看看。
/** * @deprecated Use {@link #SYSTEM_UI_FLAG_LOW_PROFILE} instead. */ public static final int STATUS_BAR_HIDDEN = SYSTEM_UI_FLAG_LOW_PROFILE;
發現已經被棄用了,SYSTEM_UI_FLAG_LOW_PROFILE替代了它。
/** * Flag for {@link #setSystemUiVisibility(int)}: View has requested the * system UI to enter an unobtrusive "low profile" mode. * * <p>This is for use in games, book readers, video players, or any other * "immersive" application where the usual system chrome is deemed too distracting. * * <p>In low profile mode, the status bar and/or navigation icons may dim. * * @see #setSystemUiVisibility(int) */ public static final int SYSTEM_UI_FLAG_LOW_PROFILE = 0x00000001;
從這一段介紹看出,這個常量是在setSystemUiVisibility()傳入的參數,竟然涉及到了沉浸式模式:用在游戲,電子書閱讀或者任何“身臨其境”的應用,而在一般的系統瀏覽器中被認為是太分心的。這個留在下一篇博客細說吧,還打算封一個工具庫。
好的,內容非常的多,但不怎么常用。
人往高處走,水往低處流。