简体   繁体   English

如何在 flutter 中剪辑可变大小的小部件?

[英]How do I clip a variable sized widget in flutter?

I'm building a chat app where audio messages can accompany the text.我正在构建一个聊天应用程序,其中音频消息可以伴随文本。 The widget that displays this is a very standard looking chat bubble (think iMessage) with one twist - the bubble becomes a progress bar when the audio is playing.显示此内容的小部件是一个非常标准的聊天气泡(想想 iMessage),但有一个转折——当音频播放时,气泡变成了一个进度条。 The progress bar is essentially just a gradual change in the background color.进度条本质上只是背景颜色的渐变。 You can see the layout in this dartpad (hit run).您可以在这个dartpad中看到布局(点击运行)。 A screenshot of the mock is here:模拟的屏幕截图在这里:

在此处输入图像描述

Because the chat bubble is rounded, I need the progress bar to round only at the end.因为聊天气泡是圆形的,所以我需要进度条只在最后才圆形。 In other words, it should always be rounded on the left as it is flush with the left side of the message but it should be flat on the right until it hits the end of the message.换句话说,它应该总是在左边四舍五入,因为它与消息的左侧齐平,但它应该在右边是平的,直到它到达消息的末尾。 I think ClipRRect is the right widget to do this.我认为ClipRRect是执行此操作的正确小部件。

However, because the message bubble width is variable, I use a FractionallySizedBox as the progress bar.但是,因为消息气泡的宽度是可变的,所以我使用FractionallySizedBox作为进度条。 1/10th the way through the audio, it should be 1/10th the width of the chat bubble.通过音频的 1/10,应该是聊天气泡宽度的 1/10。 Then I use Positioned.fill to wrap the progress bar so that the fraction is taken out of the full message bubble width.然后我使用Positioned.fill包裹进度条,以便从完整的消息气泡宽度中取出分数。 ClipRRect does not seem to play nicely wrapping Positioned.fill I believe it expects the child to have a set size: ClipRRect似乎不能很好地包装Positioned.fill我相信它希望孩子有一个固定的大小:

RenderBox was not laid out: RenderClipRRect#3b019 relayoutBoundary=up13
'package:flutter/src/rendering/box.dart':
Failed assertion: line 1694 pos 12: 'hasSize'

This is a dartpad to the version with the not-working ClipRRect .这是具有不工作ClipRRect的版本的飞镖板。 Is there some other widget I can wrap Position.fill in to make it clippable?是否有其他一些小部件可以包装Position.fill以使其可剪辑? Or maybe a better way to lay this out?或者也许是一种更好的方式来解决这个问题?

Please try the following code.请尝试以下代码。

import 'package:flutter/material.dart';

final Color darkBlue = Color.fromARGB(255, 18, 32, 47);

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: Center(
          child: ChatAudioTextBubble("Test message"),
        ),
      ),
    );
  }
}

class ChatAudioTextBubble extends StatefulWidget {
  final String text;

  ChatAudioTextBubble(this.text);

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

class _ChatAudioTextBubbleState extends State<ChatAudioTextBubble>
    with SingleTickerProviderStateMixin {
  AnimationController _controller;

  @override
  void initState() {
    _controller = AnimationController(
      lowerBound: 0.0,
      upperBound: 1.0,
      value: 0.0,
      duration: const Duration(milliseconds: 1000),
      vsync: this,
    )..addListener(() {
        this.setState(() {});
      });
    super.initState();
  }

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

  void _onTapHandler() {
    _controller.reset();
    _controller.forward(from: 0.0);
  }

  Widget build(BuildContext context) {
    return GestureDetector(
        behavior: HitTestBehavior.translucent,
        onTap: () {
          _onTapHandler();
          print(
              "Plays the audio and starts the animation which takes _controller.value from 0-1");
        },
        child: Stack(children: [
          Positioned.fill(
              child: Container(
            decoration: BoxDecoration(
                borderRadius: BorderRadius.circular(10),
                color: Color(0xFFE6E6E6)),
          )),
          Container(
              constraints: BoxConstraints(
                  minWidth: 40,
                  maxWidth: MediaQuery.of(context).size.width * 0.70),
              child: _buildTextChild()),
          Positioned.fill(
            child: ClipRRect(
              borderRadius: BorderRadius.only(
                topRight: Radius.circular(10.0),
                bottomRight: Radius.circular(10.0),
              ),
              child: FractionallySizedBox(
                alignment: Alignment.centerLeft,
                heightFactor: 1,
                widthFactor: _controller == null ? 0 : _controller.value,
                child: Container(
                  decoration: BoxDecoration(
                    shape: BoxShape.rectangle,
                    color: Colors.blue.withOpacity(0.3),
                    borderRadius: BorderRadius.only(
                      topLeft: Radius.circular(10.0),
                      topRight: Radius.zero,
                      bottomLeft: Radius.circular(10.0),
                      bottomRight: Radius.zero,
                    ),
                  ),
                ),
              ),
            ),
          ),
        ]));
  }

  Widget _buildTextChild() {
    final color = Colors.black;
    return Padding(
        padding: EdgeInsets.fromLTRB(16, 8, 16, 8),
        child: Text(widget.text, style: TextStyle(color: color, fontSize: 18)));
  }
}


声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在颤振中将可变大小的小部件剪辑成固定大小? - How to clip a variable sized widget into a fixed size in flutter? 如何在 flutter 中剪辑小部件 - How to clip a widget in flutter 如何调整 Gridview flutter 中的网格大小? - How do I sized of grid in Gridview flutter? 如何在颤动中剪裁定位小部件的角 - How to clip the corners of Positioned widget in flutter 如何在颤振中实现剪辑工具栏小部件 - How to implement clip toolbar widget in flutter Flutter - 如何从子小部件调用父小部件函数,同时还使用变量保持状态? - Flutter - How do I call a Parent widget function from child widget while also maintaining the state with a variable? 我如何正确地将变量从有状态小部件初始化为 flutter 中的另一个小部件并维护 state? - How do i correctly initialise a variable from a stateful widget to another widget in flutter and maintain state? 如何在颤动中夹住标签栏容器的边缘? - How do I clip the edges of my tab bar container in flutter? 我如何在 flutter 中旋转我的小盒子? - How do i rotate my fractionally sized box in flutter? 如何从函数访问变量并在我的小部件中使用它 - Flutter 存储变量 - How do I access variable from a function and use it in my widget - Flutter storage variable
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM