动态更改小部件的文本颤动/飞镖

Posted

技术标签:

【中文标题】动态更改小部件的文本颤动/飞镖【英文标题】:Change widget's text dynamically flutter/dart 【发布时间】:2021-01-28 05:03:57 【问题描述】:

我尝试编写生成随机数组值并显示在小部件卡上的代码(每次打开他都会显示数组string中的另一个值) 在实践中,代码从数组中选择一个单元格,每次我打开小部件时,它都会显示第一个选择的单元格(没有变化) 我使用了 slimycard 包 (https://pub.dev/packages/slimy_card)

// in 'homepage' class widget build
child: StreamBuilder(
            initialData: false,
            stream: slimyCard.stream,
            builder: ((BuildContext context, AsyncSnapshot snapshot) 
              return ListView(
                padding: EdgeInsets.only(top: 150),
                children: <Widget>[
                  // SlimyCard is being called here.
                  SlimyCard(
                    color: Colors.transparent.withOpacity(0.2),
                    topCardHeight: 450,
                    width: 400,
                    topCardWidget: topCardWidget(),
                    bottomCardWidget: bottomCardWidget(),
                  ),
                ],
              );
            ),
          )
// the widget I want to change his text every time he's opened.
  Widget bottomCardWidget() 
    return FutureBuilder(
        future: _getfromlist(widget.mode),
        initialData: 'loading..',
        builder: (BuildContext context, AsyncSnapshot<String> text) 
          return new Text(
            text.data,
            style: TextStyle(
              color: Colors.white,
              fontSize: 19,
              fontWeight: FontWeight.w500,
            ),
            textAlign: TextAlign.center,
          );
        );
  
// _getfromlist func
  Future<String> _getfromlist(int type) async 
    final getter = Random().nextInt(myList[type].length);
    var setter = myList[type][getter];
    var text = '$setter';
    return await new Future(() => text);
  

希望你能理解我的意图。 请帮忙,谢谢大家:)

【问题讨论】:

你的问题有点不清楚。你到底想达到什么目的? 【参考方案1】:

您可以在下面复制粘贴运行完整代码 第 1 步:在 initState 中,监听打开/关闭

  @override
  void initState() 
    slimyCard.stream.listen((value) 
      if (value) 
        handleFuture();
      
    );

第 2 步:使用 ValueNotifierValueListenableBuilder 构建 bottomCardWidget

final ValueNotifier<String> _notify = ValueNotifier<String>("");

void handleFuture() async 
    String text = await _getfromlist(1);
    _notify.value = text;
  
...  
Widget bottomCardWidget() 
    return ValueListenableBuilder(
        valueListenable: _notify,
        builder: (BuildContext context, String value, Widget child) 
          return Text(
            value,
            style: TextStyle(
              color: Colors.white,
              fontSize: 19,
              fontWeight: FontWeight.w500,
            ),
            textAlign: TextAlign.center,
          );
        );
    

工作演示

完整代码

import 'dart:math';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:slimy_card/slimy_card.dart';

void main() 
  WidgetsFlutterBinding.ensureInitialized();
  //Don't worry about these codes here, as they are not relevant for this example.
  SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
    statusBarColor: Colors.transparent,
    statusBarIconBrightness: Brightness.dark,
    systemNavigationBarColor: Colors.white,
    systemNavigationBarIconBrightness: Brightness.dark,
    systemNavigationBarDividerColor: Colors.transparent,
  ));
  SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);

  runApp(MyApp());


class MyApp extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        scaffoldBackgroundColor: Colors.white,
        fontFamily: 'Poppins',
      ),
      home: HomePage(),
    );
  


class HomePage extends StatefulWidget 
  @override
  _HomePageState createState() => _HomePageState();


class _HomePageState extends State<HomePage> 
  final ValueNotifier<String> _notify = ValueNotifier<String>("");

  void handleFuture() async 
    String text = await _getfromlist(1);
    _notify.value = text;
  

  @override
  void initState() 
    slimyCard.stream.listen((value) 
      if (value) 
        handleFuture();
      
    );

    super.initState();
  

  @override
  Widget build(BuildContext context) 
    return Scaffold(
      body: StreamBuilder(
        // This streamBuilder reads the real-time status of SlimyCard.
        initialData: false,
        stream: slimyCard.stream, //Stream of SlimyCard
        builder: ((BuildContext context, AsyncSnapshot snapshot) 
          return ListView(
            padding: EdgeInsets.zero,
            children: <Widget>[
              SizedBox(height: 100),
              SlimyCard(
                // In topCardWidget below, imagePath changes according to the
                // status of the SlimyCard(snapshot.data).
                topCardWidget: topCardWidget((snapshot.data)
                    ? 'https://picsum.photos/250?image=9'
                    : 'https://picsum.photos/250?image=15'),
                bottomCardWidget: bottomCardWidget(),
              )
            ],
          );
        ),
      ),
    );
  

  // This widget will be passed as Top Card's Widget.
  Widget topCardWidget(String imagePath) 
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Container(
          height: 70,
          width: 70,
          decoration: BoxDecoration(
            color: Colors.white,
            borderRadius: BorderRadius.circular(15),
            image: DecorationImage(image: NetworkImage(imagePath)),
            boxShadow: [
              BoxShadow(
                color: Colors.black.withOpacity(0.1),
                blurRadius: 20,
                spreadRadius: 1,
              ),
            ],
          ),
        ),
        SizedBox(height: 15),
        Text(
          'The Rock',
          style: TextStyle(color: Colors.white, fontSize: 20),
        ),
        SizedBox(height: 15),
        Text(
          'He asks, what your name is. But!',
          style: TextStyle(
              color: Colors.white.withOpacity(0.8),
              fontSize: 12,
              fontWeight: FontWeight.w500),
        ),
        SizedBox(height: 10),
      ],
    );
  

  // This widget will be passed as Bottom Card's Widget.
  Widget bottomCardWidget() 
    return ValueListenableBuilder(
        valueListenable: _notify,
        builder: (BuildContext context, String value, Widget child) 
          return Text(
            value,
            style: TextStyle(
              color: Colors.white,
              fontSize: 19,
              fontWeight: FontWeight.w500,
            ),
            textAlign: TextAlign.center,
          );
        );
  

// _getfromlist func
  Future<String> _getfromlist(int type) async 
    final getter = Random().nextInt(100);
    //var setter = myList[type][getter];
    var text = '$getter';
    return Future.value(text);
  

【讨论】:

非常热情的回答。 @LironAbutbul,很高兴为您提供帮助。如果对您有帮助,请将其标记为答案。谢谢。 @chunhunghan 已标记。顺便说一句,如果您向我解释如何更改流值,我会很高兴? (在这种情况下,自动打开“x”上的底部小部件(在另一个函数的 setState 处)? @LironAbutbul, 需要修改源码 Step1: 添加key SlimyCard( key: _key, Step 2: rename _SlimyCardState 为 SlimyCardState, Step 3: 使用 GlobalKey 做final SlimyCardState cardState = _key.currentState ; cardState.action();

以上是关于动态更改小部件的文本颤动/飞镖的主要内容,如果未能解决你的问题,请参考以下文章

在文本小部件中为不同的字母颤动不同的颜色

在颤动中对齐 Row 小部件的子项内的文本

每 5 秒更新一次文本小部件,而不在颤动中使用“setstate()”

颤动中非动态容器小部件的水平轮播

在颤动中单击按钮时添加小部件时处理动态复选框列表

如何在 android 中动态更改 EditText 小部件的文本大小?