How to copy the value of a Widget Text to another using onPressed property of a button

Viewed 586

I need to copy a value of a Text Widget and copy this to another.

I tried to this using keys, but I don't know how to acess the Text Widget in this case.

Is it possible to do in Flutter, using the onPressed property?

import 'package:flutter/material.dart';

class TextWidget extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text( 
              "Value to be copied",
              key: Key('text1')
            ),
            RaisedButton(
              onPressed: (){
                // code here
              },
              child: Text("Copy value"),
            ),
            SizedBox(height: 40),
            Text(
              "",
              key: Key('text2')
            )
          ],
        ),
      ),
    );
  }
}
3 Answers

Answering your question directly: you can access text inside Text widget using its data property.

Text widget = Text('text value');
String text = widget.data;
print(text); // text value

Next, you can't access widgets by their key properties. At least you shouldn't, because they were designed for different purpose: here's a video and an article about keys in Flutter.

What you can do here is turn your TextWidget from StatelessWidget into StatefulWidget and render contents of your second Text based on the state. Good introduction into what the state is and why you should use it can be found on official Flutter website: Start thinking declaratively.

Then you can save your first Text widget in a variable and then access its contents directly using data property update, then update state of the whole widget.

Example 1 on DartPad

More canonical and in general preferrable approach is to render contents of both buttons based on the state and get desired text from state variable and not from the widget itself, as proposed by Sebastian and MSARKrish.

Example 2 on DartPad

Note that you can't change data attribute of a Text widget imperatively, like you would do in JavaScript DOM API with innerText:

_textWidget.data = "New text"; // Doesn't work

because its data is final. In Flutter you have to think declaratively, and it worth it.

class TextWidget extends StatefulWidget {
@override
 _TextWidgetState createState() => _TextWidgetState();
 }

class _TextWidgetState extends State<TextWidget> {
  String text1Value = "text to be copied";

  String text2Value = "";

   @override
   Widget build(BuildContext context) {
     return Scaffold(
       body: Center(
         child: Column(
           mainAxisAlignment: MainAxisAlignment.center,
           children: [
             Text(
               text1Value,
              ),
             RaisedButton(
               onPressed: () {
                 setState(() {
                   text2Value = text1Value;
                  });
               },
               child: Text("Copy value"),
             ),
             SizedBox(height: 40),
            Text(
              text2Value,
            )
        ],
    ),
  ),
  );
 }
}

Try this

import 'package:flutter/material.dart';

final Color darkBlue = Color.fromARGB(255, 18, 32, 47);

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: Center(
          child: MyWidget(),
        ),
      ),
    );
  }
}

class MyWidget extends StatefulWidget {
  @override
  _MyWidgetState createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  String _text = "Value to be copied";
  bool _buttonToggle;

  @override
  void initState() {
    super.initState();

    _buttonToggle = false;
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Text(_text),
        SizedBox(height: 40),
        RaisedButton(
          onPressed: _toggle,
          child: Text("Copy value"),
        ),
        Switch(
          value: _buttonToggle,
          onChanged: (_) => _toggle(),
        ),
        SizedBox(height: 40),
        Text(_buttonToggle ? _text : '')
      ],
    );
  }

  void _toggle() {
    setState(() => _buttonToggle = !_buttonToggle);
  }
}
Related