Как я могу вставить другой виджет вместо другого, когда один из них нажат?

Я разработчик флаттера начального уровня, и я некоторое время застрял в этой проблеме, я пробовал разные вещи.

Я пытаюсь сделать «Заголовок заметки» (этот конкретный виджет), всплывающим

Описание app_issue

тогда это должно отображаться вместо желаемый результат

Два разных содержимого на вкладке «Мои заметки» — это два виджета с отслеживанием состояния, а вкладка «Мои заметки» — это еще один виджет с отслеживанием состояния.

Я пытался использовать функцию, но она не работает

enum MyNoteContent {
  staticNote,
  dynamicNote,
}

MyNoteContent selectedContent = MyNoteContent.staticNote;

Widget updateMyNotes() {
  if (selectedContent == MyNoteContent.staticNote) {
    return MyNoteStatic();
  } else {
    return MyNoteDynamic();
  }
}

а затем я вызываю функцию в виджете MyNotes

class _MyNotesTabState extends State<MyNotesTab> {
  @override
  Widget build(BuildContext context) {
    return updateMyNotes();
  }
}

Я пытаюсь обновить значение в первом отображаемом содержимом (в своем собственном виджете), чтобы при нажатии оно должно было измениться.

class _MyNoteStaticState extends State<MyNoteStatic> {
  @override
  Widget build(BuildContext context) {
    return Container(
      child: RawMaterialButton(
          onPressed: () {
            setState(() {
              selectedContent = MyNoteContent.dynamicNote;
              updateMyNotes();
            });
          },

Но это не работает

Код для воспроизведения проблемы

Пожалуйста, создайте минимальный воспроизводимый пример. Немного неясно, какой код у вас сейчас есть. Сделайте что-то, что мы можем вставить в Dartpad и показать проблему.

Christopher Moore 14.12.2020 05:04

Я только что добавил это. Это ссылка на GitHubGist.

davidn 14.12.2020 05:19

Вставьте полный пример прямо в свой вопрос и постарайтесь удалить как можно больше лишнего кода.

Christopher Moore 14.12.2020 05:27

setState не влияет на другие виджеты!

Yadu 14.12.2020 05:53

@Yadu Это не очень точно. Вызов setState у дочернего элемента не может напрямую повлиять на родителя, но обратный вызов создаст эффект.

Christopher Moore 14.12.2020 05:56

Я перефразирую это, setState — это функция, которая принадлежит классу State, при вызове она перестроит состояние виджета, которому она принадлежит, она может перестроить дочерние элементы, но определенно не перестроит родителя, если вы не найдете так, как @ChristopherMoore ответил, чтобы восстановить родителя на основе отзывов ребенка

Yadu 14.12.2020 06:15

@Yadu Я думаю, теперь я понял логику. Спасибо за вклад.

davidn 14.12.2020 06:19
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
7
249
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема здесь в том, что setState вы звоните для класса _MyNoteStaticState. Это означает, что он будет перестраивать только виджет MyNoteStatic. Но для того, чтобы страница изменилась, нужно пересобрать ее родителя _MyNotesTabState. Поэтому вам нужно вызвать метод setState для _MyNotesTabState, что можно сделать, передав обратный вызов от _MyNotesTabState к _MyNoteStaticState.

Во-первых, переместите updateMyNotes и selectedContent в класс _MyNotesTabState, так как это единственное место, где они нужны.

Создайте новую функцию, которая перестраивает _MyNotesTabState и изменяет selectedContent в _MyNotesTabState.

void changeNote() {
  setState(() {
    selectedContent = MyNoteContent.dynamicNote;
  });
}

Передайте это MyNoteStatic

Widget updateMyNotes() {
  if (selectedContent == MyNoteContent.staticNote) {
    return MyNoteStatic(changeNote);
  } else {
    return MyNoteDynamic();
  }
}

и измените MyNoteStatic, чтобы принять этот обратный вызов в качестве параметра

class MyNoteStatic extends StatefulWidget {
  final VoidCallback callback;
  MyNoteStatic(this.callback);

  @override
  _MyNoteStaticState createState() => _MyNoteStaticState();
}

Затем передайте этот обратный вызов вашей кнопке вместо того, что у вас есть сейчас:

child: RawMaterialButton(
  onPressed: widget.callback,
)

Полный соответствующий код, включающий вышеуказанные изменения:

enum MyNoteContent {
  staticNote,
  dynamicNote,
}

class MyNotesTab extends StatefulWidget {
  @override
  _MyNotesTabState createState() => _MyNotesTabState();
}

class _MyNotesTabState extends State<MyNotesTab> {
  MyNoteContent selectedContent = MyNoteContent.staticNote;
  
  @override
  Widget build(BuildContext context) {
    return updateMyNotes();
  }
  
  Widget updateMyNotes() {
    if (selectedContent == MyNoteContent.staticNote) {
      return MyNoteStatic(changeNote);
    } else {
      return MyNoteDynamic();
    }
  }
  
  void changeNote() {
    setState(() {
      selectedContent = MyNoteContent.dynamicNote;
    });
  }
}

//Static Note
class MyNoteStatic extends StatefulWidget {
  final VoidCallback callback;
  MyNoteStatic(this.callback);

  @override
  _MyNoteStaticState createState() => _MyNoteStaticState();
}

class _MyNoteStaticState extends State<MyNoteStatic> {
  @override
  Widget build(BuildContext context) {
    return Container(
      child: RawMaterialButton(
          onPressed: widget.callback,
...

@davidn Также, пожалуйста, попробуйте отредактировать свой код непосредственно в своем вопросе, чтобы это могло принести больше пользы будущим пользователям.

Christopher Moore 14.12.2020 05:55

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