Flutter ListView.builder中如何根据课程浏览次数启用/禁用InkWell
核心实现原理
Flutter中InkWell的onTap属性传入null时就会自动禁用点击交互,你之前的写法不生效是因为Flutter采用声明式UI,组件属性在build阶段就确定了,异步回调里直接修改属性不会触发UI重绘,必须通过状态变量管理禁用状态,更新状态后触发组件重新build才能生效。
具体实现步骤
新增状态变量存储禁用状态
你可以给Lesson数据模型新增一个isLocked布尔字段,或者在当前页面维护一个Map<int, bool>存储对应课程ID的锁定状态,默认值为false。修改浏览次数查询逻辑,更新状态
查询到浏览次数后调用setState更新锁定状态,触发UI重绘:
checkViewsCount() async { var viewCount = await checkLessonViews(lesson.id.toString(), lesson.lessonType); setState(() { // 浏览次数>=2则锁定课程 lesson.isLocked = int.parse(viewCount) >= 2; }); }
记得在页面初始化(initState阶段)遍历所有课程,挨个调用该方法查询浏览次数。
- 动态绑定InkWell的onTap属性
根据锁定状态决定是否传入点击回调:
return InkWell( // 锁定时传null自动禁用点击 onTap: lesson.isLocked ? null : () { setState(() { _activeLesson = lesson; }); lessonAction(lesson); }, // 原有child代码保持不变 child: Column( children: <Widget>[ Container( padding: EdgeInsets.symmetric(vertical: 10, horizontal: 30), width: double.infinity, child: Row( children: <Widget>[ Expanded( flex: 2, child: Customtext( text: lessonCount.toString(), fontSize: 16 ) ), Expanded( flex: 8, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ Customtext( text: lesson.title, fontSize: 14, colors: kTextColor, fontWeight: FontWeight.bold, ), getLessonSubtitle(lesson), ], ) ), ], ), ), Divider(), ], ), );
可选优化
你可以给锁定的课程增加视觉提示,降低卡片透明度或者增加锁图标,让用户直观知道课程不可点击:
// 示例:给Container增加半透明遮罩 Container( padding: EdgeInsets.symmetric(vertical: 10, horizontal: 30), width: double.infinity, // 锁定时增加浅灰色遮罩 color: lesson.isLocked ? Colors.grey.withOpacity(0.2) : Colors.transparent, child: ... )
内容的提问来源于stack exchange,提问作者slackgate
相关产品推荐
相关产品推荐

