Выровнять пользовательский нарисованный текст в flutter

#flutter

#flutter

Вопрос:

Мне нужно создать пользовательский виджет (в Flutter), который содержит текст в определенной позиции. Когда я рисую текст с помощью TextPainter, я устанавливаю TextAlign равным центру. Текст по-прежнему отображается с выравниванием по левому краю. Что я делаю не так?

 TextSpan span = TextSpan(style: TextStyle(color: Colors.white, fontSize: textSize), text: 'T');
TextPainter tp = TextPainter(text: span, textAlign: TextAlign.center, textDirection: TextDirection.ltr);
tp.layout();
tp.paint(canvas, Offset(pos.x, pos.y));
  

Комментарии:

1. посмотрите, какие параметры вы можете передать layout методу

2. Из документа: layout({double minWidth: 0.0, double maxWidth: double.infinity }) → void' . Выравнивание не работает без ограничений по ширине?

3. установите MaxWidth равным 200 и посмотрите, что получится, затем измените его на 400 и сравните результаты

4. Я попробовал это, но положение осталось прежним.

5. ХОРОШО, итак, что вы хотите расположить по центру? и центрировать по отношению к чему? ваш текст состоит только из буквы «Т»?

Ответ №1:

Выровнять пользовательский нарисованный текст с помощью CustomPainter в Flutter

Чтобы просто центрировать текст на холсте, вычислите его смещение:

 void _paintText(Canvas canvas, Size size) {
  final textSpan = TextSpan(
    text: 'n/a',
  );
  final textPainter = TextPainter(
    text: textSpan,
    textDirection: TextDirection.ltr,
  );
  textPainter.layout();
  textPainter.paint(
    canvas,
    Offset(
      // Do calculations here:
      (size.width - textPainter.width) * 0.5,
      (size.height - textPainter.height) * 0.5,
    ),
  );
}
  

Комментарии:

1. Могу я узнать, почему вы умножили на 0,5?

2. @BalajiRamadoss size.width * 0.5 находится в центре холста. Чтобы найти начало моего текстового интервала, я вычитаю textPainter.width * 0.5 , что равно (size.width - textPainter.width) * 0.5

Ответ №2:

для позиции X убедитесь, что для макета установлено значение 0 для минимальной и максимальной ширины

 textPainter.layout(minWidth: 0, maxWidth: 0); 
  

для позиции Y необходимо вычесть высоту самого текста

 final position = Offset(xPOS, yPOS - (textPainter.height / 2));
  

вот пример кода

 void _drawTextAt(String text, Offset position, Canvas canvas) {
    final textStyle = TextStyle(
      color: Colors.black,
      fontSize: 30,
    );
    final textSpan = TextSpan(
      text: 'O',
      style: textStyle,
    );
    final textPainter = TextPainter(
        text: textSpan,
        textDirection: TextDirection.ltr,
        textAlign: TextAlign.center);
    textPainter.layout(minWidth: 0, maxWidth: 0);
    Offset drawPosition =
        Offset(position.dx, position.dy - (textPainter.height / 2));
    textPainter.paint(canvas, drawPosition);
  }
  

Чтобы использовать эту функцию, вызовите, например

   _drawTextAt('A', Offset(20, 20), canvas);
  

Комментарии:

1. хм, если минимальная / максимальная ширина равна 0, символы будут просто отображаться вертикально. Хорошо, если у вас всего один символ, но в остальном для меня буквы идут вертикально, а не горизонтально. Я подозреваю, что вы можете захотеть, чтобы максимальная ширина была равна double.infinity, а x в смещении было position.dx — TextPainter.width / 2 ?

Ответ №3:

 double width = 100, height = 200, r = 63;
    canvas.drawCircle(Offset(width, height), r, Paint()..color = Colors.purple);
    ParagraphBuilder paragraphBuilder =
        ParagraphBuilder(ParagraphStyle(textAlign: TextAlign.center))
          ..addText('Hello');
    ParagraphConstraints paragraphConstraints =
        ParagraphConstraints(width: r * 2);
    Paragraph paragraph = paragraphBuilder.build()
      ..layout(paragraphConstraints);
    canvas.drawParagraph(
        paragraph, Offset(width - r, height - paragraph.height / 2));
  

Ответ №4:

С помощью Alignment.inscribe вы можете выровнять текст любым способом. 🙂

 extension CanvasExt on Canvas {
    void drawTextInRect(
        Rect rect,
        Alignment alignment,
        TextPainter painter,
    ) {
        final offsetRect = alignment.inscribe(painter.size, rect);
        painter.paint(this, offsetRect.topLeft);
    }
}
  

Ответ №5:

Я использовал drawParagraph, и он хорошо работает

 final ui.ParagraphBuilder paragraphBuilder = ui.ParagraphBuilder(
        ui.ParagraphStyle(textDirection: ui.TextDirection.ltr),
      )
      ..addText('Your Text');
final ui.Paragraph paragraph = paragraphBuilder.build()
        ..layout(ui.ParagraphConstraints(width: textSize.width));
canvas.drawParagraph(paragraph, textOffset);
  

вы можете изменить стиль абзаца так, как вам нравится.

Комментарии:

1. откуда вы взяли textSize и textOffset ?

2. Смещение и размер области, в которой вы хотите закрасить текст на холсте