Flutter - передача данных между виджетами на одном экране - PullRequest
0 голосов
/ 04 апреля 2020

У меня есть один экран, разделенный на 2 половины. Верхняя половина имеет вид списка, а нижняя будет отображать детали, основанные на onTap: из listTile в представлении списка выше.

Мой код выглядит примерно так, после удаления всех ненужных частей:

return Scaffold(
  appBar: AppBar(
    ...
    // app bar details
      ...
    ), // AppBar

body: SingleChildScrollView (
        child: Column(
            children: <Widget>[ 
             ...
             Container(
                ...
                child: populatelistview();
                ), 

             SizedBox(height: ...),
              ...
              ...
             Container(
                ...
                child: detailsView();
                ),
             ... 
            ],
          ), // Column
     ) // SingleChildScrollView

Таким образом, чтобы заполнить detailsView данными, основанными на onTap (), из listview, мне нужно будет передать некоторую переменную (или некоторый идентификатор) из listview в detailsView.

Ранее я использовал Navigator.pu sh (см .: https://flutter.dev/docs/cookbook/navigation/passing-data), но это сработало бы только при переходе с одного экрана на другой. У меня проблемы с отправкой данных из списка в подробный просмотр на том же экране.

Возможно, я смотрю на это по-другому или просто не могу правильно выполнить поиск.

Буду признателен, если кто-нибудь укажет мне правильное направление.

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

Заранее спасибо.

Будьте в безопасности !!

Ответы [ 4 ]

0 голосов
/ 07 апреля 2020

Спасибо всем, кто пытался помочь мне. Однако теперь я решил эту проблему с помощью Inherited Widget.

Inherited Widget больше подходил для моей ситуации, когда мне нужно было передавать данные из одного виджета в другой без изменения экрана.

0 голосов
/ 04 апреля 2020

Вы можете передавать такую ​​информацию. Используйте переменную в своем классе для хранения информации о выбранном элементе.

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: MyWidget(),
      ),
    );
  }
}

class MyWidget extends StatefulWidget {
  @override
  createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  int _item;

  @override
  void initState() {
    super.initState();
    _item = null;
  }

  @override
  Widget build(BuildContext context) {
    return Column(
        mainAxisSize: MainAxisSize.max,
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: <Widget>[
          Expanded(
            child: ListView.builder(
                itemCount: 100,
                itemBuilder: (context, i) {
                  return ListTile(
                    title: Text('Item $i'),
                    onTap: () => setState(() => _item = i),
                  );
                }),
          ),
          Container(height: 2, color: Colors.grey),
          Expanded(
            child: Container(
              color: Colors.grey[100],
              child: Center(
                child: Text(_item == null
                    ? 'Select an item'
                    : 'Item $_item was selected',),
              ),
            ),
          ),
        ]);
  }
}

Result

Надеюсь, это поможет!

0 голосов
/ 04 апреля 2020

Если это виджет stateful, попробуйте использовать setState()

См. Пример кода ниже:

class Test extends State<StatusPage> {
String text = 'Hello';

  @override
  Widget build(BuildContext context) {

    Widget details = Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      mainAxisSize: MainAxisSize.min,
      children: <Widget>[
        Text(text),
      ],
    );

    return Scaffold(
      appBar: AppBar(),
      body: SingleChildScrollView(
        child: Column(
          children: <Widget>[
            ListView.builder(
              itemCount: 4,
              shrinkWrap: true,
              itemBuilder: (BuildContext context, int index) {
                return ListTile(
                  title: Text('Item #$index'),
                  onTap: () {
                    setState(() {
                      text == 'Hello' ? text = 'Test' : text = 'Hello';
                    });
                  },
                );
              },
            ),
            SizedBox(height: 54),
            details,
          ],
        ), // Column
      ),
    );
  }


}
0 голосов
/ 04 апреля 2020

Я бы посоветовал вам использовать управление состоянием провайдера, это будет легко реализовать, оба ваших представления будут иметь некоторый ChangeNotifier, вот некоторый фрагмент, который может вам помочь:


populatelistview:
GestureDetector(
  onTap: (){
       notifier.setId(id);
    },
child:// your child


detailsView:
Container(
   child: Text(notifier.id),
)


Уведомление об изменении
class Notifier extends ChangeNotifier {

int id;

void setId(int id){
  this.id = id;
  notifyListeners();// Here the magic happens
}
...