HarmonyOS鸿蒙Next中@Bulider不更新
HarmonyOS鸿蒙Next中@Bulider不更新
大佬们老师们好!
下面是demo是我模拟我们壳工程的现阶段的状态
有2个前提条件
@Entry内容不允许改变
NativeDragListViewMidea只能是Builder函数导出
前面这2个是因为我们使用的是同层渲染Web()渲染 然后映射标签 使用的new WrappedBuilder创建的组件
是否能在MideaDragListViewMidea组件里面修改?我现在就是params数据修改监听不到 复现的话 demo顶上的按钮点击切换数据是有变化的ui不会变
import curves from '[@ohos](/user/ohos).curves'
import lottie, { AnimationItem } from '[@ohos](/user/ohos)/lottie'
import ObjectUtil from './utils'
interface globalFace {
visibility?: number;
alpha?: number;
width?: number;
height?: number;
margin?: number[]; //view的外边距数组,大小为4. left,top,right,bottom
padding?: number[]
textColor?: string,
textSize?: number,
fontWeight?: number | string
fontFamilyPath?: string
cornerRadius?: number
backgroundColor?: string
}
interface globalLottleFace {
animUrl?: string //lottie动画链接
animRepeatCount?: number
width?: number
height?: number
}
interface itemViewFace {
id: number | string;
url?: string; //图片链接
text?: string;
animUrl?: string; //动画链接
enable?: boolean; // 可以被选中 被删除被复制 ?
backgroundColor?: string;
isSelected?: boolean; //是否选中
animRepeatCount?: number; //动画重复次数
isEditable?: boolean; //是否可编辑
visibility?: number; //view的显示属性。0-隐藏,1-显示,2-隐藏但保留占位
textColor?: string; //字体颜色
textSize?: number; //字体大小
fontFamilyPath?: string; //字体家族
fontFamilyName?: string; //字体名称
width?: number; //-1表示match_parent, -2表示wrap_content, >=0表示具体的大小 现阶段处理-1 -2就自适应
height?: number
margin?: number[]
padding?: number[]
alpha?: number; //透明度
cornerRadius?: number
selectedBorderColor?: string //选中时列表项的边框颜色。默认是
normalBorderColor?: string //未选中时列表项的边框颜色。默认是
selectedBorderWidth?: number //选中时列表项的边框宽度。默认是0
normalBorderWidth?: number //未选中时列表项的边框宽度。默认是0
}
interface textFace extends globalFace {
text?: string;
}
interface leftIconFace extends globalFace {
url?: string;
}
interface iconFace {
alpha?: number;
url?: string;
visibility?: number
width?: number;
height?: number;
margin?: number[]
padding?: number[]
}
interface rightIconFace extends globalFace {
url?: string
}
interface selectIconFace extends globalFace {
url?: string
selectedUrl?: string //选择图标,需要配置selectedUrl,默认不可见就行,进入编辑状态会主动展示
}
interface loadingAnimViewFace extends globalFace, globalLottleFace {}
interface bgAnimViewFace extends globalFace, globalLottleFace {}
interface frontAnimViewFace extends globalFace, globalLottleFace {}
interface buttonFace extends globalFace {
url?: string
textColor?: string; //文字颜色
textSize?: number; //文字大小
backgroundColor?: string;
cornerRadius?: number
text?: string
fontWeight?: string | number
}
interface listFace {
itemView: itemViewFace,
text: textFace,
leftTopIcon: leftIconFace,
iconImage: iconFace,
rightIcon: rightIconFace,
selectIcon: selectIconFace,
actionButton: buttonFace
}
interface layoutFace {
marginStart: number,
marginEnd: number,
marginTop: number,
marginBottom: number
}
interface bgImgFace extends globalFace {
url?: string;
}
interface MideaDragListData {
id?: string | number,
isEditable?: boolean,
itemView?: itemViewFace,
text?: textFace,
leftTopIcon?: leftIconFace,
iconImage?: iconFace,
rightIcon?: rightIconFace,
selectIcon?: selectIconFace,
actionButton?: buttonFace,
bgImage?: bgImgFace //背景图片
loadingAnimView?: loadingAnimViewFace //点击执行loading动画
bgAnimView?: bgAnimViewFace //执行中的动画
frontAnimView?: frontAnimViewFace //执行成功动画
enable?: boolean //是否可操作
}
interface MideaDragListViewMideaParamsFace {
itemViewHeight?: number, // 高度
spanCount?: number, //列数
spaceSize?: number, //列间距
isEditable?: boolean, //控制整个列表是否可编辑,默认是false, 为true时才显示编辑按钮
isEditing?: boolean, //是否处于编辑状态
layoutConfig?: layoutFace,
list?: MideaDragListData[],
globalData?: MideaDragListData //全局默认参数 每个对象的默认值
}
[@Observed](/user/Observed)
class MideaDragListViewMideaParams {
data: MideaDragListViewMideaParamsFace
componentId: string
width?: number
height?: number
constructor() {
this.data = {
list: []
}
this.componentId = ''
}
}
[@Component](/user/Component)
struct MideaDragListViewMidea {
[@ObjectLink](/user/ObjectLink)
[@Watch](/user/Watch)('paramsWatchFn') //监听
params: MideaDragListViewMideaParams
private canvasContextMap: Map<string, CanvasRenderingContext2D> = new Map()
private animationMap: Map<string, AnimationItem> = new Map()
[@State](/user/State) myRotate: number = 0; // 旋转角度
[@State](/user/State) list: MideaDragListData[] = [] // 列表项数组
[@State](/user/State) selectedItem: MideaDragListData | undefined = {} // 选中项,初始值为undefined
private globalPositionY: number = 0 // 全局Y位置,初始值为0
[@State](/user/State) domWidth: number = 0 // 构建器尺寸
[@State](/user/State) domHeight: number = 0 // 构建器尺寸
[@State](/user/State) containerHeight: number = 0 // 容器高度
[@State](/user/State) containerWidth: number = 0 // 容器宽度
// 拖动元素初始位置
[@State](/user/State) dragStartX: number = 0 // 拖动开始的X位置
[@State](/user/State) dragStartY: number = 0 // 拖动开始的Y位置
// 拖动元素偏移距离
[@State](/user/State) offsetX: number = 0 // 拖动偏移的X距离
[@State](/user/State) offsetY: number = 0 // 拖动偏移的Y距离
// 拖动后滚动距离
[@State](/user/State) scrollLen: number = 0 // 滚动距离
[@State](/user/State) dragOffsetX: number = 0 // 拖动后的X偏移
[@State](/user/State) dragOffsetY: number = 0 // 拖动后的Y偏移
private scroller: Scroller = new Scroller(); // 滚动控制器
[@State](/user/State) spanCount: number = 4
private componentId: string = ''
timer: number = -1
init() {
this.spanCount = this.params?.data?.spanCount ?? 4
this.list = this.params?.data?.list || []
console.info('list', this.list)
if (this.params.data.isEditing) {
this.animationTo()
}
this.initList(this.params?.data?.globalData || {})
}
initList(data: MideaDragListData) {
this.list= this.list.map(item => {
item.text = ObjectUtil.Assign(data?.text || {}, item.text)
item.actionButton = ObjectUtil.Assign(data?.actionButton || {}, item.actionButton)
item.leftTopIcon = ObjectUtil.Assign(data?.leftTopIcon || {}, item.leftTopIcon)
item.iconImage = ObjectUtil.Assign(data?.iconImage || {}, item.iconImage)
item.rightIcon = ObjectUtil.Assign(data?.rightIcon || {}, item.rightIcon)
item.selectIcon = ObjectUtil.Assign(data?.selectIcon || {}, item.selectIcon)
item.bgImage = ObjectUtil.Assign(data?.bgImage || {}, item.bgImage)
item.loadingAnimView = ObjectUtil.Assign(data?.loadingAnimView || {}, item.loadingAnimView)
item.bgAnimView = ObjectUtil.Assign(data?.bgAnimView || {}, item.bgAnimView)
item.frontAnimView = ObjectUtil.Assign(data?.frontAnimView || {}, item.frontAnimView)
item.itemView = ObjectUtil.Assign(data?.itemView || {} as itemViewFace, item.itemView)
item.id = item.itemView.id
return item
}, (item: MideaDragListData) => {
return `${item?.itemView?.id}-${item?.itemView?.isSelected}`
})
console.log('cdj---list', JSON.stringify(this.list))
}
animationTo() {
clearInterval(this.timer)
this.timer = setInterval(() => {
animateTo({ curve: curves.interpolatingSpring(0, 1, 1000, 138) }, () => {
this.myRotate = this.myRotate === -6 ? 6 : -6;
})
}, 140);
}
// 页面隐藏时统一清理
onPageHide() {
console.log('onPageHide')
this.animationMap.forEach(anim => anim.destroy())
this.animationMap.clear()
lottie.destroy()
}
aboutToAppear(): void {
this.init()
this.componentId = this.params?.componentId;
}
paramsWatchFn() {
console.info('this?.params?.data', JSON.stringify(this?.params?.data))
this.init()
this.domWidth = (this.containerWidth) / this.spanCount;
if (!this.params.data.isEditing) {
clearInterval(this.timer)
this.myRotate = 0
}
}
[@Builder](/user/Builder)
MideaToggle($$: MideaDragListData) {
Image($$?.itemView?.isSelected ?
($$?.selectIcon?.selectedUrl || this.params?.data?.globalData?.selectIcon?.selectedUrl)
: ($$?.selectIcon?.url || this.params?.data?.globalData?.selectIcon?.url)
)
.draggable(false).attributeModifier(new defaultAttr($$?.selectIcon as globalFace))
.onClick(() => {
console.log('item.itemView.isSelected', $$?.itemView?.isSelected)
if ($$?.itemView) {
$$.itemView.isSelected = !$$.itemView.isSelected;
}
this.onSelectItems()
this.updateListItem($$)
})
}
[@Builder](/user/Builder)
MideaButton(item: MideaDragListData) {
Button(item?.actionButton?.text ).draggable(false)
.attributeModifier(new defaultAttr(item?.actionButton as globalFace))
.onClick(() => {
console.log('我是儿子')
})
}
[@Builder](/user/Builder)
MideaRightIcon(item: MideaDragListData) {
Image(item?.rightIcon?.url).draggable(false)
.attributeModifier(new defaultAttr(item?.rightIcon as globalFace))
}
[@Builder](/user/Builder)
ItemBuilder($$: MideaDragListData) {
Flex({
direction: FlexDirection.Column,
justifyContent: FlexAlign.SpaceAround
}) {
if (!this.params.data.isEditing) {
this.LottieBox('bgAnimView', $$?.bgAnimView)
this.LottieBox('frontAnimView', $$?.frontAnimView)
}
Image($$?.leftTopIcon?.url)
.attributeModifier(new defaultAttr($$?.leftTopIcon as globalFace))
.position({
left: 0,
top: 0
})
Flex({
justifyContent: FlexAlign.SpaceBetween
}) {
Image(
$$?.iconImage?.url
).draggable(false)
.attributeModifier(new defaultAttr($$?.iconImage as globalFace))
if (!this.params.data.isEditing) {
this.MideaButton($$)
this.MideaRightIcon($$)
this.LottieBox('loadingAnimView', $$?.loadingAnimView)
} else {
this.MideaToggle($$);
}
}
Text($$?.text?.text)
.attributeModifier(new defaultAttr($$?.text as globalFace))
.textOverflow({ overflow: TextOverflow.Ellipsis })
.maxLines(1)
}
.attributeModifier(new defaultAttr($$?.itemView as globalFace))
.borderWidth($$?.itemView?.normalBorderColor || this.params?.data?.globalData?.itemView?.normalBorderColor)
.borderColor($$?.itemView?.normalBorderWidth || this.params?.data?.globalData?.itemView?.normalBorderWidth)
.visibility(0)
.rotate({
z: 1,
angle: this.myRotate
})
.onClick(() => {
console.log('我是粑粑')
})
.enabled($$?.itemView?.enable || this.params?.data?.globalData?.enable)
}
[@Builder](/user/Builder)
dragBuilder() {
Flex() {
if (this.selectedItem?.itemView?.id) {
this.ItemBuilder(this.selectedItem)
}
}
.hitTestBehavior(HitTestMode.None)
.zIndex(1)
.width(this.domWidth)
.position({ x: this.dragStartX + this.offsetX, y: this.dragStartY + this.offsetY - this.globalPositionY })
.onAreaChange((_, newValue) => {
if (this.selectedItem === undefined) {
return
}
if (newValue.position.y && newValue.position.y < 0) {
this.scroller.scrollEdge(Edge.Top, { velocity: 300 })
} else if (newValue.position.y && newValue.position.y > this.containerHeight - this.domHeight) {
this.scroller.scrollEdge(Edge.End, { velocity: 300 })
} else {
this.scroller.scrollTo(this.scroller.currentOffset())
}
})
}
reset() {
this.selectedItem = {}
this.scrollLen = 0
this.dragStartX = 0
this.dragStartY = 0
this.dragOffsetX = 0
this.dragOffsetY = 0
this.offsetX = 0
this.offsetY = 0
this.scroller.scrollTo(this.scroller.currentOffset())
}
itemMove(index: number, newIndex: number) {
let tmp = this.list.splice(index, 1)
this.list.splice(newIndex, 0, tmp[0])
}
getIndex() {
let index = -1;
index = this.list.findIndex(item => item?.itemView?.id == this?.selectedItem?.itemView?.id)
return index
}
handleDrag() {
const index = this.getIndex();
if (index < 0) {
return;
}
const boundaryA = this.spanCount + 1; //边界 5
const boundaryB = this.spanCount; //边界 4
const boundaryC = this.spanCount - 1; //边界 3
let x = this.offsetX - this.dragOffsetX; //当前位置 = 移动后的位置 - 点击位置
let y = this.scrollLen + this.offsetY - this.dragOffsetY; // 当前位置 = y轴滚动偏差 + 移动后的位置 - 点击位置
//拉到容器外需要限制一下
y = y > this.domHeight ? this.domHeight : y
x = x > (this.containerWidth - (this.domWidth / 2)) ? (this.containerWidth - (this.domWidth / 2)) : x
let itemWidth = this.domWidth; //拖拽容器宽度的边界
let translateWidth = itemWidth / 2; // 拖拽容器中心位置
let slashLength = itemWidth / 2; // 实际容器边界
let itemHeight = this.domHeight; // 拖拽容器高度的边界
let translateHeight = itemHeight / 2; // 拖拽容器中心位置
let slashHeight = itemHeight / 2; // 实际容器边界
const z = (str: number) => Number.parseInt(str.toString())
const getLog = (text: string) => {
console.info(text, JSON.stringify({
index,
y: z(y),
x: z(x),
offsetX: z(this.offsetX),
offsetY: z(this.offsetY),
dragOffsetY: z(this.dragOffsetY),
dragOffsetX: z(this.dragOffsetX),
containerWidth: z(this.containerWidth)
}));
};
//交换的时候 中间间隔多少个兄弟元素
const offest = (index % boundaryB) - (this.list.length % boundaryB)
console.info('日志1', JSON.stringify({
x,
offest,
xxx: x * offest,
y,
translateWidth,
translateHeight,
offsetX: this.offsetX,
dragOffsetX: this.dragOffsetX,
dragOffsetY: this.dragOffsetY
}))
if (y >= translateHeight && (x < slashLength && x > -slashLength)) {
// 从上移动到下 元素向前补位
if (index + boundaryA > (this.list.length)) {
return
}
this.itemMove(index, index + boundaryB)
this.dragOffsetY += itemHeight;
getLog('上到下');
} else if (y <= -translateHeight && (x < slashLength && x > -slashLength)) {
// 从下到上
if (index < boundaryB) {
return
}
this.itemMove(index, index - boundaryB)
this.dragOffsetY -= itemHeight;
getLog('下到上');
console.info('下到上', index, index - boundaryB)
} else if (x >= translateWidth && (y < slashHeight && y > -slashHeight)) {
// 从左到右
if (index + 1 >= this.list.length) { //边界不动 不补位
return;
}
this.itemMove(index, index + 1);
this.dragOffsetX += itemWidth;
getLog('左到右');
} else if (x <= -translateWidth && (y < slashHeight && y > -slashHeight)) {
// 从右到左
if (index % boundaryB === 0) {
return
}
this.itemMove(index, index - 1)
this.dragOffsetX -= itemWidth;
getLog('右到左');
} else if (x >= translateWidth && y >= translateHeight) {
// 右下移动
if (index % boundaryB === boundaryC || index + boundaryA > this.list.length) {
return
}
this.itemMove(index, index + boundaryA)
this.dragOffsetX += itemWidth;
this.dragOffsetY += itemHeight;
getLog('右下角');
} else if (x >= translateWidth && y <= -translateHeight) {
// 右上移动
if (index % boundaryB === boundaryC || (index - boundaryC < 0)) {
return;
}
this.itemMove(index, index - boundaryC);
this.dragOffsetX += itemWidth;
this.dragOffsetY -= itemHeight;
getLog('右上角');
} else if (x <= -translateWidth && y <= -translateHeight) {
// 左上
if (index % boundaryB === 0 || (index - boundaryA < 0)) {
return
}
this.itemMove(index, index - boundaryA)
this.dragOffsetX -= itemWidth;
this.dragOffsetY -= itemHeight;
getLog('左上角');
} else if (
x <= -(translateWidth + (this.domWidth * offest)) && y >= translateHeight) {
console.info('左下', JSON.stringify({
x,
offest,
xxx: x * offest,
y,
translateWidth,
domWidth: this.domWidth,
translateHeight,
offsetX: this.offsetX
}))
if (index % boundaryB === 0) {
return
}
this.itemMove(index, this.list.length)
// 记录交换后的位置 -自身宽度以及间隔元素宽度 只有在最后一行不填满的情况 并且是倒数第二行交换的时候才需要计算
this.dragOffsetX -= (itemWidth + (itemWidth * offest));
this.dragOffsetY += itemHeight;
console.info('dragOffsetY~~~', this.dragOffsetY)
}
console.info('dddd', JSON.stringify({
x,
offest,
xxx: x * offest,
y,
translateWidth,
translateHeight,
offsetX: this.offsetX,
dragOffsetX: this.dragOffsetX,
dragOffsetY: this.dragOffsetY
}))
}
// 设计事件
updateListItem(data: MideaDragListData): void {
const id = data?.itemView?.id
if (!id) {
return;
}
const index = this.list.findIndex(item => item.itemView?.id === id);
if (index === -1) {
return;
}
// 创建新对象
const newItem = data as MideaDragListData;
// 替换数组元素
this.list.splice(index, 1, newItem);
this.list = this.list.slice();
}
private getListData() {
return this.list
}
onSelectItems() { //是编辑状态下,选中的 item的 id 数组 返回的是ids:["21675327"]
const selectedIds = this.list
.filter(item => item?.itemView?.isSelected)
.map(item => item?.itemView?.id);
console.log('cdj------selectedIds', selectedIds,)
}
//lottie动画相关----------------------------
[@Builder](/user/Builder)
LottieBox(name: string, item?: globalLottleFace) {
Canvas(this.createCanvasContext(name))
.onReady(() => {
const ctx = this.createCanvasContext(name)
ctx.imageSmoothingEnabled = true
ctx.imageSmoothingQuality = 'medium'
if (!this.animationMap.has(name)) {
this.loadAnimation(name, item as globalLottleFace)
}
})
.attributeModifier(new defaultAttr(item as globalFace))// .zIndex(name === 'frontAnimView' ? 100 : 0)
.position(name !== 'loadingAnimView' ? {
right: 0,
top: 0,
bottom: 0,
left: 0
} : {})
}
// 创建并缓存 Canvas 渲染上下文
createCanvasContext(name: string): CanvasRenderingContext2D {
if (!this.canvasContextMap.has(name)) {
const settings = new RenderingContextSettings(true)
const context = new CanvasRenderingContext2D(settings)
this.canvasContextMap.set(name, context)
}
return this.canvasContextMap.get(name)!
}
// 加载动画
loadAnimation(name: string, item: globalLottleFace) {
const context = this.createCanvasContext(name)
this.animationMap.get(name)?.destroy()
const animation = lottie.loadAnimation({
container: context,
renderer: 'canvas',
autoplay: true,
loop: item?.animRepeatCount,
name,
contentMode: name !== 'loadingAnimView' ? 'Fill' : 'Contain',
uri: item?.animUrl
})
this.animationMap.set(name, animation)
}
build() {
Column() {
Button('切换编辑状态').onClick(() => {
this.params.data.isEditing = !this.params.data.isEditing
console.log('编辑状态', this.params.data.isEditing)
})
Text(`${this.params.data.isEditing}`)
Column() {
if (this?.selectedItem?.itemView?.id !== undefined) {
this.dragBuilder()
}
Scroll(this.scroller) {
Column() {
Grid() {
ForEach(this.list, (item: MideaDragListData) => {
GridItem() {
this.ItemBuilder(item)
}
.opacity(this.selectedItem?.itemView?.id === item?.itemView?.id ? 0 : 1)
.onClick((event) => {
})
.gesture( //手势事件
GestureGroup(GestureMode.Sequence,
LongPressGesture({ repeat: true })//长按手指事件
.onAction((event?: GestureEvent) => {
console.log('cdj==', JSON.stringify(event?.target))
if (!this.params.data.isEditable) {
return
}
if (this.params.data.isEditable) {
this.animationTo()
}
this.params.data.isEditing = true
//点击坐标
if (this.selectedItem?.itemView?.id === undefined) {
this.selectedItem = item
this.dragStartX = Number(event?.target.area.globalPosition.x)
this.dragStartY = Number(event?.target.area.globalPosition.y)
}
})
.onActionEnd(() => {
this.reset()
}),
PanGesture({ fingers: 1, direction: null, distance: 0 })//1指拖动时
.onActionStart((event) => { //开始拖动
if (!this.params.data.isEditable) {
return
}
this.scrollLen = 0
this.selectedItem = item
})
.onActionUpdate(event => { //拖动过程中
this.offsetY = event.offsetY
this.offsetX = event.offsetX
//curve 动画曲线 速度 弹性 刚度 阻尼
animateTo({ curve: curves.interpolatingSpring(0, 1, 400, 38) }, () => {
this.handleDrag()
})
})
.onActionEnd((event) => { //抬起 结束
this.reset()
})
)
.onCancel(() => {
this.reset()
})
)
}, (item: MideaDragListData) => {
return `${item?.itemView?.id}-${item?.itemView?.isSelected}`
})
}
.columnsTemplate(`repeat(${this.spanCount}, 1fr)`)
.columnsGap(this.params.data.spaceSize ?? 10) // 列与列间距
.rowsGap(10) // 行与行
}
.padding(10)
.alignItems(HorizontalAlign.Start)
}
.width(this.params.width)
.height(this.params.height || 400)
.align(Alignment.Top)
.scrollBar(BarState.Off) //隐藏滚动条
.onDidScroll((x, y) => {
if (this?.selectedItem?.itemView?.id !== undefined) {
this.scrollLen += y //滚动距离
// this.handleDrag()
}
})
.onAreaChange((_, newValue) => {
if (!this?.params?.data?.list?.length) {
return
}
console.info('this.globalPositionY ', JSON.stringify(newValue))
//初始化
this.globalPositionY = Number(newValue.globalPosition.y)
this.containerWidth = Number(newValue.width)
this.containerHeight = Number(newValue.height)
this.domWidth = (this.containerWidth) / this.spanCount;
const size = this?.params?.data?.spaceSize ?? 10
const dowSize = (size * this.spanCount) + size
console.log('newValue.height', this.containerHeight, this?.params?.data?.spaceSize, this.spanCount,
this?.params?.data?.list?.length)
this.domHeight = (this.containerHeight - dowSize) / (this?.params?.data?.list?.length / this.spanCount) ?? 60
// 高度减去间距 / 长度/行数得到每列几个
console.info('domWidth', this.domWidth)
console.info('containerHeight', this.containerHeight)
})
}
.clip(true)
}
}
}
[@Observed](/user/Observed)
class defaultAttr implements AttributeModifier<ButtonAttribute | TextAttribute | FlexAttribute> {
data: globalFace = {}
visibilitArr = [Visibility.None, Visibility.Visible, Visibility.Hidden] // 0-隐藏,1-显示,2-隐藏但占位
constructor(item: globalFace) {
this.data = item || {}
console.log('init', item)
}
applyNormalAttribute(instance: ButtonAttribute | TextAttribute | FlexAttribute | CanvasAttribute): void {
try {
const fontStyle = instance as ButtonAttribute | TextAttribute
fontStyle.fontColor(this.data?.textColor ?? '#000000')
fontStyle.fontWeight(this.data?.fontWeight)
fontStyle.fontFamily(this.data?.fontFamilyPath)
fontStyle.fontSize(this.data?.textSize ?? 16)
} catch (e) {}
instance.visibility(
this.visibilitArr[this.data.visibility ?? 1]
)
instance.width(this.data?.width )
instance.backgroundColor(this.data?.backgroundColor)
instance.height(this.data?.height )
instance.borderRadius(this.data?.cornerRadius)
instance.margin({
top: this.data?.margin?.[1] ?? 0,
left: this.data?.margin?.[0] ?? 0,
right: this.data?.margin?.[2] ?? 0,
bottom: this.data?.margin?.[3] ?? 0
})
instance.padding({
top: this.data?.padding?.[1] ?? 0,
left: this.data?.padding?.[0] ?? 0,
right: this.data?.padding?.[2] ?? 0,
bottom: this.data?.padding?.[3] ?? 0
})
instance.opacity(this.data?.alpha)
}
}
[@Builder](/user/Builder)
export function NativeDragListViewMidea($$: MideaDragListViewMideaParams) {
MideaDragListViewMidea({
params: {
data: $$.data,
componentId: $$.componentId,
width: $$.width,
height: $$.height
}
})
}
[@Entry](/user/Entry)
[@Component](/user/Component)
struct demo {
initData: MideaDragListViewMideaParamsFace = {}
aboutToAppear(): void {
this.initData = {
spanCount: 2, //列数
spaceSize: 8,
isEditable: true, //控制整个列表是否可编辑,默认是false, 为true时才显示编辑按钮
layoutConfig: {
marginStart: 15,
marginEnd: 15,
marginTop: 0,
marginBottom: 0
},
list: [
{
"itemView": {
"id": 21675327,
"enable": true,
"backgroundColor": "#F6F7F9",
"isSelected": false
},
"text": {
"text": "离家场景49",
"alpha": 1,
"textColor": "#5e8392",
"visibility": 1,
},
"leftTopIcon": {
"visibility": 1,
"alpha": 1,
"url": "http://10.133.240.64:5501/dist/midea-rooms/assets/img/new2025@2x.png"
},
"iconImage": {
"alpha": 1,
"url": "https://xxx/sit/app/v1/manual_scene_icon/1.png"
},
"rightIcon": {
"visibility": 1,
"alpha": 1,
"url": "http://10.133.240.64:5501/dist/midea-rooms/assets/img/home_ic_wrong_s@2x.png"
},
"selectIcon": {
"visibility": 1
},
"actionButton": {
"visibility": 0
}
},
{
"itemView": {
"id": 21675325,
"enable": true,
"backgroundColor": "#F6F7F9",
"isSelected": false
},
"text": {
"text": "离家场景48",
"alpha": 1
},
"leftTopIcon": {
"visibility": 0,
"alpha": 1,
"url": "http://10.133.240.64:5501/dist/midea-rooms/assets/img/new2025@2x.png"
},
"iconImage": {
"alpha": 1,
"url": "https://xxx/sit/app/v1/manual_scene_icon/1.png"
},
"rightIcon": {
"visibility": 0,
"alpha": 1
},
"selectIcon": {
"visibility": 1
},
"actionButton": {
"visibility": 1
}
},
{
isEditable: true,
"itemView": {
"id": 21674863,
"enable": true,
"backgroundColor": "#F6F7F9",
"isSelected": false
},
"text": {
"text": "离家场景45",
"alpha": 1
},
"leftTopIcon": {
"visibility": 0,
"alpha": 1,
"url": "http://10.133.240.64:5501/dist/midea-rooms/assets/img/new2025@2x.png"
},
"iconImage": {
"alpha": 1,
"url": "https://xxx/sit/app/v1/manual_scene_icon/1.png"
},
"rightIcon": {
"visibility": 0,
"alpha": 1
},
"selectIcon": {
"visibility": 1
},
"actionButton": {
"visibility": 1
}
},
{
"itemView": {
"id": 21675191,
"enable": true,
"backgroundColor": "#F6F7F9",
"isSelected": false
},
"text": {
"text": "复制离家场景45",
"alpha": 1
},
"leftTopIcon": {
"visibility": 0,
"alpha": 1,
"url": "http://10.133.240.64:5501/dist/midea-rooms/assets/img/new2025@2x.png"
},
"iconImage": {
"alpha": 1,
"url": "https://xxx/sit/app/v1/manual_scene_icon/1.png"
},
"rightIcon": {
"visibility": 0,
"alpha": 1
},
"selectIcon": {
"visibility": 1
},
"actionButton": {
"visibility": 1
}
},
{
isEditable: true,
"itemView": {
"id": 21134863,
"enable": true,
"backgroundColor": "#F6F7F9",
"isSelected": false
},
"text": {
"text": "离家场景45",
"alpha": 1
},
"leftTopIcon": {
"visibility": 0,
"alpha": 1,
"url": "http://10.133.240.64:5501/dist/midea-rooms/assets/img/new2025@2x.png"
},
"iconImage": {
"alpha": 1,
"url": "https://xxx/sit/app/v1/manual_scene_icon/1.png"
},
"rightIcon": {
"visibility": 0,
"alpha": 1
},
"selectIcon": {
"visibility": 1
},
"actionButton": {
"visibility": 1
}
},
{
"itemView": {
"id": 21675391,
"enable": true,
"backgroundColor": "#F6F7F9",
"isSelected": false
},
"text": {
"text": "复制离家场景45",
"alpha": 1
},
"leftTopIcon": {
"visibility": 0,
"alpha": 1,
"url": "http://10.133.240.64:5501/dist/midea-rooms/assets/img/new2025@2x.png"
},
"iconImage": {
"alpha": 1,
"url": "https://xxx/sit/app/v1/manual_scene_icon/1.png"
},
"rightIcon": {
"visibility": 0,
"alpha": 1
},
"selectIcon": {
"visibility": 1
},
"actionButton": {
"visibility
更多关于HarmonyOS鸿蒙Next中@Bulider不更新的实战教程也可以访问 https://www.itying.com/category-93-b0.html
2 回复
在HarmonyOS鸿蒙Next中,@Builder
装饰器用于定义可复用的UI组件。如果发现@Builder
不更新,可能的原因包括:
-
状态未更新:确保传递给
@Builder
的状态变量已更新。使用@State
或@Link
等装饰器管理状态,确保状态变化时UI重新渲染。 -
依赖未变化:
@Builder
依赖于传入的参数,如果参数未变化,UI不会更新。检查参数是否正确传递并变化。 -
组件未重新构建:确保父组件在状态变化时重新构建,从而触发
@Builder
的更新。 -
使用
@Watch
监控变化:在@Builder
中使用@Watch
装饰器监控特定状态变量的变化,确保状态变化时触发更新。
检查以上几点,确保@Builder
能正确响应状态变化并更新UI。