1
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
## 1.0.0(2024-06-07)
|
||||
|
||||
### 新增
|
||||
- 实现键盘高度实时监听核心功能
|
||||
- 添加安全区域高度自动计算逻辑
|
||||
|
||||
### 优化
|
||||
- 重构readme文档结构,增加使用示例章节
|
||||
- 完善TS类型声明文件
|
||||
|
||||
### 兼容
|
||||
- 支持Android/iOS双平台键盘监听
|
||||
@@ -0,0 +1,83 @@
|
||||
{
|
||||
"id": "x-keyboardheightchange-s",
|
||||
"displayName": "x-keyboardheightchange-s",
|
||||
"version": "1.0.0",
|
||||
"description": "x-keyboardheightchange-s",
|
||||
"keywords": [
|
||||
"x-keyboardheightchange-s"
|
||||
],
|
||||
"repository": "",
|
||||
"engines": {
|
||||
"HBuilderX": "^3.6.8"
|
||||
},
|
||||
"dcloudext": {
|
||||
"type": "uts",
|
||||
"sale": {
|
||||
"regular": {
|
||||
"price": "0.00"
|
||||
},
|
||||
"sourcecode": {
|
||||
"price": "0.00"
|
||||
}
|
||||
},
|
||||
"contact": {
|
||||
"qq": ""
|
||||
},
|
||||
"declaration": {
|
||||
"ads": "",
|
||||
"data": "",
|
||||
"permissions": ""
|
||||
},
|
||||
"npmurl": ""
|
||||
},
|
||||
"uni_modules": {
|
||||
"dependencies": [],
|
||||
"encrypt": [],
|
||||
"platforms": {
|
||||
"cloud": {
|
||||
"tcb": "u",
|
||||
"aliyun": "u",
|
||||
"alipay": "u"
|
||||
},
|
||||
"client": {
|
||||
"Vue": {
|
||||
"vue2": "u",
|
||||
"vue3": "u"
|
||||
},
|
||||
"App": {
|
||||
"app-android": "u",
|
||||
"app-ios": "u",
|
||||
"app-harmony": "u"
|
||||
},
|
||||
"H5-mobile": {
|
||||
"Safari": "u",
|
||||
"Android Browser": "u",
|
||||
"微信浏览器(Android)": "u",
|
||||
"QQ浏览器(Android)": "u"
|
||||
},
|
||||
"H5-pc": {
|
||||
"Chrome": "u",
|
||||
"IE": "u",
|
||||
"Edge": "u",
|
||||
"Firefox": "u",
|
||||
"Safari": "u"
|
||||
},
|
||||
"小程序": {
|
||||
"微信": "u",
|
||||
"阿里": "u",
|
||||
"百度": "u",
|
||||
"字节跳动": "u",
|
||||
"QQ": "u",
|
||||
"钉钉": "u",
|
||||
"快手": "u",
|
||||
"飞书": "u",
|
||||
"京东": "u"
|
||||
},
|
||||
"快应用": {
|
||||
"华为": "u",
|
||||
"联盟": "u"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
# x-keyboardheightchange-s
|
||||
|
||||
### 开发文档
|
||||
[TMUI4.0文档](https://xui.tmui.design/)
|
||||
[TMUI4.0组件库](https://ext.dcloud.net.cn/plugin?id=16369)
|
||||
|
||||
### 介绍
|
||||
|
||||
`x-keyboardheightchange-s` 是一个用于监听键盘高度变化的UTS插件,可以实时获取键盘弹出和收起时的高度变化,方便开发者处理键盘遮挡UI的问题。该插件会自动处理安全区域高度,返回实际可用的键盘高度值。
|
||||
|
||||
### 兼容性
|
||||
|
||||
| IOS | Android | WEB | 小程序 |
|
||||
| --- | --- | --- | --- |
|
||||
| 支持 | 支持 | x | x |
|
||||
|
||||
### API 说明
|
||||
|
||||
#### keyboardHeightChange(callback)
|
||||
|
||||
监听键盘高度变化,返回一个取消监听的函数。
|
||||
|
||||
**参数说明:**
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
| callback | Function | 是 | 键盘高度变化的回调函数,参数为键盘高度(单位px) |
|
||||
|
||||
**返回值:**
|
||||
|
||||
| 类型 | 说明 |
|
||||
| --- | --- |
|
||||
| Function | 取消监听的函数,调用此函数可以注销键盘高度监听 |
|
||||
|
||||
### 使用示例
|
||||
|
||||
```typescript
|
||||
// 引入模块
|
||||
import { keyboardHeightChange } from '@/uni_modules/x-keyboardheightchange-s/utssdk';
|
||||
|
||||
// 注册键盘高度监听
|
||||
const cancelKeyboardListener = keyboardHeightChange((height: number) => {
|
||||
console.log('当前键盘高度:', height);
|
||||
|
||||
// 键盘弹出
|
||||
if (height > 0) {
|
||||
// 处理键盘弹出逻辑
|
||||
}
|
||||
// 键盘收起
|
||||
else {
|
||||
// 处理键盘收起逻辑
|
||||
}
|
||||
});
|
||||
|
||||
// 在组件销毁时注销监听
|
||||
onUnload(() => {
|
||||
// 调用返回的函数取消监听
|
||||
cancelKeyboardListener();
|
||||
});
|
||||
```
|
||||
|
||||
### 注意事项
|
||||
|
||||
1. 该插件已自动处理安全区域高度,返回的高度值已减去底部安全区域高度
|
||||
2. iOS平台使用系统通知监听键盘高度变化
|
||||
3. Android平台通过原生方法监听键盘高度变化
|
||||
4. 只有当键盘高度发生变化时才会触发回调
|
||||
5. 键盘收起时,回调函数的参数为0
|
||||
6. 请务必在组件销毁时调用返回的取消函数,避免内存泄漏
|
||||
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"minSdkVersion": "21"
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
|
||||
import keyboardHeightChangeByKt from 'uts.sdk.modules.utsXKeyboardheightchangeS.keyboardHeightChangeByKt';
|
||||
|
||||
|
||||
// 监听键盘高度变化
|
||||
@UTSJS.keepAlive
|
||||
export const keyboardHeightChange = (callback : (h : number) => void):()=>void => {
|
||||
const cancelFun = keyboardHeightChangeByKt(UTSAndroid.getUniActivity()!,(keyboardHeight:Int)=>{
|
||||
callback(UTSAndroid.devicePX2px(keyboardHeight))
|
||||
});
|
||||
const cancel = ()=>{
|
||||
cancelFun()
|
||||
};
|
||||
return cancel;
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
package uts.sdk.modules.utsXKeyboardheightchangeS
|
||||
import android.app.Activity
|
||||
import android.graphics.Rect
|
||||
import android.os.Build
|
||||
import android.view.View
|
||||
import android.view.ViewTreeObserver
|
||||
import android.view.WindowInsets
|
||||
|
||||
typealias cacelCallBack = () -> Unit
|
||||
|
||||
fun keyboardHeightChangeByKt(activity: Activity, callback: (height: Int) -> Unit): cacelCallBack {
|
||||
val rootView = activity.window.decorView.rootView
|
||||
val rect = Rect()
|
||||
var lastHeight = 0
|
||||
|
||||
val listener = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
// Android 11及以上使用WindowInsets API
|
||||
View.OnApplyWindowInsetsListener { _, insets ->
|
||||
val imeHeight = insets.getInsets(WindowInsets.Type.ime()).bottom
|
||||
val navigationBarHeight = insets.getInsets(WindowInsets.Type.navigationBars()).bottom
|
||||
val keyboardHeight = if (imeHeight > 0) imeHeight - navigationBarHeight else 0
|
||||
|
||||
if (keyboardHeight != lastHeight) {
|
||||
lastHeight = keyboardHeight
|
||||
callback(keyboardHeight)
|
||||
}
|
||||
insets
|
||||
}
|
||||
} else {
|
||||
// Android 5.0 - Android 10使用传统方法
|
||||
ViewTreeObserver.OnGlobalLayoutListener {
|
||||
rootView.getWindowVisibleDisplayFrame(rect)
|
||||
val screenHeight = rootView.height
|
||||
val keyboardHeight = screenHeight - rect.bottom
|
||||
|
||||
// 考虑导航栏高度
|
||||
val navigationBarHeight = getNavigationBarHeight(activity)
|
||||
|
||||
val actualKeyboardHeight = if (keyboardHeight > navigationBarHeight) {
|
||||
keyboardHeight - navigationBarHeight
|
||||
} else 0
|
||||
|
||||
if (actualKeyboardHeight != lastHeight) {
|
||||
lastHeight = actualKeyboardHeight
|
||||
callback(actualKeyboardHeight)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
rootView.setOnApplyWindowInsetsListener(listener as View.OnApplyWindowInsetsListener)
|
||||
} else {
|
||||
rootView.viewTreeObserver.addOnGlobalLayoutListener(listener as ViewTreeObserver.OnGlobalLayoutListener)
|
||||
}
|
||||
|
||||
return {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
rootView.setOnApplyWindowInsetsListener(null)
|
||||
} else {
|
||||
rootView.viewTreeObserver.removeOnGlobalLayoutListener(listener as ViewTreeObserver.OnGlobalLayoutListener)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 添加原生方法检测导航栏高度
|
||||
private fun getNavigationBarHeight(activity: Activity): Int {
|
||||
val resources = activity.resources
|
||||
val resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android")
|
||||
return if (resourceId > 0 && hasNavigationBar(activity)) {
|
||||
resources.getDimensionPixelSize(resourceId)
|
||||
} else 0
|
||||
}
|
||||
|
||||
// 检测设备是否有导航栏
|
||||
private fun hasNavigationBar(activity: Activity): Boolean {
|
||||
val windowManager = activity.windowManager
|
||||
val d = windowManager.defaultDisplay
|
||||
|
||||
val realDisplayMetrics = android.util.DisplayMetrics()
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
||||
d.getRealMetrics(realDisplayMetrics)
|
||||
}
|
||||
|
||||
val displayMetrics = android.util.DisplayMetrics()
|
||||
d.getMetrics(displayMetrics)
|
||||
|
||||
return realDisplayMetrics.heightPixels > displayMetrics.heightPixels
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"deploymentTarget": "12"
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
import { NotificationCenter, OperationQueue, Notification } from "Foundation";
|
||||
import { UIResponder } from "UIKit";
|
||||
import { CGRect } from "CoreFoundation";
|
||||
|
||||
// 监听键盘高度变化
|
||||
@UTSJS.keepAlive
|
||||
export function keyboardHeightChange(callback : (h : number) => void):()=>void {
|
||||
let lastHeight = 0
|
||||
const showObserver = NotificationCenter.default.addObserver(
|
||||
forName = UIResponder.keyboardWillShowNotification,
|
||||
object= null,
|
||||
queue= OperationQueue.main,
|
||||
using = (notification:Notification)=>{
|
||||
if(notification==null) return;
|
||||
let keyboardFrame = notification.userInfo?.get(UIResponder.keyboardFrameEndUserInfoKey) as CGRect|null
|
||||
if(keyboardFrame==null) return;
|
||||
const keyGrect = keyboardFrame! as CGRect;
|
||||
let keyboardheight = keyGrect.height
|
||||
|
||||
// 计算实际键盘高度(减去安全区域)
|
||||
let actualKeyboardHeight = Math.max(0, Number(keyboardheight) - uni.getWindowInfo().safeAreaInsets.bottom)
|
||||
// 只有当高度变化时才回调
|
||||
if(actualKeyboardHeight != lastHeight) {
|
||||
lastHeight = actualKeyboardHeight
|
||||
DispatchQueue.main.async(execute = () : void => {
|
||||
callback(actualKeyboardHeight)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
)
|
||||
|
||||
const hideObserver = NotificationCenter.default.addObserver(
|
||||
forName = UIResponder.keyboardWillHideNotification,
|
||||
object= null,
|
||||
queue= OperationQueue.main,
|
||||
using = (_:Foundation.Notification)=>{
|
||||
if(lastHeight != 0) {
|
||||
lastHeight = 0
|
||||
DispatchQueue.main.async(execute = () : void => {
|
||||
callback(0)
|
||||
})
|
||||
}
|
||||
}
|
||||
)
|
||||
const cancel = ()=>{
|
||||
NotificationCenter.default.removeObserver(showObserver)
|
||||
NotificationCenter.default.removeObserver(hideObserver)
|
||||
};
|
||||
return cancel
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
type cacelCall = () => void;
|
||||
export const keyboardHeightChange = (callback : (h : number) => void) : cacelCall => {
|
||||
const fun = (result) => {
|
||||
callback(result.height)
|
||||
}
|
||||
wx.onKeyboardHeightChange(fun)
|
||||
return () => {
|
||||
wx.offKeyboardHeightChange(fun)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
type cacelCall = () => void;
|
||||
export const keyboardHeightChange = (callback : (h : number) => void) : cacelCall => {
|
||||
|
||||
|
||||
|
||||
return () => {
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user