Могу ли я использовать «индекс» в виджете PageView в другом виджете?

Я делаю приложение на два раздела: один (верхний) - это PageView область виджетов, другой (нижний раздел) - это Container область виджетов. Я хочу, чтобы нижний раздел показывал «мы на X-странице», когда я меняю страницы в верхнем разделе.

Я попытался использовать index виджета PageView в виджете «Контейнер», но консоль сказала «undefined name 'index'». Итак, я объявил как int index; как глобальную переменную и попытался снова, но это не сработало. Я думаю, что этот index отличается от index виджета PageView.

import 'package:flutter/material.dart';

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  static final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
  final controller = PageController(initialPage: 0);
  var scrollDirection = Axis.horizontal;
  var actionIcon = Icons.swap_vert;
  int index;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: _scaffoldKey,
      appBar: AppBar(
        centerTitle: true,
        title: Text('it\'s a drill for page view'),
      ),
      body: _buildBody(),
    );
  }

  Widget _buildBody() {
    return SafeArea(
      child: Column(
        children: <Widget>[
          Expanded(
            child: PageView.builder(
              controller: controller,
              itemCount: 5,
              itemBuilder: (context, index) {
                return Text('it is ${index} page');
              },
            )
          ),
          Expanded(
            child: FittedBox(
              fit: BoxFit.fitWidth,
              child: Container(
                color: Colors.blue,
                child: Text('we are in ${index} page!'),
              ),
            ),
          )
        ],
      ),
    );
  }
}

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


person Jinsub Kim    schedule 08.09.2019    source источник


Ответы (2)


да. как controller.page для текущей страницы.

class Sample extends StatelessWidget{

final int value;
Sample(this.value);

build(context) => Text("you are in $value");
}

и используйте Sample(controller.page)

РЕДАКТИРОВАТЬ: ваш код должен быть

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  static final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
  final controller = PageController(initialPage: 0);
  var scrollDirection = Axis.horizontal;
  var actionIcon = Icons.swap_vert;
  int currentPage=0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: _scaffoldKey,
      appBar: AppBar(
        centerTitle: true,
        title: Text('it\'s a drill for page view'),
      ),
      body: _buildBody(),
    );
  }

  Widget _buildBody() {
    return SafeArea(
      child: Column(
        children: <Widget>[
          Expanded(
              child: PageView.builder(
                controller: controller,
                itemCount: 5,
                itemBuilder: (context, index) {
                  return Text('it is ${index} page');
                },
                onPageChanged: (page){
                  setState(() {
                    currentPage=page;
                  });
                },
              )
          ),
          Expanded(
            child: FittedBox(
              fit: BoxFit.fitWidth,
              child: Container(
                color: Colors.blue,
                child: Text('we are in ${currentPage} page!'),
              ),
            ),
          )
        ],
      ),
    );
  }
}
person Doc    schedule 08.09.2019
comment
Большое спасибо! Благодаря вашей помощи я получил почти то, что хотел. - person Jinsub Kim; 08.09.2019
comment
Но есть еще две проблемы. Один из них Sample (controller.page) кажется двойным. Хотя я объявил значение как int, консоль сообщает, что тип аргумента double не может быть назначен типу параметра int. Итак, я объявил значение двойным, это сработало. К сожалению, здесь возникает другая проблема. Когда я запускаю эмулятор, кажется, что он работает хорошо, но он не меняет номер (например, 3.0, потому что я объявил его двойным), когда я меняю страницы. Я думаю, это потому, что я сделал класс Sample как statelessWidget, но не уверен - person Jinsub Kim; 08.09.2019
comment
используйте 1_ - person Doc; 08.09.2019
comment
для второй части вам нужно вызвать setState() в вашем классе, который содержит просмотр страницы для обновления пользовательского интерфейса. Есть функция onPageChanged (int) см. (api.flutter.dev/flutter/widgets /PageView-class.html), который вызывается при изменении страницы, поэтому вызовите здесь setState - person Doc; 08.09.2019
comment
Мне очень жаль заставлять вас ждать. У меня много дел, как у студента. Думаю, я не могу сегодня проверить ваше решение. Не могли бы вы дать мне немного времени? - person Jinsub Kim; 08.09.2019
comment
Я написал код без редактора, поэтому я подумал, что если мой код не работает, то все - person Doc; 08.09.2019
comment
Не работает .. но спасибо за вашу искреннюю помощь. Я использую андроид-студию. - person Jinsub Kim; 09.09.2019
comment
Я наконец решил эту проблему благодаря тебе! Теперь это действительно отлично работает. Большое тебе спасибо. Надеюсь, твой день будет счастливым! С любовью. - person Jinsub Kim; 13.09.2019

Просто добавьте слушателя в PageController вот так:

  @override
  void initState() {
    super.initState();
    index = 0;
    controller.addListener(() {
      setState(() {
        index = controller.page.toInt();
      });
    });
  }
person Spatz    schedule 08.09.2019
comment
Спасибо, что ответили мне. Могу я спросить вас, где находится PageController? Мне ужасно жаль, что я новичок в этом программировании. Думаю, сейчас не могу проверить. Заканчивая что-то делать, проверю. - person Jinsub Kim; 08.09.2019
comment
вот он final controller = PageController(initialPage: 0); - person Spatz; 08.09.2019
comment
работает отлично! Большое тебе спасибо. Но есть разница во времени. нижний следует за верхним примерно на 0,5 секунды. Любое предложение? - person Jinsub Kim; 09.09.2019
comment
Замените controller.page.toInt() на controller.page.round(), и задержка исчезнет. - person Spatz; 09.09.2019
comment
Все еще есть задержка. Я задам новый вопрос по этому поводу. Если вы свободны, приходите, чтобы помочь мне с новым вопросом. - person Jinsub Kim; 13.09.2019