HarmonyOS list删除条目时,如何添加动画效果?

list列表删除条目时,需要添加个从右向左移除的一个动画,如何添加设置呢?目前删除条目,不使用自带的左滑删除,而是我们自己添加的按钮,点击按钮删除

需求:当前页面为待办列表,每个item上有个子组件image(垃圾桶标志),点击垃圾桶去删除当前待办的条目,点击后弹出确认是否删除的dialog,点击确认后,删除当前待办,并且将该条目移除,移除过程中需要添加动画效果,将该条目从屏幕右侧缓慢移除屏幕外的动画效果。

@Observed
export class SinglePlatformBean{
  appid:string = ''
  cordovaid:string = ''
  date:number = 0
  deleted:number = 0
  id:number = 0
  if_can_praise:string = ''
  if_can_share:string = ''
  is_completed:number = 0
  platform_id:number = 0
  platform_title:string = ''
  status:number = 0
  sumary:string = ''
  title:string = ''
  type:number = 0
  url:string = ''

  constructor() {
  }
}



@CustomDialog
export struct CustomControllerDialog {
  controller?: CustomDialogController
  cancel: () => void = () => {
  }
  confirm: () => void = () => {
  }
  title?: string = ''

  build() {
    Column() {
      Text('是否忽略该待办')
        .fontColor($r('app.color.ice_black'))
        .fontSize(17)
        .margin({ bottom: 10 })

      Text('待办:' + this.title)
        .fontSize(15)
        .fontColor($r('app.color.rgb_color_51'))
        .width('100%')
        .textAlign(TextAlign.Start)
        .maxLines(1)
        .ellipsisMode(EllipsisMode.CENTER)

      Text('\n' + '说明:此操作只忽略iCE的待办提醒,不变更具体的业务状态。')
        .fontSize(15)
        .fontColor($r('app.color.rgb_color_51'))
        .width('100%')
        .textAlign(TextAlign.Start)

      Divider()
        .margin({ top: 10 })
        .height(1)

      Row(){
        Divider().height(30).width(1)
          .backgroundColor($r('app.color.rgb_color_204'))
        // .align(Alignment.Start)
        Row() {
          Text('取消').fontSize(15)
            .width('50%')
            .fontColor($r('app.color.rgb_color_0_112_192'))
            .textAlign(TextAlign.Center)
            .onClick(() => {
              this.cancel()
            })
          Divider().height(30).width(1)
            .backgroundColor($r('app.color.rgb_color_204'))
          Text('确定').fontSize(15)
            .fontColor($r('app.color.rgb_color_0_112_192'))
            .width('50%')
            .textAlign(TextAlign.Center)
            .onClick(() => {
              this.confirm()
            })

        }
        .height(30)
        .width('100%')
        .justifyContent(FlexAlign.SpaceEvenly)

        Divider().height(30).width(1)
          .backgroundColor($r('app.color.rgb_color_204'))

      }

      Divider().height(1)
    }
    // .justifyContent(FlexAlign.Center)
    .padding(20)
  }
}




import { PullToRefresh } from '@ohos/pulltorefresh';
import { LogUtil } from '@pura/harmony-utils';
import { SinglePlatformBean } from '../model/SinglePlatformBean';
import { CustomControllerDialog } from './CustomControllerDialog';
import { TestListComp } from './TestListComp';

@Entry
@Component
export struct TestPage {
  @State message: string = 'Hello World';
  @State singlePlatfroms: SinglePlatformBean[] = []
  private scroller: Scroller = new Scroller();
  platFormId: number = 0
  dialogController: CustomDialogController | null = new CustomDialogController({
    builder: CustomControllerDialog({
      cancel: () => {
        this.onCancel()
      },
      confirm: () => {
        this.onConfirm()
      },
      // title: this.platFormTitle
    }),
    alignment: DialogAlignment.Center,
  })

  aboutToAppear(): void {
    for (let i = 0; i < 10; i++) {
      let obj = new SinglePlatformBean()
      //通过这个值在刷新UI
      obj.is_completed = 1 //1是待办, 2是已办
      obj.id = i
      obj.cordovaid = ''
      this.singlePlatfroms.push(obj)
    }
  }

  onCancel() {
    if (this.dialogController != undefined) {
      this.dialogController.close()
    }
  }

  onConfirm() {
    this.singlePlatfroms.forEach((obj: SinglePlatformBean, index: number) => {
      if (obj.id == this.platFormId) {

        //点击当前条目后更新数据源,删除条目,并且驱动UI更新,删除的时候需要当前条目有移动条目的动画效果
        this.singlePlatfroms.splice(index, 1)

        LogUtil.debug('待办状态修改前--obj.id---' + obj.id + '----' + obj.is_completed)
        // obj.is_completed = 2
        LogUtil.debug('待办状态修改后--' + obj.is_completed)
      }
    })
  }

  build() {
    Column() {
      //列表
      PullToRefresh({
        data: $singlePlatfroms,
        scroller: this.scroller,
        customList: () => {
          this.getListView()
        },
        onRefresh: () => {
          return new Promise<string>((resolve, reject) => {
            resolve('刷新完成')
          });
        },
        // 可选项,上拉加载更多回调
        onLoadMore: () => {
          return new Promise<string>((resolve, reject) => {
            resolve('加载完成')
          });
        },
        customLoad: null,
        customRefresh: null,
      })
        .alignRules({
          top: { anchor: 'nav', align: VerticalAlign.Bottom },
          bottom: { anchor: '__container__', align: VerticalAlign.Bottom }
        })
    }
  }

  @Builder
  getListView() {
    List({ scroller: this.scroller }) {
      ForEach(this.singlePlatfroms, (singlePlatfrom: SinglePlatformBean, index?: number) => {
        ListItem() {
          TestListComp({
            singlePlatfrom: singlePlatfrom, changeState: (item: number, title: string) => {
              //待办变已办
              console.debug('item--' + item)
              if (this.dialogController != null) {
                this.dialogController.open()
                this.platFormId = item
              }
            }
          })
        }
      })
    }.width('96%')
    .margin({ top: 10, bottom: 10 })
    .edgeEffect(EdgeEffect.None) // 必须设置列表为滑动到边缘无效果
    .scrollBar(BarState.Off)
  }
}





import { SinglePlatformBean } from '../model/SinglePlatformBean'

@Component
export struct TestListComp {
  @ObjectLink singlePlatfrom: SinglePlatformBean
  changeState?: (item: number,title:string) => (void)

  build() {
    Column() {
      RelativeContainer() {
        Column() {
          Text(this.singlePlatfrom.title)
            .fontSize(17)
            .fontColor($r('app.color.rgb_color_51'))
            .maxLines(2)
            .margin({
              top: 15
            })
            .ellipsisMode(EllipsisMode.END)

          Text(this.singlePlatfrom.sumary)
            .fontSize(15)
            .fontColor($r('app.color.black_66666'))
            .margin({ top: 15 })

          //0不显示 1待办 2已办
          if (this.singlePlatfrom.is_completed == 1) {
            this.deletePlatBuilder()
          }
        }
        .alignItems(HorizontalAlign.Start)
        .borderRadius(10)
        .backgroundColor($r('app.color.start_window_background'))
        .width('100%')
        .padding(17)
        .height('auto')
        .id("singlePlatfrom")
        if (this.singlePlatfrom.is_completed == 1) {
          Image($r('app.media.icon_platform_status_daiban'))
            .width(45)
            .alignRules({
              right: { anchor: 'singlePlatfrom', align: HorizontalAlign.End },
              top: { anchor: 'singlePlatfrom', align: VerticalAlign.Top }
            })
        } else if (this.singlePlatfrom.is_completed == 2) {
          Image($r('app.media.icon_platform_status_yiban'))
            .width(45)
            .alignRules({
              right: { anchor: 'singlePlatfrom', align: HorizontalAlign.End },
              top: { anchor: 'singlePlatfrom', align: VerticalAlign.Top }
            })
        }
      }
      .height('auto')
    }
    .margin({ bottom: 15 })
    .width('100%')
  }

  @Builder
  deletePlatBuilder() {
    // 虚线
    Column() {
      Divider()
        .height(0)
        .borderWidth(0.8)
        .borderColor($r('app.color.rgb_color_204'))
        .borderStyle(BorderStyle.Dashed)
        .margin({ top: 10, bottom: 10 })

      Image($r('app.media.daiban_hulue_img'))
        .width(20)
        .onClick(() => {
          if (this.changeState) {
            this.changeState(this.singlePlatfrom.id,this.singlePlatfrom.title)
          }
        })
    }
    .alignItems(HorizontalAlign.Start)
  }
}
阅读 495
1 个回答

可按照下面代码修改验证,只列举核心代码

//获取屏幕宽度
aboutToAppear(): void {
  for (let i = 0; i < 10; i++) {
  let obj = new SinglePlatformBean()
  //通过这个值在刷新UI
  obj.is_completed = 1 //1是待办, 2是已办
  obj.id = i
  obj.title = i + ''
  obj.poiLeft = 0
  obj.cordovaid = ''
  this.singlePlatfroms.push(obj)
}

let displayInfo = display.getDefaultDisplaySync()
this.screenWidth = displayInfo.width
console.log('width----',this.screenWidth)
}
//1.首先在model增加位置信息,然后布局中添加该position,后续用作动画使用
@Observed
class SinglePlatformBean{
  poiLeft:number = 0
  constructor() {
  }
}

build() {
  Column() {
    RelativeContainer() {
      Column() {
      }
    }
  }
  .position({left: this.singlePlatfrom.poiLeft})
}
// 2.在dialog回调事件中,找到点击的item,进行动画和数据更新
onConfirm() {
  if (this.dialogController != undefined) {
    this.dialogController.close()
  }
  animateTo({ duration: 500,onFinish: () => {
    console.info('play end')
    let obj: SinglePlatformBean | undefined = this.singlePlatfroms.find((item)=>{return item.id == this.platFormId})
    if (obj != undefined) {
      console.log('item----',JSON.stringify(obj))
      console.log('item----',this.singlePlatfroms.indexOf(obj))
      this.singlePlatfroms.splice(this.singlePlatfroms.indexOf(obj), 1)
    }

  }}, () => {
    let obj: SinglePlatformBean | undefined = this.singlePlatfroms.find((item)=>{return item.id == this.platFormId})
    if (obj) {
      obj.poiLeft = -this.screenWidth
    }
  })
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进