簡體   English   中英

將文本包裝在一個圓圈內(Flutter)

[英]Wrapping text inside a circle (Flutter)

是否可以在 Flutter 中將文本包裝在一個圓圈內? 這是一個失敗的例子。 理想情況下,文本將適合圓圈內並且僅在末尾溢出。

ClipOval(
  child: SizedBox.expand(
    child: Text(
      "Round and round the rugged rocks, the rascally rascals ran. Round and round the rugged rocks, the rascally rascals ran. Round and round the rugged rocks, the rascally rascals ran. Round and round the rugged rocks, the rascally rascals ran. ",
      softWrap: true,
      overflow: TextOverflow.fade,
    ),
  ),
),

在此處輸入圖像描述

截至目前(2019 年 7 月),Flutter 不直接支持非矩形形狀的文本布局。

使用現有的 API,應該可以通過實現以下步驟來實現類似的自定義效果:

  • 創建一個列。
  • 在第 1 行以圓形寬度布局單行文本
  • 獲取最后一個布局字符的字符索引(使用 getBoxesForRange 和 getPositionForOffset)
  • 截斷要在索引處布局的文本的前面以獲得剩余文本。
  • 將剩下的文本排成一行文本,寬度為圓的第 2 行。第 2 行的 y 位置可以通過添加單行 1 的高度獲得。
  • 重復直到不再填充文本或圓圈。 將列中的所有文本居中放置。

那應該能讓你接近一些東西。 該實現必須處理每個 y 位置的圓寬度的所有計算以及手動定位每行文本。

小文字解決方案

我提出了這個解決方案,它適用於小文本:

ClipOval(
    child: Container(
        height: 30.0,
        margin: const EdgeInsets.all(20),
        width:  price.length * 10.0,
        decoration: BoxDecoration(color: Colors.white70,
        border: Border.all(color: Color(0x00ffffff), width: 0.0),
            borderRadius: BorderRadius.all(Radius.elliptical(price.length * 10.0, 30))), // this line makes the coffee.
        child: Center(child:Text(price, style: const TextStyle(color: Color(0xff2200ff))))
)),

注意:0xff2200ff 是藍色,Colors.white70 是背景色。

如果您希望形狀像圓形一樣非常圓,只需將 30.0 替換為 text.length * 10.0 作為容器的高度和邊框半徑。

對於那些想要處理長文本的解決方案的人,您可以采用我的解決方案並添加您自己的函數,該函數將根據文本長度創建圓形文本(通過添加 \\n)。

在此處輸入圖片說明

我希望它會有所幫助。

像這樣的東西。

import 'dart:math' as math;
import 'package:flutter/material.dart';

class CircleTextWrapper extends StatelessWidget {
  const CircleTextWrapper({
    Key? key,
    this.radius = 110,
    this.text =
        "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s.",
    this.textStyle = const TextStyle(fontSize: 20),
    this.startAngle = 0,
  }) : super(key: key);
  final double radius;
  final String text;
  final double startAngle;
  final TextStyle textStyle;
  @override
  Widget build(BuildContext context) => CustomPaint(
        painter: _Painter(
          radius,
          text,
          textStyle,
        ),
      );
}

class _Painter extends CustomPainter {
  _Painter(this.radius, this.text, this.textStyle, {this.padding = 12});
  final double radius;
  final String text;
  final double padding;

  final TextStyle textStyle;
  final _textPainter = TextPainter(textDirection: TextDirection.ltr);
  final Paint _paint = Paint()
    ..blendMode
    ..color = Colors.white
    ..strokeWidth = 2
    ..style = PaintingStyle.stroke;
  @override
  void paint(Canvas canvas, Size size) {
    canvas.translate(size.width / 2, size.height / 2);
    canvas.drawCircle(Offset.zero, radius + padding, _paint);

    String lineText = "";
    _textPainter.text = TextSpan(text: lineText, style: textStyle);
    _textPainter.layout(
      minWidth: 0,
      maxWidth: double.maxFinite,
    );

    double y = -radius + _textPainter.height * .6;
    double x = math.sqrt(radius * radius - y * y);
    for (int i = 0; i < text.length; i++) {
      lineText += text[i];
      _textPainter.text = TextSpan(text: lineText, style: textStyle);
      _textPainter.layout(
        minWidth: 0,
        maxWidth: double.maxFinite,
      );

      if (_textPainter.width >=
          (Offset(-x, y) - Offset(x, y)).distance - textStyle.fontSize! * .5) {
        _textPainter.paint(canvas, Offset(-x, y - _textPainter.height * .6));
        // canvas.drawLine(Offset(-x, y), Offset(x, y), _paint);
        y += _textPainter.height;
        x = math.sqrt(radius * radius - y * y);
        lineText = "";
      }

      if (i == text.length - 1) {
        _textPainter.paint(canvas, Offset(-x, y - _textPainter.height * .6));
        //  canvas.drawLine(Offset(-x, y), Offset(x, y), _paint);
      }
    }
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) => true;
}

結果:

所需結果的屏幕截圖,圓圈內包含的文本

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM