颤动:使用TapGestureRecognizer更改TextSpan的文本样式

问题描述 投票:2回答:1

我想让文字的每个单词都可以点击。然后,当点击特定单词时,它的textcolor应该改变。

使每个单词可单击可以正常工作。但是,当我点击一个单词时,文本颜色会以某种方式改变。这是我走了多远:

import 'package:flutter/material.dart';
import 'package:flutter/gestures.dart';

 class MakeStringClickable extends StatefulWidget{
 @override
 State<StatefulWidget> createState() {
 // TODO: implement createState
 return _MakeStringClickableState();
 }
 }

class _MakeStringClickableState extends State<MakeStringClickable>{

String textToSplit = 'I would like to make each word clickable. On click of a particular word it's color should change.';

@override
Widget build(BuildContext context) {
return Scaffold(
  body: Container(
      alignment: Alignment.center,
      child: _buildTextSpanWithSplittedText(textToSplit, context)
  ),
);
}

RichText _buildTextSpanWithSplittedText(String textToSplit, BuildContext context) {
bool isPressed = false;
final splittedText = textToSplit.split(" ");
final spans = new List<TextSpan>();

  for(int i = 0; i <= splittedText.length - 1; i++ ){
    spans.add(TextSpan(
      text: splittedText[i].toString() + " ",
      style: TextStyle(color: isPressed ? Colors.black : Colors.red),
      recognizer: new TapGestureRecognizer()..onTap = () {
      setState(() {isPressed = !isPressed;});
      }
    ));
  }
  return RichText(text: TextSpan(children: spans));
}
}

当我点击它时,我希望任何单词的颜色都变为黑色,但不知何故,改变样式不会按预期工作。我希望有人能够帮助我。

split dart flutter styles uitapgesturerecognizer
1个回答
1
投票

第一个问题是你在_buildTextSpanWithSplittedText方法中有isPressed,它将在每次重新绘制时被覆盖。如果将该变量保持在类级别,它将应用于所有TextSpans。 所以可能的解决方案是使用List,这里是一个例子:

import 'package:flutter/material.dart';
import 'package:flutter/gestures.dart';

class MakeStringClickable extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _MakeStringClickableState();
  }
}

class _MakeStringClickableState extends State<MakeStringClickable> {
  List<TapSection> sections;
  String textToSplit =
      'FirstWord would like to make each word clickable. On click of a particular word it\'s color should change.';
  TapGestureRecognizer r1;
  @override
  void initState() {
    sections = List<TapSection>();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Container(
        alignment: Alignment.center,
        child: _buildTextSpanWithSplittedText(textToSplit, context));
  }

  RichText _buildTextSpanWithSplittedText(
      String textToSplit, BuildContext context) {
    final splittedText = textToSplit.split(" ");
    final spans = List<TextSpan>();
    for (int i = 0; i <= splittedText.length - 1; i++) {
      var tapSection = TapSection(callBack: () {
        setState(() {});
      });
      sections.add(tapSection);
      spans.add(TextSpan(
          text: splittedText[i].toString() + " ",
          style: TextStyle(
              color: sections[i].isPressed ? Colors.black : Colors.red),
          recognizer: sections[i].recognizer));
    }
    return RichText(text: TextSpan(children: spans));
  }
}

class TapSection {
  TapGestureRecognizer recognizer;
  bool isPressed = false;
  final Function callBack;

  TapSection({this.callBack}) {
    recognizer = TapGestureRecognizer();
    recognizer.onTap = () {
      this.isPressed = !this.isPressed;
      this.callBack();
    };
  }
}

请注意,我们需要将setState作为此解决方案的回调调用。 希望这有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.