【每日学点鸿蒙知识】userAgent识别问题、StatusBar颜色、taskpool中操作同一个对象、scroll组件
1、HarmonyOS window.navigator.userAgent.toLowerCase()方法获取的值都有哪些?
h5暂无法通过window.navigator.userAgent识别,只能通过原生注入固定字段识别, 可以参考这篇文档:https://developer.huawei.com/consumer/cn/forum/topic/0201145720536373106?fid=0101587866109860105
2、HarmonyOS 如何动态设置StatusBar内的字体颜色?
APP设置了沉浸式布局,在切换主题颜色的时候,最顶部的状态栏字体颜色不会变化,请问该怎么处理?下面的代码时我们的设置方式:
private checkDarkMode(darkModeConfig: DarkModeSettingsConfig): void {
AppStorage.setOrCreate<DarkModeSettingsConfig>('darkModeConfig', darkModeConfig);
let applicationContext = getContext(this).getApplicationContext();
let colorMode: ConfigurationConstant.ColorMode = ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET;
if (darkModeConfig.switchType === DarkModeType.FOLLOW_UP) {
colorMode = (getContext(this) as common.UIAbilityContext).config.colorMode ||
ConfigurationConstant.ColorMode.COLOR_MODE_LIGHT;
} else if (darkModeConfig.switchType === DarkModeType.DARK) {
colorMode = ConfigurationConstant.ColorMode.COLOR_MODE_DARK;
} else {
colorMode = ConfigurationConstant.ColorMode.COLOR_MODE_LIGHT;
}
AppStorage.setOrCreate('currentColorMode', colorMode);
applicationContext.setColorMode(colorMode);
try {
AppUtil.getMainWindow()?.setWindowSystemBarProperties({
statusBarContentColor: colorMode === ConfigurationConstant.ColorMode.COLOR_MODE_DARK ? '0xffffffff' : '0x00000000',
}, (err: BusinessError) => {
const errCode: number = err.code;
if (errCode) {
console.error('Failed to set the system bar properties. Cause: ' + JSON.stringify(err));
return;
}
console.info('Succeeded in setting the system bar properties.');
});
} catch (exception) {
console.error('Failed to set the system bar properties. Cause: ' + JSON.stringify(exception));
}
}
目前设置状态栏颜色是使用窗口的API,调整维度是从整个窗口进行调整。需要做到页面的级别的话就需要在页面的生命周期中进行调整控制,在需要改变的页面直接调用setWindowSystemBarProperties方法。 可以参考官方文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/js-apis-window-V5#setwindowsystembarproperties9
示例代码如下:
onPageShow(): void {
window.getLastWindow(getContext(), (err, data) => {
let win: window.Window;
if (err.code) {
console.error("error code :" + JSON.stringify(err.code))
return;
}
try {
win = data;
//设置窗口为全屏模式
win.setWindowLayoutFullScreen(true);
// 设置状态栏
win.setWindowSystemBarProperties({
// 设置状态栏颜色为其他颜色
statusBarColor: '#00ff00',
// 设置状态栏文本颜色为白色
statusBarContentColor: '#353535'
})
console.info('带状态栏沉浸式窗口设置完成')
} catch (expextion) {
console.error("error cause :" + JSON.stringify(expextion))
}
})
}
//demo实现使用API10, 完整demo如下:
import window1 from '@ohos.window';
import { BusinessError } from '@ohos.base';
import Stack from '@ohos.util.Stack';
class StatusBarColor {
statusBarColor: string;
statusBarContentColor: string
constructor(statusBarColor: string, statusBarContentColor: string) {
// 状态栏背景
this.statusBarColor = statusBarColor;
// 状态栏内容
this.statusBarContentColor = statusBarContentColor;
}
}
export class StatusBarUtils {
static testNumber: number = 0;
private static barColor: Stack<StatusBarColor> = new Stack();
private static setBarColor(statusBarColor: StatusBarColor) {
let mainWindow: window1.Window | undefined = AppStorage.get("mainWindow")
let sysBarProps: window1.SystemBarProperties = {
statusBarColor: statusBarColor.statusBarColor,
statusBarContentColor: statusBarColor.statusBarContentColor,
};
mainWindow?.setWindowSystemBarProperties(sysBarProps, (err: BusinessError) => {
let errCode: number = err.code;
if (errCode) {
console.error('[StaticUtils] Failed to set the system bar properties. Cause: ' + JSON.stringify(err));
return;
}
console.info('[StaticUtils] Succeeded in setting the system bar properties.');
});
}
static pushStatusColor(statusBarColor: string, statusBarContentColor: string) {
StatusBarUtils.barColor.push(new StatusBarColor(statusBarColor, statusBarContentColor))
StatusBarUtils.setBarColor(StatusBarUtils.barColor.peek());
}
static popStatusColor() {
if (!StatusBarUtils.barColor.isEmpty()) {
StatusBarUtils.barColor.pop();
if (!StatusBarUtils.barColor.isEmpty()) {
StatusBarUtils.setBarColor(StatusBarUtils.barColor.peek());
}
}
}
}
3、HarmonyOS如何在多个taskpool中操作同一个对象?
这边的目标是在多个taskpool线程里共同操作一个缓存类,给缓存类里塞值,taskpool是线程隔离的,因此使用sendable注解,使用sendable注解之后发现某些类型的字段不能序列化,这个有什么解决办法吗? 或者如果不用sendadble的话 有没有其他在多个线程中操作同一个缓存对象的方法呢?
只有SharedArrayBuffer共享和@sendable,没有其他方式
4、HarmonyOS scroll组件问题?
1、如何利用 ontouch回调 处理 多指的y轴偏移距离计算
2、为什么scroll嵌套relative,无法滚动 :relative包含2个Row组件,第一个组件位于第二个组件上方,且第二个组件高度100%
1、如何利用 ontouch回调 处理 多指的y轴偏移距离计算y轴偏移量可以使用PanGesture事件的onActionUpdate方法,这个方法可以获得手势的偏移量,也可以设置触发滑动手势的手指数,参考链接:https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-basic-gestures-pangesture-0000001815767760#ZH-CN_TOPIC_0000001815767760__%E4%BA%8B%E4%BB%B6如果 =确实需要使用ontouch回调处理,那么就需要记录下手指按压时得y轴坐标和手指抬起时的y轴坐标,然后二者相减,即可获得y轴偏移量,多指时每根手指的位置都会记录下来,可以通过TouchEvent对象的touches数组获取,其中手指排序是以触摸屏幕先后来确定的
2、RelativeContainer组件无法滚动的问题,可以设置RelativeContainer内第二个子组件是以第一个子组件作为锚点且位于第一个子组件下方,且RelativeContainer的height属性设置为auto。至于为什么两个Row组件时不滚动,是因为RelativeContainer组件本身是以屏幕左上角为起始位置进行渲染绘制,而超过左上角的部分会不可见或不渲染,进而导致无法滚动,所以如果想让RelativeContainer组件本身可滑动的话,那么子组件锚点得确定为屏幕左上角的那个组件3、scrollTo动画结束没有回调
5、HarmonyOS appStorage的更新,遮罩中使用并为触发重新渲染?
当storage发生更新时,所有使用到的组件均会发生更新,所以想将一个遮罩(overlay)封装起来,去引用对应的key,然后通过一个开关去打开关闭遮罩(更新storage),但是事实上并没有触发更新。
自定义弹窗的所有参数,不支持动态刷新,@Link和@Prop的刷新机制不同,@Link相当于引用传递,@State更新后会直接通知@Link。这里建议使用@Link