[Daily HarmonyOS Next Knowledge] List Collapse Animation, Obfuscation Issue, bindPopup Problems, etc.
1. How to implement list collapse animation effects?
- When the height of listItem is known, collapse animation can be achieved by controlling height changes.
- When the height of listItem is unknown, collapse animation can be achieved by adding/removing data in
animateTo.
2. How to add compilation parameters in HarmonyOS?
- Add in CMakeLists.txt:
# Set build type to Release, which disables debug information
set(CMAKE_BUILD_TYPE Release)
# The -s flag optimizes compilation to generate shorter code
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s")
# Solve symbol conflicts
set(CMAKE_SHARED_LINKER_FLAGS "-Wl,-Bsymbolic")
# Unified additions:
# Enable stack protection; capture buffer overflow security issues; code optimization; integer overflow checks, etc.
set(CMAKE_CXX_FLAGS "-fstack-protector-all -D_FORTIFY_SOURCE=2 -O2 -ftrapv -s")
- Add in externalnativeoptions configuration:
The
externalNativeOptionsparameter in the module-levelbuild-profile.json5is the entry for compiling C/C++ files in NDK projects. You can specify the CMake script path viapath, configure CMake parameters viaarguments, set C++ compiler parameters viacppFlags, and configure compilation architectures viaabiFilters:
"externalNativeOptions": {
"path": "./src/main/cpp/CMakeLists.txt",
"arguments": "-DCMAKE_BUILD_TYPE=Release",
"cppFlags": "-fstack-protector-all -D_FORTIFY_SOURCE=2 -O2 -ftrapv -s",
}
3. bindPopup style issues?
Problems:
- Inability to change the rounded corner size of the Popup window.
- When
enableArrowistrue, the arrow color is white. Can the arrow color be changed?
Solutions:
-
Problem 1: Set
radiusto change the rounded corner size of the Popup window. For details, see https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-universal-attributes-popup-0000001774121186#ZH-CN_TOPIC_0000001774121186__bindpopup. -
Problem 2: The arrow color cannot be modified currently; only the bubble background color can be set via
popupColor.
4. How to locate obfuscation issues?
Scenario: Debugging works, but Release mode reports errors or crashes.
定位Means:
- Add obfuscation configuration
-disable-obfuscationto turn off all obfuscation. - Compile in Release mode. If the exception disappears, confirm it is caused by obfuscation.
- Comment out the
-compactobfuscation configuration to check the specific error location.
Compilation Output Directory: build/default/cache/default/default@HarCompileArkTS/esmodule/release
Cause: Issues arise because attribute names, method names, or parameter names are obfuscated. Use -keep-property-name, -keep-global-name, or -keep to prevent obfuscation of specific elements.
5. Based on what positioning is the offset attribute of BindPopup offset?
What is the reference point for the offset of bindpopup? For example, if offset is set to x: 100, y: 100, based on which point are x and y offset when touching the screen?
Answer: The reference point is the top-left anchor of the bound component.
- Note: The specifications of
bindpopuphave changed in 5.0. The写法 in current Webview documents is no longer fully compatible with the long-press menu function. To usebindpopup, add a component with size 0 before the Webview component (at the same layer) to carrybindpopup. - According to current UX specifications, a horizontal offset of 7vp is required to ensure the popup menu stays within the screen range.
Sample Code:
import web_webview from '@ohos.web.webview'
import pasteboard from '@ohos.pasteboard'
const TAG = 'ContextMenu';
@Entry
@Component
struct WebComponent {
controller: web_webview.WebviewController = new web_webview.WebviewController()
private result: WebContextMenuResult | undefined = undefined;
@State linkUrl: string = '';
@State offsetX: number = 0;
@State offsetY: number = 0;
@State showMenu: boolean = false;
@Builder
// Build custom menu and trigger function interface
MenuBuilder() {
// Menu displayed as a vertical list.
Menu() {
// Display specific item menu items in Menu.
MenuItem({
content: '复制图片',
})
.width(100)
.height(50)
.onClick(() => {
this.result?.copyImage();
this.showMenu = false;
})
MenuItem({
content: '剪切',
})
.width(100)
.height(50)
.onClick(() => {
this.result?.cut();
this.showMenu = false;
})
MenuItem({
content: '复制',
})
.width(100)
.height(50)
.onClick(() => {
this.result?.copy();
this.showMenu = false;
})
MenuItem({
content: '粘贴',
})
.width(100)
.height(50)
.onClick(() => {
this.result?.paste();
this.showMenu = false;
})
MenuItem({
content: '复制链接',
})
.width(100)
.height(50)
.onClick(() => {
let pasteData = pasteboard.createData('text/plain', this.linkUrl);
pasteboard.getSystemPasteboard().setData(pasteData, (error) => {
if (error) {
return;
}
})
this.showMenu = false;
})
MenuItem({
content: '全选',
})
.width(100)
.height(50)
.onClick(() => {
this.result?.selectAll();
this.showMenu = false;
})
}
.width(150)
.height(300)
.backgroundColor("#eeeeee")
}
build() {
Column() {
Row()
.width(0)
.height(0)
.position({ x: 0, y: 0 })
.bindPopup(this.showMenu,
{
builder: this.MenuBuilder(),
enableArrow: false,
placement: Placement.LeftTop,
targetSpace: 0,
shadow: {
radius: 0
},
offset: { x: this.offsetX - 7, y: this.offsetY },
mask: false,
onStateChange: (e) => {
if (!e.isVisible) {
this.showMenu = false;
this.result!.closeContextMenu();
}
}
})
Web({ src: '', controller: this.controller })// Trigger custom popup
.onControllerAttached(() => {
this.controller.setCustomUserAgent(this.controller.getUserAgent() + " Android")
this.controller.loadUrl($rawfile("OnContextMenuShow/index.html"))
})// Trigger custom popup
.onContextMenuShow((event) => {
if (event) {
this.result = event.result
console.info("x coord = " + event.param.x())
console.info("link url = " + event.param.getLinkUrl())
this.linkUrl = event.param.getLinkUrl()
}
console.info(TAG, `x: ${this.offsetX}, y: ${this.offsetY}`);
this.showMenu = true;
this.offsetX = Math.max(px2vp(event?.param.x() ?? 0) - 0, 0);
this.offsetY = Math.max(px2vp(event?.param.y() ?? 0) - 0, 0);
return true
})
}
}
}
Top comments (0)