如何在颤动中制作可复制的文本小部件?

Text小部件上有长标签时,会出现一个带有“ copy”的工具提示。当点击“复制”文本内容应该复制到系统剪贴板。

以下内容将长时间点击复制文本,但不显示“复制”,因此用户不会知道,内容将被复制到剪贴板。

class CopyableText extends StatelessWidget {
final String data;
final TextStyle style;
final TextAlign textAlign;
final TextDirection textDirection;
final bool softWrap;
final TextOverflow overflow;
final double textScaleFactor;
final int maxLines;
CopyableText(
this.data, {
this.style,
this.textAlign,
this.textDirection,
this.softWrap,
this.overflow,
this.textScaleFactor,
this.maxLines,
});
@override
Widget build(BuildContext context) {
return new GestureDetector(
child: new Text(data,
style: style,
textAlign: textAlign,
textDirection: textDirection,
softWrap: softWrap,
overflow: overflow,
textScaleFactor: textScaleFactor,
maxLines: maxLines),
onLongPress: () {
Clipboard.setData(new ClipboardData(text: data));
},
);
}
}
66432 次浏览

You can use a SnackBar to notify the user about the copy.

Here is a relevant code:

String _copy = "Copy Me";


@override
Widget build(BuildContext context) {
final key = new GlobalKey<ScaffoldState>();
return new Scaffold(
key: key,
appBar: new AppBar(
title: new Text("Copy"),
centerTitle: true,
),
body:
new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new GestureDetector(
child: new Text(_copy),
onLongPress: () {
Clipboard.setData(new ClipboardData(text: _copy));
key.currentState.showSnackBar(
new SnackBar(content: new Text("Copied to Clipboard"),));
},
),
new TextField(
decoration: new InputDecoration(hintText: "Paste Here")),
]),




);
}

EDIT

I was working on something and I did the followin, so I thought of revisiting this answer:

enter image description here

import "package:flutter/material.dart";
import 'package:flutter/services.dart';


void main() {
runApp(new MaterialApp(home: new MyApp(),
));
}


class MyApp extends StatefulWidget {
@override
_MyAppState createState() => new _MyAppState();
}


class _MyAppState extends State<MyApp> with TickerProviderStateMixin {
String _copy = "Copy Me";


@override
Widget build(BuildContext context) {
final key = new GlobalKey<ScaffoldState>();
return new Scaffold(
key: key,
appBar: new AppBar(
title: new Text("Copy"),
centerTitle: true,
),
body:
new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new GestureDetector(
child: new CustomToolTip(text: "My Copyable Text"),
onTap: () {


},
),
new TextField(
decoration: new InputDecoration(hintText: "Paste Here")),
]),




);
}
}


class CustomToolTip extends StatelessWidget {


String text;


CustomToolTip({this.text});


@override
Widget build(BuildContext context) {
return new GestureDetector(
child: new Tooltip(preferBelow: false,
message: "Copy", child: new Text(text)),
onTap: () {
Clipboard.setData(new ClipboardData(text: text));
},
);
}
}

Since Flutter 1.9 you can use

SelectableText("Lorem ipsum...")

When text is selected the "Copy" context button will appear.

enter image description here

SelectableText(
"Copy me",
onTap: () {
// you can show toast to the user, like "Copied"
},
)

If you want to have different styling for text, use

SelectableText.rich(
TextSpan(
children: [
TextSpan(text: "Copy me", style: TextStyle(color: Colors.red)),
TextSpan(text: " and leave me"),
],
),
)

enter image description here

There is also list of properties it in SelectableText to enable option copy, paste, selectAll, cut

        child: Center(
child: SelectableText('Hello Flutter Developer',
cursorColor: Colors.red,
showCursor: true,
toolbarOptions: ToolbarOptions(
copy: true,
selectAll: true,
cut: false,
paste: false
),
style: Theme.of(context).textTheme.body2)
),

SelectableText widget

        const SelectableText(
this.data, {
Key key,
this.focusNode,
this.style,
this.strutStyle,
this.textAlign,
this.textDirection,
this.showCursor = false,
this.autofocus = false,
ToolbarOptions toolbarOptions,
this.maxLines,
this.cursorWidth = 2.0,
this.cursorRadius,
this.cursorColor,
this.dragStartBehavior = DragStartBehavior.start,
this.enableInteractiveSelection = true,
this.onTap,
this.scrollPhysics,
this.textWidthBasis,
})

enter image description here

I use Clipboard.setData inside function.

...
child: RaisedButton(
onPressed: (){
Clipboard.setData(ClipboardData(text: "$textcopy"));
},
disabledColor: Colors.blue[400],
child: Text("Copy", style: TextStyle(color: Colors.white),),
),

I created a helper class CopiableText to accomplish my job. Just copy the class from below and put it in your code.

Helper class

copiable_text_widget.dart

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


class CopiableText extends StatelessWidget {
final String text;
final String copyMessage;
final Widget child;


CopiableText(this.text, {this.copyMessage, this.child});


@override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
child: InkWell(
onTap: () {
Scaffold.of(context).showSnackBar(SnackBar(
content: Text(this.copyMessage ?? 'Copied to clipboard'),
));
Clipboard.setData(new ClipboardData(text: this.text));
},
child: Align(
alignment: Alignment.centerLeft,
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 2),
child: this.child ??
Text(
this.text,
style: TextStyle(color: Color(0xFF1E272E), fontSize: 14),
),
),
),
),
);
}
}

Use it in different ways

import 'package:chaincargo_courier/ui/widgets/copiable_text_widget.dart';
import 'package:flutter/material.dart';


class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
child: Column(
children: [
// Just straightforward, click to copy
CopiableText('You are awesome'),


// Give a custom confirmation message
CopiableText(
'Asia, Nepal, Biratnagar',
copyMessage: 'Address copied to clipboard',
),


// Set custom child
CopiableText(
'Stunning view of mount everest',
copyMessage: 'Caption copied to clipboard',
child: Column(
children: [
Image.network(
'https://cdn.pixabay.com/photo/2010/11/29/mount-everest-413_960_720.jpg',
errorBuilder: (BuildContext context, Object exception,
StackTrace stackTrace) {
return Text('Cannot load picture');
},
),
Text('Stunning view of mount everest')
],
),
),
],
),
);
}
}

Just use SelectableText

 SelectableText(
iosInfo.identifierForVendor.toString(),
),