新增礼物墙相关内容
This commit is contained in:
215
TabLayout/src/main/java/com/angcyo/tablayout/DslGravity.kt
Normal file
215
TabLayout/src/main/java/com/angcyo/tablayout/DslGravity.kt
Normal file
@@ -0,0 +1,215 @@
|
||||
package com.angcyo.tablayout
|
||||
|
||||
import android.graphics.Rect
|
||||
import android.graphics.RectF
|
||||
import android.view.Gravity
|
||||
|
||||
/**
|
||||
* [android.view.Gravity] 辅助计算类
|
||||
* Email:angcyo@126.com
|
||||
* @author angcyo
|
||||
* @date 2019/12/13
|
||||
* Copyright (c) 2019 ShenZhen O&M Cloud Co., Ltd. All rights reserved.
|
||||
*/
|
||||
class DslGravity {
|
||||
|
||||
/**束缚范围*/
|
||||
val gravityBounds: RectF = RectF()
|
||||
|
||||
/**束缚重力*/
|
||||
var gravity: Int = Gravity.LEFT or Gravity.TOP
|
||||
|
||||
/**使用中心坐标作为定位参考, 否则就是四条边*/
|
||||
var gravityRelativeCenter: Boolean = true
|
||||
|
||||
/**额外偏移距离, 会根据[Gravity]自动取负值*/
|
||||
var gravityOffsetX: Int = 0
|
||||
var gravityOffsetY: Int = 0
|
||||
|
||||
fun setGravityBounds(rectF: RectF) {
|
||||
gravityBounds.set(rectF)
|
||||
}
|
||||
|
||||
fun setGravityBounds(rect: Rect) {
|
||||
gravityBounds.set(rect)
|
||||
}
|
||||
|
||||
fun setGravityBounds(
|
||||
left: Int,
|
||||
top: Int,
|
||||
right: Int,
|
||||
bottom: Int
|
||||
) {
|
||||
gravityBounds.set(left.toFloat(), top.toFloat(), right.toFloat(), bottom.toFloat())
|
||||
}
|
||||
|
||||
fun setGravityBounds(
|
||||
left: Float,
|
||||
top: Float,
|
||||
right: Float,
|
||||
bottom: Float
|
||||
) {
|
||||
gravityBounds.set(left, top, right, bottom)
|
||||
}
|
||||
|
||||
//计算后的属性
|
||||
var _horizontalGravity: Int = Gravity.LEFT
|
||||
var _verticalGravity: Int = Gravity.TOP
|
||||
var _isCenterGravity: Boolean = false
|
||||
var _targetWidth = 0f
|
||||
var _targetHeight = 0f
|
||||
var _gravityLeft = 0
|
||||
var _gravityTop = 0
|
||||
var _gravityRight = 0
|
||||
var _gravityBottom = 0
|
||||
|
||||
//根据gravity调整后的offset
|
||||
var _gravityOffsetX = 0
|
||||
var _gravityOffsetY = 0
|
||||
|
||||
/**根据[gravity]返回在[gravityBounds]中的[left] [top]位置*/
|
||||
fun applyGravity(
|
||||
width: Float = _targetWidth,
|
||||
height: Float = _targetHeight,
|
||||
callback: (centerX: Int, centerY: Int) -> Unit
|
||||
) {
|
||||
|
||||
_targetWidth = width
|
||||
_targetHeight = height
|
||||
|
||||
val layoutDirection = 0
|
||||
val absoluteGravity = Gravity.getAbsoluteGravity(gravity, layoutDirection)
|
||||
val verticalGravity = gravity and Gravity.VERTICAL_GRAVITY_MASK
|
||||
val horizontalGravity = absoluteGravity and Gravity.HORIZONTAL_GRAVITY_MASK
|
||||
|
||||
//调整offset
|
||||
_gravityOffsetX = when (horizontalGravity) {
|
||||
Gravity.RIGHT -> -gravityOffsetX
|
||||
Gravity.END -> -gravityOffsetX
|
||||
else -> gravityOffsetX
|
||||
}
|
||||
_gravityOffsetY = when (verticalGravity) {
|
||||
Gravity.BOTTOM -> -gravityOffsetY
|
||||
else -> gravityOffsetY
|
||||
}
|
||||
|
||||
//计算居中的坐标
|
||||
val centerX = when (horizontalGravity) {
|
||||
Gravity.CENTER_HORIZONTAL -> (gravityBounds.left + gravityBounds.width() / 2 + _gravityOffsetX).toInt()
|
||||
Gravity.RIGHT -> (gravityBounds.right + _gravityOffsetX - if (gravityRelativeCenter) 0f else _targetWidth / 2).toInt()
|
||||
Gravity.END -> (gravityBounds.right + _gravityOffsetX - if (gravityRelativeCenter) 0f else _targetWidth / 2).toInt()
|
||||
else -> (gravityBounds.left + _gravityOffsetX + if (gravityRelativeCenter) 0f else _targetWidth / 2).toInt()
|
||||
}
|
||||
|
||||
val centerY = when (verticalGravity) {
|
||||
Gravity.CENTER_VERTICAL -> (gravityBounds.top + gravityBounds.height() / 2 + _gravityOffsetY).toInt()
|
||||
Gravity.BOTTOM -> (gravityBounds.bottom + _gravityOffsetY - if (gravityRelativeCenter) 0f else _targetHeight / 2).toInt()
|
||||
else -> (gravityBounds.top + _gravityOffsetY + if (gravityRelativeCenter) 0f else _targetHeight / 2).toInt()
|
||||
}
|
||||
|
||||
//缓存
|
||||
_horizontalGravity = horizontalGravity
|
||||
_verticalGravity = verticalGravity
|
||||
_isCenterGravity = horizontalGravity == Gravity.CENTER_HORIZONTAL &&
|
||||
verticalGravity == Gravity.CENTER_VERTICAL
|
||||
|
||||
_gravityLeft = (centerX - _targetWidth / 2).toInt()
|
||||
_gravityRight = (centerX + _targetWidth / 2).toInt()
|
||||
_gravityTop = (centerY - _targetHeight / 2).toInt()
|
||||
_gravityBottom = (centerY + _targetHeight / 2).toInt()
|
||||
|
||||
//回调
|
||||
callback(centerX, centerY)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认计算出的是目标中心点坐标参考距离
|
||||
* [com.angcyo.drawable.DslGravity.getGravityRelativeCenter]
|
||||
* */
|
||||
fun dslGravity(
|
||||
rect: RectF, //计算的矩形
|
||||
gravity: Int, //重力
|
||||
width: Float, //放置目标的宽度
|
||||
height: Float, //放置目标的高度
|
||||
offsetX: Int = 0, //额外的偏移,会根据[gravity]进行左右|上下取反
|
||||
offsetY: Int = 0,
|
||||
callback: (dslGravity: DslGravity, centerX: Int, centerY: Int) -> Unit
|
||||
): DslGravity {
|
||||
val _dslGravity = DslGravity()
|
||||
_dslGravity.setGravityBounds(rect)
|
||||
_config(_dslGravity, gravity, width, height, offsetX, offsetY, callback)
|
||||
return _dslGravity
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认计算出的是目标中心点坐标参考距离
|
||||
* [com.angcyo.drawable.DslGravity.getGravityRelativeCenter]
|
||||
* */
|
||||
fun dslGravity(
|
||||
rect: Rect, //计算的矩形
|
||||
gravity: Int, //重力
|
||||
width: Float, //放置目标的宽度
|
||||
height: Float, //放置目标的高度
|
||||
offsetX: Int = 0, //额外的偏移,会根据[gravity]进行左右|上下取反
|
||||
offsetY: Int = 0,
|
||||
callback: (dslGravity: DslGravity, centerX: Int, centerY: Int) -> Unit
|
||||
): DslGravity {
|
||||
val _dslGravity = DslGravity()
|
||||
_dslGravity.setGravityBounds(rect)
|
||||
_config(_dslGravity, gravity, width, height, offsetX, offsetY, callback)
|
||||
return _dslGravity
|
||||
}
|
||||
|
||||
private fun _config(
|
||||
_dslGravity: DslGravity,
|
||||
gravity: Int, //重力
|
||||
width: Float, //放置目标的宽度
|
||||
height: Float, //放置目标的高度
|
||||
offsetX: Int = 0, //额外的偏移,会根据[gravity]进行左右|上下取反
|
||||
offsetY: Int = 0,
|
||||
callback: (dslGravity: DslGravity, centerX: Int, centerY: Int) -> Unit
|
||||
) {
|
||||
_dslGravity.gravity = gravity
|
||||
_dslGravity.gravityOffsetX = offsetX
|
||||
_dslGravity.gravityOffsetY = offsetY
|
||||
_dslGravity.applyGravity(width, height) { centerX, centerY ->
|
||||
callback(_dslGravity, centerX, centerY)
|
||||
}
|
||||
}
|
||||
|
||||
/**居中*/
|
||||
fun Int.isCenter(): Boolean {
|
||||
val layoutDirection = 0
|
||||
val absoluteGravity = Gravity.getAbsoluteGravity(this, layoutDirection)
|
||||
val verticalGravity = this and Gravity.VERTICAL_GRAVITY_MASK
|
||||
val horizontalGravity = absoluteGravity and Gravity.HORIZONTAL_GRAVITY_MASK
|
||||
|
||||
return verticalGravity == Gravity.CENTER_VERTICAL && horizontalGravity == Gravity.CENTER_HORIZONTAL
|
||||
}
|
||||
|
||||
fun Int.isLeft(): Boolean {
|
||||
val layoutDirection = 0
|
||||
val absoluteGravity = Gravity.getAbsoluteGravity(this, layoutDirection)
|
||||
val horizontalGravity = absoluteGravity and Gravity.HORIZONTAL_GRAVITY_MASK
|
||||
|
||||
return horizontalGravity == Gravity.LEFT
|
||||
}
|
||||
|
||||
fun Int.isRight(): Boolean {
|
||||
val layoutDirection = 0
|
||||
val absoluteGravity = Gravity.getAbsoluteGravity(this, layoutDirection)
|
||||
val horizontalGravity = absoluteGravity and Gravity.HORIZONTAL_GRAVITY_MASK
|
||||
|
||||
return horizontalGravity == Gravity.RIGHT
|
||||
}
|
||||
|
||||
fun Int.isTop(): Boolean {
|
||||
val verticalGravity = this and Gravity.VERTICAL_GRAVITY_MASK
|
||||
return verticalGravity == Gravity.TOP
|
||||
}
|
||||
|
||||
fun Int.isBottom(): Boolean {
|
||||
val verticalGravity = this and Gravity.VERTICAL_GRAVITY_MASK
|
||||
return verticalGravity == Gravity.BOTTOM
|
||||
}
|
||||
Reference in New Issue
Block a user