android全局浮窗悬,下沉式通知的一种实现 | Android悬浮窗Window应用

当你浏览公众号时来了一条新消息,通知在屏幕顶部会以自顶向下动画的形式入场,而且它是跨界面的全局浮窗(效果如下图)。虽然上一篇中抽象的浮窗工具类已经能实现这个需求。但本文在此基础上再封装一些更加友好的 API 来实现下沉式通知。

c56af3c86709

跨界面浮窗

这是 Android Window 应用的第二篇,系列文章目录如下:

预定义常用位置

上一篇抽象的show()接口通过指定x、y能精确地在屏幕任意位置显示浮窗。但有时候业务需求是模糊的,比如“在屏幕右侧中间显示浮窗”。如果能新增一个 API,再预定义一些常用位置,这样业务层就可以不用关心窗口坐标的计算。

屏幕的上下左右 4 个方向是常用位置,每个位置又可以有三种gravity:起点、中点、终点。组合一下就有 12 个常用位置。

当然可以定义 12 个常量,它们的值从 0-11 。但当每个位置新增一种 gravity,则要新增 4 个常量。将上下左右的方位和 gravity 分成两组可以解决这个问题:

object FloatWindow : View.OnTouchListener {

//'方位常量组'

const val POSIITION_TOP = 1

const val POSITION_LEFT = 2

const val POSITION_RIGHT = 3

const val POSITION_BOTTOM = 4

//'gravity常量组'

const val GRAVITY_START = 100

const val GRAVITY_MID = 101

const val GRAVITY_END = 102

}

重载一个带有常用位置参数的show()函数:

object FloatWindow : View.OnTouchListener {

fun show(

context: Context,

tag: String,

windowInfo: WindowInfo? = windowInfoMap[tag],

//'新增参数:位置'

position: Int,

//'新增参数:gravity'

gravity: Int

) {

//'根据常用位置计算窗口左上角坐标,省略了计算过程'

when (position){

POSITION_TOP -> {

when (gravity) -> {

GRAVITY_START -> {...}

GRAVITY_MID -> {...}

GRAVITY_END -> {...}

else -> {...}

}

}

POSITION_LEFT -> {

when (gravity) -> {

GRAVITY_START -> {...}

GRAVITY_MID -> {...}

GRAVITY_END -> {...}

else -> {...}

}

}

POSITION_RIGHT -> {

when (gravity) -> {

GRAVITY_START -> {...}

GRAVITY_MID -> {...}

GRAVITY_END -> {...}

else -> {...}

}

}

POSITION_BOTTOM -> {

when (gravity) -> {

GRAVITY_START -> {...}

GRAVITY_MID -> {...}

GRAVITY_END -> {...}

else -> {...}

}

}

else -> {...}

}

//'将计算出的坐标传入上一篇抽象的show函数'

show( context, tag, windowInfo, x, y, false)

}

}

没毛病,但show()函数新增了两个参数,而且这两个参数得合起来才表达一个完整的语义:窗口的位置。

二进制位管理多个状态

有没有什么办法将两个参数合并成一个参数?有!更好的解决方案就藏在View的源码里:

public class View {

/*

* '状态常量'

* |-------|-------|-------|-------|

* 1 PFLAG_WANTS_FOCUS

* 1 PFLAG_FOCUSED

* 1 PFLAG_SELECTED

* 1 PFLAG_IS_ROOT_NAMESPACE

* 1 PFLAG_HAS_BOUNDS

* 1 PFLAG_DRAWN

* 1 PFLAG_DRAW_ANIMATION

* 1 PFLAG_SKIP_DRAW

* 1 PFLAG_REQUEST_TRANSPARENT_REGIONS

* 1 PFLAG_DRAWABLE_STATE_DIRTY

* 1 PFLAG_MEASURED_DIMENSION_SET

* 1 PFLAG_FORCE_LAYOUT

* 1 PFLAG_LAYOUT_REQUIRED

* 1 PFLAG_PRESSED

* 1 PFLAG_DRAWING_CACHE_VALID

* 1 PFLAG_ANIMATION_STARTED

* 1 PFLAG_SAVE_STATE_CALLED

* 1 PFLAG_ALPHA_SET

* 1 PFLAG_SCROLL_CONTAINER

* 1 PFLAG_SCROLL_CONTAINER_ADDED

* 1 PFLAG_DIRTY

* 1 PFLAG_DIRTY_MASK

* 1 PFLAG_OPAQUE_BACKGROUND

* 1 PFLAG_OPAQUE_SCROLLBARS

* 11 PFLAG_OPAQUE_MASK

* 1 PFLAG_PREPRESSED

* 1 PFLAG_CANCEL_NEXT_UP_

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值