[Code with me]开发背单词App | Flutter框架 | 无需任何前置知识教程 #6

1.现在要和questions.dart交互,从其中抓取数据并体现出来

位置:questions_screen.dart中

我们先将questions数组的第一个参数赋值给currentQuestion变量,questions[0]也代表了我们要显示第一个答题卡  QuizQuestion('Apple', ['苹果', '梨子', '香蕉', '荔枝'])。

final currentQuestion = questions[0];

我们不希望一个一个地去获取questions中answer的数据,而是利用一个map方法帮助我们统统地遍历出来。

...currentQuestion.answers.map((answer) {
     return AnswerButton(answerText: answer, onTap: () {});
})

解释:我用currentQuestion的answer字符串数组,调用了map方法,它会将currentQuestion的answer字符串数组,一个一个地迭代出来并将各自的answer放进作为参数,形成一个一个AnswerButton()并放置进入一个数组中间。但是问题在于AnswerButton()外面也是一个数组,所以形成了数组中的数组,就会报错,所以要在最前面加入...三个点,这三个点会将内层的数组以一个一个的形式剥离出来,安插在外层数组中,最后就没有内层数组了。

例子如下:

const numbers = [1,2,3];
const moreNums = [numbers, 4] == [[1,2,3],4];

const moreNums = [...numbers,4] == [1,2,3,4];

整体修改完的代码如下:

class _QuestionScreenState extends State<QuestionsScreen> {
  @override
  Widget build(BuildContext context) {
    final currentQuestion = questions[0];

    return SizedBox(
      width: double.infinity, //尽量多地占用空间
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center, // 使其在y轴上居中
        children: [
          Text(
            currentQuestion.text,
            style: const TextStyle(color: Colors.white),
          ),
          const SizedBox(
            height: 30,
          ),
          ...currentQuestion.answers.map((answer) {
            return AnswerButton(answerText: answer, onTap: () {});
          }),
        ],
      ),
    );
  }
}

2.稍微调整下排列,填充,边缘

位置:questions_screen.dart中 ---> _QuestionScreenState类中 

class _QuestionScreenState extends State<QuestionsScreen> {
  @override
  Widget build(BuildContext context) {
    final currentQuestion = questions[0];

    return SizedBox(
      width: double.infinity, //尽量多地占用空间
      child: Container(
        margin: const EdgeInsets.all(40),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center, // 使其在y轴上居中
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            Text(
              currentQuestion.text,
              style: const TextStyle(color: Colors.white),
              textAlign: TextAlign.center,
            ),
            const SizedBox(
              height: 30,
            ),
            ...currentQuestion.answers.map((answer) {
              return AnswerButton(answerText: answer, onTap: () {});
            }),
          ],
        ),
      ),
    );
  }
}

解释:第(12)行:这行代码的功能就是将x轴的占据拉满

           第(8)行:我在Column类外侧包含一个Container类

           第(9)行:由于第(12)行代码将x轴占据拉满了,我们需要用margin属性来稍微地缩小点

           第(17)行:用于将标题居中。

 3.要将答案洗乱掉

数组有个方法叫做shuffle(),它的意思就是洗牌,可以将数组里面的排序洗乱掉。

但是这个shuffle方法会修改原始数组,而不是创建一个新的数组然后再改变它,所以它会污染数据,所以我们要用创建一个副本然后再调用shuffle。

位置:在根目录下,lib -->  models --> quiz_question.dart

我们在quiz_question.dart里面再新增一个getShuffledAnswer()的方法,用来创建数组副本并洗乱排序。

class QuizQuestion {
  const QuizQuestion(this.text, this.answers);

  final String text;
  final List<String> answers;

  List<String> getShuffledAnswer() {
    final shuffledList = List.of(answers);// 复制一个数组
    shuffledList.shuffle(); // 洗牌
    return shuffledList;
  }
}

所以这个方法的返回类型是List<String>;

List.of()方法可以将answer数组复制出一份,并存储在shuffledList中;

紧接着用 shuffledList.shuffle(),我们就成功地让这个副本数组洗乱了。

最后返回这个洗乱了的副本数组。


回到questions_screen.dart中

将原来的迭代显示按钮的代码更换为如下:

...currentQuestion.getShuffledAnswer().map((answer) {
   return AnswerButton(answerText: answer, onTap: () {});
}),

用getShuffledAnswer()方法返回一个排序乱了的数组替换了之前的固定排序数组answer。

保存下,刷新后再看看。

所以的确是成功了,我们成功地打乱了数组的排序。

4.选择并点击完答案后,要切入下一个界面

        I.答题卡的显示取决于question数组的索引,在这里是0为第一个,这是写死的。接下来既然要让它动态地变化这个就要用变量。

final currentQuestion = questions[0];

        II.添加一个currentQuestionIndex变量,并且在每次我们点击答案之后都加1,于是答题卡就跟着变化。

        位置:在_QuestionScreenState中:

 添加索引变量。

var currentQuestionIndex = 0;

添加答案按钮answerQuestion方法并在每次点击之后索引都加1。

  void answerQuestion() {
    setState(() {
      currentQuestionIndex++;
    });
  }

修改onTap属性的方法为answerQuestion,注意不要加上(),否则它会自己执行。

...currentQuestion.getShuffledAnswer().map((answer) {
  return AnswerButton(answerText: answer, onTap: answerQuestion);
}),

整体代码如下: 

class _QuestionScreenState extends State<QuestionsScreen> {
  var currentQuestionIndex = 0; //索引变量

  void answerQuestion() {
    setState(() {
      currentQuestionIndex++; //每次按下答案,索引变量都加一
    });
  }

  @override
  Widget build(BuildContext context) {
    final currentQuestion = questions[currentQuestionIndex]; //将当前的索引变量存储在currentQuestion中

    return SizedBox(
      width: double.infinity, //尽量多地占用空间
      child: Container(
        margin: const EdgeInsets.all(40),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center, // 使其在y轴上居中
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            Text(
              currentQuestion.text,
              style: const TextStyle(color: Colors.white),
              textAlign: TextAlign.center,
            ),
            const SizedBox(
              height: 30,
            ),
            ...currentQuestion.getShuffledAnswer().map((answer) {  //根据索引变量显示不同答题卡
              return AnswerButton(answerText: answer, onTap: answerQuestion); 
            }),
          ],
        ),
      ),
    );
  }
}

保存下,试下:

整体上成功了,最后会出问题,因为索引过界了,不过之后会处理。 

5.再稍微地修改下外观

        I.注意到,如果答案长度很长的话,下面哪一行就有些不居中。

位置:在answer_button.dart中 ---> build() ---> child:Text()中

新增一个textAlign属性,赋值TextAlign.center。

child: Text(
    answerText,
    textAlign: TextAlign.center, //使字体居中
));

保存后,再看下,就居中了。 

        II.来学习如何导入新字体,并使用它吧

a.首先进入这个链接https://pub.dev/packages/google_fonts

b.点击红框的Installing

c.此为将该字体包安装至本机的步骤;再最上面的终端处,点击新建终端或快捷键ctrl+shift+`

 d.在终端处,输入该命令,回车运行。

flutter pub add google_fonts

紧接着,在根目录下的pubspec.yaml文件中,你会发现google_fonts,说明安装成功了,根据时间不同,版本也不同,但没关系。

 

 e.在questions_screen.dart中,将该字体包引入

import 'package:google_fonts/google_fonts.dart';

在 _QuestionScreenState类 ---> build() ---> SizeBox() --> Container() ---> Column() ---> Text()

对Text()内部进行修改如下:

Text(
   currentQuestion.text,
   style: GoogleFonts.lato(
      color: const Color.fromARGB(255, 211, 162, 251),,
      fontSize: 24,
      fontWeight: FontWeight.bold,
    ),
   textAlign: TextAlign.center,
),

添加一个style属性:并赋值GoogleFonts,即我们刚刚引入的字体包,我们选择lato字体,并且进行了一些参数的修改。


注意:可能你会出现像我这样的问题

解决方法:

在pubspec.yaml文件中,将google_fonts修改为 6.1.0,注意前面不要有^符号,就OK啦


f.既然引入了google字体,那不妨把封面也改下吧:

来到start_screen.dart文件中,找到Text()组件修改为如下:

Text(
   'Learn Word the fun way',
    style: GoogleFonts.lato(    //引入谷歌字体
         color: const Color.fromARGB(255, 216, 192, 250),
         fontSize: 24),
),

来看下成果吧:

 

  • 21
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值