文档管理中心
FAQ应用框架开发UI框架组件使用分类筛选功能异常

分类筛选功能异常

问题现象

点击打开筛选界面,有分类和主题两个部分,主题可以多选,若没有选择主题,则分类只能选择一个。但是选择主题后,多选分类,此时再将选择的主题全部取消,分类还是会保存多选状态。

背景知识

模态转场是新的界面覆盖在旧的界面上,旧的界面不消失的一种转场方式,常用于实现筛选框、侧边栏等功能。

问题定位

  1. 使用DevEco Testing中的UIViewer工具,查看筛选界面的布局,发现筛选界面使用半模态转场实现,内容使用线性布局以及Grid组件实现,不涉及与H5页面的交互。
  2. 根据问题现象,推测在取消全部主题的场景中未重置分类。
  3. 排查代码,查看是否有单独记录分类和主题两个内容的选择状态,并在主题选择为空时将分类的选择也重置。

分析结论

当主题的选择内容从有变无时,未对分类选项做重置操作,导致取消主题的所有选择后,分类仍为多选状态。

修改建议

在点击主题选项时添加判断,若主题选择为空并且分类为多项状态,则将筛选重置,示例代码如下:

收起
自动换行
深色代码主题
复制
  1. import { PromptAction, UIContext } from '@kit.ArkUI';
  2. @ObservedV2
  3. // 观察点击事件
  4. class textFont { // 创建一个文本类
  5. tex: number = 0;
  6. @Trace isClick: boolean = false; // 记录是否被点击
  7. constructor(tex: number) {
  8. this.tex = tex; // 初始化文本值
  9. }
  10. }
  11. @Entry
  12. @Component
  13. struct BindSheetSelect {
  14. @State isShowSheet: boolean = false; // 控制筛选框显隐
  15. selectList: Array<textFont> = []; // 分类列表
  16. themeList: Array<textFont> = []; // 主题列表
  17. @State selectNum: number = 0; // 选择的分类数量
  18. @State themeNum: number = 0; // 选择的主题数量
  19. uiContext: UIContext = this.getUIContext();
  20. promptAction: PromptAction = this.uiContext.getPromptAction();
  21. aboutToAppear(): void {
  22. for (let i = 0; i < 4; i++) { // 初始化列表
  23. this.selectList.push(new textFont(i));
  24. this.themeList.push(new textFont(i));
  25. }
  26. }
  27. @Builder
  28. SheetBuilder() {
  29. Column() {
  30. Column({ space: 30 }) {
  31. Row() {
  32. Text('分类')
  33. }
  34. .width('100%')
  35. .justifyContent(FlexAlign.Start)
  36. .padding({
  37. left: 30
  38. })
  39. Grid() {
  40. ForEach(this.selectList, (item: textFont) => {
  41. GridItem() {
  42. Row() {
  43. Text(item.tex.toString())
  44. .fontColor('#0A59F7')
  45. }
  46. .backgroundColor('#0d000000')
  47. .borderWidth(item.isClick ? 1 : 0)
  48. .borderColor('#0A59F7')
  49. .opacity(item.isClick ? 1 : (this.selectNum ? (this.themeNum ? 1 : 0.4) : 1))
  50. .borderRadius(20)
  51. .width(100)
  52. .height(30)
  53. .justifyContent(FlexAlign.Center)
  54. }
  55. .onClick(() => { // 切换点击状态
  56. if (!item.isClick) { // 若没有被点亮
  57. if (!this.selectNum) { // 没有选择过分类,可以选一个
  58. item.isClick = true;
  59. this.selectNum++;
  60. } else {
  61. if (this.themeNum) { // 选了主题,可以多选分类
  62. item.isClick = true;
  63. this.selectNum++;
  64. }
  65. }
  66. } else { // 若被点亮了,则取消点亮状态
  67. item.isClick = false;
  68. this.selectNum--;
  69. }
  70. })
  71. })
  72. }
  73. .width('100%')
  74. .height(80)
  75. .columnsTemplate('1fr 1fr 1fr')
  76. .rowsGap(20)
  77. Row() {
  78. Text('主题')
  79. }
  80. .width('100%')
  81. .justifyContent(FlexAlign.Start)
  82. .padding({
  83. left: 30
  84. })
  85. Grid() { // 使用网格容器选项列表
  86. ForEach(this.themeList, (item: textFont) => {
  87. GridItem() {
  88. Row() {
  89. Text(item.tex.toString()) // 选项内容
  90. .fontColor('#0A59F7')
  91. }
  92. .backgroundColor('#0d000000')
  93. .borderWidth(item.isClick ? 1 : 0)
  94. .borderColor('#0A59F7')
  95. .borderRadius(20)
  96. .width(100)
  97. .height(30)
  98. .justifyContent(FlexAlign.Center)
  99. }
  100. .onClick(() => {
  101. if (item.isClick) { // 判断选项是否被点击
  102. item.isClick = !item.isClick;
  103. this.themeNum--; // 主题选择数量
  104. if (this.themeNum === 0 && this.selectNum > 1) { // 当主题选项为空,且分类为多选,则将所有选项全部重置
  105. this.selectNum = 0; // 清空分类选项
  106. for (let i = 0; i < 4; i++) { // 重置所有内容
  107. this.selectList[i].isClick = false;
  108. this.themeList[i].isClick = false;
  109. }
  110. }
  111. } else {
  112. item.isClick = !item.isClick;
  113. this.themeNum++;
  114. }
  115. })
  116. })
  117. }
  118. .width('100%')
  119. .height(80)
  120. .columnsTemplate('1fr 1fr 1fr')
  121. .rowsGap(20)
  122. Row() {
  123. Button('确定')
  124. .onClick(() => {
  125. if (!this.selectNum) {
  126. this.promptAction.openToast({
  127. message: '未选分类'
  128. });
  129. } else if (!this.themeNum) {
  130. this.promptAction.openToast({
  131. message: '未选主题'
  132. });
  133. } else {
  134. this.isShowSheet = false;
  135. }
  136. })
  137. Button('取消')
  138. .onClick(() => {
  139. this.isShowSheet = false;
  140. })
  141. }
  142. .width('100%')
  143. .height('15%')
  144. .justifyContent(FlexAlign.SpaceEvenly)
  145. }
  146. }
  147. .width('100%')
  148. .height('100%')
  149. }
  150. @Builder
  151. titleBuilder() {
  152. Column() {
  153. Text('筛选')
  154. }
  155. .width('100%')
  156. .justifyContent(FlexAlign.Center)
  157. }
  158. build() {
  159. Column() {
  160. Button('点击打开筛选框')
  161. .onClick(() => {
  162. this.isShowSheet = !this.isShowSheet;
  163. })
  164. .bindSheet($$this.isShowSheet, this.SheetBuilder(), {
  165. detents: [SheetSize.MEDIUM, SheetSize.LARGE, 600],
  166. preferType: SheetType.BOTTOM,
  167. title: this.titleBuilder(),
  168. showClose: false,
  169. dragBar: false,
  170. backgroundColor: Color.White
  171. })
  172. }.width('100%').height('100%')
  173. .justifyContent(FlexAlign.Center)
  174. }
  175. }
在 FAQ 中进行搜索
请输入您想要搜索的关键词