Flutter: изменение текущей вкладки на панели вкладок с помощью кнопки

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

Я также хочу знать, как связать эту вкладку с какой-либо другой кнопкой.

Вот скриншот моей домашней страницы.

Homepage with navigation tabs and floating action button

Ответ 1

Вам нужно получить контроллер TabBar и вызвать его animateTo() с помощью кнопки onPressed().

import 'package:flutter/material.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      home: new MyTabbedPage(),
    );
  }
}

class MyTabbedPage extends StatefulWidget {
  const MyTabbedPage({Key key}) : super(key: key);

  @override
  _MyTabbedPageState createState() => new _MyTabbedPageState();
}

class _MyTabbedPageState extends State<MyTabbedPage> with SingleTickerProviderStateMixin {
  final List<Tab> myTabs = <Tab>[
    new Tab(text: 'LEFT'),
    new Tab(text: 'RIGHT'),
  ];

  TabController _tabController;

  @override
  void initState() {
    super.initState();
    _tabController = new TabController(vsync: this, length: myTabs.length);
  }

  @override
  void dispose() {
    _tabController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("Tab demo"),
        bottom: new TabBar(
          controller: _tabController,
          tabs: myTabs,
        ),
      ),
      body: new TabBarView(
        controller: _tabController,
        children: myTabs.map((Tab tab) {
          return new Center(child: new Text(tab.text));
        }).toList(),
      ),
      floatingActionButton: new FloatingActionButton(
        onPressed: () => _tabController.animateTo((_tabController.index + 1) % 2), // Switch tabs
        child: new Icon(Icons.swap_horiz),
      ),
    );
  }
}

Если вы используете GlobalKey для MyTabbedPageState вы можете получить контроллер из любого места, так что вы можете вызвать animateTo() с любой кнопки.

class MyApp extends StatelessWidget {
  static final _myTabbedPageKey = new GlobalKey<_MyTabbedPageState>();

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      home: new MyTabbedPage(
        key: _myTabbedPageKey,
      ),
    );
  }
}

Вы можете назвать это из любого места:

MyApp._myTabbedPageKey.currentState._tabController.animateTo(...);

Ответ 2

Если вы хотите перейти на определенную страницу, вы можете использовать

PageController.jumpToPage(int)

Однако, если вам нужна анимация, вы должны использовать

PageController.animateToPage(page, duration: duration, curve: curve)

Простой пример, демонстрирующий это.

// create a PageController
final _controller = PageController();
bool _shouldAnimate = true; // whether we animate or jump

@override
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(),
    floatingActionButton: FloatingActionButton(
      onPressed: () {
        if (_shouldAnimate) {
          // animates to page1 with animation
          _controller.animateToPage(1, duration: Duration(seconds: 1), curve: Curves.easeOut);  
        } else {
          // jump to page1 without animation
          _controller.jumpToPage(1);
        }
      },
    ),
    body: PageView(
      controller: _controller, // assign it to PageView
      children: <Widget>[
        FlutterLogo(colors: Colors.orange), // page0
        FlutterLogo(colors: Colors.green), // page1
        FlutterLogo(colors: Colors.red), // page2
      ],
    ),
  );
}

Ответ 3

chemamolin ответвыше правильный, но для дополнительного пояснения/подсказки, если вы хотите вызывать ваш tabcontroller "откуда угодно", также убедитесь, что tabcontroller не является частным свойством класса, удалив подчеркивание, иначе удаленный класс не сможет видеть tabcontroller с примером, предоставленным даже при использовании GlobalKey.

Другими словами, измените

TabController _tabController;

to:

TabController tabController;

и изменить

MyApp._myTabbedPageKey.currentState._tabController.animateTo(...);

to:

MyApp._myTabbedPageKey.currentState.tabController.animateTo(...);

и везде вы ссылаетесь на tabcontroller.