#java #android #flutter #dart #mobile
Вопрос:
в настоящее время я изучаю флаттер и дарт. Я искал, но не мог его найти.
Я хочу поместить кнопку «Избранное» рядом с именами в списке, и при нажатии на нее я просто хочу, чтобы она сортировала избранное на другой странице.
Вот мой код:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HomeScreen(),
);
}
}
class HomeScreen extends StatefulWidget {
AnaEkran createState() => AnaEkran();
}
class AnaEkran extends State<HomeScreen> {
static List<String> mainDataList = [
"Apple",
"Apricot",
"Banana",
"Blackberry",
"Coconut",
"Date",
"Fig",
"Gooseberry",
"Grapes",
"Lemon",
"Litchi",
"Mango",
"Orange",
"Papaya",
"Peach",
"Pineapple",
"Pomegranate",
"Starfruit"
];
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 2,
child: Scaffold(
appBar: AppBar(
title: Text('NickName Generator'),
backgroundColor: Colors.deepPurple,
bottom: TabBar(
tabs: [
Tab(icon: Icon(Icons.article_rounded)),
Tab(icon: Icon(Icons.favorite)),
],
),
),
body: ListView.builder(
itemCount: mainDataList.length,
itemBuilder: (context, index) {
return Card (
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Text(mainDataList[index],style: TextStyle(fontSize: 19.0),),
),
);
},
),
),
);
}
}
И вот как это выглядит. Тот же список появляется на второй странице, но я хочу, чтобы туда добавлялись только любимые слова.
Ответ №1:
Я постараюсь объяснить каждый необходимый шаг, так что потерпите.
Во-первых, вам нужно создать новый список, который будет списком избранных строк
List<String> mainDataList = [
"Apple",
"Apricot",
"Banana",
"Blackberry",
"Coconut",
"Date",
"Fig",
"Gooseberry",
"Grapes",
"Lemon",
"Litchi",
"Mango",
"Orange",
"Papaya",
"Peach",
"Pineapple",
"Pomegranate",
"Starfruit"
];
List<String> favoriteDataList = [];
Теперь в качестве тела для вашего каркаса вы должны добавить виджеты TabBarView, которые содержат список виджетов. Количество виджетов в этом списке должно совпадать с количеством вкладок, которые вы добавили в панель вкладок, так как всякий раз, когда вы нажимаете на одну из вкладок в ней, она перемещается в виджеты TabBarView, соответствующие индексу.
Таким образом, тело для вашего эшафота должно выглядеть примерно так:
TabBarView(
children: [
ListView.builder(
itemCount: mainDataList.length,
itemBuilder: (context, index) {
return Card(
child: Row(
children: [
Expanded(
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Text(
mainDataList[index],
style: const TextStyle(fontSize: 19.0),
),
),
),
ElevatedButton(
onPressed: () {
setState(() {
favoriteDataList.add(mainDataList[index]);
});
},
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all<Color>(
Colors.deepPurple,
),
),
child: const Icon(
Icons.favorite,
color: Colors.white,
),
),
],
),
);
},
),
favoriteDataList.isEmpty
? const Center(
child: Text(
'There are no favorites yet!',
style: TextStyle(color: Colors.black),
),
)
: ListView.builder(
itemCount: favoriteDataList.length,
itemBuilder: (context, index) {
return Card(
child: Row(
children: [
Expanded(
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Text(
favoriteDataList[index],
style: const TextStyle(fontSize: 19.0),
),
),
),
ElevatedButton(
onPressed: () {
setState(() {
favoriteDataList
.remove(favoriteDataList[index]);
});
},
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all<Color>(
Colors.deepPurple,
),
),
child: const Icon(
Icons.remove,
color: Colors.white,
),
),
],
),
);
},
),
],
),
Конечно, там много кода, я собираюсь разделить его на части, чтобы лучше объяснить.
Как вы можете видеть, сначала у нас есть два виджета внутри дочерних элементов панели вкладок, первый из них тот, который был у вас, есть некоторые отличия, так как я добавил строку, а внутри нее-кнопку с повышением, которая позаботится о добавлении нужного элемента в список избранных:
ElevatedButton(
onPressed: () {
setState(() {
favoriteDataList.add(mainDataList[index]);
});
},
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all<Color>(
Colors.deepPurple,
),
),
child: const Icon(
Icons.favorite,
color: Colors.white,
),
),
Итак, важной частью этой кнопки является метод onPressed, поскольку вы создали StatefulWidget, мы можем сказать, что состояние было изменено, используя метод setState, он получает функцию. Зачем вам это нужно? Потому что вам нужен способ сообщить пользовательскому интерфейсу, что состояние изменилось, поэтому его нужно перестроить.
Например, в безгосударственном виджете у вас нет метода setState, поэтому вы не сможете обновить пользовательский интерфейс без использования некоторых специальных виджетов или какого-либо конкретного решения для управления состоянием (например, блока).
Прямо сейчас, когда пользователь нажимает эту кнопку избранного, мы собираемся добавить выбранный элемент из главного списка в список избранного, используя индекс элемента, который мы только что нажали. И, как я уже упоминал ранее, поскольку состояние было изменено, пользовательский интерфейс будет перестроен, поэтому, когда вы нажмете вкладку «Избранное», вы увидите, что выбранный элемент был добавлен.
Кнопка с повышением на второй вкладке имеет некоторые небольшие отличия
ElevatedButton(
onPressed: () {
setState(() {
favoriteDataList
.remove(favoriteDataList[index]);
});
},
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all<Color>(
Colors.deepPurple,
),
),
child: const Icon(
Icons.remove,
color: Colors.white,
),
),
Помимо другого значка, вместо добавления элементов мы хотим удалить их, поэтому всякий раз, когда мы нажимаем кнопку, элемент, расположенный в том же индексе, будет удален из списка избранных.
Я также использовал тернарный оператор для отображения виджета, если favoriteDataList не:
favoriteDataList.isEmpty
? const Center(
child: Text(
'There are no favorites yet!',
style: TextStyle(color: Colors.black),
),
)
: ListView.builder(
Если пусто, мы показываем Центр… а если нет, то просмотр списка…
И это почти все, конечно, есть некоторые улучшения в этом коде, например, если вы нажмете один и тот же элемент на первой вкладке несколько раз, он будет добавлен в список избранных несколько раз. Но я думаю, что пример работает, и вы сможете поиграть с ним и исправить его!
Извините за длинный пост, надеюсь, это поможет!
Комментарии:
1. прежде всего, большое вам спасибо. Вы очень хорошо объяснили. Я надеюсь, что буду такой же, как ты. Я новичок в флаттере. Одна вещь, которую я заметил, заключается в том, что, когда я дважды нажимаю кнопку «Избранное», она дважды добавляет слово в список.
2. для(int i=0;i
3. я добавляю этот блок для добавления элемента в список избранных, но это не сработало :d
4. Не за что! Не волнуйся, я не настолько хорош, тебе просто нужно продолжать практиковаться! Да, это одна из проблем, о которой я упоминал в конце своего ответа, вам просто нужно найти способ проверить, есть ли этот элемент в списке, прежде чем добавлять его снова. Есть несколько проблем с циклом for, который вы использовали: 1) Вы добавляете элемент в обоих случаях 2) Вы повторяете список избранных, и если элемента нет в списке основных, вы пытаетесь добавить его, что не имеет смысла, так как каждый элемент в списке избранных будет в основном списке.
5. Я думаю, что вы можете достичь того, чего хотите, используя два цикла for, один для итерации mainDataList и внутри этого, другой для итерации favoriteDataList и проверки, существует ли элемент, который вы хотите добавить, уже в favoriteDataList. Это еще один простой способ проверить, существует ли элемент в списке: если (!favoriteDataList.содержит(mainDataList[индекс])) { favoriteDataList.add(mainDataList[индекс]); } Здесь я просто проверяю, есть ли элемент, который я хочу добавить в список, уже там, поэтому, если его там нет, добавьте его в список. В любом случае, продолжайте пытаться сделать это с помощью цикла for!