如何为自定义选项卡栏式小部件添加动画?

huangapple go评论57阅读模式
英文:

How to animate custom tab bar kind of widget?

问题

所以我有一个小部件,允许用户从两个或更多选项卡中选择一个选项卡。这在功能上运行良好,但我希望以这样的方式对其进行动画处理,即当用户单击其他非活动选项卡时,白色背景会滑动到该选项卡,而不仅仅是立即出现在那里。是否有办法在当前代码中实现这一点,或者我需要相应地更新我的代码?

**这是当前的代码:**
```dart
import 'package:flutter/material.dart';

// ... (其余代码未变)
英文:

So I have this widget that allows the user to select a tab from two or more tabs. This works fine in functionality but I want to animate it in such a way that when the user clicks on the other inactive tab, the white background slides to that tab instead of just appearing there instantly. Is there any way I can achieve this with the current code or do I need to update my code accordingly?

Here is the current code:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  MyApp({Key? key}) : super(key: key);

  final GlobalKey headerKey = GlobalKey();

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(home: HomePage());
  }
}

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  int active = 1;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('App bar')),
      body: Column(
        children: [
          const SizedBox(
            height: 20,
          ),
          const Text('Select one'),
          const SizedBox(
            height: 20,
          ),
          SelectOne(),
        ],
      ),
    );
  }
}

class SelectOne extends StatefulWidget {
  const SelectOne({super.key});

  @override
  State<SelectOne> createState() => _SelectOneState();
}

class _SelectOneState extends State<SelectOne> {
  // tab bar values
  final List<String> values = ['one', 'two'];

  // active value
  late String activeValue;

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

    // setting the active value
    activeValue = values[0];
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
        color: Theme.of(context).primaryColor,
        borderRadius: BorderRadius.circular(100),
        border: Border.all(
          color: Theme.of(context).primaryColor,
          width: 2,
        ),
      ),
      child: Row(
          children: values.map(
        (value) {
          // whether the item is selected or not
          final bool isSelected = value == activeValue;

          return Expanded(
            child: GestureDetector(
              onTap: () {
                // setting the active value
                setState(() {
                  activeValue = value;
                });
              },
              child: Container(
                alignment: Alignment.center,
                padding: const EdgeInsets.all(6),
                decoration: BoxDecoration(
                  color: isSelected ? Colors.white : null,
                  borderRadius: BorderRadius.circular(100),
                ),
                child: Text(
                  value,
                  style: Theme.of(context).textTheme.bodyMedium!.copyWith(
                        fontWeight: isSelected ? FontWeight.w500 : null,
                        color: isSelected ? Colors.black : Colors.white,
                      ),
                ),
              ),
            ),
          );
        },
      ).toList()),
    );
  }
}

Here is the current output
如何为自定义选项卡栏式小部件添加动画?

答案1

得分: 2

以下是代码的翻译部分:

Flutter中,有一个名为Tabbar的内置小部件,你应该使用它,而不是<br>

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  MyApp({Key? key}) : super(key: key);

  final GlobalKey headerKey = GlobalKey();

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(home: HomePage());
  }
}

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

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('App bar')),
      body: Column(
        children: [
          const SizedBox(height: 20),
          const Text('Select one'),
          const SizedBox(height: 20),
          const SelectOne(),
        ],
      ),
    );
  }
}

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

  @override
  State<SelectOne> createState() => _SelectOneState();
}

class _SelectOneState extends State<SelectOne> with SingleTickerProviderStateMixin {
  late TabController _tabController;

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

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

  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
        color: Theme.of(context).primaryColor,
        borderRadius: BorderRadius.circular(100),
        border: Border.all(
          color: Theme.of(context).primaryColor,
          width: 2,
        ),
      ),
      child: TabBar(
        controller: _tabController,
        tabs: [
          Tab(text: 'one'),
          Tab(text: 'two'),
        ],
        labelStyle: Theme.of(context).textTheme.bodyMedium!.copyWith(
          fontWeight: FontWeight.w500,
          color: Colors.black,
        ),
        unselectedLabelStyle: Theme.of(context).textTheme.bodyMedium!.copyWith(
          fontWeight: null,
          color: Colors.white,
        ),
        indicator: BoxDecoration(
          color: Colors.white,
          borderRadius: BorderRadius.circular(100),
        ),
        onTap: (index) {
          // 处理选项卡选择
        },
      ),
    );
  }
}
尝试这段代码,希望能对你有所帮助。如果有帮助,请了解Tabbar小部件和控制器
英文:

there is a widget named Tabbar is inbuild in flutter you should use that instead<br>

import &#39;package:flutter/material.dart&#39;;
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
MyApp({Key? key}) : super(key: key);
final GlobalKey headerKey = GlobalKey();
@override
Widget build(BuildContext context) {
return const MaterialApp(home: HomePage());
}
}
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
State&lt;HomePage&gt; createState() =&gt; _HomePageState();
}
class _HomePageState extends State&lt;HomePage&gt; {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text(&#39;App bar&#39;)),
body: Column(
children: [
const SizedBox(height: 20),
const Text(&#39;Select one&#39;),
const SizedBox(height: 20),
const SelectOne(),
],
),
);
}
}
class SelectOne extends StatefulWidget {
const SelectOne({Key? key}) : super(key: key);
@override
State&lt;SelectOne&gt; createState() =&gt; _SelectOneState();
}
class _SelectOneState extends State&lt;SelectOne&gt; with SingleTickerProviderStateMixin {
late TabController _tabController;
@override
void initState() {
super.initState();
_tabController = TabController(length: 2, vsync: this);
}
@override
void dispose() {
_tabController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
color: Theme.of(context).primaryColor,
borderRadius: BorderRadius.circular(100),
border: Border.all(
color: Theme.of(context).primaryColor,
width: 2,
),
),
child: TabBar(
controller: _tabController,
tabs: [
Tab(text: &#39;one&#39;),
Tab(text: &#39;two&#39;),
],
labelStyle: Theme.of(context).textTheme.bodyMedium!.copyWith(
fontWeight: FontWeight.w500,
color: Colors.black,
),
unselectedLabelStyle: Theme.of(context).textTheme.bodyMedium!.copyWith(
fontWeight: null,
color: Colors.white,
),
indicator: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(100),
),
onTap: (index) {
// Handle tab selection
},
),
);
}
}

try this code i hope it helps you, if this helps then learn about tabbar widget and controller .

答案2

得分: -1

如果您需要创建自定义的选项卡栏部件,可以使用layoutBuilder,使用动画定位来处理白色部分,并仅更改其x值。

英文:

If you need to make a custom tabbar widget, you can use layoutBuilder, with animated positioned, for the white part, and just change its x value

huangapple
  • 本文由 发表于 2023年5月7日 09:44:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/76191890.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定