Created
October 1, 2019 21:50
-
-
Save chunhtai/7041cb818162e244b64adccd61a5024f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import 'package:flutter/material.dart'; | |
| import 'package:flutter/gestures.dart'; | |
| import 'package:flutter/widgets.dart'; | |
| import 'package:flutter/rendering.dart'; | |
| void main() => runApp(MyApp()); | |
| class MyApp extends StatelessWidget { | |
| // This widget is the root of your application. | |
| @override | |
| Widget build(BuildContext context) { | |
| return MaterialApp( | |
| title: 'Scroll Performance', | |
| theme: ThemeData( | |
| // This is the theme of your application. | |
| // | |
| // Try running your application with "flutter run". You'll see the | |
| // application has a blue toolbar. Then, without quitting the app, try | |
| // changing the primarySwatch below to Colors.green and then invoke | |
| // "hot reload" (press "r" in the console where you ran "flutter run", | |
| // or simply save your changes to "hot reload" in a Flutter IDE). | |
| // Notice that the counter didn't reset back to zero; the application | |
| // is not restarted. | |
| primarySwatch: Colors.blue, | |
| ), | |
| home: MyHomePage(title: 'Flutter Demo Home Page'), | |
| ); | |
| } | |
| } | |
| class MyHomePage extends StatefulWidget { | |
| MyHomePage({Key key, this.title}) : super(key: key); | |
| final String title; | |
| @override | |
| _MyHomePageState createState() => _MyHomePageState(); | |
| } | |
| class _MyHomePageState extends State<MyHomePage> { | |
| @override | |
| Widget build(BuildContext context) { | |
| return Scaffold( | |
| appBar: AppBar( | |
| title: Text(widget.title), | |
| ), | |
| body: Scrollable( | |
| viewportBuilder: (BuildContext context, ViewportOffset offset) { | |
| return ArticleRichText( | |
| offset: offset, | |
| ); | |
| }, | |
| ) | |
| // This trailing comma makes auto-formatting nicer for build methods. | |
| ); | |
| } | |
| } | |
| class ArticleRichText extends StatefulWidget { | |
| ArticleRichText({Key key, this.offset}) : super(key: key); | |
| final ViewportOffset offset; | |
| @override | |
| ArticleRichTextState createState() => ArticleRichTextState(); | |
| } | |
| class ArticleRichTextState extends State<ArticleRichText> { | |
| Offset _lastTapDownPosition; | |
| GlobalKey key = GlobalKey(); | |
| TextPainter get textPainter { | |
| return renderObject.textPainter; | |
| } | |
| CustomRenderParagraph get renderObject { | |
| return key.currentContext.findRenderObject(); | |
| } | |
| Offset get _paintOffset { | |
| return Offset(0.0, -widget.offset.pixels); | |
| } | |
| @override | |
| Widget build(BuildContext context) { | |
| // The custom widget will be pretty much copy paste from RichText | |
| // but with the CustomRenderParagraph. | |
| // The CustomRenderParagraph will also be pretty much the same as RenderParagraph | |
| // but with exposing the api to textpainter. | |
| return CustomRichText( | |
| key: key, | |
| text: TextSpan( | |
| text: 'this this this this this this this this this this this this this this this this this this this this this this this this \nthis this this this this this this this this this this this this this this this this this this this this this this this \n', | |
| recognizer: TapGestureRecognizer() | |
| ..onTapDown = (TapDownDetails details) { | |
| _lastTapDownPosition = details.globalPosition; | |
| } | |
| ..onTap = () { | |
| final TextPosition tapPosition = textPainter.getPositionForOffset(renderObject.globalToLocal(_lastTapDownPosition - _paintOffset)); | |
| // you should have the text index to find out which word it is clicked | |
| } | |
| ), | |
| ); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment