简体   繁体   English

Flutter 中文本小部件内的可拖动文本部分

[英]Draggable text Portion inside Text Widget in Flutter

I am making a game where users can drag some portion - which is highligted with RED in the image - of String while not hurting rest of the String.我正在制作一个游戏,用户可以在不伤害字符串的 rest 的情况下拖动字符串的某些部分(图像中用红色突出显示)。 To specify which text can be draggable, I encoded draggable portion in this format: x{String}x.为了指定哪些文本可以拖动,我将可拖动部分编码为以下格式:x{String}x。 And I decoded it in _constructGame function. I expected a well-organized String but it turns out it didn't happen.我在 _constructGame function 中解码了它。我期待一个组织良好的字符串,但事实证明它没有发生。 I encountered with a logical error, rather than a system error.我遇到了逻辑错误,而不是系统错误。 But I can't just figure out.但我不能只是弄清楚。 I tried making research but they are irrelevant with my issue.我尝试进行研究,但它们与我的问题无关。

To reach my goal, I also used a list of widget that goes like fixed text, draggable portion, fixed text, ...为了达到我的目标,我还使用了一个小部件列表,比如固定文本、可拖动部分、固定文本……

import 'dart:math';

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:schoolproject/GameTextList.dart';

class GameRoute extends StatefulWidget {

  @override
  State<StatefulWidget> createState() => _GameRouteState();
  
}

class _GameRouteState extends State<GameRoute>{

  // Random().nextInt(GameTextList.texts.length)
  String gameText = GameTextList.texts[0];

  Draggable _createDraggableText(String text) {
    return Draggable<String>(
      data: text,
      child: Text(
        text,
        style: TextStyle(fontWeight: FontWeight.bold, color: Colors.red),
      ),
      feedback: Text(
        text,
        style: TextStyle(fontSize: 16.0,fontWeight: FontWeight.bold, color: Colors.red),
      ),
      childWhenDragging: Text(
        text,
        style: TextStyle(color: Colors.grey),
      ),
    );
  }

  // Precondition: There must be at least one draggable
  List<Widget> _constructGame(String mes) {
    List<Widget> widgets = <Widget>[];

    // Decode the message
    int i = 0;
    int j = 0;
    while (i != mes.length - 1) {
      if (mes[i] == "x" && mes[i + 1] == "{") {
        var last = mes.indexOf("}x", i);
        widgets.add(Text(mes.substring(j, i))); // Bugün hava çok
        widgets.add(_createDraggableText(mes.substring(i + 2, last))); // soğuktu
        j = last + 2;
      }
      i++;
    }
    // add the remaining part of the text
    widgets.add(Text(mes.substring(j, mes.length)));
    return widgets;
  }


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("Egzersiz")),
      body: Wrap(
        children: _constructGame(gameText),
      )
      );
  }

}

class GameTextList {
    static List<String> texts = [
      "Bugün hava çok x{soğuktuuuuuuuuuuuuuuu}x. Fakat üstümüze mont giymeyi x{unuttuk}x. Şu an yağmur x{yağıyor}x. Son zamanlarda"
          " hava düzensiz olabileceğinden tedbirli olmak x{gerekecekmiş}x.",

      "Planktonların varlığı ekosistem için x{mühimdir}x hatta onlar x{olmasaydı}x  Dünyadaki canlıların bir çoğu yok "
          "x{olurdu}x. Nitekim bu canlılar atmosferdeki oksijenin %50'sini x{oluştururlar}x. Yine de insanlar bilinçsizce"
          " denize atık bırakmaya devam x{ederse}x solunulacak bir x{kalmayacak}x.",

      "Uranyumun keşfedildiği tarih x{1789'dur}x.",

      """
Yapma x{ne olursun}x, bırak o yerimi x{doldursun}x. Bana ihtiyacın x{olursa}x sarıl ona, elbet x{unutursun}x.x{Girmişşe}x kalbine bambaşka biri...""",

    ];
}

美国广播公司

abc2

abc3

after analyse your code, I made some changes in _constructGame in your method now its working.分析您的代码后,我对您的方法中的_constructGame进行了一些更改,现在它可以正常工作了。 i simply debug and identify that you need add only one word at time in widgets list just like you do for extract x{Draggable Word}x .so i add code for normal string & commented old lines for the same.我只是简单地调试并确定您一次只需要在小部件列表中添加一个单词,就像您为提取x{Draggable Word}x所做的那样。所以我为普通字符串添加代码并为相同的旧行添加注释。

Added code:添加代码:

final noramlStringArray = normalString.split(" ");
    noramlStringArray.asMap().forEach((index, word) {
    if (index != (noramlStringArray.length - 1)) {
      widgets.add(Text("$word ")); // add word with trailing space 
    } else {
      widgets.add(Text(word)); // add last word without space 
    }
});

Added String extension for remove extra white spaces if string contains double or more spaces which replace with single white space.如果字符串包含用单个空格替换的双倍或更多空格,则添加String extension以删除多余的空格。

extension on String {
  String removeExtraWhiteSpace() {
    return replaceAll(RegExp("[ \t\r\f]"), " ");
  }
}

used removeExtraWhiteSpace() extension in below line.在下面的行中使用了 removeExtraWhiteSpace()扩展。

_constructGame(gameText.removeExtraWhiteSpace()) _constructGame(gameText.removeExtraWhiteSpace())

replace your _constructGame method with below code.用下面的代码替换你的_constructGame方法。

 // Precondition: There must be at least one draggable
List<Widget> _constructGame(String mes) {
    List<Widget> widgets = <Widget>[];
    
    try {
      // Decode the message
      int i = 0;
      int j = 0;
      while (i != mes.length - 1) {
        if (mes[i] == "x" && mes[i + 1] == "{") {
          var last = mes.indexOf("}x", i);
    
          final normalString = mes.substring(j, i);
          final noramlStringArray = normalString.split(" ");
          noramlStringArray.asMap().forEach((index, word) {
            if (index != (noramlStringArray.length - 1)) {
              widgets.add(Text("$word ")); // add word with trailing space 
            } else {
              widgets.add(Text(word)); // add last word without space 
            }
          });
    
          //widgets.add(Text(mes.substring(j, i))); // Bugün hava çok
    
          widgets
              .add(_createDraggableText(mes.substring(i + 2, last))); // soğuktu
          j = last + 2;
        }
        i++;
      }
      // add the remaining part of the text
      //widgets.add(Text(mes.substring(j, mes.length)));
      final normalString = mes.substring(j, mes.length);
    
      final noramlStringArray = normalString.split(" ");
      noramlStringArray.asMap().forEach((index, word) {
        if (index != (noramlStringArray.length - 1)) {
          widgets.add(Text("$word "));
        } else {
          widgets.add(Text(word));
        }
      });
      return widgets;
    } catch (ex) {
      debugPrint("Error: $ex");
      return widgets;
    }
}

if your word will not set in remain width then only it will set in newline automatically.如果您的单词不会设置为保持宽度,那么它只会自动设置为换行符。

在此处输入图像描述

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM