HarmonyOS 鸿蒙Next List 删除数据源UI更新的同时 如何设置删除动画效果
HarmonyOS 鸿蒙Next List 删除数据源UI更新的同时 如何设置删除动画效果
有的话麻烦提供下示例代码
index.ets
import { LazyDataSource } from '../model/LazyDataSource'
@Observed
export class Item {
constructor(data: string
) {
this.data = data
}
public data: string
public offsetY: number = 0
public scale: number = 1
public opacity: number = 1
}
@Extend(Button)
function circleStyle(background: ResourceColor) {
.type(ButtonType.Circle)
.backgroundColor(background)
}
@Component
export struct CardItem {
@ObjectLink item: Item
build() {
Row() {
Text(this.item.data)
.fontSize(16)
.width(“100%”)
.height(“100%”)
.textAlign(TextAlign.Center)
.borderRadius(12)
}
.translate({ y: this.item.offsetY })
.borderRadius(12)
.height(108)
.justifyContent(FlexAlign.Center)
.width(“100%”)
.backgroundColor("#fff")
}
}
@Entry
@Component
export struct ListPinAnimation {
@State dataSource: LazyDataSource<Item> = new LazyDataSource()
@State CurrentIndex: string = ‘undefined’
private scrollerForList: Scroller = new Scroller()
@State EndOffset:number = 0
@Builder
renderSwipeAction(item: Item) {
Row({ space: 12 }) {
Stack().flexGrow(6)
Button().circleStyle(“rgb(63, 196, 63)”)
Stack().flexGrow(6)
Button().circleStyle(“rgb(0, 157, 227)”)
Stack().flexGrow(6)
Button().circleStyle(“rgb(239, 29, 31)”).onClick(() => {
this.CurrentIndex = item.data
const index = this.dataSource.indexOf(item)
this.EndOffset = 0
animateTo({ duration: 0 }, () => {
this.dataSource.deleteItem(item)
})
for (let i = 0; i < this.dataSource.totalCount(); ++i) {
const element = this.dataSource.getData(i)
if (i < index) {
element.offsetY = this.EndOffset
} else {
element.offsetY = 120 + this.EndOffset
}
}
for (let i = 0; i < this.dataSource.totalCount(); ++i) {
const element = this.dataSource.getData(i)
animateTo({
curve: Curve.Friction,
duration: 350,
delay: Math.abs(index - i) * 16.67,
}, () => {
element.offsetY = 0
})
}
})
Stack().flexGrow(1)
}.padding(12)
}
build() {
Column() {
List({ space: 12, scroller: this.scrollerForList }) {
LazyForEach(this.dataSource, (item: Item) => {
ListItem() {
CardItem({ item:item })
}
.transition(
// 只需要删除动效,所以使用不对成的过度效果
TransitionEffect.asymmetric(// 入场动效:无
TransitionEffect.IDENTITY,
// 退场动效:尺寸缩放变化+透明度变化
TransitionEffect.scale({ x: 0.75, y: 0.75 })
.animation({ curve: Curve.Friction, duration: 300 })
.combine(
TransitionEffect.OPACITY.animation({ curve: Curve.Sharp, duration: 300 })
)
)
)
.clip(false)
.zIndex(this.CurrentIndex == item.data ? 1 : 2)
.swipeAction({ end: this.renderSwipeAction(item) })
.width(“100%”)
}, (item: Item) => item.data)
}
.height(“100%”)
.scrollBar(BarState.Off)
.onScroll((scrollOffset: number, scrollState: ScrollState) => {
console.log(<span class="hljs-subst">${scrollOffset}</span>
)
this.EndOffset = scrollOffset
})
}
.backgroundColor("#f1f2f3")
.height(“100%”)
.padding(24)
.width(“100%”)
}
aboutToAppear() {
for (let i = 0; i < 50; i++) {
this.dataSource.pushItem(new Item(i.toString()))
}
}
}
```
LazyDataSource.ets
```
export class LazyDataSource<T> implements IDataSource {
private elements: T[]
private listeners: Set<DataChangeListener>
constructor(elements: T[] = []) {
this.elements = elements
this.listeners = new Set()
}
public totalCount(): number {
return this.elements.length
}
public getData(index: number): T {
return this.elements[index]
}
public indexOf(item: T): number {
return this.elements.indexOf(item)
}
public pinItem(item: T, index: number): void {
this.elements.splice(index, 1)
this.elements.unshift(item)
this.listeners.forEach(listener => listener.onDataReloaded())
}
public addItem(item: T) {
this.elements.unshift(item)
this.listeners.forEach(listener => listener.onDataAdd(0))
}
public pushItem(item: T) {
this.elements.push(item)
this.listeners.forEach(listener => listener.onDataAdd(this.elements.length - 1))
}
public insertItem(item: T, index: number) {
this.elements.splice(index, 0, item)
this.listeners.forEach(listener => listener.onDataAdd(index))
}
public deleteItem(item: T): void {
const index = this.elements.indexOf(item)
if (index < 0) {
return
}
this.elements.splice(index, 1)
this.listeners.forEach(listener => listener.onDataDelete(index))
}
public deleteItemByIndex(index: number): void {
this.elements.splice(index, 1)
this.listeners.forEach(listener => listener.onDataDelete(index))
}
public registerDataChangeListener(listener: DataChangeListener): void {
this.listeners.add(listener)
}
public unregisterDataChangeListener(listener: DataChangeListener): void {
this.listeners.delete(listener)
}
}
更多关于HarmonyOS 鸿蒙Next List 删除数据源UI更新的同时 如何设置删除动画效果的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS鸿蒙系统中,为Next List组件设置删除数据源后的UI更新及删除动画效果,可以通过以下步骤实现:
-
数据源更新:
- 当你从数据源中移除某个项目时,确保数据源列表(例如ArrayList)已正确更新。
- 调用适配器的
notifyDataSetChanged()
或notifyItemRemoved(int position)
方法来通知列表更新。
-
动画效果设置:
- 在你的
RecyclerView.Adapter
中,重写onBindViewHolder
方法,并在其中设置动画。 - 可以通过
ViewHolder
的itemView
获取到要动画的视图,然后使用AnimationUtils.loadAnimation
加载动画资源。 - 在删除数据后,立即对相应的视图应用动画,例如淡出或滑动效果。
- 在你的
-
同步UI与动画:
- 确保数据源更新和动画执行是同步进行的,即在数据源更新后紧接着启动动画。
- 可以通过在
notifyItemRemoved
之后立即启动动画来实现。
示例代码片段(伪代码):
// 假设你有一个名为adapter的RecyclerView.Adapter实例
dataSource.remove(position);
adapter.notifyItemRemoved(position);
View viewToRemove = recyclerView.findViewHolderForAdapterPosition(position).itemView;
Animation animation = AnimationUtils.loadAnimation(context, R.anim.slide_out_right);
viewToRemove.startAnimation(animation);
注意:以上代码仅为示例,实际实现需根据具体需求调整。如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html