标签: WindowManager

浮窗WindowManager view返回和Home按键事件监听

出于功能需求,需要在所有的view之上显示浮窗,于是需要在WindowManager的View上处理返回键的响应,

mFloatingWindowView =  layoutInflater.inflate(R.layout.floating_window, null, false);


mFloatingWindowLayoutParams = new WindowManager.LayoutParams();
  // 设置window type
        mUserConversationWindowParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;

        mUserConversationWindowParams.format = PixelFormat.TRANSLUCENT;// 设置图片格式,效果为背景透明

        // 设置Window flag
        mUserConversationWindowParams.flags =
                //可使用FLAG_DISMISS_KEYGUARD选项直接解除非加锁的锁屏状态。此选项只用于*顶层的全屏幕窗口。
                WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
                
                        | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL   //必须  设置窗口不拦截窗口范围之外事件
                    
                         |WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH  // 必须  设置在有FLAG_NOT_TOUCH_MODAL属性时,窗口之外事件发生时自己也获取事件

                        | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
mWindowManager.addView(mFloatingWindowView, mFloatingWindowLayoutParams);

这里千万要注意不能用WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,我就是死在这上面的,如果设置成FLAG_NOT_FOCUSABLE,死都收不到返回键的事件的!

 

import android.content.Context;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.widget.LinearLayout;

/**
 * Created by KB-Shirlman on 4/26/2016.
 */
public class FloatingWindowView extends LinearLayout {
    public FloatingWindowView(Context context) {
        super(context);
    }

    public FloatingWindowView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public FloatingWindowView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        if (event.getKeyCode() == KeyEvent.KEYCODE_BACK
                || event.getKeyCode() == KeyEvent.KEYCODE_SETTINGS) {
if(event.getAction()==KeyEvent.ACTION_DOWN){   //按键  按下和移开会有两个不同的事件所以需要区分
          closecao();   //点击返回 要执行的方法
}
} return super.dispatchKeyEvent(event); }  }

 

floating_window.xml

下面附赠哪都能搜索的到的WidnowManager Home按键监听。

打开浮窗时调用:

关闭浮窗时调用:

WindowManager.LayoutParams全解

WindowManager.LayoutParams全解

public static class

WindowManager.LayoutParams

extends ViewGroup.LayoutParams
implements Parcelable

java.lang.Object
   ? android.view.ViewGroup.LayoutParams
   ? android.view.WindowManager.LayoutParams

WindowManager.LayoutParams 是 WindowManager 接口的嵌套类;它继承于 ViewGroup.LayoutParams; 它用于向WindowManager描述Window的管理策略。

主要成员常量
Window flag系列
该系列主要用于对Window的flag进行设置。设置Window的flag,可以直接对Window的getAttributes()得到其 WindowManager.LayoutParams对象,然后直接对它flag变量操作。也可以Window的addFlags(int flags)方法,setFlags(int flags, int mask)方法,clearFlags(int flags)方法进行操作。
比如设置全屏:
 Window window = getWindow();
 WindowManager.LayoutParams winParams = win.getAttributes();
 winParams.flags=winParams.flags|WindowManager.LayoutParams.FLAG_FULLSCREEN;
 或
 window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
 或
 window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
 取消全屏
 Window window = getWindow();
 winParams.flags=winParams.flags&~WindowManager.LayoutParams.FLAG_FULLSCREEN;
 或
 window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
 或
window.setFlags(0, WindowManager.LayoutParams.FLAG_FULLSCREEN);
所有Window flag如下:
int FLAGS_CHANGED 用于表示flags发生了变化,关于此的详细内容请看后文。
int FLAG_ALLOW_LOCK_WHILE_SCREEN_ON Window flag: as long as this window is visible to the user, allow the lock screen to activate while the screen is on.
当该window对用户可见的时候,允许锁屏。
int FLAG_ALT_FOCUSABLE_IM Window flag: invert the state of FLAG_NOT_FOCUSABLE with respect to how this window interacts with the current method.
int FLAG_BLUR_BEHIND Window flag: blur everything behind this window.
让该window后所有东西都模糊(blur)
int FLAG_DIM_BEHIND Window flag: everything behind this window will be dimmed.
让该window后所有的东西都成暗淡(dim)
int FLAG_DISMISS_KEYGUARD Window flag: when set the window will cause the keyguard to be dismissed,
only if it is not a secure lock keyguard.
int FLAG_DITHER Window flag: turn on dithering when compositing this window to the screen.
开启抖动(dithering)
int FLAG_FORCE_NOT_FULLSCREEN Window flag: Override {@link #FLAG_FULLSCREEN and force the screen decorations (such as status bar) to be shown.
恢复window非全屏显示  (让背景不是暗淡的)
int FLAG_FULLSCREEN Window flag: Hide all screen decorations (e.g.
让window进行全屏显示
int FLAG_HARDWARE_ACCELERATED Indicates whether this window should be hardware accelerated.

对该window进行硬件加速.

该flag必须在设置你的Activity或Dialog的Content View之前进行设置,

而且如果你在mainfest文件中用android:hardwareAccelerated开启了该属性的话,那么你在程序中就不能再改变它。mainfest文件中android:hardwareAccelerated属性默认是开启的(“true”)。

int FLAG_IGNORE_CHEEK_PRESSES Window flag: intended for windows that will often be used when the user is holding the screen against their face, it will aggressively filter the event stream to prevent unintended presses in this situation that may not be desired for a particular window, when such an event stream is detected, the application will receive a CANCEL motion event to indicate this so applications can handle this accordingly by taking no action on the event until the finger is released.
int FLAG_KEEP_SCREEN_ON Window flag: as long as this window is visible to the user, keep the device’s screen turned on and bright.
当该window对用户可见时,让设备屏幕处于高亮(bright)状态。
int FLAG_LAYOUT_INSET_DECOR Window flag: a special option only for use in combination with FLAG_LAYOUT_IN_SCREEN.
int FLAG_LAYOUT_IN_SCREEN Window flag: place the window within the entire screen, ignoring decorations around the border (a.k.a.
让window占满整个手机屏幕,不留任何边界(border)
int FLAG_LAYOUT_NO_LIMITS Window flag: allow window to extend outside of the screen.
window大小不再不受手机屏幕大小限制,即window可能超出屏幕之外,这时部分内容在屏幕之外。
int FLAG_NOT_FOCUSABLE Window flag: this window won’t ever get key input focus, so the user can not send key or other button events to it.
让window不能获得焦点,这样用户快就不能向该window发送按键事件及按钮事件
int FLAG_NOT_TOUCHABLE Window flag: this window can never receive touch events.
让该window不接受触摸屏事件
int FLAG_NOT_TOUCH_MODAL Window flag: Even when this window is focusable (its {@link #FLAG_NOT_FOCUSABLE is not set),
allow any pointer events outside of the window to be sent to the windows behind it.
即使在该window在可获得焦点情况下,仍然把该window之外的任何event发送到该window之后的其他window.
int FLAG_SCALED Window flag: a special mode where the layout parameters are used to perform scaling of the surface when it is composited to the screen.
int FLAG_SECURE Window flag: don’t allow screen shots while this window is displayed.
当该window在进行显示的时候,不允许截屏。
int FLAG_SHOW_WALLPAPER Window flag: ask that the system wallpaper be shown behind your window.
在该window后显示系统的墙纸(wallpaper)
int FLAG_SHOW_WHEN_LOCKED Window flag: special flag to let windows be shown when the screen is locked.
当锁屏的时候,显示该window.
int FLAG_SPLIT_TOUCH Window flag: when set the window will accept for touch events outside of its bounds to be sent to other windows that also support split touch. When this flag is not set, the first pointer that goes down determines the window to which all subsequent touches go until all pointers go up. When this flag is set, each pointer (not necessarily the first) that goes down determines the window to which all subsequent touches of that pointer will go until that pointer goes up thereby enabling touches with multiple pointers to be split across multiple windows
当该window在可以接受触摸屏情况下,让因在该window之外,而发送到后面的window的触摸屏可以支持split touch.
int FLAG_TOUCHABLE_WHEN_WAKING Window flag: When set, if the device is asleep when the touch screen is pressed, you will receive this first touch event.
当手机处于睡眠状态时,如果屏幕被按下,那么该window将*个收到到事件
int FLAG_TURN_SCREEN_ON Window flag: when set as a window is being added or made visible, once the window has been shown then the system will poke the power manager’s user activity (as if the user had woken up the device) to turn the screen on.
当然window被显示的时候,系统将把它当做一个用户活动事件,以点亮手机屏幕。
int FLAG_WATCH_OUTSIDE_TOUCH Window flag: if you have set FLAG_NOT_TOUCH_MODAL, you can set this flag to receive a single special MotionEvent with the action MotionEvent.ACTION_OUTSIDE
for touches that occur outside of your window.
如果你设置了该flag,那么在你FLAG_NOT_TOUNCH_MODAL的情况下,即使触摸屏事件发送在该window之外,其事件被发送到了后面的window,那么该window仍然将以MotionEvent.ACTION_OUTSIDE形式收到该触摸屏事件
softInputMode系列
该系列主要用于表示softInputMode,我们可以通过WindowManager.LayoutParams的softInputMode变量直接进行设置。softInputMode只能是一个显示软键盘时的window调整方式bite与一个控制软键盘显示状态的bite的组合。
显示软键盘时的window调整方式可以是SOFT_INPUT_ADJUST_NOTHING,SOFT_INPUT_ADJUST_PAN,
SOFT_INPUT_ADJUST_RESIZE,SOFT_INPUT_ADJUST_UNSPECIFIED之一。
用于描述软键盘显示的规则可以是SOFT_INPUT_STATE_ALWAYS_HIDDEN,SOFT_INPUT_STATE_ALWAYS_VISIBLE,
SOFT_INPUT_STATE_HIDDEN,SOFT_INPUT_STATE_VISIBLE,SOFT_INPUT_STATE_UNSPECIFIED之一
关于softInputMode的更多知识请参考《软件盘的开关》
所有的softInputMode系列常量如下:
int SOFT_INPUT_ADJUST_NOTHING Adjustment option for softInputMode: set to have a window not adjust for a shown input method.
当显示软键盘时,不调整window的布局
int SOFT_INPUT_ADJUST_PAN Adjustment option for softInputMode: set to have a window pan when an input method is shown, so it doesn’t need to deal with resizing but just panned by the framework to ensure the current input focus is visible.
当显示软键盘时,调整window的空白区域来显示软键盘。即使调整空白区域,软键盘还是有可能遮挡一些有内容区域,这时用户就只有退出软键盘才能看到这些被遮挡区域并进行交互。
int SOFT_INPUT_ADJUST_RESIZE Adjustment option for softInputMode: set to allow the window to be resized when an input method is shown, so that its contents are not covered by the input method.
当显示软键盘时,调整window内的控件大小以便显示软键盘。这样的话控件可能会变形。
int SOFT_INPUT_ADJUST_UNSPECIFIED Adjustment option for softInputMode: nothing specified.
不指定显示软件盘时,window的调整方式。
int SOFT_INPUT_IS_FORWARD_NAVIGATION Bit for softInputMode: set when the user has navigated forward to the window.
表示用户导航(navigate)到了你的window
int SOFT_INPUT_MASK_ADJUST Mask for softInputMode of the bits that determine the way that the window should be adjusted to accommodate the soft input window.
显示软键盘时,用于表示window调整方式的bite的mask。
显示软键盘时的window调整方式可以是SOFT_INPUT_ADJUST_NOTHING,SOFT_INPUT_ADJUST_PAN,SOFT_INPUT_ADJUST_RESIZE,SOFT_INPUT_ADJUST_UNSPECIFIED。
用于描述软键盘显示的规则可以是SOFT_INPUT_STATE_ALWAYS_HIDDEN,SOFT_INPUT_STATE_ALWAYS_VISIBLE,
SOFT_INPUT_STATE_HIDDEN,SOFT_INPUT_STATE_VISIBLE,SOFT_INPUT_STATE_UNSPECIFIED之一
int SOFT_INPUT_MASK_STATE Mask for softInputMode of the bits that determine the desired visibility state of the soft input area for this window.
用于描述软键盘显示规则的bite的mask.
int SOFT_INPUT_MODE_CHANGED 用于表示softInputMode发生了变化。关于此的详细内容请看后文。
int SOFT_INPUT_STATE_ALWAYS_HIDDEN Visibility state for softInputMode:
please always hide any soft input area when this window receives focus.
总是隐藏软键盘。
int SOFT_INPUT_STATE_ALWAYS_VISIBLE Visibility state for softInputMode:
please always make the soft input area visible when this window receives input focus.
总是显示软键盘
int SOFT_INPUT_STATE_HIDDEN Visibility state for softInputMode:
please hide any soft input area when normally appropriate (when the user is navigating forward to your window).
用户导航(navigate)到你的窗口的时候,隐藏软键盘
int SOFT_INPUT_STATE_UNCHANGED Visibility state for softInputMode: please don’t change the state of the soft input area.
int SOFT_INPUT_STATE_UNSPECIFIED Visibility state for softInputMode: no state has been specified.
没有软键盘显示的约定规则
int SOFT_INPUT_STATE_VISIBLE Visibility state for softInputMode: please show the soft input area when normally appropriate
(when the user is navigating forward to your window).
用户导航(navigate)到你的窗口的时候,显示软键盘
Window type系列
该系列主要用于表示window的类型。我们可以通过WindowManager.LayoutParams的type变量直接进行设置.
int TYPE_APPLICATION Window type: a normal application window.
普通的应用程序window,token必须设置为Activity的token,以指出该窗口属谁
int TYPE_APPLICATION_ATTACHED_DIALOG Window type: like TYPE_APPLICATION_PANEL, but layout of the window happens as that of a top-level window, not as a child of its container.
对话框。类似于面板窗口,绘制类似于顶层窗口,而不是宿主的子窗口。
int TYPE_APPLICATION_MEDIA Window type: window for showing media (e.g.
媒体窗口,例如视频。显示于宿主窗口下层。
int TYPE_APPLICATION_PANEL Window type: a panel on top of an application window.
面板窗口,显示于宿主窗口上层
int TYPE_APPLICATION_STARTING Window type: special application window that is displayed while the application is starting.
用于应用程序启动时所显示的窗口。应用本身不要使用这种类型。它用于让系统显示些信息,直到应用程序可以开启自己的窗口
int TYPE_APPLICATION_SUB_PANEL Window type: a sub-panel on top of an application window.
应用程序窗口的子面板。显示于所有面板窗口的上层。(GUI的一般规律,越“子”越靠上)
int TYPE_BASE_APPLICATION Window type: an application window that serves as the “base” window of the overall application; all other application windows will appear on top of it.
所有程序窗口的“基地”窗口,其他应用程序窗口都显示在它上面。
int TYPE_CHANGED 表示window的类型发生了变化,关于此的详细内容请看后文。
int TYPE_INPUT_METHOD Window type: internal input methods windows, which appear above the normal UI.
内部输入法窗口,显示于普通UI之上。应用程序可重新布局以免被此窗口覆盖
int TYPE_INPUT_METHOD_DIALOG Window type: internal input methods dialog windows, which appear above the current input method window.
内部输入法对话框,显示于当前输入法窗口之上
int TYPE_KEYGUARD Window type: keyguard window.
锁屏窗口
int TYPE_KEYGUARD_DIALOG Window type: dialogs that the keyguard shows
锁屏时显示的对话框
int TYPE_PHONE Window type: phone.
电话窗口。它用于电话交互(特别是呼入)。它置于所有应用程序之上,状态栏之下。
int TYPE_PRIORITY_PHONE Window type: priority phone UI, which needs to be displayed even if the keyguard is active.
电话优先,当锁屏时显示。此窗口不能获得输入焦点,否则影响锁屏。
int TYPE_SEARCH_BAR Window type: the search bar.
搜索栏。只能有一个搜索栏;它位于屏幕上方。
int TYPE_STATUS_BAR Window type: the status bar.
状态栏类型的window。只能有一个状态栏window;它位于屏幕顶端,其他窗口都位于它下方。
int TYPE_STATUS_BAR_PANEL Window type: panel that slides out from over the status bar
状态栏的滑动面板
int TYPE_SYSTEM_ALERT Window type: system window, such as low power alert.
系统提示window,比如电池低的警告。它总是出现在应用程序窗口之上。
int TYPE_SYSTEM_DIALOG Window type: panel that slides out from the status bar
系统对话框。(例如音量调节框)
int TYPE_SYSTEM_ERROR Window type: internal system error windows, appear on top of everything they can.
系统内部错误提示,显示于所有内容之上
int TYPE_SYSTEM_OVERLAY Window type: system overlay windows, which need to be displayed on top of everything else.
系统顶层窗口。显示在其他一切内容之上。此窗口不能获得输入焦点,否则影响锁屏。
int TYPE_TOAST Window type: transient notifications.
toast类型的window
int TYPE_WALLPAPER Window type: wallpaper window,
placed behind any window that wants to sit on top of the wallpaper.
用于墙纸的window
window 的类型被分为了3大类:
Application windows (ranging from FIRST_APPLICATION_WINDOW to LAST_APPLICATION_WINDOW) are normal top-level application windows. For these types of windows, the token must be set to the token of the activity they are a part of (this will normally be done for you if token is null).
Sub-windows (ranging from FIRST_SUB_WINDOW to LAST_SUB_WINDOW) are associated with another top-level window. For these types of windows, the token must be the token of the window it is attached to.
System windows (ranging from FIRST_SYSTEM_WINDOW to 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.
系统专门定义了FIRST_APPLICATION_WINDOW , LAST_APPLICATION_WINDOW,FIRST_SUB_WINDOW, LAST_SUB_WINDOW,
FIRST_SYSTEM_WINDOW,LAST_SYSTEM_WINDOW 以表示window的3大类型的类型的取值的范围。
int FIRST_APPLICATION_WINDOW Start of window types that represent normal application windows.
Constant Value: 1 (0x00000001)
int FIRST_SUB_WINDOW Start of types of sub-windows.
Constant Value: 1000 (0x000003e8)
int FIRST_SYSTEM_WINDOW Start of system-specific window types.
Constant Value: 2000 (0x000007d0)
int LAST_APPLICATION_WINDOW End of types of application windows.
Constant Value: 99 (0x00000063)
int LAST_SUB_WINDOW End of types of sub-windows.
Constant Value: 1999 (0x000007cf)
int LAST_SYSTEM_WINDOW End of types of system windows.
Constant Value: 2999 (0x00000bb7)
关于更多请看下文《WindowManager.LayoutParams(下)》

WindowManager.LayoutParams(下)  

2011-08-07 08:08:54|  分类: Android基础 |  标签:windowmanager   |字号中小 订阅

本文参照自:http://developer.android.com/reference/android/view/WindowManager.LayoutParams.html

BRIGHTNESS系列
该系列主要用于设置window的brightness(screenBrightness/buttonBrightness)。我们可以通过WindowManager.LayoutParams的screenBrightness/buttonBrightness变量直接进行设置。
其中screenBrightness表示屏幕的brightness,而buttonBrightness表示一般按键和键盘按键的brightness
float BRIGHTNESS_OVERRIDE_FULL Value for screenBrightness and buttonBrightness
indicating that the screen or button backlight brightness should be set to the hightest value
when this window is in front.
把brightness(screenBrightness/buttonBrightness)设置到*高值。
float BRIGHTNESS_OVERRIDE_NONE Default value for screenBrightness and buttonBrightness indicating that the brightness value is not overridden for this window and normal brightness policy should be used.
不对brightness(screenBrightness/buttonBrightness)重新进行设置,采用默认的普通值。
float BRIGHTNESS_OVERRIDE_OFF Value for screenBrightness and buttonBrightness indicating that the screen or button backlight brightness should be set to the lowest value when this window is in front.
把brightness(screenBrightness/buttonBrightness)设置到*低值。
changed系列
该系列主要用于 int copyFrom (WindowManager.LayoutParams o)函数中。
在函数中,首先将用参数中传入的WindowManager.LayoutParams的信息复制到本WindowManager.LayoutParams中,然后返回一个整数,以bite形式表示调用该函数后WindowManager.LayoutParams的哪些信息发送了变化
int ALPHA_CHANGED 用于表示成员变量alpha是否被改变
int ANIMATION_CHANGED 用于表示成员变量windowAnimations是否被改变
int DIM_AMOUNT_CHANGED 用于表示成员变量dimAmount是否被改变
int FLAGS_CHANGED 用于表示成员变量flags是否被改变
int LAYOUT_CHANGED 用于表示layout是否被改变.这里的layout是指以下变量所包含的信息:
width,height,x,y, verticalMargin,verticalWeight,horizontalMargin,horizontalWeight
int SCREEN_BRIGHTNESS_CHANGED 用于表示brightness是否被改变.
这里的brightness是指以下变量对应的信息:screenBrightness,buttonBrightness
int SCREEN_ORIENTATION_CHANGED 用于表示成员变量screenOrientation是否被改变
int SOFT_INPUT_MODE_CHANGED 用于表示成员变量softInputMode是否被改变
int TITLE_CHANGED 用于表示成员变量title是否被改变
int TYPE_CHANGED 用于表示成员变量type是否被改变
int FORMAT_CHANGED Constant Value: 8 (0x00000008)
用于表示成员变量format是否被改变
成员变量
继承于ViewGroup.LayoutParams的成员变量
public int height Information about how tall the view wants to be.
public LayoutAnimationController.AnimationParameters layoutAnimationParameters Used to animate layouts.
public int width Information about how wide the view wants to be.
自身的成员变量
public static final Creator<WindowManager.LayoutParams> CREATOR
public float alpha An alpha value to apply to this entire window.
public float buttonBrightness This can be used to override the standard behavior of the button and keyboard backlights.
public float dimAmount When FLAG_DIM_BEHIND is set, this is the amount of dimming to apply.
public int flags Various behavioral options/flags.
public int format The desired bitmap format.
public int gravity Placement of window within the screen as per Gravity.
public float horizontalMargin The horizontal margin, as a percentage of the container’s width, between the container and the widget.
public float horizontalWeight Indicates how much of the extra space will be allocated horizontally to the view associated with these LayoutParams.
public int memoryType This field is deprecated. this is ignored
public String packageName Name of the package owning this window.
public float screenBrightness This can be used to override the user’s preferred brightness of the screen.
public int screenOrientation Specific orientation value for a window.
public int softInputMode Desired operating mode for any soft input area.
public int systemUiVisibility Control the visibility of the status bar.
public IBinder token Identifier for this window.
public int type The general type of window.
public float verticalMargin The vertical margin, as a percentage of the container’s height, between the container and the widget.
public float verticalWeight Indicates how much of the extra space will be allocated vertically to the view associated with these LayoutParams.
public int windowAnimations A style resource defining the animations to use for this window.
public int x X position for this window.
public int y Y position for this window.
成员函数
ublic Methods
final int copyFrom(WindowManager.LayoutParams o)
String debug(String output)

Returns a String representation of this set of layout parameters.
int describeContents()

Describe the kinds of special objects contained in this Parcelable’s marshalled representation.
final CharSequence getTitle()
static boolean mayUseInputMethod(int flags)

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.
final void setTitle(CharSequence title)
String toString()

Returns a string containing a concise, human-readable description of this object.
void writeToParcel(Parcel out, int parcelableFlags)

Flatten this object in to a Parcel.
window与软件盘交互设置WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL 同时不能设WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE

Android顶部弹出提示语的三种实现方式

Android顶部弹出提示语的三种实现方式:

WindowManager、PopupWindow、Toast

需求:在主页Activity顶部从上向下滑动出现提示条,且5秒后自动从下向上滑动消失。

自定义布局文件:layout_tips.xml

// layout_tips.xml
<LinearLayout
android:layout_width=”match_parent”
android:layout_height=”120px”
android:paddingStart=”20px”
android:paddingEnd=”20px”
android:gravity=”center”
android:background=”#cc000000″>

<TextView
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_marginTop=”30px”
android:layout_marginBottom=”30px”
android:text=”提示语”
android:textSize=”38px”
android:textColor=”@android:color/white”/>
</LinearLayout>

自定义滑动动画:

<style name=”popwindowAnimStyle” parent=”android:Animation”>
<item name=”android:windowEnterAnimation”>@anim/anim_popup_show</item>
<item name=”android:windowExitAnimation”>@anim/anim_popup_exit</item>
</style>

自定义出现动画:anim_popup_show.xml

<set xmlns:android=”http://schemas.android.com/apk/res/android”>
<translate
android:fromYDelta=”-120%”
android:toYDelta=”0″
android:duration=”400″/>
</set>

自定义消失动画:anim_popup_exit.xml

<set xmlns:android=”http://schemas.android.com/apk/res/android”>
<translate
android:fromYDelta=”0″
android:toYDelta=”-120%”
android:duration=”400″/>
</set>

一、WindowManager实现
优点:可始终显示在当前Activity内所有Fragment、Dialog之上;
缺点:若切换Activity,则被新Activity覆盖。

View contentView = LayoutInflater.from(this).inflate(R.layout.layout_tips, null);
WindowManager windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
if(windowManager != null) {
WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();
layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | //不拦截页面点击事件
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
layoutParams.format = PixelFormat.TRANSLUCENT;
layoutParams.gravity = Gravity.TOP;
layoutParams.y = (int) getResources().getDimension(R.dimen.y30);
layoutParams.height = (int) getResources().getDimension(R.dimen.y119);
layoutParams.windowAnimations = R.style.popwindowAnimStyle; //自定义动画
windowManager.addView(contentView, layoutParams);

new Handler().postDelayed(new Runnable() {
@Override
public void run() {
if(windowManager != null) {
windowManager.removeViewImmediate(contentView);
windowManager = null;
}
}
}, 3000);
}

二、PopupWindow实现
缺点:会被当前Activity新出现的Fragment、Dialog覆盖。

View contentView = LayoutInflater.from(this).inflate(R.layout.layout_tips, null);
contentView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
DisplayMetrics dm = getResources().getDisplayMetrics();
PopupWindow popupWindow = new PopupWindow(contentView, dm.widthPixels – contentView.getPaddingStart() * 2,
(int) getResources().getDimension(R.dimen.y120));
popupWindow.setOutsideTouchable(false); //点击外部区域不消失
popupWindow.setTouchable(false);
popupWindow.setBackgroundDrawable(null);
popupWindow.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED);
popupWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
popupWindow.setAnimationStyle(R.style.popwindowAnimStyle); //自定义动画
popupWindow.showAtLocation(tvShopDeviceName, Gravity.TOP | Gravity.CENTER_HORIZONTAL,
0, (int) getResources().getDimension(R.dimen.y30)); //指定顶部位置

new Handler().postDelayed(new Runnable() {
@Override
public void run() {
popupWindow.dismiss();
}
}, 3000);

三、Toast实现
优点:可始终显示在屏幕*上层,不被新Activity覆盖;
缺点:Android 7.0后无法自定义显示/隐藏动画,默认为渐隐渐现。

View contentView = LayoutInflater.from(this).inflate(R.layout.layout_tips, null);
Toast videoToast = Toast.makeText(this, “”, Toast.LENGTH_LONG);
videoToast.setGravity(Gravity.TOP | Gravity.CENTER_HORIZONTAL, 0, (int) getResources().getDimension(R.dimen.y30));
videoToast.setView(contentView);
try {
Object mTN = getField(videoToast, “mTN”);
if(mTN != null) {
Object mParams = getField(mTN, “mParams”);
if(mParams instanceof WindowManager.LayoutParams) {
WindowManager.LayoutParams params = (WindowManager.LayoutParams) mParams;
//params.windowAnimations = R.style.popwindowAnimStyle; //自定义动画无效
params.width = dm.widthPixels – contentView.getPaddingStart() * 2;
params.height = (int) getResources().getDimension(R.dimen.y120);
}
}
} catch (Exception e){
e.printStackTrace();
}
videoToast.show();

private Object getField(Object object, String fieldName)
throws NoSuchFieldException, IllegalAccessException{
Field field = object.getClass().getDeclaredField(fieldName);
if(field != null) {
field.setAccessible(true);
return field.get(object);
}
return null;
}

Android 之 Window、WindowManager 与窗口管理

其实在android中真正展示给用户的是window和view,activity在android中所其的作用主要是处理一些逻辑问题,比如生命周期的管理、建立窗口等。在android中,窗口的管理还是比较重要的一块,因为他直接负责把内容展示给用户,并和用户进行交互。响应用户的输入等。

在讲窗口管理时,有必要先说下ViewManager这个接口,这个接口主要有以下的实现子接口和实现类,分别是:WindowManager和ViewGroup里面还有三个重要的方法:

      * addView(); 

     * updateViewLayout();

     * removeView();

在WindowManager中,addView方法表示的是将主窗口中的顶级view(也就是DecorView)添加到WindowManager中,并建立会话。接下来会详细介绍。我们先来看看Window

Window:

Window是android中的窗口,表示顶级窗口的意思,也就是主窗口,它有两个实现类,PhoneWindow和MidWindow,我们一般的activity对应的主要是PhoneWindow,在activity中经常使用的setContentView等方法也是在这个里面实现的。

    @Override

    public void setContentView(View view,ViewGroup.LayoutParams params) {
        if (mContentParent == null) {
            installDecor();

        } else {
            mContentParent.removeAllViews();

        }

        mContentParent.addView(view, params);

        final Callback cb = getCallback();

        if (cb != null) {
           cb.onContentChanged();  //窗口类容发生变化时更新

        }

    }

 每个主窗口中都有一个View,称之为DecorView,是主窗口中的顶级view(实际上就是ViewGroup),在View中有两个成员变量叫做mParent、mChildren,它是用来管理view的上下级关系的。而ViewGroup是对一组View的管理。因此,在ViewGroup中建立了所有view的关系网。而*终ViewGroup附属在主窗口上。这样就很容易在窗口中通过findViewById找到具体的View了。view中的事件处理也是根据这个路径来处理的。

我们再来看看ActivityThead中的两个重要的方法(至于ActivityThead将在一篇中详细介绍):

           performLaunchActivity( );

            handleResumeActivity( );

在performLaunchActivity中,会调用activity.attach方法建立一个window, 在handleResumeActivity方法中启动activity的时候,会将主窗口加入到WindowManager中

             View decor =r.window.getDecorView();  //获得窗口的顶级View

      decor.setVisibility(View.INVISIBLE);

      ViewManager wm= a.getWindowManager();    //WindowManager继承自ViewManager

      WindowManager.LayoutParams l =r.window.getAttributes();

      a.mDecor = decor;

      l.type =WindowManager.LayoutParams.TYPE_BASE_APPLICATION;

     l.softInputMode |= forwardBit;

     if (a.mVisibleFromClient) {
         a.mWindowAdded = true;

         wm.addView(decor, l);  //实际上是把主窗口的顶级view加入到WindowMangaer

      }

我们再来看看WindowManager。

WindowManager:

WindowManager主要用来管理窗口的一些状态、属性、view增加、删除、更新、窗口顺序、消息收集和处理等。

通过Context.getSystemService(Context.WINDOW_SERVICE)的方式可以获得WindowManager的实例.

WindowManager继承自ViewManager,里面涉及到窗口管理的三个重要方法,分别是:

     * addView(); 

     * updateViewLayout();

     * removeView();  

在WindowManager中还有一个重要的静态类LayoutParams.通过它可以设置和获得当前窗口的一些属性。

我们先来看看addView()方法,在addView中,会利用LayoutParams获得window的View属性,并为每个window创建ViewRoot,ViewRoot是View和WindowManager之间的桥梁,真正把View传递给WindowManager的是通过ViewRoot的setView()方法,ViewRoot实现了View和WindowManager之间的消息传递。在将主窗口添加到WindowManger时,它首先会建立一个代理对象:

              wm=(WindowManagerImpl)context.getSystemService(Context.WINDOW_SERVICE)

并且打开会话(IWindowSession),之后Window将通过该会话与WindowManager建立联系,

来看下setView方法:

         try {

        res =sWindowSession.add(mWindow, mWindowAttributes,

         getHostVisibility(), mAttachInfo.mContentInsets);

     } catch (RemoteException e) {
         mAdded = false;

        mView = null;

         mAttachInfo.mRootView =null;

         unscheduleTraversals();

         throw newRuntimeException(“Adding window failed”, e);

      } finally {
         if (restore) {
            attrs.restore();

         }

      }

在这段代码中,ViewRoot通过IWindowSession把窗口添加到WindowManager中。ViewRoot继承了Handler,实际上它的本质就是一个Handler,窗口中View的事件处理、消息发送、回调等将通过ViewRoot来处理。

这样就完成了把窗口添加到WindowManager中,并交由WindowManager来管理窗口的view、事件、消息收集处理等。

友情链接: SITEMAP | 旋风加速器官网 | 旋风软件中心 | textarea | 黑洞加速器 | jiaohess | 老王加速器 | 烧饼哥加速器 | 小蓝鸟 | tiktok加速器 | 旋风加速度器 | 旋风加速 | quickq加速器 | 飞驰加速器 | 飞鸟加速器 | 狗急加速器 | hammer加速器 | trafficace | 原子加速器 | 葫芦加速器 | 麦旋风 | 油管加速器 | anycastly | INS加速器 | INS加速器免费版 | 免费vqn加速外网 | 旋风加速器 | 快橙加速器 | 啊哈加速器 | 迷雾通 | 优途加速器 | 海外播 | 坚果加速器 | 海外vqn加速 | 蘑菇加速器 | 毛豆加速器 | 接码平台 | 接码S | 西柚加速器 | 快柠檬加速器 | 黑洞加速 | falemon | 快橙加速器 | anycast加速器 | ibaidu | moneytreeblog | 坚果加速器 | 派币加速器 | 飞鸟加速器 | 毛豆APP | PIKPAK | 安卓vqn免费 | 一元机场加速器 | 一元机场 | 老王加速器 | 黑洞加速器 | 白石山 | 小牛加速器 | 黑洞加速 | 迷雾通官网 | 迷雾通 | 迷雾通加速器 | 十大免费加速神器 | 猎豹加速器 | 蚂蚁加速器 | 坚果加速器 | 黑洞加速 | 银河加速器 | 猎豹加速器 | 海鸥加速器 | 芒果加速器 | 小牛加速器 | 极光加速器 | 黑洞加速 | movabletype中文网 | 猎豹加速器官网 | 烧饼哥加速器官网 | 旋风加速器度器 | 哔咔漫画 | PicACG | 雷霆加速