【问题标题】:How to change AppBar colour when another tab is selected using ChangeNotifierProvider on Flutter?在 Flutter 上使用 ChangeNotifierProvider 选择另一个选项卡时如何更改 AppBar 颜色?
【发布时间】:2020-05-24 13:55:01
【问题描述】:

我知道如何使用选项卡控制器更改 AppBar 的颜色并设置状态,但是每次我单击另一个选项卡时,都会重新构建所有小部件,并且我的应用程序会再次调用 http.get。我知道提供程序包可用于通过使用 ChangeNotifierProvider 和 notifyListeners() 仅更改某些小部件而不影响其他小部件。但是当我尝试实现这一点时,颜色不会改变。我打印了颜色以确保在单击另一个选项卡时调用该方法,并且确定一切似乎都正常。在调用 notifyListeners() 改变颜色值的时候好像有问题。

代码如下:

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider<ColorChange>(
      create: (context) => ColorChange(),
      child: MaterialApp(
        theme: ThemeData.light(),
        home: SimpleTab(),
      ),
    );
  }
}

TabController controller;

class ColorChange extends ChangeNotifier {
  Color color = colors[0];

  Color getColor() {
    return color;
  }

  void changeColor() {
    color = colors[controller.index];
    print(color);
    notifyListeners();
  }
}

List<Color> colors = const [
  Colors.green,
  Colors.yellow,
  Colors.red,
  Colors.blue,
  Colors.deepOrange,
  Colors.deepPurple,
];

class SimpleTab extends StatefulWidget {
  @override
  _SimpleTabState createState() => _SimpleTabState();
}

class _SimpleTabState extends State<SimpleTab>
    with SingleTickerProviderStateMixin {

  @override
  void initState() {
    super.initState();
    controller = TabController(length: colors.length, vsync: this);
    controller.addListener(ColorChange().changeColor);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Simple Tab Demo"),
        backgroundColor: Provider.of<ColorChange>(context).getColor(),
        bottom: TabBar(
          controller: controller,
          tabs: [
            Tab(
              text: 'Green',
            ),
            Tab(
              text: 'Yellow',
            ),
            Tab(
              text: 'Red',
            ),
            Tab(
              text: 'Blue',
            ),
            Tab(
              text: 'Orange',
            ),
            Tab(
              text: 'Purple',
            ),
          ],
          isScrollable: true,
        ),
      ),
      body: TabBarView(
        controller: controller,
        children: <Widget>[
          Container(
            // some future builder using http.get
          ),
          Container(
            // some future builder using http.get
          ),
          Container(
            // some future builder using http.get
          ),
          Container(
            // some future builder using http.get
          ),
          Container(
            // some future builder using http.get
          ),
          Container(
            // some future builder using http.get
          ),
        ],
      ),
    );
  }
}

请帮忙!

【问题讨论】:

  • 你检查过这个问题吗? stackoverflow.com/questions/45327207/…
  • 这不是我想要的。您提供的解决方案使用了 setstate(),这不适合我的情况,因为我不想重建所有小部件。

标签: user-interface flutter dart


【解决方案1】:

您需要添加“onTap”参数。此外,您每次还使用 getColor() 方法返回相同的颜色。更改它,使其在不同的索引处返回不同的颜色。

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider<ColorChange>(
      create: (context) => ColorChange(),
      child: MaterialApp(
        theme: ThemeData.light(),
        home: SimpleTab(),
      ),
    );
  }
}

List<Color> colors = const [
  Colors.green,
  Colors.yellow,
  Colors.red,
  Colors.blue,
  Colors.deepOrange,
  Colors.deepPurple,
];

class ColorChange extends ChangeNotifier {
  Color getColor(int index) {            <-------Changed
    return colors[index];
  }

  void changeColor(int index) {
    Color color = colors[index];
    print(color);
    notifyListeners();
  }
}

class SimpleTab extends StatefulWidget {
  @override
  _SimpleTabState createState() => _SimpleTabState();
}

class _SimpleTabState extends State<SimpleTab>
    with SingleTickerProviderStateMixin {
  TabController controller;

  @override
  void initState() {
    controller = TabController(length: colors.length, vsync: this);

    //
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Simple Tab Demo"),
        backgroundColor:
            Provider.of<ColorChange>(context).getColor(controller.index),
        bottom: TabBar(
          controller: controller,
          onTap: (index) {                   <---------Add this call back
            Provider.of<ColorChange>(context, listen: false).changeColor(index);
          },
          tabs: [
            Tab(
              text: 'Green',
            ),
            Tab(
              text: 'Yellow',
            ),
            Tab(
              text: 'Red',
            ),
            Tab(
              text: 'Blue',
            ),
            Tab(
              text: 'Orange',
            ),
            Tab(
              text: 'Purple',
            ),
          ],
          isScrollable: true,
        ),
      ),
      body: TabBarView(
        controller: controller,
        children: <Widget>[
          Container(
              // some future builder using http.get
              ),
          Container(
              // some future builder using http.get
              ),
          Container(
              // some future builder using http.get
              ),
          Container(
              // some future builder using http.get
              ),
          Container(
              // some future builder using http.get
              ),
          Container(
              // some future builder using http.get
              ),
        ],
      ),
    );
  }
}

【讨论】:

猜你喜欢
  • 2020-09-10
  • 1970-01-01
  • 2022-01-18
  • 1970-01-01
  • 1970-01-01
  • 2017-10-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多