Flutter: вызов функции для состояния дочернего виджета - PullRequest
0 голосов
/ 28 мая 2018

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

В частности, у меня есть класс PlayerContainer, который создает VideoPlayer и имеет переменную-член дляVideoPlayerController.Когда я нажимаю кнопку воспроизведения, мой основной класс должен вызывать play () для VideoPlayerController состояния, поэтому я создал функцию внутри класса State, но я не знаю, как получить доступ к этой функции из родительского виджета.

Это вообще возможно?Или я все об этом говорю не так?

Ответы [ 3 ]

0 голосов
/ 28 мая 2018

Государственное управление - это единственное, что они бросили в этом отношении.Я использовал статические переменные (если мне нужно обмениваться данными между состояниями) и GlobalKeys (только для одного быстрого, грязного решения), чтобы сделать это.Мы предположительно будем использовать InheritedWidgets, это просто невероятно для чего-то, что должно быть простым.Обычно я просто делаю это:

// top of code here - this is global
final videoPlayerKey = GlobalKey();

class VideoPlayerContainer extends StatelessWidget {
    static VideoPlayerController videoPlayerController;
    ...
    @override
    Widget build(BuildContext context) {
        videoPlayerController = VideoPlayerController(...);
        // the static variable is empty until the container is built

        return Container(
            child: VideoPlayer(
                child: PlayButton(onTap: () => 
                    videoPlayerKey.currentState.setState(
                    () => VideoPlayerContainer.videoPlayerController.play();
                ))
            ),
        ); 
    }
}

class VideoPlayer extends StatefulWidget {
final Key key = videoPlayerKey;
    ...
}

class VideoPlayerState extends State<VideoPlayer> {
    ...
}

Нам нужно получить currentState videoPlayerKey для использования setState () и перезапустить метод сборки, чтобы он знал, обновить , и тогда мы можем получитьконтроллер для игрока, где бы он ни хранился, используя статическую переменную.Это может быть в VideoPlayer или в любом другом месте, которого нет в VideoPlayerContainer, потому что он статический - просто важно назначить GlobalKey для любого виджета, который необходимо будет перестроить.Это будет работать, потому что всякий раз, когда пользователь может нажать на кнопку, статическая переменная будет установлена ​​для любого пустого места для чтения методом build () VideoPlayerContainer.Для этого метода важно отметить, что более важно присоединить GlobalKey к элементу, который необходимо обновить - вы можете поместить static pageController буквально везде и установить его из любой точки в build () или initState ().

Примечания. Это не будет работать, если вы попытаетесь использовать несколько VideoPlayers в одном макете, потому что GlobalKeys должны быть уникальными, и все VideoPlayers будут инициализированы с одним и тем же ключом.Это скорее грязный взлом, чем что-либо другое.Сейчас я работаю над более надежным решением для управления состоянием, чтобы решить подобные вещи.

0 голосов
/ 10 ноября 2018

Я знаю, что довольно поздно на вечеринку, но у меня есть кое-что, что, я думаю, могло бы помочь.Итак, вам нужно сделать четыре (4) вещи в вашем VideoPlayerController классе:
1. Создайте экземпляр вашего класса состояний.
2. Создайте метод (play), который будет доступен в вашем PlayerContainer class
3. В вашем методе используйте экземпляр VideoPlayerControllerState для вызова метода в вашем классе состояний.
4. Наконец, когда вы createState, сделайте это, используя уже созданный вами экземпляр.

class VideoPlayerController extends StatefulWidget {
  final VideoPlayerControllerState vpcs = VideoPlayerControllerState();

  void play() {
    vpcs.play();
  }

  @override
  State<StatefulWidget> createState() => vpcs;
}

Как видите, метод play использует vpcs (экземпляр VideoPlayerControllerState) для вызова метода play уже в вашем классе состояний.

В вашем классе PlayerContainer используйтеваша переменная-член для вызова метода воспроизведения.

class PlayerContainerState extends State<PlayerContainer> {
  VideoPlayerController _vpc;

  @override
  void initState() {
    super.initState();
    _vpc = VideoPlayerController();
  }
  ...

  void _handlePressPlay(){
    _vpc.play();
  } 
  ...

  @override
  Widget build(BuildContext context) {
    return ... //your video player widget using _vpc as your VideoPlayerController
      _vpc,
    );
  }
}

Вы можете вызвать _handlePressPlay() из метода onPressed вашей кнопки воспроизведения.В качестве альтернативы, просто укажите _vpc.play() в методе onPressed.Ваш выбор: -).

0 голосов
/ 28 мая 2018

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

Основные способы, которыми дочерний виджет может бытьНа предка влияют следующие факторы: перестройка с другими параметрами или прослушивание того, что меняет предок.Для последнего вы можете использовать InheritedWidget где-нибудь о ребенке.Если дочерний элемент ссылается на InheritedWidget, он перестраивается при изменении IW.Другой способ - прослушать поток событий, сгенерированный предком.

Возможно, вам будет проще всего создать всю страницу за одну сборку, пока она не станет громоздкой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...