HBuilderX

HBuilderX

极客开发工具
uni-app

uni-app

开发一次,多端覆盖
uniCloud

uniCloud

云开发平台
HTML5+

HTML5+

增强HTML5的功能体验
MUI

MUI

上万Star的前端框架

如何实现全局可调用弹窗

问题现象
应用/元服务如何实现一个全局可调用的弹窗?

背景知识
windowStage为窗口管理器,管理各个基本窗口单元。
通过CustomDialogController类显示自定义弹窗,需要使用@CustomDialog定义弹窗内容。调用弹窗时,需要new CustomDialogController(),并将@CustomDialog作为CustomDialogControllerOptions中的builder参数传入。
openCustomDialog用于创建并弹出dialogContent对应的自定义弹窗。
解决方案
实现一个全局可调用弹窗,可通过如下三种方式实现:

方案一:实现全局可调用弹窗推荐使用:不依赖UI组件的全局自定义弹出框 (openCustomDialog),示例请参考完整示例。
方案二:可使用子窗口方式实现全局可调用弹窗,实现方式如下:
在EntryAbility.ets中通过AppStorage获取窗口管理器用于后续获取Window实例实现子窗口的创建与销毁,代码如下:
import { ConfigurationConstant, UIAbility } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { window } from '@kit.ArkUI';

const DOMAIN = 0x0000;

export default class EntryAbility extends UIAbility {
onCreate(): void {
try {
this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET);
} catch (err) {
hilog.error(DOMAIN, 'testTag', 'Failed to set colorMode. Cause: %{public}s', JSON.stringify(err));
}
hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate');
}

onDestroy(): void {
hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy');
}

onWindowStageCreate(windowStage: window.WindowStage): void {
AppStorage.setOrCreate('windowStage', windowStage);
windowStage.loadContent('pages/Index', (err) => {
if (err.code) {
hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err));
return;
}
hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.');
});
}

onWindowStageDestroy(): void {
// Main window is destroyed, release UI related resources
hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');
}

onForeground(): void {
// Ability has brought to foreground
hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground');
}

onBackground(): void {
// Ability has back to background
hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground');
}
};
SubWindow.ets页面封装打开弹窗createMySubWindowFun方法,通过createSubWindow实现弹窗的弹出,使用setUIContent设置SubPage页面为子窗口加载的具体页面内容,通过moveWindowTo、resize等方法设置子窗口样式。封装deleteMySubWindowFun方法通过destroyWindow实现弹窗的关闭。代码如下:
import { window } from '@kit.ArkUI';
import { BusinessError } from '@kit.BasicServicesKit';

// 获取windowStage
let windowStage = AppStorage.get('windowStage') as window.WindowStage;
let windowClass: window.Window | undefined = undefined;

export class mySubWindow {
createMySubWindowFun(subWindowName: string) {
// 创建子窗口
windowStage.createSubWindow(subWindowName, (err: BusinessError, data) => {
windowClass = data;
data.setUIContent('pages/SubPage', () => {
// 设置子窗口左上角坐标
data.moveWindowTo(150, 300);
// 设置子窗口大小
data.resize(1000, 1000);
// 展示子窗口
data.showWindow();
});
});
}

deleteMySubWindowFun() {
if (windowClass) {
windowClass.destroyWindow();
}
}
}
SubPage.ets页面用于展示子窗页面内容,代码如下:
// 子窗口显示页面
import { mySubWindow } from '../utils/SubWindow';

@Entry
@Component
struct SubPage {
mySubWindow: mySubWindow = new mySubWindow();

build() {
Column() {
Text('子窗口页面')
.fontSize(40)
.margin({ top: 30 });
Button('点击关闭')
.onClick(() => {
this.mySubWindow.deleteMySubWindowFun();
})
.margin({ top: 100 });
}
.width('100%')
.height('100%');
}
}
Index.ets页面使用方式通过引入SubWindow页面,通过调用封装的createMySubWindowFun方法实现弹窗的打开,代码如下:
import { mySubWindow } from '../utils/SubWindow';

@Entry
@Component
struct Index {
mySubWindow: mySubWindow = new mySubWindow();

build() {
RelativeContainer() {
Text('点击打开弹窗')
.id('HelloWorld')
.fontSize(30)
.fontWeight(FontWeight.Bold)
.alignRules({
center: { anchor: 'container', align: VerticalAlign.Center },
middle: { anchor: 'container', align: HorizontalAlign.Center }
})
.onClick(() => {
this.mySubWindow.createMySubWindowFun('mySubWindow');
});
}
.height('100%')
.width('100%')
.backgroundColor('#F1F3F5');
}
}
运行效果图如下:

点击放大

方案三:通过自定义弹窗(CustomDialog)封装成自定义组件的方式:
封装弹窗控制方法Dialog.ets,使用@watch监听外部传入的变量变化,通过CustomDialogController控制弹窗的显示隐藏,代码如下:
import { CustomDialogView } from './CustomDialogView';

@Component
export struct Dialog {
// 监听外部传入的visible变量,visible值发生变化时触发onChange回调函数
@Watch('onChange') @Link visible: boolean;
onCancel?: () => void;
onConfirm?: () => void;
// 通过CustomDialogController的builder参数绑定弹窗组件CustomDialogView
private controller = new CustomDialogController({
builder: CustomDialogView({
visible: $visible,
onCancel: this.onCancel,
onConfirm: this.onConfirm,
}),
autoCancel: false,
alignment: DialogAlignment.Center,
});

// 当visible的值变化时触发回调
onChange(): void {
if (this.visible) {
this.controller.open();
} else {
this.controller.close();
}
}

// 二次封装的Dialog组件主要通过控制器控制弹窗,不需要任何界面
build() {
}
}
封装弹窗视图页面CustomDialogView.ets,作用于弹窗中作为展示页面,代码如下:
@CustomDialog
export struct CustomDialogView {
@Link visible: boolean;
controller: CustomDialogController;
// 弹窗交互事件参数,点击确认和取消按钮时的回调函数
onCancel?: () => void;
onConfirm?: () => void;

build() {
Column() {
Text('自定义弹窗')
.margin({ top: 20, bottom: 40 });
Button('点击关闭弹窗').onClick(() => {
// 重置弹窗显隐参数
this.visible = false;
// 关闭弹窗
this.controller.close();
});
}
.width('100%')
.height(200)
.backgroundColor(Color.White);
}
}
使用弹窗页面CustomDialog.ets,通过给引入的Dialog组件传入visible控制弹窗的弹出,代码如下:
import { Dialog } from './Dialog';

@Entry
@Component
export struct CustomDialog {
// 外部定义visible变量作为弹窗组件入参,控制弹窗显隐
@State visible: boolean = false;

build() {
Column({ space: 20 }) {
Button('点击打开弹窗')
// 点击修改visible变量后,visible的值可以被Dialog组件监听并响应
.onClick(() => this.visible = !this.visible)
.margin({ top: 40 });
// 通过双向绑定visible变量,实现外部控制弹窗
Dialog({
visible: $visible,
});
}
.width('100%');
}
}
运行效果图如下:

点击放大

总结
实现全局可调用弹窗可通过openCustomDialog、子窗口与自定义弹窗方式实现,openCustomDialog通过ComponentContent封装内容可以与UI界面解耦,调用更加灵活,可以满足开发者的封装诉求,优先推荐使用。子窗口方式需要使用页面当作弹窗内容且需要获取窗口管理器,代码复杂性较高。自定义弹窗方式与调用UI界面耦合性较高也不建议使用。
https://coub.com/view/4b7ub4
https://coub.com/view/4b7ub3
https://coub.com/view/4b7ub2
https://coub.com/view/4b7ub0
https://coub.com/view/4b7uay
https://coub.com/view/4b7uax
https://coub.com/view/4b7uav
https://coub.com/view/4b7uap
https://coub.com/view/4b7uao
https://coub.com/view/4b7ual
https://coub.com/view/4b7uad
https://coub.com/view/4b7uaa
https://coub.com/view/4b7ua7
https://coub.com/view/4b7ua5
https://coub.com/view/4b7ua2
https://coub.com/view/4b7ua1
https://coub.com/view/4b7u9z
https://coub.com/view/4b7u9y
https://coub.com/view/4b7u9x
https://coub.com/view/4b7u9p
https://coub.com/view/4b7u9k
https://coub.com/view/4b7u9j
https://coub.com/view/4b7u9i
https://coub.com/view/4b7u9g
https://coub.com/view/4b7u9d
https://coub.com/view/4b7u9a
https://coub.com/view/4b7u98
https://coub.com/view/4b7u96
https://coub.com/view/4b7u94
https://coub.com/view/4b7u92
https://coub.com/view/4b7u91
https://coub.com/view/4b7u8z
https://coub.com/view/4b7u8t
https://coub.com/view/4b7u8q
https://coub.com/view/4b7u8p
https://coub.com/view/4b7u8n
https://coub.com/view/4b7u8j
https://coub.com/view/4b7u8i
https://coub.com/view/4b7u78
https://coub.com/view/4b7u76
https://coub.com/view/4b7u72
https://coub.com/view/4b7u6v
https://coub.com/view/4b7u6t
https://coub.com/view/4b7u6r
https://coub.com/view/4b7u6o
https://coub.com/view/4b7u6m
https://coub.com/view/4b7u6l
https://coub.com/view/4b7u6j
https://coub.com/view/4b7u6h
https://coub.com/view/4b7u6f
https://coub.com/view/4b7u6d
https://coub.com/view/4b7u6a
https://coub.com/view/4b7u67
https://coub.com/view/4b7u65
https://coub.com/view/4b7u60
https://coub.com/view/4b7u5t
https://coub.com/view/4b7u5p
https://coub.com/view/4b7u5i
https://coub.com/view/4b7u4t
https://coub.com/view/4b7u4p
https://coub.com/view/4b7u4l
https://coub.com/view/4b7u46
https://coub.com/view/4b7u3v
https://coub.com/view/4b7u3u
https://coub.com/view/4b7u3t
https://coub.com/view/4b7u3r
https://coub.com/view/4b7u3o
https://coub.com/view/4b7u3l
https://coub.com/view/4b7u3k
https://coub.com/view/4b7u3h
https://coub.com/view/4b7u3a
https://coub.com/view/4b7u38
https://coub.com/view/4b7u35
https://coub.com/view/4b7u34
https://coub.com/view/4b7u33
https://coub.com/view/4b7u30
https://coub.com/view/4b7u2z
https://coub.com/view/4b7u2w

https://coub.com/view/4b7pz5
https://coub.com/view/4b7pz2
https://coub.com/view/4b7pyu
https://coub.com/view/4b7pyr
https://coub.com/view/4b7pyp
https://coub.com/view/4b7pym
https://coub.com/view/4b7pyk
https://coub.com/view/4b7pya
https://coub.com/view/4b7py6
https://coub.com/view/4b7py5
https://coub.com/view/4b7py2
https://coub.com/view/4b7pxi
https://coub.com/view/4b7px8
https://coub.com/view/4b7pxd
https://coub.com/view/4b7px4
https://coub.com/view/4b7px2
https://coub.com/view/4b7pwy
https://coub.com/view/4b7pwt
https://coub.com/view/4b7pwi
https://coub.com/view/4b7pwb
https://coub.com/view/4b7pvo
https://coub.com/view/4b7pvk
https://coub.com/view/4b7pvf
https://coub.com/view/4b7pvd
https://coub.com/view/4b7pv9
https://coub.com/view/4b7pv7
https://coub.com/view/4b7puz
https://coub.com/view/4b7puu
https://coub.com/view/4b7pur
https://coub.com/view/4b7puj
https://coub.com/view/4b7puf
https://coub.com/view/4b7puc
https://coub.com/view/4b7pu5
https://coub.com/view/4b7pu3
https://coub.com/view/4b7pty
https://coub.com/view/4b7ptw
https://coub.com/view/4b7ptu
https://coub.com/view/4b7ptt
https://coub.com/view/4b7ptr
https://coub.com/view/4b7ptp
https://coub.com/view/4b7ptn
https://coub.com/view/4b7ptm
https://coub.com/view/4b7ptk
https://coub.com/view/4b7ptj
https://coub.com/view/4b7ptf
https://coub.com/view/4b7ptd
https://coub.com/view/4b7ptb
https://coub.com/view/4b7pt9
https://coub.com/view/4b7pt6
https://coub.com/view/4b7psx
https://coub.com/view/4b7pso
https://coub.com/view/4b7psl
https://coub.com/view/4b7psh
https://coub.com/view/4b7psc
https://coub.com/view/4b7ps7
https://coub.com/view/4b7ps2
https://coub.com/view/4b7prv
https://coub.com/view/4b7prm
https://coub.com/view/4b7prj
https://coub.com/view/4b7pri

https://coub.com/view/4b7lh7
https://coub.com/view/4b7lh5
https://coub.com/view/4b7lh4
https://coub.com/view/4b7lh1
https://coub.com/view/4b7lh0
https://coub.com/view/4b7lgx
https://coub.com/view/4b7lgu
https://coub.com/view/4b7lgr
https://coub.com/view/4b7lgo
https://coub.com/view/4b7lgj
https://coub.com/view/4b7lgh
https://coub.com/view/4b7lgd
https://coub.com/view/4b7lgb
https://coub.com/view/4b7lg6
https://coub.com/view/4b7lg2
https://coub.com/view/4b7lfw
https://coub.com/view/4b7lft
https://coub.com/view/4b7lfn
https://coub.com/view/4b7lfh
https://coub.com/view/4b7lfa
https://coub.com/view/4b7lek
https://coub.com/view/4b7leh
https://coub.com/view/4b7lef
https://coub.com/view/4b7lec
https://coub.com/view/4b7leb
https://coub.com/view/4b7le7
https://coub.com/view/4b7le1
https://coub.com/view/4b7ldz
https://coub.com/view/4b7ldx
https://coub.com/view/4b7ldw
https://coub.com/view/4b7ldt
https://coub.com/view/4b7ldq
https://coub.com/view/4b7ldn
https://coub.com/view/4b7lda
https://coub.com/view/4b7ld8
https://coub.com/view/4b7ld4
https://coub.com/view/4b7lcz
https://coub.com/view/4b7lcv
https://coub.com/view/4b7lcq
https://coub.com/view/4b7lco
https://coub.com/view/4b7lcm
https://coub.com/view/4b7lcj
https://coub.com/view/4b7lcd
https://coub.com/view/4b7lc9
https://coub.com/view/4b7lc0
https://coub.com/view/4b7lbx
https://coub.com/view/4b7lbw
https://coub.com/view/4b7lbv
https://coub.com/view/4b7lbu
https://coub.com/view/4b7lbt
https://coub.com/view/4b7lbc
https://coub.com/view/4b7lb5
https://coub.com/view/4b7lax
https://coub.com/view/4b7laj
https://coub.com/view/4b7laf
https://coub.com/view/4b7lae
https://coub.com/view/4b7lab
https://coub.com/view/4b7la7
https://coub.com/view/4b7l9u
https://coub.com/view/4b7l9s
https://coub.com/view/4b7l9q
https://coub.com/view/4b7l9n
https://coub.com/view/4b7l9k
https://coub.com/view/4b7l9j
https://coub.com/view/4b7l9i
https://coub.com/view/4b7l9h
https://coub.com/view/4b7l9g
https://coub.com/view/4b7l9f
https://coub.com/view/4b7l99
https://coub.com/view/4b7l95
https://coub.com/view/4b7l93
https://coub.com/view/4b7l90
https://coub.com/view/4b7l8u
https://coub.com/view/4b7l8r
https://coub.com/view/4b7l8q
https://coub.com/view/4b7l8p
https://coub.com/view/4b7l8o
https://coub.com/view/4b7l8m
https://coub.com/view/4b7l8k
https://coub.com/view/4b7l8g
https://coub.com/view/4b7l8f
https://coub.com/view/4b7l8e
https://coub.com/view/4b7l8b
https://coub.com/view/4b7l88
https://coub.com/view/4b7l86
https://coub.com/view/4b7l84
https://coub.com/view/4b7l81
https://coub.com/view/4b7l7z
https://coub.com/view/4b7l7x
https://coub.com/view/4b7l7w
https://coub.com/view/4b7l7v
https://coub.com/view/4b7l7u
https://coub.com/view/4b7l7s

继续阅读 »

问题现象
应用/元服务如何实现一个全局可调用的弹窗?

背景知识
windowStage为窗口管理器,管理各个基本窗口单元。
通过CustomDialogController类显示自定义弹窗,需要使用@CustomDialog定义弹窗内容。调用弹窗时,需要new CustomDialogController(),并将@CustomDialog作为CustomDialogControllerOptions中的builder参数传入。
openCustomDialog用于创建并弹出dialogContent对应的自定义弹窗。
解决方案
实现一个全局可调用弹窗,可通过如下三种方式实现:

方案一:实现全局可调用弹窗推荐使用:不依赖UI组件的全局自定义弹出框 (openCustomDialog),示例请参考完整示例。
方案二:可使用子窗口方式实现全局可调用弹窗,实现方式如下:
在EntryAbility.ets中通过AppStorage获取窗口管理器用于后续获取Window实例实现子窗口的创建与销毁,代码如下:
import { ConfigurationConstant, UIAbility } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { window } from '@kit.ArkUI';

const DOMAIN = 0x0000;

export default class EntryAbility extends UIAbility {
onCreate(): void {
try {
this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET);
} catch (err) {
hilog.error(DOMAIN, 'testTag', 'Failed to set colorMode. Cause: %{public}s', JSON.stringify(err));
}
hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate');
}

onDestroy(): void {
hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy');
}

onWindowStageCreate(windowStage: window.WindowStage): void {
AppStorage.setOrCreate('windowStage', windowStage);
windowStage.loadContent('pages/Index', (err) => {
if (err.code) {
hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err));
return;
}
hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.');
});
}

onWindowStageDestroy(): void {
// Main window is destroyed, release UI related resources
hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');
}

onForeground(): void {
// Ability has brought to foreground
hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground');
}

onBackground(): void {
// Ability has back to background
hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground');
}
};
SubWindow.ets页面封装打开弹窗createMySubWindowFun方法,通过createSubWindow实现弹窗的弹出,使用setUIContent设置SubPage页面为子窗口加载的具体页面内容,通过moveWindowTo、resize等方法设置子窗口样式。封装deleteMySubWindowFun方法通过destroyWindow实现弹窗的关闭。代码如下:
import { window } from '@kit.ArkUI';
import { BusinessError } from '@kit.BasicServicesKit';

// 获取windowStage
let windowStage = AppStorage.get('windowStage') as window.WindowStage;
let windowClass: window.Window | undefined = undefined;

export class mySubWindow {
createMySubWindowFun(subWindowName: string) {
// 创建子窗口
windowStage.createSubWindow(subWindowName, (err: BusinessError, data) => {
windowClass = data;
data.setUIContent('pages/SubPage', () => {
// 设置子窗口左上角坐标
data.moveWindowTo(150, 300);
// 设置子窗口大小
data.resize(1000, 1000);
// 展示子窗口
data.showWindow();
});
});
}

deleteMySubWindowFun() {
if (windowClass) {
windowClass.destroyWindow();
}
}
}
SubPage.ets页面用于展示子窗页面内容,代码如下:
// 子窗口显示页面
import { mySubWindow } from '../utils/SubWindow';

@Entry
@Component
struct SubPage {
mySubWindow: mySubWindow = new mySubWindow();

build() {
Column() {
Text('子窗口页面')
.fontSize(40)
.margin({ top: 30 });
Button('点击关闭')
.onClick(() => {
this.mySubWindow.deleteMySubWindowFun();
})
.margin({ top: 100 });
}
.width('100%')
.height('100%');
}
}
Index.ets页面使用方式通过引入SubWindow页面,通过调用封装的createMySubWindowFun方法实现弹窗的打开,代码如下:
import { mySubWindow } from '../utils/SubWindow';

@Entry
@Component
struct Index {
mySubWindow: mySubWindow = new mySubWindow();

build() {
RelativeContainer() {
Text('点击打开弹窗')
.id('HelloWorld')
.fontSize(30)
.fontWeight(FontWeight.Bold)
.alignRules({
center: { anchor: 'container', align: VerticalAlign.Center },
middle: { anchor: 'container', align: HorizontalAlign.Center }
})
.onClick(() => {
this.mySubWindow.createMySubWindowFun('mySubWindow');
});
}
.height('100%')
.width('100%')
.backgroundColor('#F1F3F5');
}
}
运行效果图如下:

点击放大

方案三:通过自定义弹窗(CustomDialog)封装成自定义组件的方式:
封装弹窗控制方法Dialog.ets,使用@watch监听外部传入的变量变化,通过CustomDialogController控制弹窗的显示隐藏,代码如下:
import { CustomDialogView } from './CustomDialogView';

@Component
export struct Dialog {
// 监听外部传入的visible变量,visible值发生变化时触发onChange回调函数
@Watch('onChange') @Link visible: boolean;
onCancel?: () => void;
onConfirm?: () => void;
// 通过CustomDialogController的builder参数绑定弹窗组件CustomDialogView
private controller = new CustomDialogController({
builder: CustomDialogView({
visible: $visible,
onCancel: this.onCancel,
onConfirm: this.onConfirm,
}),
autoCancel: false,
alignment: DialogAlignment.Center,
});

// 当visible的值变化时触发回调
onChange(): void {
if (this.visible) {
this.controller.open();
} else {
this.controller.close();
}
}

// 二次封装的Dialog组件主要通过控制器控制弹窗,不需要任何界面
build() {
}
}
封装弹窗视图页面CustomDialogView.ets,作用于弹窗中作为展示页面,代码如下:
@CustomDialog
export struct CustomDialogView {
@Link visible: boolean;
controller: CustomDialogController;
// 弹窗交互事件参数,点击确认和取消按钮时的回调函数
onCancel?: () => void;
onConfirm?: () => void;

build() {
Column() {
Text('自定义弹窗')
.margin({ top: 20, bottom: 40 });
Button('点击关闭弹窗').onClick(() => {
// 重置弹窗显隐参数
this.visible = false;
// 关闭弹窗
this.controller.close();
});
}
.width('100%')
.height(200)
.backgroundColor(Color.White);
}
}
使用弹窗页面CustomDialog.ets,通过给引入的Dialog组件传入visible控制弹窗的弹出,代码如下:
import { Dialog } from './Dialog';

@Entry
@Component
export struct CustomDialog {
// 外部定义visible变量作为弹窗组件入参,控制弹窗显隐
@State visible: boolean = false;

build() {
Column({ space: 20 }) {
Button('点击打开弹窗')
// 点击修改visible变量后,visible的值可以被Dialog组件监听并响应
.onClick(() => this.visible = !this.visible)
.margin({ top: 40 });
// 通过双向绑定visible变量,实现外部控制弹窗
Dialog({
visible: $visible,
});
}
.width('100%');
}
}
运行效果图如下:

点击放大

总结
实现全局可调用弹窗可通过openCustomDialog、子窗口与自定义弹窗方式实现,openCustomDialog通过ComponentContent封装内容可以与UI界面解耦,调用更加灵活,可以满足开发者的封装诉求,优先推荐使用。子窗口方式需要使用页面当作弹窗内容且需要获取窗口管理器,代码复杂性较高。自定义弹窗方式与调用UI界面耦合性较高也不建议使用。
https://coub.com/view/4b7ub4
https://coub.com/view/4b7ub3
https://coub.com/view/4b7ub2
https://coub.com/view/4b7ub0
https://coub.com/view/4b7uay
https://coub.com/view/4b7uax
https://coub.com/view/4b7uav
https://coub.com/view/4b7uap
https://coub.com/view/4b7uao
https://coub.com/view/4b7ual
https://coub.com/view/4b7uad
https://coub.com/view/4b7uaa
https://coub.com/view/4b7ua7
https://coub.com/view/4b7ua5
https://coub.com/view/4b7ua2
https://coub.com/view/4b7ua1
https://coub.com/view/4b7u9z
https://coub.com/view/4b7u9y
https://coub.com/view/4b7u9x
https://coub.com/view/4b7u9p
https://coub.com/view/4b7u9k
https://coub.com/view/4b7u9j
https://coub.com/view/4b7u9i
https://coub.com/view/4b7u9g
https://coub.com/view/4b7u9d
https://coub.com/view/4b7u9a
https://coub.com/view/4b7u98
https://coub.com/view/4b7u96
https://coub.com/view/4b7u94
https://coub.com/view/4b7u92
https://coub.com/view/4b7u91
https://coub.com/view/4b7u8z
https://coub.com/view/4b7u8t
https://coub.com/view/4b7u8q
https://coub.com/view/4b7u8p
https://coub.com/view/4b7u8n
https://coub.com/view/4b7u8j
https://coub.com/view/4b7u8i
https://coub.com/view/4b7u78
https://coub.com/view/4b7u76
https://coub.com/view/4b7u72
https://coub.com/view/4b7u6v
https://coub.com/view/4b7u6t
https://coub.com/view/4b7u6r
https://coub.com/view/4b7u6o
https://coub.com/view/4b7u6m
https://coub.com/view/4b7u6l
https://coub.com/view/4b7u6j
https://coub.com/view/4b7u6h
https://coub.com/view/4b7u6f
https://coub.com/view/4b7u6d
https://coub.com/view/4b7u6a
https://coub.com/view/4b7u67
https://coub.com/view/4b7u65
https://coub.com/view/4b7u60
https://coub.com/view/4b7u5t
https://coub.com/view/4b7u5p
https://coub.com/view/4b7u5i
https://coub.com/view/4b7u4t
https://coub.com/view/4b7u4p
https://coub.com/view/4b7u4l
https://coub.com/view/4b7u46
https://coub.com/view/4b7u3v
https://coub.com/view/4b7u3u
https://coub.com/view/4b7u3t
https://coub.com/view/4b7u3r
https://coub.com/view/4b7u3o
https://coub.com/view/4b7u3l
https://coub.com/view/4b7u3k
https://coub.com/view/4b7u3h
https://coub.com/view/4b7u3a
https://coub.com/view/4b7u38
https://coub.com/view/4b7u35
https://coub.com/view/4b7u34
https://coub.com/view/4b7u33
https://coub.com/view/4b7u30
https://coub.com/view/4b7u2z
https://coub.com/view/4b7u2w

https://coub.com/view/4b7pz5
https://coub.com/view/4b7pz2
https://coub.com/view/4b7pyu
https://coub.com/view/4b7pyr
https://coub.com/view/4b7pyp
https://coub.com/view/4b7pym
https://coub.com/view/4b7pyk
https://coub.com/view/4b7pya
https://coub.com/view/4b7py6
https://coub.com/view/4b7py5
https://coub.com/view/4b7py2
https://coub.com/view/4b7pxi
https://coub.com/view/4b7px8
https://coub.com/view/4b7pxd
https://coub.com/view/4b7px4
https://coub.com/view/4b7px2
https://coub.com/view/4b7pwy
https://coub.com/view/4b7pwt
https://coub.com/view/4b7pwi
https://coub.com/view/4b7pwb
https://coub.com/view/4b7pvo
https://coub.com/view/4b7pvk
https://coub.com/view/4b7pvf
https://coub.com/view/4b7pvd
https://coub.com/view/4b7pv9
https://coub.com/view/4b7pv7
https://coub.com/view/4b7puz
https://coub.com/view/4b7puu
https://coub.com/view/4b7pur
https://coub.com/view/4b7puj
https://coub.com/view/4b7puf
https://coub.com/view/4b7puc
https://coub.com/view/4b7pu5
https://coub.com/view/4b7pu3
https://coub.com/view/4b7pty
https://coub.com/view/4b7ptw
https://coub.com/view/4b7ptu
https://coub.com/view/4b7ptt
https://coub.com/view/4b7ptr
https://coub.com/view/4b7ptp
https://coub.com/view/4b7ptn
https://coub.com/view/4b7ptm
https://coub.com/view/4b7ptk
https://coub.com/view/4b7ptj
https://coub.com/view/4b7ptf
https://coub.com/view/4b7ptd
https://coub.com/view/4b7ptb
https://coub.com/view/4b7pt9
https://coub.com/view/4b7pt6
https://coub.com/view/4b7psx
https://coub.com/view/4b7pso
https://coub.com/view/4b7psl
https://coub.com/view/4b7psh
https://coub.com/view/4b7psc
https://coub.com/view/4b7ps7
https://coub.com/view/4b7ps2
https://coub.com/view/4b7prv
https://coub.com/view/4b7prm
https://coub.com/view/4b7prj
https://coub.com/view/4b7pri

https://coub.com/view/4b7lh7
https://coub.com/view/4b7lh5
https://coub.com/view/4b7lh4
https://coub.com/view/4b7lh1
https://coub.com/view/4b7lh0
https://coub.com/view/4b7lgx
https://coub.com/view/4b7lgu
https://coub.com/view/4b7lgr
https://coub.com/view/4b7lgo
https://coub.com/view/4b7lgj
https://coub.com/view/4b7lgh
https://coub.com/view/4b7lgd
https://coub.com/view/4b7lgb
https://coub.com/view/4b7lg6
https://coub.com/view/4b7lg2
https://coub.com/view/4b7lfw
https://coub.com/view/4b7lft
https://coub.com/view/4b7lfn
https://coub.com/view/4b7lfh
https://coub.com/view/4b7lfa
https://coub.com/view/4b7lek
https://coub.com/view/4b7leh
https://coub.com/view/4b7lef
https://coub.com/view/4b7lec
https://coub.com/view/4b7leb
https://coub.com/view/4b7le7
https://coub.com/view/4b7le1
https://coub.com/view/4b7ldz
https://coub.com/view/4b7ldx
https://coub.com/view/4b7ldw
https://coub.com/view/4b7ldt
https://coub.com/view/4b7ldq
https://coub.com/view/4b7ldn
https://coub.com/view/4b7lda
https://coub.com/view/4b7ld8
https://coub.com/view/4b7ld4
https://coub.com/view/4b7lcz
https://coub.com/view/4b7lcv
https://coub.com/view/4b7lcq
https://coub.com/view/4b7lco
https://coub.com/view/4b7lcm
https://coub.com/view/4b7lcj
https://coub.com/view/4b7lcd
https://coub.com/view/4b7lc9
https://coub.com/view/4b7lc0
https://coub.com/view/4b7lbx
https://coub.com/view/4b7lbw
https://coub.com/view/4b7lbv
https://coub.com/view/4b7lbu
https://coub.com/view/4b7lbt
https://coub.com/view/4b7lbc
https://coub.com/view/4b7lb5
https://coub.com/view/4b7lax
https://coub.com/view/4b7laj
https://coub.com/view/4b7laf
https://coub.com/view/4b7lae
https://coub.com/view/4b7lab
https://coub.com/view/4b7la7
https://coub.com/view/4b7l9u
https://coub.com/view/4b7l9s
https://coub.com/view/4b7l9q
https://coub.com/view/4b7l9n
https://coub.com/view/4b7l9k
https://coub.com/view/4b7l9j
https://coub.com/view/4b7l9i
https://coub.com/view/4b7l9h
https://coub.com/view/4b7l9g
https://coub.com/view/4b7l9f
https://coub.com/view/4b7l99
https://coub.com/view/4b7l95
https://coub.com/view/4b7l93
https://coub.com/view/4b7l90
https://coub.com/view/4b7l8u
https://coub.com/view/4b7l8r
https://coub.com/view/4b7l8q
https://coub.com/view/4b7l8p
https://coub.com/view/4b7l8o
https://coub.com/view/4b7l8m
https://coub.com/view/4b7l8k
https://coub.com/view/4b7l8g
https://coub.com/view/4b7l8f
https://coub.com/view/4b7l8e
https://coub.com/view/4b7l8b
https://coub.com/view/4b7l88
https://coub.com/view/4b7l86
https://coub.com/view/4b7l84
https://coub.com/view/4b7l81
https://coub.com/view/4b7l7z
https://coub.com/view/4b7l7x
https://coub.com/view/4b7l7w
https://coub.com/view/4b7l7v
https://coub.com/view/4b7l7u
https://coub.com/view/4b7l7s

收起阅读 »

如何解决CustomDialog内嵌套Navigation导致弹窗无法底部对齐的问题

问题现象
当CustomDialog内部嵌套Navigation容器时,弹窗设置底部显示alignment: DialogAlignment.Bottom时失效,问题代码如下:

@CustomDialog
export struct MyDialog {
controller: CustomDialogController;

build() {
Navigation() {
Column() {
Text('我是弹窗')
.margin({ top: 20 });
}
.width('100%')
.height(200)
.backgroundColor(Color.White);
};
}
}

@Entry
@Component
struct Dialog {
myDiaController: CustomDialogController = new CustomDialogController({
builder: MyDialog({}),
customStyle: true, // 弹窗容器样式是否自定义
autoCancel: false, // 是否允许点击遮障层退出
alignment: DialogAlignment.Bottom, // 弹窗在竖直方向上的对齐,底部对齐失效
});

onPageShow(): void {
this.myDiaController.open();
}

build() {
}
}
问题现象如下:

点击放大

背景知识
CustomDialog:是一种常见的自定义弹窗方式,当其内部嵌套Navigation容器时,Navigation容器在不设置高度的情况下会默认撑满屏幕,而Navigation内部默认至上而下显示,所以导致弹窗的底部显示命令在显示效果上没有生效。

解决方案
由于Navigation在不设置高度时,默认撑满整个手机屏幕,导致嵌套Navigation的弹窗也是全屏显示,从而导致DialogAlignment.Bottom从体验上未生效。实际逻辑是弹窗已经是全屏显示,弹窗底部对齐后依旧是全屏显示。
为Navigation容器设置高度限制(本示例设置300vp),并设置背景颜色为蓝色后,可以发现弹窗为底部对齐效果:
@CustomDialog
export struct MyDialog {
controller: CustomDialogController;
pathStack: NavPathStack = new NavPathStack();

build() {
// 弹窗内使用Navigation可实现弹窗内路由跳转,从而更换弹窗内显示的页面
Navigation(this.pathStack) {
Column() {
Text('我是弹窗')
.margin({ top: 20 });
}
.width('100%')
.height(200)
.backgroundColor(Color.White);
}
.height(300)
.backgroundColor('#0a59f7');
}
}

@Entry
@Component
struct DialogDemo {
myDialogController: CustomDialogController = new CustomDialogController({
builder: MyDialog({}),
customStyle: true, // 弹窗容器样式是否自定义
autoCancel: false, // 是否允许点击遮障层退出
alignment: DialogAlignment.Bottom, // 弹窗在竖直方向上的对齐,底部对齐失效
});

onPageShow(): void {
this.myDialogController.open();
}

build() {
}
}
实现效果如下:

点击放大

上图中弹窗为白色与蓝色部分(其中白色是弹窗中子组件背景色,蓝色是弹窗背景色),弹窗底部对齐。

总结
多数情况下,父容器的大小在未设置尺寸限制的情况下默认自适应子组件大小,所以,该思维惯性会陷入一个误区:默认Navigation容器未设置尺寸时会自适应其子组件Column的高度200vp,从而默认弹窗高度是200vp、底部对齐命令未生效。而实际上,部分容器在未设置尺寸限制时会默认全屏显示,例如Navigation、Tabs等。
https://pastebin.com/WJ5W0twm
https://pastebin.com/jLpfh6jM
https://pastebin.com/NjyZTRcj
https://pastebin.com/Ez67aS1j
https://pastebin.com/PWLApZGh
https://pastebin.com/kgcxtYRV
https://pastebin.com/zm7shgpT
https://pastebin.com/Hs9GycZW
https://pastebin.com/7vv5yCtq
https://pastebin.com/ZS9f3J4Y
https://pastebin.com/46rvnNrr
https://pastebin.com/NwPLquMj
https://pastebin.com/MvzT3WtH
https://pastebin.com/s7291Kt8
https://pastebin.com/xRq94uf9
https://pastebin.com/uMBCp2ev
https://pastebin.com/BWMV3JqP
https://pastebin.com/XPfp8bc9
https://pastebin.com/nKfsMJA5
https://pastebin.com/aKp1dGqk
https://pastebin.com/h2EmDCVE
https://pastebin.com/rZVpf79t
https://pastebin.com/e0rWL4nZ
https://pastebin.com/T1rBGcwT
https://pastebin.com/GW3cpe4h
https://pastebin.com/7L9MDU8B
https://pastebin.com/DdCFC9uX
https://pastebin.com/H6JCTycv
https://pastebin.com/2rF8HFxn
https://pastebin.com/27LRXmHN
https://pastebin.com/vZNhsMEz
https://pastebin.com/EUv3D6T5
https://pastebin.com/DhBRDNpd
https://pastebin.com/LJQy75bK
https://pastebin.com/8Thp0a3g
https://pastebin.com/mHTr3cC7
https://pastebin.com/9ceFaWS0
https://pastebin.com/XfLnUar9
https://pastebin.com/2Ktya3Wm
https://pastebin.com/mMC8tKu4
https://pastebin.com/GGXKYc2R
https://pastebin.com/KjeqQ7WL
https://pastebin.com/pgkpMu3E
https://pastebin.com/WrTGvh8T
https://pastebin.com/PTmNxwCM
https://pastebin.com/nYB5PuJ3
https://pastebin.com/cPwhmWyN
https://pastebin.com/sfACvBXT
https://pastebin.com/BdWfvQ4M
https://pastebin.com/6Y4DCw3k
https://pastebin.com/uiiHmdFq
https://pastebin.com/epBnZPYr
https://pastebin.com/pzrtCDpT
https://pastebin.com/8Y7NGzus
https://pastebin.com/nEh0yKwb
https://pastebin.com/1y8Pauz0
https://pastebin.com/VBdFdQAX
https://pastebin.com/Gzsyyvan
https://pastebin.com/d6KRbrEp
https://pastebin.com/digDdLJy
https://pastebin.com/vXZwSt7S
https://pastebin.com/PFArZUea
https://pastebin.com/fbtycRsf
https://pastebin.com/hZy1Ej5X
https://pastebin.com/q5Ux9M5v
https://pastebin.com/QpqL4m8e
https://pastebin.com/ryZX354t
https://pastebin.com/7fLHzGaX
https://pastebin.com/AK4yYQ8V
https://pastebin.com/K9h66hwy
https://pastebin.com/nsVap5H0
https://pastebin.com/swvzwCcG
https://pastebin.com/DWzPDMcY
https://pastebin.com/rZjvixYp
https://pastebin.com/MJAQGYNi
https://pastebin.com/gr2HUq25
https://pastebin.com/G59auG15
https://pastebin.com/USKWbQEt
https://pastebin.com/FCWwERJp
https://pastebin.com/pk8Mg2gd
https://pastebin.com/EweSwHmL
https://pastebin.com/NgbmDKYh
https://pastebin.com/dA414jhS
https://pastebin.com/4DP40dP2
https://pastebin.com/8wJ89BfG
https://pastebin.com/np7qgdcd
https://pastebin.com/waRHhrn0
https://pastebin.com/XfgUtMpu
https://pastebin.com/H2Gn2Cd2
https://pastebin.com/YghYQ0uy
https://pastebin.com/gj198nVk
https://pastebin.com/BMvr1bRK
https://pastebin.com/stJjWb7K
https://pastebin.com/PgV71Qx1
https://pastebin.com/rjS5iJhU
https://pastebin.com/naLAjPCs
https://pastebin.com/9Zd4qDyw
https://pastebin.com/NF88dyqv
https://pastebin.com/TyG5AVCY
https://pastebin.com/09sR3TSA
https://pastebin.com/GMCCXfv4
https://pastebin.com/ekY0AWb5
https://pastebin.com/ydiwskGD
https://pastebin.com/dVAGRzeJ
https://pastebin.com/iPPHqvfH
https://pastebin.com/w2dhvkWf
https://pastebin.com/mJdRLzGT
https://pastebin.com/c0bQVCVG
https://pastebin.com/QxWJcQAE
https://pastebin.com/URvark7U
https://pastebin.com/HYmjV2sW
https://pastebin.com/dxAu9Mws
https://pastebin.com/TqsS1fuf
https://pastebin.com/fD3GdwWA
https://pastebin.com/eummuY4R
https://pastebin.com/Zi6pLB5b
https://pastebin.com/AGrFQH97
https://pastebin.com/JAXJz8ue
https://pastebin.com/vDcgWd7V
https://pastebin.com/Ny9Rpnqc
https://pastebin.com/FHC1TNwz
https://pastebin.com/DAm7ysS3
https://pastebin.com/XT3ukakt
https://pastebin.com/Y8rD5b75
https://pastebin.com/p1ywR3cC
https://pastebin.com/8Bf036kt
https://pastebin.com/jQVftHBx
https://pastebin.com/n3AC806q
https://pastebin.com/HaQjLjxt
https://pastebin.com/Az91WjQy
https://pastebin.com/TuQUMZxV
https://pastebin.com/xrcq9wBE
https://pastebin.com/XUSJaa6K
https://pastebin.com/kmRpMKVd
https://pastebin.com/vJrrEp4a
https://pastebin.com/aMHtNZwQ
https://pastebin.com/hj0XLquF
https://pastebin.com/10MqCtqC
https://pastebin.com/diTK3Pbx
https://pastebin.com/8cgt7F7S
https://pastebin.com/e1VQgBmN
https://pastebin.com/fXUSWCNx
https://pastebin.com/r7rQyL9M
https://pastebin.com/21AGukpK
https://pastebin.com/g5a4KjRk
https://pastebin.com/Gha4HHQa
https://pastebin.com/UVUx04a9
https://pastebin.com/UZ8wV9iD
https://pastebin.com/fBLkWarW
https://pastebin.com/9AxDJFZh
https://pastebin.com/Ccapyvbv
https://pastebin.com/GHkYrv7E
https://pastebin.com/nLvZnY0S
https://pastebin.com/UyxZ5bTB
https://pastebin.com/nDtYHgrc
https://pastebin.com/HPsCHN5d
https://pastebin.com/cBLNxnW1
https://pastebin.com/EhH7qWW2
https://pastebin.com/ARGDwZDM
https://pastebin.com/Efm309DL
https://pastebin.com/Nty90f6F
https://pastebin.com/5vzhFkmH
https://pastebin.com/QhaJcfCq
https://pastebin.com/G6WKRLhJ
https://pastebin.com/8iWWkQ0i
https://pastebin.com/cWQWa4sy
https://pastebin.com/6KBPeVqL

继续阅读 »

问题现象
当CustomDialog内部嵌套Navigation容器时,弹窗设置底部显示alignment: DialogAlignment.Bottom时失效,问题代码如下:

@CustomDialog
export struct MyDialog {
controller: CustomDialogController;

build() {
Navigation() {
Column() {
Text('我是弹窗')
.margin({ top: 20 });
}
.width('100%')
.height(200)
.backgroundColor(Color.White);
};
}
}

@Entry
@Component
struct Dialog {
myDiaController: CustomDialogController = new CustomDialogController({
builder: MyDialog({}),
customStyle: true, // 弹窗容器样式是否自定义
autoCancel: false, // 是否允许点击遮障层退出
alignment: DialogAlignment.Bottom, // 弹窗在竖直方向上的对齐,底部对齐失效
});

onPageShow(): void {
this.myDiaController.open();
}

build() {
}
}
问题现象如下:

点击放大

背景知识
CustomDialog:是一种常见的自定义弹窗方式,当其内部嵌套Navigation容器时,Navigation容器在不设置高度的情况下会默认撑满屏幕,而Navigation内部默认至上而下显示,所以导致弹窗的底部显示命令在显示效果上没有生效。

解决方案
由于Navigation在不设置高度时,默认撑满整个手机屏幕,导致嵌套Navigation的弹窗也是全屏显示,从而导致DialogAlignment.Bottom从体验上未生效。实际逻辑是弹窗已经是全屏显示,弹窗底部对齐后依旧是全屏显示。
为Navigation容器设置高度限制(本示例设置300vp),并设置背景颜色为蓝色后,可以发现弹窗为底部对齐效果:
@CustomDialog
export struct MyDialog {
controller: CustomDialogController;
pathStack: NavPathStack = new NavPathStack();

build() {
// 弹窗内使用Navigation可实现弹窗内路由跳转,从而更换弹窗内显示的页面
Navigation(this.pathStack) {
Column() {
Text('我是弹窗')
.margin({ top: 20 });
}
.width('100%')
.height(200)
.backgroundColor(Color.White);
}
.height(300)
.backgroundColor('#0a59f7');
}
}

@Entry
@Component
struct DialogDemo {
myDialogController: CustomDialogController = new CustomDialogController({
builder: MyDialog({}),
customStyle: true, // 弹窗容器样式是否自定义
autoCancel: false, // 是否允许点击遮障层退出
alignment: DialogAlignment.Bottom, // 弹窗在竖直方向上的对齐,底部对齐失效
});

onPageShow(): void {
this.myDialogController.open();
}

build() {
}
}
实现效果如下:

点击放大

上图中弹窗为白色与蓝色部分(其中白色是弹窗中子组件背景色,蓝色是弹窗背景色),弹窗底部对齐。

总结
多数情况下,父容器的大小在未设置尺寸限制的情况下默认自适应子组件大小,所以,该思维惯性会陷入一个误区:默认Navigation容器未设置尺寸时会自适应其子组件Column的高度200vp,从而默认弹窗高度是200vp、底部对齐命令未生效。而实际上,部分容器在未设置尺寸限制时会默认全屏显示,例如Navigation、Tabs等。
https://pastebin.com/WJ5W0twm
https://pastebin.com/jLpfh6jM
https://pastebin.com/NjyZTRcj
https://pastebin.com/Ez67aS1j
https://pastebin.com/PWLApZGh
https://pastebin.com/kgcxtYRV
https://pastebin.com/zm7shgpT
https://pastebin.com/Hs9GycZW
https://pastebin.com/7vv5yCtq
https://pastebin.com/ZS9f3J4Y
https://pastebin.com/46rvnNrr
https://pastebin.com/NwPLquMj
https://pastebin.com/MvzT3WtH
https://pastebin.com/s7291Kt8
https://pastebin.com/xRq94uf9
https://pastebin.com/uMBCp2ev
https://pastebin.com/BWMV3JqP
https://pastebin.com/XPfp8bc9
https://pastebin.com/nKfsMJA5
https://pastebin.com/aKp1dGqk
https://pastebin.com/h2EmDCVE
https://pastebin.com/rZVpf79t
https://pastebin.com/e0rWL4nZ
https://pastebin.com/T1rBGcwT
https://pastebin.com/GW3cpe4h
https://pastebin.com/7L9MDU8B
https://pastebin.com/DdCFC9uX
https://pastebin.com/H6JCTycv
https://pastebin.com/2rF8HFxn
https://pastebin.com/27LRXmHN
https://pastebin.com/vZNhsMEz
https://pastebin.com/EUv3D6T5
https://pastebin.com/DhBRDNpd
https://pastebin.com/LJQy75bK
https://pastebin.com/8Thp0a3g
https://pastebin.com/mHTr3cC7
https://pastebin.com/9ceFaWS0
https://pastebin.com/XfLnUar9
https://pastebin.com/2Ktya3Wm
https://pastebin.com/mMC8tKu4
https://pastebin.com/GGXKYc2R
https://pastebin.com/KjeqQ7WL
https://pastebin.com/pgkpMu3E
https://pastebin.com/WrTGvh8T
https://pastebin.com/PTmNxwCM
https://pastebin.com/nYB5PuJ3
https://pastebin.com/cPwhmWyN
https://pastebin.com/sfACvBXT
https://pastebin.com/BdWfvQ4M
https://pastebin.com/6Y4DCw3k
https://pastebin.com/uiiHmdFq
https://pastebin.com/epBnZPYr
https://pastebin.com/pzrtCDpT
https://pastebin.com/8Y7NGzus
https://pastebin.com/nEh0yKwb
https://pastebin.com/1y8Pauz0
https://pastebin.com/VBdFdQAX
https://pastebin.com/Gzsyyvan
https://pastebin.com/d6KRbrEp
https://pastebin.com/digDdLJy
https://pastebin.com/vXZwSt7S
https://pastebin.com/PFArZUea
https://pastebin.com/fbtycRsf
https://pastebin.com/hZy1Ej5X
https://pastebin.com/q5Ux9M5v
https://pastebin.com/QpqL4m8e
https://pastebin.com/ryZX354t
https://pastebin.com/7fLHzGaX
https://pastebin.com/AK4yYQ8V
https://pastebin.com/K9h66hwy
https://pastebin.com/nsVap5H0
https://pastebin.com/swvzwCcG
https://pastebin.com/DWzPDMcY
https://pastebin.com/rZjvixYp
https://pastebin.com/MJAQGYNi
https://pastebin.com/gr2HUq25
https://pastebin.com/G59auG15
https://pastebin.com/USKWbQEt
https://pastebin.com/FCWwERJp
https://pastebin.com/pk8Mg2gd
https://pastebin.com/EweSwHmL
https://pastebin.com/NgbmDKYh
https://pastebin.com/dA414jhS
https://pastebin.com/4DP40dP2
https://pastebin.com/8wJ89BfG
https://pastebin.com/np7qgdcd
https://pastebin.com/waRHhrn0
https://pastebin.com/XfgUtMpu
https://pastebin.com/H2Gn2Cd2
https://pastebin.com/YghYQ0uy
https://pastebin.com/gj198nVk
https://pastebin.com/BMvr1bRK
https://pastebin.com/stJjWb7K
https://pastebin.com/PgV71Qx1
https://pastebin.com/rjS5iJhU
https://pastebin.com/naLAjPCs
https://pastebin.com/9Zd4qDyw
https://pastebin.com/NF88dyqv
https://pastebin.com/TyG5AVCY
https://pastebin.com/09sR3TSA
https://pastebin.com/GMCCXfv4
https://pastebin.com/ekY0AWb5
https://pastebin.com/ydiwskGD
https://pastebin.com/dVAGRzeJ
https://pastebin.com/iPPHqvfH
https://pastebin.com/w2dhvkWf
https://pastebin.com/mJdRLzGT
https://pastebin.com/c0bQVCVG
https://pastebin.com/QxWJcQAE
https://pastebin.com/URvark7U
https://pastebin.com/HYmjV2sW
https://pastebin.com/dxAu9Mws
https://pastebin.com/TqsS1fuf
https://pastebin.com/fD3GdwWA
https://pastebin.com/eummuY4R
https://pastebin.com/Zi6pLB5b
https://pastebin.com/AGrFQH97
https://pastebin.com/JAXJz8ue
https://pastebin.com/vDcgWd7V
https://pastebin.com/Ny9Rpnqc
https://pastebin.com/FHC1TNwz
https://pastebin.com/DAm7ysS3
https://pastebin.com/XT3ukakt
https://pastebin.com/Y8rD5b75
https://pastebin.com/p1ywR3cC
https://pastebin.com/8Bf036kt
https://pastebin.com/jQVftHBx
https://pastebin.com/n3AC806q
https://pastebin.com/HaQjLjxt
https://pastebin.com/Az91WjQy
https://pastebin.com/TuQUMZxV
https://pastebin.com/xrcq9wBE
https://pastebin.com/XUSJaa6K
https://pastebin.com/kmRpMKVd
https://pastebin.com/vJrrEp4a
https://pastebin.com/aMHtNZwQ
https://pastebin.com/hj0XLquF
https://pastebin.com/10MqCtqC
https://pastebin.com/diTK3Pbx
https://pastebin.com/8cgt7F7S
https://pastebin.com/e1VQgBmN
https://pastebin.com/fXUSWCNx
https://pastebin.com/r7rQyL9M
https://pastebin.com/21AGukpK
https://pastebin.com/g5a4KjRk
https://pastebin.com/Gha4HHQa
https://pastebin.com/UVUx04a9
https://pastebin.com/UZ8wV9iD
https://pastebin.com/fBLkWarW
https://pastebin.com/9AxDJFZh
https://pastebin.com/Ccapyvbv
https://pastebin.com/GHkYrv7E
https://pastebin.com/nLvZnY0S
https://pastebin.com/UyxZ5bTB
https://pastebin.com/nDtYHgrc
https://pastebin.com/HPsCHN5d
https://pastebin.com/cBLNxnW1
https://pastebin.com/EhH7qWW2
https://pastebin.com/ARGDwZDM
https://pastebin.com/Efm309DL
https://pastebin.com/Nty90f6F
https://pastebin.com/5vzhFkmH
https://pastebin.com/QhaJcfCq
https://pastebin.com/G6WKRLhJ
https://pastebin.com/8iWWkQ0i
https://pastebin.com/cWQWa4sy
https://pastebin.com/6KBPeVqL

收起阅读 »

设置Text字体颜色后,手机运行项目,字体仍显示为黑色

问题现象
在ArkTS项目中设置Text字体颜色fontColor为蓝色后,手机运行项目,字体仍显示为黑色。多台同型号手机运行同一项目,只有一台出现该问题。

解决方案
该问题的出现是由于问题手机开启了“高对比度文字”开关,开启“高对比度文字”后,所有应用的浅色背景字体均会显示为黑色。

解决方案:

关闭“设置”-“辅助功能”-“高对比度文字”开关。
如需配置应用字体颜色不跟随系统“高对比度文字”变化,可设置text.setTextHighContrast模式为TEXT_APP_DISABLE_HIGH_CONTRAST,关闭应用的文字渲染高对比度配置,该模式的优先级高于系统设置中的高对比度文字配置。此方法从HarmonyOS 6.0.0(API version 20)开始支持。
配置方法:text.setTextHighContrast(text.TextHighContrast.TEXT_APP_DISABLE_HIGH_CONTRAST)。
https://pastebin.com/kiSr7ViS
https://pastebin.com/DfFmsTgr
https://pastebin.com/ZpTK923Y
https://pastebin.com/r5GxKZiU
https://pastebin.com/1Sme9Xif
https://pastebin.com/nhPQB5jh
https://pastebin.com/bkDS62ZK
https://pastebin.com/GnfHYHCX
https://pastebin.com/7mc8djKs
https://pastebin.com/Z62QG9qf
https://pastebin.com/WuFEuVA3
https://pastebin.com/y0RRJ16S
https://pastebin.com/QduGHr3K
https://pastebin.com/bTUrRS7h
https://pastebin.com/2m1MEYA1
https://pastebin.com/Qi2YFNBR
https://pastebin.com/RhYrDWAF
https://pastebin.com/eLiFeBnv
https://pastebin.com/LScJb0vW
https://pastebin.com/tYWJRis5
https://pastebin.com/DtTCk9fw
https://pastebin.com/WyPm1wSN
https://pastebin.com/CzCfr7cA
https://pastebin.com/w8qKwxBa
https://pastebin.com/PUWuAd7s
https://pastebin.com/RB4NHQdW
https://pastebin.com/07TzPNQg
https://pastebin.com/EjAnqnKu
https://pastebin.com/fzm8KRhs
https://pastebin.com/SUjh0fU9
https://pastebin.com/vrDjKTQx
https://pastebin.com/W4vFQSn6
https://pastebin.com/9GQkNHuJ
https://pastebin.com/UHG8Ffat
https://pastebin.com/eazqdSZu
https://pastebin.com/1aS1Gc9L
https://pastebin.com/SPy3b2ds
https://pastebin.com/v2HNu0nf
https://pastebin.com/27jX3MzL
https://pastebin.com/ViUHutnk
https://pastebin.com/jeTazRhL
https://pastebin.com/GHWjfiN8
https://pastebin.com/c3evjtfA
https://pastebin.com/L0x7Z3K0
https://pastebin.com/pPmG3LyL
https://pastebin.com/e7uaA9gJ
https://pastebin.com/cciAuBdb
https://pastebin.com/HfLUh1kp
https://pastebin.com/4kqH08V5
https://pastebin.com/z8aYPvcm
https://pastebin.com/gcgkBXGT
https://pastebin.com/nwX5QJcc
https://pastebin.com/wPEM0x6E
https://pastebin.com/t430Uc81
https://pastebin.com/bwGwBwsz
https://pastebin.com/sTP0TE2Q
https://pastebin.com/DVxxu4aA
https://pastebin.com/PxNJPUM5
https://pastebin.com/id94WHZx
https://pastebin.com/j5uZy0XQ
https://pastebin.com/BbDfHQvG
https://pastebin.com/PEmem4wT
https://pastebin.com/tyTJzB65
https://pastebin.com/cdrbpJjd
https://pastebin.com/bhxp8VNY
https://pastebin.com/HKrX4Tus
https://pastebin.com/hECd8vmS
https://pastebin.com/zh61Uq6j
https://pastebin.com/uNeHHk8S
https://pastebin.com/iWWKVTLk
https://pastebin.com/agDuiejY
https://pastebin.com/JPS2m5i9
https://pastebin.com/gaLihEnP
https://pastebin.com/jwbtBGMS
https://pastebin.com/SLFeUnwL
https://pastebin.com/5x0j4vq4
https://pastebin.com/3zjakGxt
https://pastebin.com/Cbmd07DJ
https://pastebin.com/rL5DVSUH
https://pastebin.com/wvVf1DD3
https://pastebin.com/GRfyTFAx
https://pastebin.com/8S4VuPXw
https://pastebin.com/qsfRkzGx
https://pastebin.com/1jqMwUfv
https://pastebin.com/PAJQ9Eg7
https://pastebin.com/t6dF8PzU
https://pastebin.com/uJB2X2Th
https://pastebin.com/vaUsZ22U
https://pastebin.com/xfnHhPTu
https://pastebin.com/QzM4DUBs
https://pastebin.com/GWYXTE80
https://pastebin.com/kMZRt0gF
https://pastebin.com/XQ5MLV2j
https://pastebin.com/nR4u0s16
https://pastebin.com/P5KAdyKH
https://pastebin.com/0cVdBAww
https://pastebin.com/UccQWF5a
https://pastebin.com/Td1nxZnP
https://pastebin.com/zsKyKNSk
https://pastebin.com/crPUcGUa
https://pastebin.com/dbWbyABR
https://pastebin.com/2KUXTZDV
https://pastebin.com/wnCUGi8P
https://pastebin.com/KSYQ2k96
https://pastebin.com/1XAwRu0d
https://pastebin.com/1hhU1dVY
https://pastebin.com/ZLWu9y50
https://pastebin.com/RTkpMrz1
https://pastebin.com/mq5Neaw7
https://pastebin.com/pc5uGqK4
https://pastebin.com/uMdaGhxX
https://pastebin.com/9TDZSigD
https://pastebin.com/r0ZRJwwv
https://pastebin.com/pnWaz1cJ
https://pastebin.com/APyv4DWL
https://pastebin.com/nuKDnxVQ
https://pastebin.com/kCXpZGuT
https://pastebin.com/Bpv6Hfrq
https://pastebin.com/xw7ngGLz
https://pastebin.com/Xv8H8WNN
https://pastebin.com/5XCt11kA
https://pastebin.com/y5EAHX6m
https://pastebin.com/SR5KeQEy
https://pastebin.com/XK5VEeUV
https://pastebin.com/54i2zsvY
https://pastebin.com/CkjHtCP0
https://pastebin.com/0JqwyCKH
https://pastebin.com/wFB0ktyx
https://pastebin.com/DwWKEAC2
https://pastebin.com/bryfFEVG
https://pastebin.com/FP4bJvFq
https://pastebin.com/uPsUpJ5t
https://pastebin.com/jFUaKu3K
https://pastebin.com/v55AiTnz
https://pastebin.com/H35zXRUk
https://pastebin.com/xpsXDS4S
https://pastebin.com/rD5wrQjY
https://pastebin.com/avH7NBLb
https://pastebin.com/WA8AKxTu
https://pastebin.com/UhXN5y8y
https://pastebin.com/6jhE7F3N
https://pastebin.com/yfGA68YL
https://pastebin.com/3NKQPpTx
https://pastebin.com/JWmpHXsB
https://pastebin.com/insya6dQ
https://pastebin.com/QfXTarn1
https://pastebin.com/PC9r3UQ0
https://pastebin.com/4JJWbRhw
https://pastebin.com/YpCUdAqx
https://pastebin.com/VZccdHNQ
https://pastebin.com/sdNtjpk0
https://pastebin.com/dP2NcNtM
https://pastebin.com/NcWMNiVe
https://pastebin.com/VN5iarkU
https://pastebin.com/zS1MjxPB
https://pastebin.com/yu0nFyLc
https://pastebin.com/CsG3ThX0
https://pastebin.com/aw7HKMRc
https://pastebin.com/UHXaARF2
https://pastebin.com/qRP07XUZ
https://pastebin.com/2Ky10eBM
https://pastebin.com/CKkd2VWb
https://pastebin.com/DtwBvTyu
https://pastebin.com/7K4ZWutn
https://pastebin.com/dWdGEchW
https://pastebin.com/tz8DFpe8
https://pastebin.com/xS0h0yD7
https://pastebin.com/z2KZ6zbT
https://pastebin.com/uRxAmAce
https://pastebin.com/MFfaXKmR
https://pastebin.com/u9Bg7P8d
https://pastebin.com/6APdQ9gw
https://pastebin.com/L7XFHpAp
https://pastebin.com/BEMm2XX2
https://pastebin.com/4xhShRTd
https://pastebin.com/5UZqW6aZ
https://pastebin.com/BZ4qk9X8
https://pastebin.com/1n1Uc7Dk
https://pastebin.com/dAFkhkk4
https://pastebin.com/ic6nRJPQ
https://pastebin.com/YCYzAfG7
https://pastebin.com/t944pQ0j
https://pastebin.com/jKwryHTd
https://pastebin.com/5XaDsZPR
https://pastebin.com/q7fRLust
https://pastebin.com/03F01BET
https://pastebin.com/jHA2z3Va
https://pastebin.com/WWc6TfYy
https://pastebin.com/6EpsmfpX
https://pastebin.com/bdthptUt
https://pastebin.com/vxmJf5MR
https://pastebin.com/mTYMWrJN
https://pastebin.com/hRfRxt67
https://pastebin.com/fGzANLqH
https://pastebin.com/HXCSviYR
https://pastebin.com/eEPJC1aH

继续阅读 »

问题现象
在ArkTS项目中设置Text字体颜色fontColor为蓝色后,手机运行项目,字体仍显示为黑色。多台同型号手机运行同一项目,只有一台出现该问题。

解决方案
该问题的出现是由于问题手机开启了“高对比度文字”开关,开启“高对比度文字”后,所有应用的浅色背景字体均会显示为黑色。

解决方案:

关闭“设置”-“辅助功能”-“高对比度文字”开关。
如需配置应用字体颜色不跟随系统“高对比度文字”变化,可设置text.setTextHighContrast模式为TEXT_APP_DISABLE_HIGH_CONTRAST,关闭应用的文字渲染高对比度配置,该模式的优先级高于系统设置中的高对比度文字配置。此方法从HarmonyOS 6.0.0(API version 20)开始支持。
配置方法:text.setTextHighContrast(text.TextHighContrast.TEXT_APP_DISABLE_HIGH_CONTRAST)。
https://pastebin.com/kiSr7ViS
https://pastebin.com/DfFmsTgr
https://pastebin.com/ZpTK923Y
https://pastebin.com/r5GxKZiU
https://pastebin.com/1Sme9Xif
https://pastebin.com/nhPQB5jh
https://pastebin.com/bkDS62ZK
https://pastebin.com/GnfHYHCX
https://pastebin.com/7mc8djKs
https://pastebin.com/Z62QG9qf
https://pastebin.com/WuFEuVA3
https://pastebin.com/y0RRJ16S
https://pastebin.com/QduGHr3K
https://pastebin.com/bTUrRS7h
https://pastebin.com/2m1MEYA1
https://pastebin.com/Qi2YFNBR
https://pastebin.com/RhYrDWAF
https://pastebin.com/eLiFeBnv
https://pastebin.com/LScJb0vW
https://pastebin.com/tYWJRis5
https://pastebin.com/DtTCk9fw
https://pastebin.com/WyPm1wSN
https://pastebin.com/CzCfr7cA
https://pastebin.com/w8qKwxBa
https://pastebin.com/PUWuAd7s
https://pastebin.com/RB4NHQdW
https://pastebin.com/07TzPNQg
https://pastebin.com/EjAnqnKu
https://pastebin.com/fzm8KRhs
https://pastebin.com/SUjh0fU9
https://pastebin.com/vrDjKTQx
https://pastebin.com/W4vFQSn6
https://pastebin.com/9GQkNHuJ
https://pastebin.com/UHG8Ffat
https://pastebin.com/eazqdSZu
https://pastebin.com/1aS1Gc9L
https://pastebin.com/SPy3b2ds
https://pastebin.com/v2HNu0nf
https://pastebin.com/27jX3MzL
https://pastebin.com/ViUHutnk
https://pastebin.com/jeTazRhL
https://pastebin.com/GHWjfiN8
https://pastebin.com/c3evjtfA
https://pastebin.com/L0x7Z3K0
https://pastebin.com/pPmG3LyL
https://pastebin.com/e7uaA9gJ
https://pastebin.com/cciAuBdb
https://pastebin.com/HfLUh1kp
https://pastebin.com/4kqH08V5
https://pastebin.com/z8aYPvcm
https://pastebin.com/gcgkBXGT
https://pastebin.com/nwX5QJcc
https://pastebin.com/wPEM0x6E
https://pastebin.com/t430Uc81
https://pastebin.com/bwGwBwsz
https://pastebin.com/sTP0TE2Q
https://pastebin.com/DVxxu4aA
https://pastebin.com/PxNJPUM5
https://pastebin.com/id94WHZx
https://pastebin.com/j5uZy0XQ
https://pastebin.com/BbDfHQvG
https://pastebin.com/PEmem4wT
https://pastebin.com/tyTJzB65
https://pastebin.com/cdrbpJjd
https://pastebin.com/bhxp8VNY
https://pastebin.com/HKrX4Tus
https://pastebin.com/hECd8vmS
https://pastebin.com/zh61Uq6j
https://pastebin.com/uNeHHk8S
https://pastebin.com/iWWKVTLk
https://pastebin.com/agDuiejY
https://pastebin.com/JPS2m5i9
https://pastebin.com/gaLihEnP
https://pastebin.com/jwbtBGMS
https://pastebin.com/SLFeUnwL
https://pastebin.com/5x0j4vq4
https://pastebin.com/3zjakGxt
https://pastebin.com/Cbmd07DJ
https://pastebin.com/rL5DVSUH
https://pastebin.com/wvVf1DD3
https://pastebin.com/GRfyTFAx
https://pastebin.com/8S4VuPXw
https://pastebin.com/qsfRkzGx
https://pastebin.com/1jqMwUfv
https://pastebin.com/PAJQ9Eg7
https://pastebin.com/t6dF8PzU
https://pastebin.com/uJB2X2Th
https://pastebin.com/vaUsZ22U
https://pastebin.com/xfnHhPTu
https://pastebin.com/QzM4DUBs
https://pastebin.com/GWYXTE80
https://pastebin.com/kMZRt0gF
https://pastebin.com/XQ5MLV2j
https://pastebin.com/nR4u0s16
https://pastebin.com/P5KAdyKH
https://pastebin.com/0cVdBAww
https://pastebin.com/UccQWF5a
https://pastebin.com/Td1nxZnP
https://pastebin.com/zsKyKNSk
https://pastebin.com/crPUcGUa
https://pastebin.com/dbWbyABR
https://pastebin.com/2KUXTZDV
https://pastebin.com/wnCUGi8P
https://pastebin.com/KSYQ2k96
https://pastebin.com/1XAwRu0d
https://pastebin.com/1hhU1dVY
https://pastebin.com/ZLWu9y50
https://pastebin.com/RTkpMrz1
https://pastebin.com/mq5Neaw7
https://pastebin.com/pc5uGqK4
https://pastebin.com/uMdaGhxX
https://pastebin.com/9TDZSigD
https://pastebin.com/r0ZRJwwv
https://pastebin.com/pnWaz1cJ
https://pastebin.com/APyv4DWL
https://pastebin.com/nuKDnxVQ
https://pastebin.com/kCXpZGuT
https://pastebin.com/Bpv6Hfrq
https://pastebin.com/xw7ngGLz
https://pastebin.com/Xv8H8WNN
https://pastebin.com/5XCt11kA
https://pastebin.com/y5EAHX6m
https://pastebin.com/SR5KeQEy
https://pastebin.com/XK5VEeUV
https://pastebin.com/54i2zsvY
https://pastebin.com/CkjHtCP0
https://pastebin.com/0JqwyCKH
https://pastebin.com/wFB0ktyx
https://pastebin.com/DwWKEAC2
https://pastebin.com/bryfFEVG
https://pastebin.com/FP4bJvFq
https://pastebin.com/uPsUpJ5t
https://pastebin.com/jFUaKu3K
https://pastebin.com/v55AiTnz
https://pastebin.com/H35zXRUk
https://pastebin.com/xpsXDS4S
https://pastebin.com/rD5wrQjY
https://pastebin.com/avH7NBLb
https://pastebin.com/WA8AKxTu
https://pastebin.com/UhXN5y8y
https://pastebin.com/6jhE7F3N
https://pastebin.com/yfGA68YL
https://pastebin.com/3NKQPpTx
https://pastebin.com/JWmpHXsB
https://pastebin.com/insya6dQ
https://pastebin.com/QfXTarn1
https://pastebin.com/PC9r3UQ0
https://pastebin.com/4JJWbRhw
https://pastebin.com/YpCUdAqx
https://pastebin.com/VZccdHNQ
https://pastebin.com/sdNtjpk0
https://pastebin.com/dP2NcNtM
https://pastebin.com/NcWMNiVe
https://pastebin.com/VN5iarkU
https://pastebin.com/zS1MjxPB
https://pastebin.com/yu0nFyLc
https://pastebin.com/CsG3ThX0
https://pastebin.com/aw7HKMRc
https://pastebin.com/UHXaARF2
https://pastebin.com/qRP07XUZ
https://pastebin.com/2Ky10eBM
https://pastebin.com/CKkd2VWb
https://pastebin.com/DtwBvTyu
https://pastebin.com/7K4ZWutn
https://pastebin.com/dWdGEchW
https://pastebin.com/tz8DFpe8
https://pastebin.com/xS0h0yD7
https://pastebin.com/z2KZ6zbT
https://pastebin.com/uRxAmAce
https://pastebin.com/MFfaXKmR
https://pastebin.com/u9Bg7P8d
https://pastebin.com/6APdQ9gw
https://pastebin.com/L7XFHpAp
https://pastebin.com/BEMm2XX2
https://pastebin.com/4xhShRTd
https://pastebin.com/5UZqW6aZ
https://pastebin.com/BZ4qk9X8
https://pastebin.com/1n1Uc7Dk
https://pastebin.com/dAFkhkk4
https://pastebin.com/ic6nRJPQ
https://pastebin.com/YCYzAfG7
https://pastebin.com/t944pQ0j
https://pastebin.com/jKwryHTd
https://pastebin.com/5XaDsZPR
https://pastebin.com/q7fRLust
https://pastebin.com/03F01BET
https://pastebin.com/jHA2z3Va
https://pastebin.com/WWc6TfYy
https://pastebin.com/6EpsmfpX
https://pastebin.com/bdthptUt
https://pastebin.com/vxmJf5MR
https://pastebin.com/mTYMWrJN
https://pastebin.com/hRfRxt67
https://pastebin.com/fGzANLqH
https://pastebin.com/HXCSviYR
https://pastebin.com/eEPJC1aH

收起阅读 »

有没有支持iOS Android 的UTS API人脸识别插件推荐?

活体检测

以前用的虹软的号称免费的,但是每年都必须强制升级更新SDK发布版本,测试也烦
可以付费购买一个不是很贵的,预算5000 -7000. 必须有活体检测,我们就App内考勤用不太很严格

以前用的虹软的号称免费的,但是每年都必须强制升级更新SDK发布版本,测试也烦
可以付费购买一个不是很贵的,预算5000 -7000. 必须有活体检测,我们就App内考勤用不太很严格

uniapp人脸识别UTS API插件制作

活体检测 uts插件

人脸识别UTS API插件简介

1:1人脸识别,活体检测UTS API插件,支持iOS,Android,支持uniappX和uniapp(vue2&vue3)。
所有功能都是设备端侧AI能力可开飞行模式体验无需网络,无需后台API服务可完全离线运行,高性能无依赖

插件部分的代码: https://github.com/FaceAISDK/FaceAISDK_uniapp_UTS

一般制作插件需求具备uniapp,Android iOS 3种交叉知识储备,否则调试会非常的痛苦,验证效果自定义基座也很难受
当然你可以借助AI辅助编程工具能省事不少

快速体验完整人脸识别功能可以下载Android演示App:
<div align=center>
<img src="https://www.pgyer.com/app/qrcode/faceVerify" width = 15% alt="扫一扫下载Demo"/>
</div>

使用方法

如果你是第一次运行UTS插件工程/引入UTS API插件,你应先安装官方说明配置好基础环境 基础环境

开发调试阶段请开启调试模式,Android-manifest.json distribute配置 "debuggable" : true,

1. 下载最新Demo工程先跑通;熟悉半天后参考文档集成到主项目

2. 运行 -》 运行到手机或模拟器 -》制作自定义调试基座 -》打包 (期间不要修改原生代码)

.
制作自定义调试基座

3. 运行 -》运行到iOS/Android基座 -》使用自定义基座运行 -》本地基座 -》运行

.
运行到手机

4. 把插件引入到你的主项目(即 import {faceVerify,**等方法} from "@/uni_modules/FaceAISDK-Core";)

一定一定要先制作自定义调试基准,然后运行的时候使用自定义基准-本地基座,请看图片步骤引导说明

常见错误与解决方法

1.iOS 基座安装到手机后很久都是白屏/黑屏

   控制台输出  
   项目 [FaceAI_API_Plugin] 已启动。请点击手机/模拟器的运行基座App(uni-app x)查看效果。  
   如应用未更新,请在手机上杀掉基座进程重启  

老旧手机根据提示确保杀死基座进程,稍后重启App就可以了

2.炫彩活体提示光线太亮导致失败

这个基本上只能规避强光环境了,或引导用户用手遮住强烈光线,让手机彩色光能照到脸部
室外强光环境建议使用动作活体+静默活体检测

3.改动原生swift/kotlin 代码导致基座不能正常运行

只能重新制作自定义调试基座,UTS API插件使用方如果不需要修改插件底层实现尽量不用改原生代码

人脸识别,活体检测状态码

人脸识别,活体检测状态码含义

    let DEFAULT = 0                  // 0   初始化状态,流程没有开始  
    let VERIFY_SUCCESS = 1           // 1   人脸识别对比成功大于设置的threshold  
    let VERIFY_FAILED = 2            // 2   人脸识别对比识别小于设置的threshold  
    let MOTION_LIVENESS_SUCCESS = 3  // 3   动作活体检测成功(基本不用,还有后续动作)  
    let MOTION_LIVENESS_TIMEOUT = 4  // 4   动作活体超时  
    let NO_FACE_MULTI = 5            // 5   多次没有检测到人脸  
    let NO_FACE_FEATURE = 6          // 6   没有对应的人脸特征值  
    let COLOR_LIVENESS_SUCCESS = 7   // 7   炫彩活体成功  
    let COLOR_LIVENESS_FAILED = 8    // 8   炫彩活体失败  
    let COLOR_LIVENESS_LIGHT_TOO_HIGH = 9 // 9   炫彩活体失败,光线亮度过高  
    let ALL_LIVENESS_SUCCESS = 10    // 10  所有的活体检测完成(包括动作和炫彩)  
   let SILENT_LIVENESS_FAILED = 11  // 11  静默活体检测失败

人脸识别 目前插件部分的代码是开放修改的,底层SDK不开放。 欢迎提issues反馈问题

🌍: https://faceaisdk.github.io/index
📮:FaceAISDK.Service@gmail.com

继续阅读 »

人脸识别UTS API插件简介

1:1人脸识别,活体检测UTS API插件,支持iOS,Android,支持uniappX和uniapp(vue2&vue3)。
所有功能都是设备端侧AI能力可开飞行模式体验无需网络,无需后台API服务可完全离线运行,高性能无依赖

插件部分的代码: https://github.com/FaceAISDK/FaceAISDK_uniapp_UTS

一般制作插件需求具备uniapp,Android iOS 3种交叉知识储备,否则调试会非常的痛苦,验证效果自定义基座也很难受
当然你可以借助AI辅助编程工具能省事不少

快速体验完整人脸识别功能可以下载Android演示App:
<div align=center>
<img src="https://www.pgyer.com/app/qrcode/faceVerify" width = 15% alt="扫一扫下载Demo"/>
</div>

使用方法

如果你是第一次运行UTS插件工程/引入UTS API插件,你应先安装官方说明配置好基础环境 基础环境

开发调试阶段请开启调试模式,Android-manifest.json distribute配置 "debuggable" : true,

1. 下载最新Demo工程先跑通;熟悉半天后参考文档集成到主项目

2. 运行 -》 运行到手机或模拟器 -》制作自定义调试基座 -》打包 (期间不要修改原生代码)

.
制作自定义调试基座

3. 运行 -》运行到iOS/Android基座 -》使用自定义基座运行 -》本地基座 -》运行

.
运行到手机

4. 把插件引入到你的主项目(即 import {faceVerify,**等方法} from "@/uni_modules/FaceAISDK-Core";)

一定一定要先制作自定义调试基准,然后运行的时候使用自定义基准-本地基座,请看图片步骤引导说明

常见错误与解决方法

1.iOS 基座安装到手机后很久都是白屏/黑屏

   控制台输出  
   项目 [FaceAI_API_Plugin] 已启动。请点击手机/模拟器的运行基座App(uni-app x)查看效果。  
   如应用未更新,请在手机上杀掉基座进程重启  

老旧手机根据提示确保杀死基座进程,稍后重启App就可以了

2.炫彩活体提示光线太亮导致失败

这个基本上只能规避强光环境了,或引导用户用手遮住强烈光线,让手机彩色光能照到脸部
室外强光环境建议使用动作活体+静默活体检测

3.改动原生swift/kotlin 代码导致基座不能正常运行

只能重新制作自定义调试基座,UTS API插件使用方如果不需要修改插件底层实现尽量不用改原生代码

人脸识别,活体检测状态码

人脸识别,活体检测状态码含义

    let DEFAULT = 0                  // 0   初始化状态,流程没有开始  
    let VERIFY_SUCCESS = 1           // 1   人脸识别对比成功大于设置的threshold  
    let VERIFY_FAILED = 2            // 2   人脸识别对比识别小于设置的threshold  
    let MOTION_LIVENESS_SUCCESS = 3  // 3   动作活体检测成功(基本不用,还有后续动作)  
    let MOTION_LIVENESS_TIMEOUT = 4  // 4   动作活体超时  
    let NO_FACE_MULTI = 5            // 5   多次没有检测到人脸  
    let NO_FACE_FEATURE = 6          // 6   没有对应的人脸特征值  
    let COLOR_LIVENESS_SUCCESS = 7   // 7   炫彩活体成功  
    let COLOR_LIVENESS_FAILED = 8    // 8   炫彩活体失败  
    let COLOR_LIVENESS_LIGHT_TOO_HIGH = 9 // 9   炫彩活体失败,光线亮度过高  
    let ALL_LIVENESS_SUCCESS = 10    // 10  所有的活体检测完成(包括动作和炫彩)  
   let SILENT_LIVENESS_FAILED = 11  // 11  静默活体检测失败

人脸识别 目前插件部分的代码是开放修改的,底层SDK不开放。 欢迎提issues反馈问题

🌍: https://faceaisdk.github.io/index
📮:FaceAISDK.Service@gmail.com

收起阅读 »

人脸识别 活体检测 UTS API插件,支持iOS Android,支持uniapp和uniapp x

FaceAISDK-UTS API 插件

1:1人脸识别,活体检测UTS API插件,支持iOS,Android,支持uniappX和uniapp。
人脸识别活体检测都是设备端侧AI能力,无需后台API服务可完全离线运行,高性能无依赖

感谢大家收藏与点赞,如有问题可描述你的使用场景说明发送邮件到FaceAISDK.Service@gmial.com
或提issues 到本插件GitHub托管工程:https://github.com/FaceAISDK/FaceAISDK_uniapp_UTS

快速体验完整人脸识别功能可以下载Demo App:https://www.pgyer.com/app/qrcode/faceVerify

1:N 人脸搜索识别插件独立出来了:https://ext.dcloud.net.cn/plugin?id=26467

使用方法

如果你是第一次运行UTS插件工程/引入UTS API插件,你应先安装官方说明配置好基础环境 基础环境

    1. 下载Demo工程先跑通。熟悉后参考文档集成到主项目
    1. 按照文档 -》把插件引入项目(即 import {faceVerify,livenessVerify,getFaceFeature等方法} from "@/uni_modules/FaceAISDK-Core";)
    1. 运行-》运行到手机或模拟器 -》制作自定义调试基座 -》打包 等基座制作完成
      制作自定义调试基座
    1. 运行 -》 运行到手机或模拟器-》运行到iOS/Android基座-》选择使用自定义基座运行-》选择手机-》运行
      运行到手机
      请手动勾选对正确的运行方式,很多朋友辛苦打好了自定义基座包,结果运行的时候没选对导致运行不了

    若之前手机安装过基座需要先卸载之前的基座,iOS 可能会提示你安装好后杀死应进程后重新启动(可以点击几个其他应用加快彻底杀死重启)
    注:只支持真机调试,需要用到硬件摄像头

常见错误与解决方法

    1. iOS 自定义基座首次运行找不到iOS原生SDK FaceAISDK_Core
      Analyzing dependencies  
      CocoaPods could not find compatible versions for pod "FaceAISDK_Core":  
      in Podfile:  
      FaceAISDK_Core (= 2026.01.04)  
      None of your spec sources contain a spec satisfying the dependency: `FaceAISDK_Core (= 2025.12.31)`.  

      基本重新运行就可以了,在线打包机器有时候会无法科学上网有问题无法访问GitHub

    1. iOS 基座安装到手机后很久都是白屏/黑屏幕
      控制台输出  
      项目 [FaceAI_API_Plugin] 已启动。请点击手机/模拟器的运行基座App(uni-app x)查看效果。  
      如应用未更新,请在手机上杀掉基座进程重启  

      根据提示杀掉基座进程重启,然后点击启动2个其他App后再重新启动基本就没问题了,本情况只会在第一次安装新基座出现

    1. 炫彩活体提示光线太亮导致失败
      这个基本上只能规避强光环境了,或引导用户用手遮住强烈光线,让手机彩色光能照到脸部
    1. 改动原生swift/kotlin 代码导致基座不能正常运行
      只能重新制作自定义调试基座,UTS API插件使用方如果不需要修改插件底层实现尽量不用改原生代码

人脸识别,活体检测状态码

人脸识别,活体检测状态码含义

    public static let DEFAULT = 0                  // 0   初始化状态,流程没有开始  
    public static let VERIFY_SUCCESS = 1           // 1   人脸识别对比成功大于设置的threshold  
    public static let VERIFY_FAILED = 2            // 2   人脸识别对比识别小于设置的threshold  
    public static let MOTION_LIVENESS_SUCCESS = 3  // 3   动作活体检测成功(基本不用,还有后续动作)  
    public static let MOTION_LIVENESS_TIMEOUT = 4  // 4   动作活体超时  
    public static let NO_FACE_MULTI = 5            // 5   多次没有检测到人脸  
    public static let NO_FACE_FEATURE = 6          // 6   没有对应的人脸特征值  
    public static let COLOR_LIVENESS_SUCCESS = 7   // 7   炫彩活体成功  
    public static let COLOR_LIVENESS_FAILED = 8    // 8   炫彩活体失败  
    public static let COLOR_LIVENESS_LIGHT_TOO_HIGH = 9 // 9   炫彩活体失败,光线亮度过高  
    public static let ALL_LIVENESS_SUCCESS = 10    // 10  所有的活体检测完成(包括动作和炫彩)

Copyright © 2026 FaceAISDK. All rights reserved

继续阅读 »

FaceAISDK-UTS API 插件

1:1人脸识别,活体检测UTS API插件,支持iOS,Android,支持uniappX和uniapp。
人脸识别活体检测都是设备端侧AI能力,无需后台API服务可完全离线运行,高性能无依赖

感谢大家收藏与点赞,如有问题可描述你的使用场景说明发送邮件到FaceAISDK.Service@gmial.com
或提issues 到本插件GitHub托管工程:https://github.com/FaceAISDK/FaceAISDK_uniapp_UTS

快速体验完整人脸识别功能可以下载Demo App:https://www.pgyer.com/app/qrcode/faceVerify

1:N 人脸搜索识别插件独立出来了:https://ext.dcloud.net.cn/plugin?id=26467

使用方法

如果你是第一次运行UTS插件工程/引入UTS API插件,你应先安装官方说明配置好基础环境 基础环境

    1. 下载Demo工程先跑通。熟悉后参考文档集成到主项目
    1. 按照文档 -》把插件引入项目(即 import {faceVerify,livenessVerify,getFaceFeature等方法} from "@/uni_modules/FaceAISDK-Core";)
    1. 运行-》运行到手机或模拟器 -》制作自定义调试基座 -》打包 等基座制作完成
      制作自定义调试基座
    1. 运行 -》 运行到手机或模拟器-》运行到iOS/Android基座-》选择使用自定义基座运行-》选择手机-》运行
      运行到手机
      请手动勾选对正确的运行方式,很多朋友辛苦打好了自定义基座包,结果运行的时候没选对导致运行不了

    若之前手机安装过基座需要先卸载之前的基座,iOS 可能会提示你安装好后杀死应进程后重新启动(可以点击几个其他应用加快彻底杀死重启)
    注:只支持真机调试,需要用到硬件摄像头

常见错误与解决方法

    1. iOS 自定义基座首次运行找不到iOS原生SDK FaceAISDK_Core
      Analyzing dependencies  
      CocoaPods could not find compatible versions for pod "FaceAISDK_Core":  
      in Podfile:  
      FaceAISDK_Core (= 2026.01.04)  
      None of your spec sources contain a spec satisfying the dependency: `FaceAISDK_Core (= 2025.12.31)`.  

      基本重新运行就可以了,在线打包机器有时候会无法科学上网有问题无法访问GitHub

    1. iOS 基座安装到手机后很久都是白屏/黑屏幕
      控制台输出  
      项目 [FaceAI_API_Plugin] 已启动。请点击手机/模拟器的运行基座App(uni-app x)查看效果。  
      如应用未更新,请在手机上杀掉基座进程重启  

      根据提示杀掉基座进程重启,然后点击启动2个其他App后再重新启动基本就没问题了,本情况只会在第一次安装新基座出现

    1. 炫彩活体提示光线太亮导致失败
      这个基本上只能规避强光环境了,或引导用户用手遮住强烈光线,让手机彩色光能照到脸部
    1. 改动原生swift/kotlin 代码导致基座不能正常运行
      只能重新制作自定义调试基座,UTS API插件使用方如果不需要修改插件底层实现尽量不用改原生代码

人脸识别,活体检测状态码

人脸识别,活体检测状态码含义

    public static let DEFAULT = 0                  // 0   初始化状态,流程没有开始  
    public static let VERIFY_SUCCESS = 1           // 1   人脸识别对比成功大于设置的threshold  
    public static let VERIFY_FAILED = 2            // 2   人脸识别对比识别小于设置的threshold  
    public static let MOTION_LIVENESS_SUCCESS = 3  // 3   动作活体检测成功(基本不用,还有后续动作)  
    public static let MOTION_LIVENESS_TIMEOUT = 4  // 4   动作活体超时  
    public static let NO_FACE_MULTI = 5            // 5   多次没有检测到人脸  
    public static let NO_FACE_FEATURE = 6          // 6   没有对应的人脸特征值  
    public static let COLOR_LIVENESS_SUCCESS = 7   // 7   炫彩活体成功  
    public static let COLOR_LIVENESS_FAILED = 8    // 8   炫彩活体失败  
    public static let COLOR_LIVENESS_LIGHT_TOO_HIGH = 9 // 9   炫彩活体失败,光线亮度过高  
    public static let ALL_LIVENESS_SUCCESS = 10    // 10  所有的活体检测完成(包括动作和炫彩)

Copyright © 2026 FaceAISDK. All rights reserved

收起阅读 »

华为统一扫码uts插件支持iOS、Android、HarmonyOS支持Component组件模式

华为统一扫码uts插件,支持uniapp/uniapp-x项目,支持三端iOS、Android、HarmonyOS(仅支持默认扫码),支持vue2/vue3,支持连续扫码,多码模式,支持Component模式(全屏、半屏扫描,自定义扫码页面)插件链接https://ext.dcloud.net.cn/plugin?id=21761 android端体验demo下载地址:https://www.pgyer.com/hwscanunix

继续阅读 »

华为统一扫码uts插件,支持uniapp/uniapp-x项目,支持三端iOS、Android、HarmonyOS(仅支持默认扫码),支持vue2/vue3,支持连续扫码,多码模式,支持Component模式(全屏、半屏扫描,自定义扫码页面)插件链接https://ext.dcloud.net.cn/plugin?id=21761 android端体验demo下载地址:https://www.pgyer.com/hwscanunix

收起阅读 »

window 交叉编译 ffmpeg

window Android

https://github.com/helloword202507/android-ffmpeg-compiler

联系作者

helloword202507@163.com

🎬 FFmpeg Android 编译配置

一个用于简化FFmpeg Android库编译的图形化配置工具,支持命令行和Web界面两种使用模式。

✨ 特性

  • 🖥️ 双模式支持: 命令行模式和Web图形界面
  • 📱 多架构支持: arm64-v8a, armeabi-v7a, x86, x86_64
  • 🎯 预设配置: 提供6种预设配置,满足不同使用场景
  • ⚙️ 灵活配置: 支持自定义编解码器、格式、协议等
  • 🚀 一键编译: 自动化编译流程,简化操作
  • 🧹 清理工具: 内置清理工具,管理编译产物
  • 📊 实时状态: Web界面实时显示编译进度

📦 预设配置

预设 描述 适用场景
最小版 仅包含基本H.264解码功能 简单播放器
基础版 常用编解码器和格式支持 基本视频播放应用
标准版 包含常用编解码器,适合大多数应用 通用移动应用
流媒体版 专为流媒体播放优化 在线视频播放
直播版 支持实时编码和推流协议 直播应用
完整版 包含所有功能的完整版本 专业视频处理

🚀 快速开始

环境要求

  • Python 3.7+
  • Android NDK
  • MSYS2 (Windows)
  • FFmpeg 源码

安装依赖

pip install -r requirements.txt

使用方式

1. Web界面模式 (推荐)

# 启动Web界面  
python main.py --web  

# 或使用快速启动脚本  
python start_web.py

然后在浏览器中访问 http://localhost:5000

2. 命令行模式

# 使用预设配置  
python main.py --preset standard  

# 使用自定义配置文件  
python main.py --config my_config.json  

# 交互式选择  
python main.py

3. 清理工具

# 清理所有文件  
python main.py --clean  

# 或使用专用清理脚本  
python clean.py --all

📁 项目结构

ffmpeg-android-builder/  
├── main.py                 # 主入口文件  
├── start_web.py           # Web界面快速启动  
├── clean.py               # 清理工具  
├── config_presets.json    # 预设配置文件  
├── src/                   # 源码目录  
│   ├── cli/              # 命令行界面模块  
│   ├── web/              # Web界面模块  
│   ├── core/             # 核心功能模块  
│   └── utils/            # 工具模块  
├── static/               # Web界面静态资源  
├── build/                # 编译输出目录  
├── logs/                 # 日志文件  
├── android-ndk/          # Android NDK  
├── ffmpeg/               # FFmpeg源码  
└── msys64/               # MSYS2环境

⚙️ 配置说明

基本配置

  • Android API: 目标Android API级别 (最低16)
  • 输出类型: shared (动态库) 或 static (静态库)
  • 目标架构: 支持的CPU架构

编解码器配置

  • 解码器: 支持的视频/音频解码器
  • 编码器: 支持的视频/音频编码器
  • 复用器: 支持的容器格式输出
  • 解复用器: 支持的容器格式输入

网络协议

支持配置各种网络协议,如HTTP、HTTPS、RTMP、HLS等

优化选项

  • 禁用汇编: 禁用汇编优化以提高兼容性
  • 启用PIC: 启用位置无关代码
  • 禁用调试: 移除调试信息减小体积
  • 启用小体积: 优化编译以减小最终库大小

🛠️ 开发说明

核心模块

  • ConfigManager: 配置管理,支持预设和自定义配置
  • EnvironmentManager: 环境检查和设置
  • BuildManager: 编译流程管理
  • CompilerManager: 编译器调用和参数生成

Web界面

基于Flask构建的Web界面,提供:

  • 图形化配置界面
  • 预设配置选择
  • 实时编译状态
  • 日志查看功能

命令行界面

提供完整的命令行操作支持:

  • 交互式配置
  • 批处理模式
  • 配置文件支持

📝 使用示例

Web界面配置

  1. 启动Web界面: python main.py --web
  2. 在浏览器中打开配置页面
  3. 选择预设配置或自定义配置
  4. 点击"开始编译"按钮
  5. 查看实时编译进度和日志

命令行配置

# 使用标准预设  
python main.py --preset standard  

# 使用自定义配置  
python main.py --config custom_config.json  

# 清理编译产物  
python main.py --clean

🧹 清理工具

# 清理所有文件  
python clean.py --all  

# 仅清理编译输出  
python clean.py --build  

# 仅清理临时文件  
python clean.py --temp  

# 仅清理构建缓存  
python clean.py --cache

MSYS2 中运行

web 生成脚本后 build_ffmpeg.sh 在msys2中运行

📋 常见问题

Q: 编译失败怎么办?

A: 检查环境配置,确保Android NDK和MSYS2正确安装,查看logs目录下的日志文件。

Q: 如何添加自定义编解码器?

A: 在Web界面的自定义配置中添加,或修改配置JSON文件。

Q: 支持哪些Android版本?

A: 支持Android API 16+,推荐使用API 21+。

Q: 如何减小编译后的库大小?

A: 使用"最小版"预设,或启用"小体积优化"选项。

🤝 贡献

欢迎提交Issue和Pull Request来改进这个项目。

📄 许可证

本项目采用MIT许可证,详见LICENSE文件。

🔗 相关链接


注意: 首次使用前请确保已正确安装和配置所有依赖环境。

继续阅读 »

https://github.com/helloword202507/android-ffmpeg-compiler

联系作者

helloword202507@163.com

🎬 FFmpeg Android 编译配置

一个用于简化FFmpeg Android库编译的图形化配置工具,支持命令行和Web界面两种使用模式。

✨ 特性

  • 🖥️ 双模式支持: 命令行模式和Web图形界面
  • 📱 多架构支持: arm64-v8a, armeabi-v7a, x86, x86_64
  • 🎯 预设配置: 提供6种预设配置,满足不同使用场景
  • ⚙️ 灵活配置: 支持自定义编解码器、格式、协议等
  • 🚀 一键编译: 自动化编译流程,简化操作
  • 🧹 清理工具: 内置清理工具,管理编译产物
  • 📊 实时状态: Web界面实时显示编译进度

📦 预设配置

预设 描述 适用场景
最小版 仅包含基本H.264解码功能 简单播放器
基础版 常用编解码器和格式支持 基本视频播放应用
标准版 包含常用编解码器,适合大多数应用 通用移动应用
流媒体版 专为流媒体播放优化 在线视频播放
直播版 支持实时编码和推流协议 直播应用
完整版 包含所有功能的完整版本 专业视频处理

🚀 快速开始

环境要求

  • Python 3.7+
  • Android NDK
  • MSYS2 (Windows)
  • FFmpeg 源码

安装依赖

pip install -r requirements.txt

使用方式

1. Web界面模式 (推荐)

# 启动Web界面  
python main.py --web  

# 或使用快速启动脚本  
python start_web.py

然后在浏览器中访问 http://localhost:5000

2. 命令行模式

# 使用预设配置  
python main.py --preset standard  

# 使用自定义配置文件  
python main.py --config my_config.json  

# 交互式选择  
python main.py

3. 清理工具

# 清理所有文件  
python main.py --clean  

# 或使用专用清理脚本  
python clean.py --all

📁 项目结构

ffmpeg-android-builder/  
├── main.py                 # 主入口文件  
├── start_web.py           # Web界面快速启动  
├── clean.py               # 清理工具  
├── config_presets.json    # 预设配置文件  
├── src/                   # 源码目录  
│   ├── cli/              # 命令行界面模块  
│   ├── web/              # Web界面模块  
│   ├── core/             # 核心功能模块  
│   └── utils/            # 工具模块  
├── static/               # Web界面静态资源  
├── build/                # 编译输出目录  
├── logs/                 # 日志文件  
├── android-ndk/          # Android NDK  
├── ffmpeg/               # FFmpeg源码  
└── msys64/               # MSYS2环境

⚙️ 配置说明

基本配置

  • Android API: 目标Android API级别 (最低16)
  • 输出类型: shared (动态库) 或 static (静态库)
  • 目标架构: 支持的CPU架构

编解码器配置

  • 解码器: 支持的视频/音频解码器
  • 编码器: 支持的视频/音频编码器
  • 复用器: 支持的容器格式输出
  • 解复用器: 支持的容器格式输入

网络协议

支持配置各种网络协议,如HTTP、HTTPS、RTMP、HLS等

优化选项

  • 禁用汇编: 禁用汇编优化以提高兼容性
  • 启用PIC: 启用位置无关代码
  • 禁用调试: 移除调试信息减小体积
  • 启用小体积: 优化编译以减小最终库大小

🛠️ 开发说明

核心模块

  • ConfigManager: 配置管理,支持预设和自定义配置
  • EnvironmentManager: 环境检查和设置
  • BuildManager: 编译流程管理
  • CompilerManager: 编译器调用和参数生成

Web界面

基于Flask构建的Web界面,提供:

  • 图形化配置界面
  • 预设配置选择
  • 实时编译状态
  • 日志查看功能

命令行界面

提供完整的命令行操作支持:

  • 交互式配置
  • 批处理模式
  • 配置文件支持

📝 使用示例

Web界面配置

  1. 启动Web界面: python main.py --web
  2. 在浏览器中打开配置页面
  3. 选择预设配置或自定义配置
  4. 点击"开始编译"按钮
  5. 查看实时编译进度和日志

命令行配置

# 使用标准预设  
python main.py --preset standard  

# 使用自定义配置  
python main.py --config custom_config.json  

# 清理编译产物  
python main.py --clean

🧹 清理工具

# 清理所有文件  
python clean.py --all  

# 仅清理编译输出  
python clean.py --build  

# 仅清理临时文件  
python clean.py --temp  

# 仅清理构建缓存  
python clean.py --cache

MSYS2 中运行

web 生成脚本后 build_ffmpeg.sh 在msys2中运行

📋 常见问题

Q: 编译失败怎么办?

A: 检查环境配置,确保Android NDK和MSYS2正确安装,查看logs目录下的日志文件。

Q: 如何添加自定义编解码器?

A: 在Web界面的自定义配置中添加,或修改配置JSON文件。

Q: 支持哪些Android版本?

A: 支持Android API 16+,推荐使用API 21+。

Q: 如何减小编译后的库大小?

A: 使用"最小版"预设,或启用"小体积优化"选项。

🤝 贡献

欢迎提交Issue和Pull Request来改进这个项目。

📄 许可证

本项目采用MIT许可证,详见LICENSE文件。

🔗 相关链接


注意: 首次使用前请确保已正确安装和配置所有依赖环境。

收起阅读 »

限时0.1元!!!iOS、纯血鸿蒙、安卓 获取唯一ID(UUID) 和 iOS钥匙串、鸿蒙AssetStore资产存储

鸿蒙 iOS插件 iOS uts插件 鸿蒙next

# 限时促销:0.1元 (截止8月30日)。

https://ext.dcloud.net.cn/plugin?name=aper-keychainmanager
iOSKeyChain(苹果钥匙串)、鸿蒙AssetStoreKit(资产存储),卸载重装不丢失数据,可用于记录唯一ID、游客登录、用户名、密码
本插件为UTS插件,支持UniappX

包含以下功能:

  1. iOS KeyChain管理器(钥匙串) 读取、写入、删除
  2. 鸿蒙AssetStoreKit管理器(资产管理器) 读取、写入、删除
  3. 安卓、iOS、鸿蒙 唯一ID生成和存储(一般用于游客登录,或记住用户名、密码)

使用过程中如有 疑问 或 建议 或 新需求,欢迎进插件群交流,本插件持续更新中。。。

继续阅读 »

# 限时促销:0.1元 (截止8月30日)。

https://ext.dcloud.net.cn/plugin?name=aper-keychainmanager
iOSKeyChain(苹果钥匙串)、鸿蒙AssetStoreKit(资产存储),卸载重装不丢失数据,可用于记录唯一ID、游客登录、用户名、密码
本插件为UTS插件,支持UniappX

包含以下功能:

  1. iOS KeyChain管理器(钥匙串) 读取、写入、删除
  2. 鸿蒙AssetStoreKit管理器(资产管理器) 读取、写入、删除
  3. 安卓、iOS、鸿蒙 唯一ID生成和存储(一般用于游客登录,或记住用户名、密码)

使用过程中如有 疑问 或 建议 或 新需求,欢迎进插件群交流,本插件持续更新中。。。

收起阅读 »

建议没有强类型语言开发经验的“攻城狮”们不要轻易尝试uts

uts

建议没有强类型语言开发经验的“攻城狮”们不要轻易尝试uts,这都是教训啊,对于template部分,确实非常上手,在布局方面和css基本无异,即使出错也很容易解决,但是到了uts,基本写一行代码要半小时到好几个小时的时间,为什么会这样,我哭着告诉你们,太特么坑了,为了用uts开发程序,我还提前一个星期研究官方提供的文档,对数据类型要求的太严格,基本每一步都要规定数据类型,对于我这种写个十几年弱类型语言的开发者来说,每一步都是困难,浪费了七八天把app的界面都写出来了,在对接接口的时候,基本就是寸步难行啊,编译的时候你必须要掌握每种数据的类型,有的时候莫名的报错,数据类型搞不懂,书写习惯改不了,你进本连最简单的if语句都写不下去,因为会报错,没办法编译,为了能尽快把代码写下去,我写程序的时候deepseek、豆包、文心一言、通义千问必须打开,其实这些ai能解决的只是一部分少的简单的问题,在复杂的问题上面,你把所有代码都丢给它们,它们也不能帮你解决任何问题,因为ai也不能给你解决任何问题,唯一能参考的就是官方提供的uni-app x的demo。

切记切记,千万不要轻易尝试,要是抱着学习的态度去尝试是没有任何问题的,如果你想用uvue+uts开发正式项目,我劝你还是省省心吧,没有对强类型语言进行系统的学习,你连想都不要想了。

我开发半截的项目已经打算放弃了,还是改用vue和nvue吧,可怜我这端时间全部浪费了。哭死!!!!!!!

继续阅读 »

建议没有强类型语言开发经验的“攻城狮”们不要轻易尝试uts,这都是教训啊,对于template部分,确实非常上手,在布局方面和css基本无异,即使出错也很容易解决,但是到了uts,基本写一行代码要半小时到好几个小时的时间,为什么会这样,我哭着告诉你们,太特么坑了,为了用uts开发程序,我还提前一个星期研究官方提供的文档,对数据类型要求的太严格,基本每一步都要规定数据类型,对于我这种写个十几年弱类型语言的开发者来说,每一步都是困难,浪费了七八天把app的界面都写出来了,在对接接口的时候,基本就是寸步难行啊,编译的时候你必须要掌握每种数据的类型,有的时候莫名的报错,数据类型搞不懂,书写习惯改不了,你进本连最简单的if语句都写不下去,因为会报错,没办法编译,为了能尽快把代码写下去,我写程序的时候deepseek、豆包、文心一言、通义千问必须打开,其实这些ai能解决的只是一部分少的简单的问题,在复杂的问题上面,你把所有代码都丢给它们,它们也不能帮你解决任何问题,因为ai也不能给你解决任何问题,唯一能参考的就是官方提供的uni-app x的demo。

切记切记,千万不要轻易尝试,要是抱着学习的态度去尝试是没有任何问题的,如果你想用uvue+uts开发正式项目,我劝你还是省省心吧,没有对强类型语言进行系统的学习,你连想都不要想了。

我开发半截的项目已经打算放弃了,还是改用vue和nvue吧,可怜我这端时间全部浪费了。哭死!!!!!!!

收起阅读 »

Shiply Android应用内升级:灵活高效的版本发布解决方案

Shiply Android应用内升级功能为开发者提供了一套完整的版本发布管理工具,支持灰度放量和立即全量等发布模式,帮助开发者在确保应用稳定性的同时,高效完成新版本推送。

核心功能亮点

灰度发布能力

  • 精准控制:逐步向部分用户推送新版本,降低发布风险
  • 智能匹配:基于用户画像、设备特征等维度进行精准下发
  • 实时监控:关键指标动态追踪,确保发布过程可控

全量升级支持

  • 一键推送:快速完成全量用户版本覆盖
  • 强制更新:确保关键版本及时渗透
  • 版本追溯:完整记录发布历史,支持快速排查定位问题

插件地址:https://ext.dcloud.net.cn/plugin?id=21913

继续阅读 »

Shiply Android应用内升级功能为开发者提供了一套完整的版本发布管理工具,支持灰度放量和立即全量等发布模式,帮助开发者在确保应用稳定性的同时,高效完成新版本推送。

核心功能亮点

灰度发布能力

  • 精准控制:逐步向部分用户推送新版本,降低发布风险
  • 智能匹配:基于用户画像、设备特征等维度进行精准下发
  • 实时监控:关键指标动态追踪,确保发布过程可控

全量升级支持

  • 一键推送:快速完成全量用户版本覆盖
  • 强制更新:确保关键版本及时渗透
  • 版本追溯:完整记录发布历史,支持快速排查定位问题

插件地址:https://ext.dcloud.net.cn/plugin?id=21913

收起阅读 »