下面是学习强国的效果

然后看下我实现的效果

重点有两个部分:

  1. 使用RichText,然后根据答案的长度,动态设置需要填空的个数。RichText中有WidgetSpan,使用这个就能方便地在RichText中添加自定义的控件,Android中应该不能这么简单地实现。


  2. 设置一个占位的TextField,它的宽度为0,也就是相当于输入框是隐藏的状态,用于获取用户的输入

下面是完整代码,这个代码是简化后的,因为实际项目中逻辑会复杂很多。实际项目中因为有填空题,单选题和多选题,挑战答题,需要分组件去开发,可以使用provider来实现各个组件间的通信。在挑战答题中还有一些动画效果。如果想完全仿学习强国的业务逻辑,还是有些复杂的。

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';//import 'learn_color_m.dart';///填空题
//GlobalKey<_FillQuestionState> fillQuestionKey = GlobalKey();class FillQuestion extends StatefulWidget {final fillQuesCallBack;FillQuestion({Key key, this.fillQuesCallBack}) : super(key: key);@override_FillQuestionState createState() => _FillQuestionState();
}class _FillQuestionState extends State<FillQuestion> {TextEditingController controller = new TextEditingController();FocusNode textFieldFocusNode = new FocusNode();double boxSize;int answerCount; //答案的字数bool isFocus = false; //用户是否点击了填空的方框:因为进入的时候第一个方框是不显示边框的,当用户点击了方框第一个方框就显示边框String fillAnswer; //题目的答案String answerValue = ""; //用户输入的答案//  String stem = "";String stem1 ="要大力发展文学艺术、新闻出版、广播影视等事业,弘扬民族优秀文化,吸收外国文化有益成果,加强";String stem2 = ",加强文化市场管理,营造良好的文化环境,不断提高人民群众的文化生活质量,使人民群众充分享受自己创造的物质文化成果。";String fillResult = "文化基础设施建设";String questionId = "";@overridevoid initState() {super.initState();answerCount = fillResult.length;boxSize = 25;}@overrideWidget build(BuildContext context) {return _buildColumn();}Widget _buildColumn() {return Column(mainAxisAlignment: MainAxisAlignment.start,children: <Widget>[RichText(strutStyle: StrutStyle(forceStrutHeight: false,height: 3,),text: TextSpan(text: stem1,style: TextStyle(color: Colors.black, fontSize:15),children: <InlineSpan>[WidgetSpan(child: _buildPlaceholder()),TextSpan(children: _buildSpans(fillResult.length, answerValue, isFocus),),TextSpan(text: stem2, style: TextStyle(color: Colors.black, fontSize: 15)),],),),],);}List<InlineSpan> _buildSpans(int count, String answerStr, bool isFocus) {List<InlineSpan> children = new List();TextSpan textSpan = new TextSpan(text: "  ");children.add(textSpan);int answerLength = answerStr.length;for (int i = 0; i < count; i++) {if (i < answerLength) {bool isShowBorder = false;if (i == count - 1) {///如果所有空都填了,最后一个方框显示边框isShowBorder = true;}WidgetSpan widgetSpan = new WidgetSpan(child: _buildSpanChild(answerStr[i], isShowBorder));children.add(widgetSpan);} else {bool isShowBorder = false;if (i == answerLength && isFocus) {isShowBorder = true;}WidgetSpan widgetSpan = new WidgetSpan(child: _buildSpanChild(" ", isShowBorder));children.add(widgetSpan);}TextSpan textSpan = new TextSpan(text: "  ");children.add(textSpan);}return children;}Widget _buildSpanChild(String dataText, bool isShowBorder) {return GestureDetector(onTap: () {///用户点击方框///如果已经回答的情况,此时不应再弹出键盘(这里只关心回答错误的情况,因为回答正确直接跳入下一题)
//        if (isConfirm) {//          return;
//        }if (!isFocus) {///如果是首次点击方框,就把第一个方框的边框显示出来setState(() {isFocus = true;answerValue = "";});}///获取键盘的焦点,并且主动调起键盘FocusScope.of(context).requestFocus(textFieldFocusNode); // 获取焦点SystemChannels.textInput.invokeMethod<void>('TextInput.show'); //主动调起键盘,否则按返回键隐藏键盘后不能再次弹出},child: Container(alignment: Alignment.center,width: boxSize,height: boxSize,child: Text(dataText,style: getTextStyle(),),decoration: getBoxDecoration(isShowBorder),),);}getTextStyle() {Color color;///确定了
//    if (isConfirm) {//      ///正确了,显示绿色;错误了,显示红色
//      color = isCorrect ? Color(0xff3EBE77) : Color(0xffF6444D);
//    }///还未确定
//    else {color = Color(0xFF4b90c5);
//    }return TextStyle(color: color, fontSize: 15);}getBoxDecoration(bool isShowBorder) {Border border;///确定了
//    if (isConfirm) {//      ///正确了,显示绿色;错误了,显示红色
//      border =
//          new Border.all(color: isCorrect ? Color(0xff3EBE77) : Color(0xffEEA6A5), width: ScreenUtil().setWidth(1));
//    }///还未确定
//    else {border =isShowBorder ? new Border.all(color: Color(0xFFdbefff), width: 1) : null;
//    }return BoxDecoration(border: border,color: Color(0xFFF2F3F5),);}///这个输入框不显示,只是用于获取用户的输入Widget _buildPlaceholder() {return Container(width: 0,child: TextField(decoration: InputDecoration(counterText: '',fillColor: Colors.transparent,),showCursor: false,style: TextStyle(color: Colors.transparent),maxLength: answerCount,focusNode: textFieldFocusNode,controller: controller,onChanged: (value) {setState(() {answerValue = value; //更新用户输入的答案,实时将答案显示在方框中});}),);}
}

如果这篇文章帮助到了大家,麻烦帮忙点个赞,谢谢!!

Flutter仿学习强国填空题相关推荐

  1. Android仿学习强国填空题考试界面

    很久不写博客了,应为一直真的都很忙,没时间写,正好今天有时间写一下O(∩_∩)O哈哈~. 起因:最近工作中遇到一个需求,使用手机进行填空题考试. 分析:因为涉及到判分,需要答案与文字一一对应,刚开始在 ...

  2. 一步步教你如何定制一个Android「填空题」控件(仿学习强国填空题控件)

    一.写在前面 开始之前,老规矩,絮絮叨叨. 本文讲解的是如何自定义一个填空题控件,实现的方式其实有很多,最重要的是了解其中实现的思路和想法,正所谓条条大路通罗马嘛. 在Android系统中,我们最常使 ...

  3. 小程序仿学习强国填空题

    效果图如下: 概述: 和后台人员商议好题目中答案的代表符号,我这边是根据_分割,答案有多少字数就写几个_. 例如: 题目:新时代政法队伍"五个过硬":__过硬.__过硬.责任过硬. ...

  4. 关于这道填空题,你会如何回答?(附带学习链接)

    曾经有一篇百万阅读量的爆文,里面出了道填空题,问: ____是铜牌,____是银牌,____是金牌,____是王牌. 小白的答案是:Java是铜牌,Linux是银牌,Hadoop是金牌,大数据是王牌. ...

  5. c语言注释的开始标记符和结束标记符分别为,C语言程序设计填空题

    C语言程序设计填空题Tag内容描述: 1.面向对象程序设计期末综合练习二 填空题 填空题 1 C 语言是在 语言的基础上发展起来的 2 C 语言的编译单位是扩展名为 的 文件 3 行尾使用注释的开始标 ...

  6. c语言程序设计填空带答案,c语言程序设计填空题及答案复习用精编-20210414010859.docx-原创力文档...

    Lele was written in 2021 Lele was written in 2021 C语言程序设计填空题及答案复习用精编 导读:在程序填空题中,已经给出了程序的主干,读者首先要理解程序 ...

  7. 前端填空题_一年前端面试总结|入职字节|2020.8

    站在未来看现在 你当像鸟飞向你的山 前言     普通本科,软件工程专业,2019年毕业进入奇安信集团(前360企业安全),实习期间遇到一群可以一起嗨的朋友,感觉很幸福,也很庆幸能够遇到hin nic ...

  8. 请给出计算231-1的python表达式_【填空题】计算2 32 -1的Python表达式可以书写为____...

    [填空题]计算2 32 -1的Python表达式可以书写为____ 更多相关问题 [判断题]军队和国防建设指导思想实行战略转变的实质是:从立足于早打.大打.打核战争的临战准备状况,转到和平时期建设的轨 ...

  9. 通讯与计算机网络作业,通讯与计算机网络作业平时作业(填空题问答和计算题)讲述.doc...

    浙江大学远程教育学院 <通讯与计算机网络>课程作业 姓名:学 号:年级:学习中心: 第1章 概述 一.填空题: 计算机网络是计算机技术与_____相结合的产物. 从资源共享的角度来定义计算 ...

最新文章

  1. 一个鉴黄师的产品之路(11-12更新)
  2. 7.10.7740.16
  3. Ubuntu首次登入与在线求助man page总结
  4. 优美的测试代码 - 行为驱动开发(BDD)
  5. C#打开文件和文件夹
  6. 实习小白::(转) Cocos2d-x 3.0 开发(十五)使用UILayout布局,制作对话界面
  7. 《精通javascript》-----------------------读书笔记
  8. c语言 mongodb,MongoDB的C语言编程实例
  9. vue中点击打开新的页面window.open()
  10. sql根据身份证计算年龄
  11. 读《股票大作手操盘术》— 利弗莫尔操作法则
  12. python demo.py_python,pycharm_【已解决】pycharm 运行 web.py demo文件问题,python,pycharm - phpStudy...
  13. 密码学入门(7):数字签名和证书
  14. S3C44B0 寄存器描述
  15. Python 医学知识图谱问答系统(一),建立医学知识图谱,基于neo4j知识图谱的医学问答体系
  16. Bezier、B样条曲线曲面
  17. ESP8266环境搭建-ESP8266_RTOS_SDK(超详细)
  18. 决策树在商业保险中的应用
  19. android自动切换暗色,超实用!Android 深色模式适配(可定时开启的APP内主题切换管理工具)...
  20. ubuntu 公网FTP搭建,解决无法连接

热门文章

  1. php导出复杂表头excel,js导出复杂表头(多级表头)的excel
  2. MySQL中主键和unique的区别
  3. tar linux 跳过解压,【linux命令】linux解压压缩命令tar详解以及压缩的时候如何跳过某一个压缩目录或文件...
  4. Obsidian中如何创作思维导图Mind-map
  5. 2018.6清北学堂day6考试
  6. 软件缺陷静态分析CodeSonar
  7. springboot整合德鲁伊
  8. matlab数组下标可为正整数和逻辑数
  9. 转:用迅雷下载Android SDK全系列
  10. Windows10_如何修改用户文件夹下的中文用户文件夹名