Flutter笔试页面

一、预览

预览

在这里插入图片描述

二、使用

1. 获取试题

(1) 实体
class ExamQuestions {
  int? id;
  int? level;
  String? subject;
  String? title;
  int? right;
  String? a;
  String? b;
  String? c;
  String? d;
  int? addtime;
  int? deltime;
}
(2) 使用
var myExamQuestions = [ExamQuestions()];

/// 获取笔试题目列表
getUserExamQuestions() async {
  var allQuestions = /// 获取试题接口
  setState(() {
    myExamQuestions = allQuestions;
  });
}

2. 倒计时

late Timer _timer;
var showTime = "20分";

/// 格式化时间
renderTime(int value) {
  if (value == 0) {
    return "0秒";
  }
  var min = value ~/ 60;
  var second = value % 60;
  if(min == 0){
    return "$second秒";
  }
  return "$min分$second秒";
}

/// 倒计时
void startCountdownTimer() {
  var countdownTime = 1200;
  const oneSec = const Duration(seconds: 1);
  var callback = (timer) async {
    if (countdownTime == 0) {
      _timer.cancel();
      toastShow("已超时,自动提交笔试考试");
    } else {
      setState(() {
        countdownTime = countdownTime - 1;
        showTime = renderTime(countdownTime);
      });
    }
  };
  _timer = Timer.periodic(oneSec, callback);
}

3. 检测题目及放弃考试

检测完成的题目

/// 检测完成的题目
testCompleteQuestion(){
  var temp = 0;
  selectOptions.forEach((element) {
    if(element != 0){
      temp++;
    }
  });
  setState(() {
    completeQuestion = temp;
  });
}

放弃考试

/// 放弃考试
_giveUpTheTest(context){
  return
    showDialog<Null>(
    context: context,
    builder: (BuildContext context) {
      return SimpleDialog(
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(20.dp),
        ),
        children: <Widget>[
          Get.getWidthBox(MediaQuery.of(context).size.width),
          Column(
            crossAxisAlignment: CrossAxisAlignment.center,
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Get.getHeightBox(20.dp),
              singleTextWeight("请在放弃考试前确认", c_00, 18.dp, fontWeight: FontWeight.bold),
              Get.getHeightBox(40.dp),
              Container(
                width: MediaQuery.of(context).size.width,
                child: Column(
                  children: [
                    Container(
                      height: 0.5.dp,
                      color: c_FF,
                      width: MediaQuery.of(context).size.width,
                    ),
                    Row(
                      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                      children: [
                        GestureDetector(
                          onTap: ()=> Navigator.of(context).pop(),
                          child: singleTextWeight("继续考试", c_00, 18.dp, fontWeight: FontWeight.normal)
                        ),
                        Container(
                          height: 99.5.dp,
                          color: c_FF,
                          width: 0.5.dp,
                        ),
                        GestureDetector(
                          onTap: ()=>Get.close(2),
                          child: singleTextWeight("确认", c_00, 18.dp, fontWeight: FontWeight.normal)
                        ),
                      ],
                    )
                  ],
                ),
              )
            ],
          )
        ],
      );
    },
  );
}

4. 总览

import 'dart:async';

/// 第三方
import 'package:get/get.dart';
import 'package:flutter/services.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';

/// 本地资源
import '../../../data/api/subject.dart';
import '../../../data/model/subject.dart';
import '../../../theme/utils/export.dart';
import '../../../utils/widget/common.dart';

class TestPage extends StatefulWidget {
  @override
  _TestPageState createState() => _TestPageState();
}

class _TestPageState extends State<TestPage> {

  var myExamQuestions = [ExamQuestions()];
  PageController _pageController = PageController(initialPage: 0);
  var selectOptions = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0].obs;
  var nowPageSelect = 0;

  late Timer _timer;
  var showTime = "20分";
  /// 已完成的题目
  var completeQuestion = 0;
  /// 按钮名称
  var tableInfo = "下一题";
  /// 当前页
  var page = 0;

  /// 获取笔试题目列表
  getUserExamQuestions() async {
    var allQuestions = await SubjectAPI.getExamQuestionList(8, 10, "少儿歌唱");
    setState(() {
      myExamQuestions = allQuestions;
    });
  }

  /// 格式化时间
  renderTime(int value) {
    if (value == 0) {
      return "0秒";
    }
    var min = value ~/ 60;
    var second = value % 60;
    if(min == 0){
      return "$second秒";
    }
    return "$min分$second秒";
  }

  /// 倒计时
  void startCountdownTimer() {
    var countdownTime = 1200;
    const oneSec = const Duration(seconds: 1);
    var callback = (timer) async {
      if (countdownTime == 0) {
        _timer.cancel();
        /// toast信息
        Fluttertoast.showToast(
            msg: "已超时,自动提交笔试考试",
            toastLength: Toast.LENGTH_SHORT,
            gravity: ToastGravity.CENTER,
            timeInSecForIosWeb: 1,
            fontSize: 16.0
        );
      } else {
        setState(() {
          countdownTime = countdownTime - 1;
          showTime = renderTime(countdownTime);
        });
      }
    };
    _timer = Timer.periodic(oneSec, callback);
  }

  /// 检测完成的题目
  testCompleteQuestion(){
    var temp = 0;
    selectOptions.forEach((element) {
      if(element != 0){
        temp++;
      }
    });
    setState(() {
      completeQuestion = temp;
    });
  }

  @override
  void initState(){
    getUserExamQuestions();
    startCountdownTimer();
    super.initState();
  }

  @override
  void dispose(){
    _timer.cancel();
    super.dispose();
  }

  /// 放弃考试
  _giveUpTheTest(context){
    return
      showDialog<Null>(
        context: context,
        builder: (BuildContext context) {
          return SimpleDialog(
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(20.dp),
            ),
            children: <Widget>[
              Get.getWidthBox(MediaQuery.of(context).size.width),
              Column(
                crossAxisAlignment: CrossAxisAlignment.center,
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  Get.getHeightBox(20.dp),
                  singleTextWeight("请在放弃考试前确认", c_00, 18.dp, fontWeight: FontWeight.bold),
                  Get.getHeightBox(40.dp),
                  Container(
                    width: MediaQuery.of(context).size.width,
                    child: Column(
                      children: [
                        Container(
                          height: 0.5.dp,
                          color: c_FF,
                          width: MediaQuery.of(context).size.width,
                        ),
                        Row(
                          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                          children: [
                            GestureDetector(
                                onTap: ()=> Navigator.of(context).pop(),
                                child: singleTextWeight("继续考试", c_00, 18.dp, fontWeight: FontWeight.normal)
                            ),
                            Container(
                              height: 99.5.dp,
                              color: c_FF,
                              width: 0.5.dp,
                            ),
                            GestureDetector(
                              onTap: ()=>Get.close(2),
                              child: singleTextWeight("确认", c_00, 18.dp, fontWeight: FontWeight.normal)
                            ),
                          ],
                        )
                      ],
                    ),
                  )
                ],
              )
            ],
          );
        },
      );
  }

  Widget body1(position){
    return Padding(
      padding: EdgeInsets.only(left: 26.dp, top: 20.dp, right: 26.dp, bottom: 20.dp),
      child: Container(
        decoration: BoxDecoration(
          color: c_FF,
          borderRadius: BorderRadius.all(
            Radius.circular(20.dp),
          ),
        ),
        child: Padding(
          padding: EdgeInsets.only(top: 16.dp),
          child: Column(
            children: [
              singleTextWeight("${position + 1}. ${myExamQuestions[position].title}", c_00, 18.dp, fontWeight: FontWeight.bold, overflow: TextOverflow.clip),
              Get.getHeightBox(10.dp),
              customerContainer(60.dp, MediaQuery.of(context).size.width, c_FF, 20.dp,
                  body: Row(
                    children: [
                      Image.asset(
                        selectOptions[position] == 1 ? R.imagesCommonRadiusSelectIcon : R.imagesCommonRadiusNoSelectIcon,
                        width: 18.dp,
                        height: 18.dp,
                      ),
                      Get.getWidthBox(10.dp),
                      Expanded(child: singleTextWeight("A  ${myExamQuestions[position].a}", c_00, 16.dp, overflow: TextOverflow.clip))
                    ],
                  ),
                  onTap: ()=>{
                    selectOptions[position] = 1,
                    testCompleteQuestion()
                  },
                  margin: EdgeInsets.only(top: 10.dp, bottom: 10.dp)
              ),
              customerContainer(60.dp, MediaQuery.of(context).size.width, c_FF, 20.dp,
                  body: Row(
                    children: [
                      Image.asset(
                        selectOptions[position] == 2 ? R.imagesCommonRadiusSelectIcon : R.imagesCommonRadiusNoSelectIcon,
                        width: 18.dp,
                        height: 18.dp,
                      ),
                      Get.getWidthBox(10.dp),
                      Expanded(child: singleTextWeight("B  ${myExamQuestions[position].b}", c_00, 16.dp, overflow: TextOverflow.clip))
                    ],
                  ),
                  onTap: ()=>{
                    selectOptions[position] = 2,
                    testCompleteQuestion()
                  },
                  margin: EdgeInsets.only(top: 10.dp, bottom: 10.dp)
              ),
              customerContainer(60.dp, MediaQuery.of(context).size.width, c_FF, 20.dp,
                  body: Row(
                    children: [
                      Image.asset(
                        selectOptions[position] == 3 ? R.imagesCommonRadiusSelectIcon : R.imagesCommonRadiusNoSelectIcon,
                        width: 18.dp,
                        height: 18.dp,
                      ),
                      Get.getWidthBox(10.dp),
                      Expanded(child: singleTextWeight("C  ${myExamQuestions[position].c}", c_00, 16.dp, overflow: TextOverflow.clip))
                    ],
                  ),
                  onTap: ()=>{
                    selectOptions[position] = 3,
                    testCompleteQuestion()
                  },
                  margin: EdgeInsets.only(top: 10.dp, bottom: 10.dp)
              ),
              customerContainer(60.dp, MediaQuery.of(context).size.width, c_FF, 20.dp,
                  body: Row(
                    children: [
                      Image.asset(
                        selectOptions[position] == 4 ? R.imagesCommonRadiusSelectIcon : R.imagesCommonRadiusNoSelectIcon,
                        width: 18.dp,
                        height: 18.dp,
                      ),
                      Get.getWidthBox(10.dp),
                      Expanded(child: singleTextWeight("D  ${myExamQuestions[position].d}", c_00, 16.dp, overflow: TextOverflow.clip))
                    ],
                  ),
                  onTap: ()=>{
                    selectOptions[position] = 4,
                    testCompleteQuestion()
                  },
                  margin: EdgeInsets.only(top: 10.dp, bottom: 10.dp)
              ),
            ],
          ),
        ),
      ),
    );
  }

  /// 主内容
  Widget mainBody(BuildContext context){
    return Column(
      children: [
        safePadding(context, c_FF),
        customerHeader(context, c_FF, "笔试考试", leftContent: GestureDetector(
          onTap: ()=>_giveUpTheTest(context),
          child: Image.asset(
            R.imagesCommonBackIcon,
            width: 24.dp,
            height: 24.dp,
          ),
        )),
        Expanded(
          child: (myExamQuestions.length > 0 && myExamQuestions[0].title != null) ? PageView.builder(
            controller: _pageController,
            physics: NeverScrollableScrollPhysics(),
            itemBuilder: (context, position) => body1(position),
            itemCount: myExamQuestions.length,
            onPageChanged: (index){
            },
          ) : Text(""),
        ),
        Padding(
          padding: EdgeInsets.only(left: 26.dp, top: 10.dp, right: 26.dp, bottom: 10.dp),
          child: Container(
            decoration: BoxDecoration(
              color: c_FF,
              borderRadius: BorderRadius.all(
                Radius.circular(20.dp),
              ),
            ),
            child: Padding(
              padding: EdgeInsets.only(top: 16.dp),
              child: Row(
                children: [
                  singleTextWeight("倒计时:$showTime", c_FDAE2D, 16.dp),
                  Expanded(child: Text("")),
                  singleTextWeight("完成度:$completeQuestion/${myExamQuestions.length}道题", c_FDAE2D, 16.dp)
                ],
              ),
            ),
          ),
        ),
        customerContainer(46.dp, MediaQuery.of(context).size.width, c_FDAE2D, 10.dp, body: Center(
          child: singleTextWeight("$tableInfo", c_FF, 16.dp),
        ), margin: EdgeInsets.only(bottom: 16.dp, left: 16.dp, right: 16.dp, top: 16.dp),
          onTap: (){
            setState(() {
              page ++;
            });
            if(page == myExamQuestions.length - 1){
              setState((){
                tableInfo = "提交成绩";
              });
            }
            _pageController.jumpToPage(page);
          }
        )
      ],
    );
  }

  @override
  Widget build(BuildContext context) {
    return customerTheme(false, SystemUiOverlayStyle.dark, mainBody(context), boxDecoration: BoxDecoration(
        color: c_FC
    ), willPop: true);
  }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

倾云鹤

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值