Как добавить тексты на каждую конкретную страницу?

Я написал код, который открывает новый контейнер каждый раз, когда вы нажимаете кнопку добавления. Каждый из этих контейнеров открывает 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 будет создавать новые тексты каждый раз, когда вы нажимаете кнопку всплывающего меню. Но я ожидал, что тексты будут добавлены только на этой конкретной странице. Но я обнаружил, что мой код добавляет тексты на каждую страницу. Как я могу добавить текст только на одну конкретную страницу?

Потребуется много изменений в вашем коде, поскольку у вас есть несколько классов, и вам потребуется передавать данные в иерархии на много шагов вниз в вашем коде, чтобы вы могли достичь того, что хотите сделать. Но, увидев ваш код, я бы посоветовал вам одну вещь, это вообще подход, который вам совсем не поможет. Вы уже сделали свой код намного сложнее, чем он мог бы быть на самом деле. попробуйте использовать редукцию для этой проблемы. это будет лучший вариант использования для этого. то, что вы пытаетесь достичь, просто, но вы усложнили его

Aman Malhotra 18.04.2019 23:05

@AmanMalhotra, можете ли вы привести пример с редукцией и флаттером?

Young 19.04.2019 06:28
6
2
167
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Проблема здесь: в вашем классе 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
            ),
          ),
        ]
    );
  }

}

Извините, но я думаю, что у меня проблема. Когда я нажимаю на контейнер и добавляю тексты, а затем выхожу, а затем снова нажимаю на контейнер, все тексты исчезают. Как я могу это исправить?

Young 15.04.2019 00:50

Сохраните счетчик в некоторой структуре, такой как карта, с идентификатором контейнера в качестве ключа и количеством счетчика в качестве значения. И каждый раз, когда вы возвращаетесь к своему предыдущему контейнеру, извлекайте количество отсчетов из этой карты.

Kalpesh Kundanani 15.04.2019 03:36

Можете ли вы привести пример?

Young 19.04.2019 06:30

После того, как я дал вам эту идею, вы пробовали что-нибудь,..?? если да, то опубликуйте свой код, я исправлю вас, если у вас возникнут какие-либо проблемы.

Kalpesh Kundanani 20.04.2019 12:29
Ответ принят как подходящий

Хорошо, если вы вообще не знаете о редуксе во флаттере. Сначала это покажется слишком сложным, но если вы изучите Redux, прежде чем смотреть на это, вы увидите, что это слишком просто для управления состоянием в Redux, не усложняя ваш код вообще. но вам придется сделать больше файлов, чтобы сохранить ваш код в порядке. Я залил код на гитхаб ссылка на который дана здесь вы можете клонировать этот проект и попробовать сами Пример карты Redux

Другие вопросы по теме