Я написал код, который открывает новый контейнер каждый раз, когда вы нажимаете кнопку добавления. Каждый из этих контейнеров открывает RPage (проверьте код, если вы не понимаете).
Код:
import 'package:flutter/material.dart';
import 'dart:io';
void main() => runApp(MainPage());
class MainPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp (
debugShowCheckedModeBanner: false,
home:Scaffold (
backgroundColor: Colors.white,
body: Column (
children: <Widget> [
Container (
height: 100.0
),
Body(),
]
)
)
);
}
}
class Body extends StatefulWidget {
@override
_BodyState createState() => _BodyState();
}
class _BodyState extends State<Body> {
final String open1 = 'open';
int count = 1;
@override
Widget build(BuildContext context) {
return Expanded (
child: Container (
child: NotificationListener<OverscrollIndicatorNotification> (
onNotification: (OverscrollIndicatorNotification overscroll) {
overscroll.disallowGlow();
},
child: PageView.builder(
reverse: true,
pageSnapping: false,
controller: PageController(viewportFraction: 0.85),
itemCount: count,
itemBuilder: (context, i) {
if (i == 0) {
return GestureDetector (
onTap: () {
Navigator.push(
context,
MaterialPageRoute (
builder: (context) => RPage (
open: open1,
)
),
);
count++;
},
child: Hero (
tag: open1,
child: Padding (
padding: EdgeInsets.only(
left: MediaQuery.of(context).size.height * 0.015,
right: MediaQuery.of(context).size.height * 0.015,
top: MediaQuery.of(context).size.width * 0.08,
bottom: MediaQuery.of(context).size.width * 0.15
),
child: Material (
borderRadius: BorderRadius.circular(40.0),
color: Colors.white,
elevation: 8.0,
child: InkWell (
child: Column (
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget> [
Icon (
Icons.add,
size: 30.0,
color: Colors.black,
)
]
),
)
)
)
)
);
}
else {
return RCard(i);
}
}
)
)
)
);
}
}
class RCard extends StatefulWidget {
final int count;
RCard(this.count);
@override
RCardState createState() => RCardState();
}
class RCardState extends State<RCard> {
int count;
String open2;
@override
void initState() {
super.initState();
count = widget.count;
open2 = 'open$count';
}
@override
Widget build(BuildContext context) {
return Hero (
tag: open2,
child: GestureDetector (
onTap: () {
Navigator.push(
context,
MaterialPageRoute (
builder: (context) => RPage (
open: open2,
)
),
);
},
child: Padding (
padding: EdgeInsets.only(
left: MediaQuery.of(context).size.height * 0.015,
right: MediaQuery.of(context).size.height * 0.015,
top: MediaQuery.of(context).size.width * 0.08,
bottom: MediaQuery.of(context).size.width * 0.15
),
child: Material (
borderRadius: BorderRadius.circular(40.0),
color: Colors.white,
elevation: 8.0,
)
)
),
);
}
}
class RPage extends StatelessWidget {
final String open;
RPage({this.open});
@override
Widget build(BuildContext context) {
return GestureDetector (
child: Hero (
tag: open,
child: Material (
child: Container (
color: Colors.white,
child: Center (
child: RBody()
)
)
)
),
onTap: () {
Navigator.pop(context);
},
);
}
}
class Constants {
static const String add = 'Add';
static const List<String> choices = <String>[
add
];
}
class RBody extends StatefulWidget {
@override
RBodyState createState() => RBodyState();
}
class RBodyState extends State<RBody> {
final String open1 = 'open';
static bool platform;
static int count = 1;
@override
Widget build(BuildContext context) {
if (Platform.isIOS) {
platform = true;
}
if (Platform.isAndroid) {
platform = false;
}
return Column (
children: <Widget> [
Container (
height: MediaQuery.of(context).size.height * 0.15,
width: MediaQuery.of(context).size.width * 1.0,
child: Row (
children: <Widget> [
Expanded (
child: Container (
alignment: Alignment(-0.9, 1.0),
child: IconButton (
iconSize: 15.0,
icon: Icon (Icons.arrow_back_ios),
onPressed: () {
Navigator.pop(context);
},
)
),
),
Expanded (
child: Container (
alignment: Alignment(0.9, 1.0),
child: platform ? RotatedBox (
quarterTurns: 1,
child: PopupMenuButton<String> (
onSelected: (_) {
setState(() {
count ++;
});
},
itemBuilder: (BuildContext context) {
return Constants.choices.map(
(String choice) {
return PopupMenuItem<String> (
value: choice,
child: Text(choice)
);
}
).toList();
},
)
) :
PopupMenuButton<String> (
onSelected: (_) {
setState(() {
count ++;
});
},
itemBuilder: (BuildContext context) {
return Constants.choices.map(
(String choice) {
return PopupMenuItem<String> (
value: choice,
child: Text(choice)
);
}
).toList();
},
)
)
)
]
),
),
Title(),
Padding (
padding: EdgeInsets.symmetric(
vertical: platform ? 10.0 : 30.0
),
),
Expanded (
child: Align (
alignment: Alignment.topCenter,
child: Container (
height: MediaQuery.of(context).size.height * 0.34,
width: MediaQuery.of(context).size.height * 1.0,
child: RList()
)
)
)
]
);
}
}
class RList extends StatefulWidget {
@override
RListState createState() => RListState();
}
class RListState extends State<RList> {
@override
Widget build(BuildContext context) {
return NotificationListener<OverscrollIndicatorNotification> (
onNotification: (OverscrollIndicatorNotification overscroll) {
overscroll.disallowGlow();
},
child: ListView.builder(
controller: PageController(viewportFraction: 0.85),
itemCount: RBodyState.count,
itemBuilder: (context, i) {
if (i == 0) {
return Container();
} else {
return Cell(i);
}
}
)
);
}
}
class Title extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container (
color: Colors.white,
height: MediaQuery.of(context).size.height * 0.2,
width: MediaQuery.of(context).size.width * 1.0,
child: Align (
alignment: Alignment.bottomCenter,
child: Material (
color: Colors.white,
child: Text (
'T I T L E',
style: TextStyle (
fontWeight: FontWeight.bold,
fontSize: 20.0,
),
)
)
)
);
}
}
class Cell extends StatefulWidget {
final int count;
Cell(this.count);
@override
CellState createState() => CellState();
}
class CellState extends State<Cell> {
@override
Widget build(BuildContext context) {
return Column (
children: <Widget> [
Material (
color: Colors.white,
child: Text (
'T E X T',
style: TextStyle (
fontSize: 12.0,
fontWeight: FontWeight.bold,
),
)
),
Padding (
padding: EdgeInsets.symmetric(
vertical: MediaQuery.of(context).size.height * 0.025
),
),
]
);
}
}
RPage будет создавать новые тексты каждый раз, когда вы нажимаете кнопку всплывающего меню. Но я ожидал, что тексты будут добавлены только на этой конкретной странице. Но я обнаружил, что мой код добавляет тексты на каждую страницу. Как я могу добавить текст только на одну конкретную страницу?
@AmanMalhotra, можете ли вы привести пример с редукцией и флаттером?
Проблема здесь: в вашем классе RBodyState
static int count = 1;
Поскольку ваша переменная count является статической, все экземпляры имеют одинаковое значение count, и в результате все ваши страницы имеют одинаковое количество T I T L E.
Используйте следующий код:
import 'package:flutter/material.dart';
import 'dart:io';
void main() => runApp(MainPage());
class MainPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp (
debugShowCheckedModeBanner: false,
home:Scaffold (
backgroundColor: Colors.white,
body: Column (
children: <Widget> [
Container (
height: 100.0
),
Body(),
]
)
)
);
}
}
class Body extends StatefulWidget {
@override
_BodyState createState() => _BodyState();
}
class _BodyState extends State<Body> {
final String open1 = 'open';
int count = 1;
@override
Widget build(BuildContext context) {
return Expanded (
child: Container (
child: NotificationListener<OverscrollIndicatorNotification> (
onNotification: (OverscrollIndicatorNotification overscroll) {
overscroll.disallowGlow();
},
child: PageView.builder(
reverse: true,
pageSnapping: false,
controller: PageController(viewportFraction: 0.85),
itemCount: count,
itemBuilder: (context, i) {
if (i == 0) {
return GestureDetector (
onTap: () {
Navigator.push(
context,
MaterialPageRoute (
builder: (context) => RPage (
open: open1,
)
),
);
count++;
},
child: Hero (
tag: open1,
child: Padding (
padding: EdgeInsets.only(
left: MediaQuery.of(context).size.height * 0.015,
right: MediaQuery.of(context).size.height * 0.015,
top: MediaQuery.of(context).size.width * 0.08,
bottom: MediaQuery.of(context).size.width * 0.15
),
child: Material (
borderRadius: BorderRadius.circular(40.0),
color: Colors.white,
elevation: 8.0,
child: InkWell (
child: Column (
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget> [
Icon (
Icons.add,
size: 30.0,
color: Colors.black,
)
]
),
)
)
)
)
);
}
else {
return RCard(i);
}
}
)
)
)
);
}
}
class RCard extends StatefulWidget {
final int count;
RCard(this.count);
@override
RCardState createState() => RCardState();
}
class RCardState extends State<RCard> {
int count;
String open2;
@override
void initState() {
super.initState();
count = widget.count;
open2 = 'open$count';
}
@override
Widget build(BuildContext context) {
return Hero (
tag: open2,
child: GestureDetector (
onTap: () {
Navigator.push(
context,
MaterialPageRoute (
builder: (context) => RPage (
open: open2,
)
),
);
},
child: Padding (
padding: EdgeInsets.only(
left: MediaQuery.of(context).size.height * 0.015,
right: MediaQuery.of(context).size.height * 0.015,
top: MediaQuery.of(context).size.width * 0.08,
bottom: MediaQuery.of(context).size.width * 0.15
),
child: Material (
borderRadius: BorderRadius.circular(40.0),
color: Colors.white,
elevation: 8.0,
)
)
),
);
}
}
class RPage extends StatelessWidget {
final String open;
RPage({this.open});
@override
Widget build(BuildContext context) {
return GestureDetector (
child: Hero (
tag: open,
child: Material (
child: Container (
color: Colors.white,
child: Center (
child: RBody()
)
)
)
),
onTap: () {
Navigator.pop(context);
},
);
}
}
class Constants {
static const String add = 'Add';
static const List<String> choices = <String>[
add
];
}
class RBody extends StatefulWidget {
@override
RBodyState createState() => RBodyState();
}
class RBodyState extends State<RBody> {
final String open1 = 'open';
static bool platform;
int count = 1;
@override
Widget build(BuildContext context) {
if (Platform.isIOS) {
platform = true;
}
if (Platform.isAndroid) {
platform = false;
}
return Column (
children: <Widget> [
Container (
height: MediaQuery.of(context).size.height * 0.15,
width: MediaQuery.of(context).size.width * 1.0,
child: Row (
children: <Widget> [
Expanded (
child: Container (
alignment: Alignment(-0.9, 1.0),
child: IconButton (
iconSize: 15.0,
icon: Icon (Icons.arrow_back_ios),
onPressed: () {
Navigator.pop(context);
},
)
),
),
Expanded (
child: Container (
alignment: Alignment(0.9, 1.0),
child: platform ? RotatedBox (
quarterTurns: 1,
child: PopupMenuButton<String> (
onSelected: (_) {
setState(() {
count ++;
});
},
itemBuilder: (BuildContext context) {
return Constants.choices.map(
(String choice) {
return PopupMenuItem<String> (
value: choice,
child: Text(choice)
);
}
).toList();
},
)
) :
PopupMenuButton<String> (
onSelected: (_) {
setState(() {
count ++;
});
},
itemBuilder: (BuildContext context) {
return Constants.choices.map(
(String choice) {
return PopupMenuItem<String> (
value: choice,
child: Text(choice)
);
}
).toList();
},
)
)
)
]
),
),
Title(),
Padding (
padding: EdgeInsets.symmetric(
vertical: platform ? 10.0 : 30.0
),
),
Expanded (
child: Align (
alignment: Alignment.topCenter,
child: Container (
height: MediaQuery.of(context).size.height * 0.34,
width: MediaQuery.of(context).size.height * 1.0,
child: RList(count)
)
)
)
]
);
}
}
class RList extends StatefulWidget {
int count;
RList(this.count);
@override
RListState createState() => RListState();
}
class RListState extends State<RList> {
@override
Widget build(BuildContext context) {
return NotificationListener<OverscrollIndicatorNotification> (
onNotification: (OverscrollIndicatorNotification overscroll) {
overscroll.disallowGlow();
},
child: ListView.builder(
controller: PageController(viewportFraction: 0.85),
itemCount: widget.count,
itemBuilder: (context, i) {
if (i == 0) {
return Container();
} else {
return Cell(i);
}
}
)
);
}
}
class Title extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container (
color: Colors.white,
height: MediaQuery.of(context).size.height * 0.2,
width: MediaQuery.of(context).size.width * 1.0,
child: Align (
alignment: Alignment.bottomCenter,
child: Material (
color: Colors.white,
child: Text (
'T I T L E',
style: TextStyle (
fontWeight: FontWeight.bold,
fontSize: 20.0,
),
)
)
)
);
}
}
class Cell extends StatefulWidget {
final int count;
Cell(this.count);
@override
CellState createState() => CellState();
}
class CellState extends State<Cell> {
@override
Widget build(BuildContext context) {
return Column (
children: <Widget> [
Material (
color: Colors.white,
child: Text (
'T E X T',
style: TextStyle (
fontSize: 12.0,
fontWeight: FontWeight.bold,
),
)
),
Padding (
padding: EdgeInsets.symmetric(
vertical: MediaQuery.of(context).size.height * 0.025
),
),
]
);
}
}
Извините, но я думаю, что у меня проблема. Когда я нажимаю на контейнер и добавляю тексты, а затем выхожу, а затем снова нажимаю на контейнер, все тексты исчезают. Как я могу это исправить?
Сохраните счетчик в некоторой структуре, такой как карта, с идентификатором контейнера в качестве ключа и количеством счетчика в качестве значения. И каждый раз, когда вы возвращаетесь к своему предыдущему контейнеру, извлекайте количество отсчетов из этой карты.
Можете ли вы привести пример?
После того, как я дал вам эту идею, вы пробовали что-нибудь,..?? если да, то опубликуйте свой код, я исправлю вас, если у вас возникнут какие-либо проблемы.
Хорошо, если вы вообще не знаете о редуксе во флаттере. Сначала это покажется слишком сложным, но если вы изучите Redux, прежде чем смотреть на это, вы увидите, что это слишком просто для управления состоянием в Redux, не усложняя ваш код вообще. но вам придется сделать больше файлов, чтобы сохранить ваш код в порядке. Я залил код на гитхаб ссылка на который дана здесь вы можете клонировать этот проект и попробовать сами Пример карты Redux
Потребуется много изменений в вашем коде, поскольку у вас есть несколько классов, и вам потребуется передавать данные в иерархии на много шагов вниз в вашем коде, чтобы вы могли достичь того, что хотите сделать. Но, увидев ваш код, я бы посоветовал вам одну вещь, это вообще подход, который вам совсем не поможет. Вы уже сделали свой код намного сложнее, чем он мог бы быть на самом деле. попробуйте использовать редукцию для этой проблемы. это будет лучший вариант использования для этого. то, что вы пытаетесь достичь, просто, но вы усложнили его