Home > database >  Flutter get the value of a widget class variable
Flutter get the value of a widget class variable

Time:06-04

I have this widget:

import 'package:flutter/material.dart';

class TextBox extends StatelessWidget {

  late var valor;
  late var largura;
  late var tamanhoLetra;

  TextBox({
    required this.largura,
    required this.tamanhoLetra
  });

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      width: largura,
      child: TextField(
        style: TextStyle(
          fontSize: tamanhoLetra,
        ),
        textAlign: TextAlign.left,
        onChanged: (String text) {
          valor = text;
        },
      ),
    );
  }
}

And in my page, where i call this widget, i want to assign the value of 'valor' to another variable.
How can i do that ?
Now i'm only calling the widget like this in my widget tree :

 TextBox(
   largura: 100, 
   tamanhoLetra: 25,
 )

CodePudding user response:

It is not possible to get a variable from a child widget into a parent widget, this is not what you are supposed to do, instead pass an onChanged callback into the Textbox widget and edit valor from there:

on the parent widget:

class MyWidget extends StatefulWidget {

  const MyWidget({Key? key}) : super(key: key);

  @override
  _MyWidgetState createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {

  String valor = '';

  @override
  Widget build(BuildContext context) {
    return TextBox(
      largura: 100, 
      tamanhoLetra: 25,
      onValorChanged: (String value) => setState(() => valor = value),
    );
  }
}

Then on your child widget:

  TextBox({Key? key, required this.onValorChanged}): super(key: key);

  final void Function(String) onValorChanged;

[...]
      TextField(
        style: TextStyle(
          fontSize: tamanhoLetra,
        ),
        textAlign: TextAlign.left,
        onChanged: onValorChanged,
      ),

[...]

You have now "moved the state up", making it so the parent widget stores the valor variable instead of the child widget.

CodePudding user response:

You have encapsulated valor inside your TextBox, so you should actually avoid using this value directly.

So, there are two things you should do:

  1. lift state up (i.e. move valor to TextBox's caller)
  2. use a callback to set the state outside of TextBox

import 'package:flutter/material.dart';

class TextPage extends StatefulWidget {...}

class _TextPageState extends State<TextPage> {
    String valor = '';

    @override
    Widget build(BuildContext context) {
        return TextBox(
            largura: MediaQuery.of(context).size.width,
            tamanhoTexto: 20,
            onChanged: (texto) => setState(() {
                valor = texto;
            }),
        );
    }
}

class TextBox extends StatelessWidget {

  // late var valor; // this no longer exists here
  final void Function(String newText) onChange; 

  // you should use final instead of late here because this class is immutable
  // it's not recommended to use var where the variable is not of dynamic type
  final double largura;
  final double tamanhoLetra;

  TextBox({
    required this.largura,
    required this.tamanhoLetra
  });

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      width: largura,
      child: TextField(
        style: TextStyle(
          fontSize: tamanhoLetra,
        ),
        textAlign: TextAlign.left,
        onChanged: onChanged,
      ),
    );
  }
}

  • Related