HarmonyOS 鸿蒙Next List组件中swipeAction显示尺寸问题
HarmonyOS 鸿蒙Next List组件中swipeAction显示尺寸问题 List组件中删除某个Item后调用DataSource的notifyDataReload,swipeAction自动出现,且尺寸不对
代码如下:
@Entry
@Component
struct CollectListPage {
@State state: CollectListState = new CollectListState()
vm: CollectListViewModel | null = null
@State dataSource: BasicDataSource<NewsModel> = this.state.newsList
aboutToAppear() {
this.vm = new CollectListViewModel(this.state)
}
build() {
Column() {
this.buildTitle()
Divider().vertical(false).color('#E1E1E1').height(1)
if (this.state.newsList.totalCount() == 0) {
this.buildEmpty()
} else {
this.buildBody()
}
this.buildFooter()
}.width('100%').height('100%')
}
@Builder
private buildTitle() {
RelativeContainer() {
Text('我的收藏')
.fontColor('#222222')
.fontSize(18)
.textAlign(TextAlign.Center)
.fontWeight(500)
.alignRules(AlignRules.CENTER)
.id('title')
.backgroundColor(Color.White)
Image(ResManager.getBackIcon())
.width(24)
.height(24)
.margin({ left: 14 })
.onClick(() => {
router.back()
})
.id('back')
.alignRules(AlignRules.LEFT_CENTER)
Text(this.state.isEdit ? '取消' : '编辑')
.fontColor(this.state.isEdit ? '#ee2b2a' : '#3d3d3d')
.fontSize(16)
.alignRules(AlignRules.RIGHT_CENTER)
.id('edit')
.onClick(() => {
this.state.isEdit = !this.state.isEdit
this.vm?.reset()
})
.padding({ right: 14 })
}
.height(44)
.width('100%')
.backgroundColor(Color.White)
}
@Builder
private buildBody() {
List({space:0}) {
LazyForEach(this.dataSource, (item: NewsModel, index: number) => {
ListItem() {
EditNewsItem({
isEdit: this.state.isEdit, news: item, onSelectChangeListener: (isSelected) => {
isSelected ? this.state.selectCount++ : this.state.selectCount--
}
})
}
.swipeAction({
end: this.state.isEdit ? null : { builder: () => this.buildSwipeDelete(index) },
edgeEffect: SwipeEdgeEffect.None
})
})
ListItem() {
Text('已显示全部收藏')
.fontSize(16)
.fontColor('#a4a4a4')
.width('100%')
.textAlign(TextAlign.Center)
.margin({ top: 15, bottom: 40 })
}
}.layoutWeight(1).cachedCount(2)
}
@Builder
private buildEmpty() {
if (this.state.loadFinish) {
Text('您还没有收藏内容哦~')
.fontSize(16)
.fontColor('#A4A4A4')
.width('100$')
.height('100%')
.textAlign(TextAlign.Center)
} else {
LoadingIndicator()
}
}
@Builder
private buildSwipeDelete(item: number) {
if (this.state.isEdit) {
Row().width(0).height(0)
} else {
Column(){
Text('删除')
.width(80)
.textAlign(TextAlign.Center)
.fontSize(15)
.fontColor(Color.White)
.onClick(() => {
this.vm?.delItem(item)
}).layoutWeight(1)
}.backgroundColor(Color.Red)
}
}
@Builder
private buildFooter() {
if (this.state.isEdit) {
Row() {
Image(this.state.selectCount == this.state.newsList.totalCount() ? $r('app.media.radio_button_checked') : $r('app.media.radio_button_normal'))
.width(20)
.height(20).onClick(() => {
this.vm?.selectAll()
}).objectFit(ImageFit.Contain)
Row().width(10)
Text('全选').fontColor('#3D3D3D').fontSize(15).onClick(() => {
this.vm?.selectAll()
})
Row().layoutWeight(1)
Text(this.state.selectCount == 0 ? '删除' : `删除(${this.state.selectCount})`)
.height(26)
.width(140)
.textAlign(TextAlign.Center)
.backgroundColor(this.state.selectCount == 0 ? Color.Gray : '#CC2B2A')
.borderRadius(5)
.fontColor(Color.White)
.fontSize(15)
.onClick(() => {
this.vm?.delBatch()
})
}
.height(40)
.width('100%')
.padding({ left: 10, right: 10 })
.borderColor({ top: '#d9d9d9' })
.borderWidth({ top: 1 })
}
}
}
@Component
export struct EditNewsItem {
@Prop isEdit: boolean
@ObjectLink news: NewsModel
onSelectChangeListener: (selected: boolean) => void | null = null
build() {
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center }) {
if (this.isEdit) {
Image(this.news.is_selected ? $r('app.media.radio_button_checked') : $r('app.media.radio_button_normal'))
.width(20)
.height(20)
.objectFit(ImageFit.Contain).margin({ left: 14 })
}
Row() {
NewsItem({
newsModel: this.news,
isHotChannel: false,
comeFromHomePage: false,
comeFromSearchResult: false,
canCache: false
})
}
.flexShrink(1).width('100%')
}.onClick(() => {
console.error(this.news.title)
if (this.isEdit) {
this.news.is_selected = !this.news.is_selected
this.onSelectChangeListener && this.onSelectChangeListener(this.news.is_selected)
}
})
}
}
@Observed
export class CollectListState {
newsList: BasicDataSource<NewsModel> = new BasicDataSource()
isEdit: boolean = false
selectCount: number = 0
loadFinish: boolean = false
}
export class CollectListViewModel extends BaseViewModel<void, CollectListState> {
page: number = 1
onCreate(): void {
this.page = 1
this.getCollectList()
}
getCollectList() {
const param = new LightWeightMap<string, string>()
param.set('device_id', AppStorage.get<string>(CommonConstants.DEVICE_ID))
param.set('page', this.page + '')
param.set('os', 'android')
LoginUtils.addUserInfo(param)
HttpManager.getInstance().post<Array<NewsModel>>(Api.COLLECT_LIST, param).then((response) => {
let news = JSONUtils.text2ClsArr<NewsModel, NewsModel>(NewsModel, response.data)
if (news != null) {
this.state.newsList.addAll(news)
}
this.state.loadFinish = true
})
}
selectAll() {
if (this.state.selectCount == this.state.newsList.totalCount()) {
this.state.selectCount = 0
for (let i = 0; i < this.state.newsList.totalCount(); i++) {
this.state.newsList.getData(i).is_selected = false
}
} else {
this.state.selectCount = this.state.newsList.totalCount()
for (let i = 0; i < this.state.newsList.totalCount(); i++) {
this.state.newsList.getData(i).is_selected = true
}
}
}
async delItem(index: number) {
const result = await this.delete(index)
if (result) {
this.state.newsList.notifyDataDelete(index)
}
}
private async delete(index: number): Promise<boolean> {
const param = new LightWeightMap<string, string>()
const news = this.state.newsList.getData(index)
param.set('device_id', AppStorage.get<string>(CommonConstants.DEVICE_ID))
param.set('os', 'android')
param.set('aid', news.aid)
param.set('type', news.type.toString())
LoginUtils.addUserInfo(param)
let result = false
await HttpManager.getInstance().post<void>(Api.DEL_COLLECT, param).then(() => {
this.state.newsList.deleteData(index)
console.error('del success:' + index)
result = true
}).catch((e: NetError) => {
promptAction.showToast({ message: e.message })
result = false
})
return result
}
async delBatch() {
for (let i = 0; i < this.state.newsList.totalCount(); i++) {
if (this.state.newsList.getData(i).is_selected) {
await this.delete(i)
}
}
this.state.isEdit = false
this.state.newsList.notifyDataReload()
}
reset() {
this.state.selectCount = 0
for (let i = 0; i < this.state.newsList.totalCount(); i++) {
this.state.newsList.getData(i).is_selected = false
}
}
}
更多关于HarmonyOS 鸿蒙Next List组件中swipeAction显示尺寸问题的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
2 回复
SwipeActionOptions的start和end对应的@builder函数中顶层必须是单个组件,不能是if/else、ForEach、LazyForEach语句。你使用了if语句也用到了多个组件,可以使用单个组件优化一下代码看看。
更多关于HarmonyOS 鸿蒙Next List组件中swipeAction显示尺寸问题的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html