Использование виджета ColorFiltered в приложениях Flutter
Целевая аудитория: Новичок
Рецепт: Использование виджета ColorFiltered для обновления цвета фона экрана обратной связи карточки викторины.
Виджет фокуса: Виджет ColorFiltered
Цель: Обновите цвет фона виджета обратной связи BottomSheet, чтобы отразить статус правильного или неправильного ответа на вопрос викторины. Оттенок красного цвета генерируется с помощью цветного фильтра для неправильного выбора, а оттенок зеленого — для правильного ответа.
ПРИМЕЧАНИЕ: На данный момент виджет ColorFiltered аварийно завершает работу в Chrome. Пожалуйста, обратитесь к Эта проблема на Флаттер Гитхаб.
Страница викторины iOS:
Android QuizPage:
Ознакомьтесь с сопутствующим видеоруководством здесь
Поехали!
Виджет ColorFilter добавляется к Выпуск флаттера 1.9. Этот виджет позволяет генерировать динамичные и яркие оттенки в зависимости от выбранных режимов наложения, часть dart.ui
в фреймворке Flutter painting.dart
файл. я использую BlendMode.hue
режим для смешивания красного и зеленого цветов с QuizPage
х Colors.lightBlueAccent
цвет.
ПРИМЕЧАНИЕ: ColorFilter
не работает в Интернете. Обратитесь к связанной проблеме здесь.
Запуск примера кода
Есть два способа, которыми вы можете опробовать пример кода в этом рецепте.
Только бег
QuizzieDemo
: этот образец можно запускать независимо. Убедитесь, что у вас естьvoid main() => runApp(QuizzieDemo());
в верхней частиquizze_demo.dart
файл.Запуск как часть приложения рецептов кода: если вы выберете эту опцию, вы сможете увидеть другие рецепты кода, перечисленные на домашней странице.
Структура кода
Есть два файла:
quizze_demo.dart
: Содержит точку входа в рецепт примера кода.
import 'package:flutter/material.dart';
import 'package:flutter_widgets/quizzie/quizze_page.dart';
//Note: Use code below to just run this demo.
// OR comment it out if you want to run it on Web as part of recipe sample app
void main() => runApp(QuizzieDemo());
class QuizzieDemo extends StatefulWidget {
@override
_QuizzieDemoState createState() => _QuizzieDemoState();
}
class _QuizzieDemoState extends State<QuizzieDemo> {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: QuizPage(),
);
}
}
quizze_page.dart
: содержит код, относящийся к QuizPage, иColorFilter
для обновления цвета фона виджета обратной связи: Нижний лист.
Давайте исследовать QuizPage
Виджет без состояния в деталях. Есть три части, чтобы QuizPage
интерфейс: Image
виджет для вопроса викторины. Text
виджет для описания вопроса. * Expanded
виджет для переноса вариантов ответа. мы используем Expanded
виджет, чтобы заполнить доступное пространство на экране. Все варианты ответов будут добавлены как child
под Expanded
виджет. QuizOptions()
виджет инкапсулирует варианты/варианты ответов на тест.
Проверить код QuizPage
виджет ниже:
class QuizPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: Column(
children: <Widget>[
Container(
padding: EdgeInsets.only(top: 50, left: 20, right: 20, bottom: 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Image.asset(
"assets/images/tomato.jpg",
),
Text(
"Is tomato a fruit or vegetable ?",
style: TextStyle(
color: Colors.lightBlueAccent,
fontWeight: FontWeight.bold,
fontSize: 30,
),
),
],
),
),
SizedBox(
height: 20,
),
Expanded(
child: Container(
decoration: BoxDecoration(
color: Colors.lightBlueAccent,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20),
topRight: Radius.circular(20)),
),
child: QuizOptions(),
),
)
],
),
);
}
}
Теперь пришло время построить QuizOptions
виджет для вариантов викторины. Одновременно может быть выбран только один ответ, поэтому имеет смысл использовать RadioListTile
представить каждый вариант ответа. QuizOptions
должен быть StatefulWidget
так как он будет отображать обратную связь с пользователем в зависимости от состояния выбора выбора.
class QuizOptions extends StatefulWidget { @override \_QuizOptionsState createState() =\> \_QuizOptionsState();
}
Управление состоянием происходит в _QuizOptionsState
учебный класс. Все варианты упакованы ListView
. С использованием enum
за Options
упростить использование в коде.
enum Options { fruit, veggie, none }
_QuizOptionsState:
class _QuizOptionsState extends State<QuizOptions> {
Options selection = Options.none;
@override
Widget build(BuildContext context) {
return ListView(
children: <Widget>[
RadioListTile(
title: Text(
"Fruit",
style:
TextStyle(fontSize: 30, color: Colors.white, letterSpacing: 3),
),
value: Options.fruit,
groupValue: selection,
onChanged: (Options value) =>
setState(() => showAnswer(context, value)),
),
RadioListTile(
title: Text(
"Vegetable",
style:
TextStyle(fontSize: 30, color: Colors.white, letterSpacing: 3),
),
value: Options.veggie,
groupValue: selection,
onChanged: (Options value) =>
setState(() => showAnswer(context, value)),
)
],
);
}
...
}
Когда выбор сделан, RadioListTile
‘с’onChanged
вызывается метод и передает текущий выбор в showAnswer
метод, как показано ниже. showAnswer
обновляет текущий выбор до переданного значения параметра и использует showModalBottomSheet
чтобы показать модальный нижний лист Material Design.
...
void showAnswer(BuildContext context, Options value) {
selection = value;
showModalBottomSheet(context: context, builder: buildBottomSheet);
}
...
showModalBottomSheet
выбирает объяснение для текущего выбора и использует ColorFiltered
виджет для применения цветового фильтра на основе правильного и неправильного выбора. ColorFiltered
использование виджета FeedbackWidget
как его child
для отображения сообщения обратной связи. ColorFilter.mode(...)
использует BlendMode.hue
и исходный цвет ответа (Colors.greenAccent
за правильный ответ и Colors.redAccent
за неправильный ответ). Его дочерний виджет FeedbackWidget
имеет Colors.lightBlueAccent
— цвет назначения. ColorFiltered
виджет может применять фильтры на основе его colorFilter
атрибут. Он может смешивать исходный цвет с целевым цветом на основе BlendMode
который BlendMode.hue
в нашем случае.
Widget buildBottomSheet(BuildContext context) {
String explanation = "";
if (selection == Options.fruit) {
explanation = "You got it! Tomato is a fruit since it has seeds in it.";
return ColorFiltered(
colorFilter: ColorFilter.mode(Colors.greenAccent, BlendMode.hue),
child: FeedbackWidget(explanation: explanation),
);
} else {
explanation =
"While many people believe a tomato is a vegetable, a tomato has seeds and thus is actually a fruit.";
return ColorFiltered(
colorFilter: ColorFilter.mode(Colors.redAccent, BlendMode.hue),
child: FeedbackWidget(explanation: explanation),
);
}
}
FeedbackWidget
является StatelessWidget. Он показывает текстовое сообщение обратной связи в Container
виджет с BoxDecoration
цвет как Colors.lightBlueAccent
.
class FeedbackWidget extends StatelessWidget {
const FeedbackWidget({
Key key,
@required this.explanation,
}) : super(key: key);
final String explanation;
@override
Widget build(BuildContext context) {
return Container(
height: 150,
decoration: BoxDecoration(
color: Colors.lightBlueAccent,
//optional radius
borderRadius: BorderRadius.only(
topRight: Radius.circular(10), topLeft: Radius.circular(10))),
child: Padding(
padding:
const EdgeInsets.only(top: 10, left: 10, right: 10, bottom: 10),
child: Text(
explanation,
style:
TextStyle(
fontSize: 25,
color: Colors.white,
wordSpacing: 5,
letterSpacing: 1),
),
),
);
}
}
И вы сделали !
Репозиторий исходного кода: Исходный код рецепта доступен здесь
Использованная литература:
- Примечания к выпуску Flutter 1.9
- Образец цветового фильтра Flutter
- Виджет ColorFiltered
- Расширенный виджет
Удачной готовки с Flutter
Понравилась статья? Не нашли интересующую вас тему? Пожалуйста, оставьте комментарии или напишите мне о темах, которые вы хотели бы, чтобы я написал
Следуй за мной в твиттер