Как я могу создать пользовательскую панель вкладок с возможностью прокрутки, подобную этой, в Flutter?

#android #flutter #user-interface #layout #widget

Вопрос:

введите описание изображения здесь

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

Какова логика переноса анимации выбранной вкладки со вкладки «Друзья» на вкладку «Семья»?

Я выяснил onHorizontalDrag свойство GestureDetector виджета для выполнения прокрутки, но все еще не могу сосредоточиться на переключении вкладок с анимацией.

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

Комментарии:

1. Можете ли вы добавить свой фрагмент кода и пробовали ли вы PageView это сделать ?

2. Нет, я не пробовал просматривать страницы. Даже если это просмотр страниц, будет ли анимация?

3. да, вы можете найти там физику, также вы можете использовать itemBuilder PageView.builder ее для дополнительной настройки.

4. Не могли бы вы поделиться фрагментом кода для этого? Это было бы большим подспорьем для меня, брат.

5. я думаю, что я предпочту IndexedStack в этом, просто дайте мне несколько раз.

Ответ №1:

Это делается с помощью PageView и пользовательской панели приложений. Однако, если вы хотите нажать событие на панели вкладок, оберните его с GestureDetector помощью make a callBack или stateManagement для удержания индекса.

Результат

введите описание изображения здесь

MainWidget

 
class BU extends StatefulWidget {
  BU({Key? key}) : super(key: key);

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

class _BUState extends State<BU> {
  int _selectedIndex = 0;

  final PageController controller = PageController(initialPage: 0);

  @override
  void initState() {
    super.initState();

    widgets = [
      ...List.generate(
        5,
        (index) => Container(
          alignment: Alignment.center,
          color: index.isEven ? Colors.cyanAccent : Colors.deepPurple,
          child: Text(
            "Item $index",
            style: TextStyle(fontSize: 44),
          ),
        ),
      )
    ];

    controller.addListener(() {
      if (controller.hasClients) {
        setState(() {
          /// you can ceil foor
          _selectedIndex = controller.page!.toInt();
        });
      }
    });
  }

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

  late List<Widget> widgets;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          AppBar(
            selectedItem: _selectedIndex,
          ),
          Expanded(
            child: Container(
                width: double.infinity,
                child: PageView(
                  controller: controller,
                  children: [...widgets],
                )),
          )
        ],
      ),
    );
  }
}
 

Панель вкладок

 
class AppBar extends StatelessWidget {
  final int selectedItem;

  const AppBar({
    Key? key,
    required this.selectedItem,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.all(8),
      color: Colors.white,
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceAround,
            children: [
              TabItemChip(
                isSelected: selectedItem == 0,
                text: "Profile",
              ),
              TabItemChip(
                isSelected: selectedItem == 1,
                text: "About",
              ),
              TabItemChip(
                isSelected: selectedItem == 2,
                text: "Friends",
              ),
            ],
          ),
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceAround,
            children: [
              TabItemChip(
                isSelected: selectedItem == 3,
                text: "Family",
              ),
              TabItemChip(
                isSelected: selectedItem == 4,
                text: "Settings",
              ),
            ],
          )
        ],
      ),
    );
  }
}

 

TabBarItemChip

 class TabItemChip extends StatelessWidget {
  final bool isSelected;
  final String text;
  const TabItemChip({
    Key? key,
    required this.text,
    required this.isSelected,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return AnimatedContainer(
      duration: Duration(milliseconds: 400),
      height: 40,
      width: 140,
      alignment: Alignment.center,
      decoration: BoxDecoration(
        color: isSelected ? Colors.cyanAccent.shade700 : Colors.white,
        borderRadius: BorderRadius.circular(12),
      ),
      child: Text(
        text,
        style: TextStyle(
          color: isSelected ? Colors.white : Colors.black,
          fontWeight: FontWeight.bold,
        ),
      ),
    );
  }
}

 

Комментарии:

1. Сработало как заклинание, приятель. Огромное спасибо!

2. Тогда не стесняйтесь закрыть вопрос, приняв это как ответ.