【问题标题】:Change text color of a Text widget onTap更改文本小部件 onTap 的文本颜色
【发布时间】:2021-05-15 22:31:53
【问题描述】:

我正在使用 ListViewBuilder 从 Firestore 集合流构建一个列表,每个项目都是列表中的一个 Text 小部件,我试图在点击 Text 小部件时更改文本的颜色,

Item 1
Item 2
Item 3

当点击/点击Item1时,Item1的文字颜色应该改变

我使用带有 setState 的 GestureDetector 实现,但在 onTap>setState 执行时,流的列表视图被重建,产生一秒钟的空白屏幕/闪烁,并在刷新后失去实际状态

var _dynamicTextColor = Colors.green;

return ListView.builder(
                  reverse: true,
                  itemCount: itemStream.length,
                  itemBuilder: (context, itemIndex) => Container(
                  child:GestureDetector(
                        onTap: (){
                          setState(() {
                            _dynamicTextColor = Colors.white;
                          });
                        },
                      child: Text(itemStream[itemIndex]['title'], style: TextStyle(color:_dynamicTextColor),),
                  ),
                ),
              );

【问题讨论】:

    标签: android firebase flutter dart


    【解决方案1】:

    您可以尝试以下方法。这将使用 selected 属性来决定哪个容器应该是蓝色的。

    class _TestState extends State<Test> {
      String selected = "first";
    
      @override
      Widget build(BuildContext context) {
        return Column(
          children: <Widget>[
            GestureDetector(
              onTap: () {
                setState(() {
                  selected = 'first';
                });
              },
              child: Container(
                height: 200,
                width: 200,
                color: selected == 'first' ? Colors.blue : Colors.transparent,
                child: Text("First"),
              ),
            ),
            GestureDetector(
              onTap: () {
                setState(() {
                  selected = 'second';
                });
              },
              child: Container(
                height: 200,
                width: 200,
                color: selected == 'second' ? Colors.blue : Colors.transparent,
                child: Text("Second"),
              ),
            ),
          ],
        );
      }
    }
    

    【讨论】:

    • 它适用于您的答案中的普通小部件,但是当涉及流时(我的情况)setState 会导致刷新/UI 重建
    【解决方案2】:

    我建议您使用状态管理,例如 Provider。 我准备了一个例子,希望你能理解并解决你的问题。

    首先,将提供程序包添加到 pubspec.yaml

      provider: ^4.3.3
    

    然后,创建一个用于管理状态的类,就像使用 setState 一样。代码是这样的:

    class ColorProvider extends ChangeNotifier {
      ColorProvider();
      bool isPressed = true;
    
      Color color = Colors.black;
    
      changeColor() {
        if (isPressed == true) {
          color = Colors.green;
          isPressed = false;
        } else {
          color = Colors.black;
          isPressed = true;
        }
        notifyListeners();
        return isPressed;
      }
    }
    

    完成后,您必须将 App 材料包装在 ChangeNotifierProvider 小部件中:

    import 'package:flutter/material.dart';
    import 'package:flutter_application_1/home_page.dart';
    import 'package:provider/provider.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return ChangeNotifierProvider(
          create: (_) => ColorProvider(),
          child: MaterialApp(
            title: 'Flutter Demo',
            theme: ThemeData(
              primarySwatch: Colors.blue,
              visualDensity: VisualDensity.adaptivePlatformDensity,
            ),
            home: HomePage(),
          ),
        );
      }
    }
    

    最后,在小部件中调用 Provider:

    import 'package:flutter/material.dart';
    import 'package:provider/provider.dart';
    
    class HomePage extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        final providerWatch = context.watch<ColorProvider>();
        final providerRead = context.read<ColorProvider>();
        String text = 'This is an example text';
        return Scaffold(
            body: Container(
          child: Center(
            child: GestureDetector(
                behavior: HitTestBehavior.translucent,
                onTap: () => providerRead.changeColor(),
                child: Text(
                  text,
                  style: TextStyle(color: providerWatch.color),
                )),
          ),
        ));
      }
    }
    

    这就是结果:

    【讨论】:

      猜你喜欢
      • 2013-04-20
      • 2021-12-04
      • 1970-01-01
      • 2021-07-07
      • 2016-08-08
      • 1970-01-01
      • 1970-01-01
      • 2018-05-15
      • 1970-01-01
      相关资源
      最近更新 更多