skip to Main Content

Good evening everyone.

I’m structuring an app on 2 columns. In the left column I would like to insert a button that updates the contents of the right column. Although keeping all the code in a single class I can do what I have in mind, creating 2 classes (one for the left column and one for the right one) I do not understand how to call the callback or setState.

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter layout demo',
      home: HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  @override
  HomePageState createState() => HomePageState();
}

class HomePageState extends State<HomePage> {
  String TestoADestra = 'TestoInizialeADestra';

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter layout demo',
      home: Scaffold(
          body: Row(
        children: [
          ColonnaSx(),
          ColonnaDx(),
        ],
      )),
    );
  }
}

class ColonnaDx extends StatefulWidget {
  @override
  ColonnaDxState createState() => ColonnaDxState();
}

class ColonnaDxState extends State<ColonnaDx> {
  @override
  Widget build(BuildContext context) {
    return Expanded(
      flex: 4,
      child: Container(
        decoration: const BoxDecoration(
          color: Colors.blue,
        ),
        child: Column(
          children: [
            Expanded(
              child: Center(
                child: Text(
                    'Here I would like to put other things but for the moment there is this'),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class ColonnaSx extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Expanded(
      flex: 1,
      child: Container(
        decoration: BoxDecoration(
          color: Colors.red,
        ),
        child: Column(
          children: [
            Expanded(
              child: Center(
                child: BottoneA(),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class BottoneA extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return TextButton(
      style: ButtonStyle(
        foregroundColor:
            MaterialStateProperty.all<Color>(Color.fromARGB(255, 72, 3, 201)),
      ),
      onPressed: () {},
      child: Text('Press here'),
    );
  }
}

I tried to insert:

  • regarding "ButtonA" the callBack function to onPressed and I declared the function before the override something like:
  final String TestoCheVorreiComparisse;
  final Function callbackFunction;
  const BottoneA({Key? key, required this.TestoCheVorreiComparisse, required this.callbackFunction}) : super(key: key);
  • as for "ColumnDX" before the override something like this:
String TestoCheVorreiComparisse="Vediamo se funziona";
  callback(varTestoSostitutivo){
    setState(() {
      TestoCheVorreiComparisse=varTestoSostitutivo;
    });
  }

I am told, and I understand why, that there is no callback function in "buttonA"… How can I do this? Thank you!

3

Answers


  1. You can use Provider and their values are global so you may use them anywhere where you want and can update state event without StatefulWidget.
    here is the link:Provider

    Login or Signup to reply.
  2. Without using third party packages, you can lift your state to their first common parent and pass the state/modification functions down to both elements.

    Login or Signup to reply.
  3. If you like to just get the tab event you can use VoidCallback, to pass data you need to use Function() callback. While the widget is nested, it you need to pass function on child. Here is the demo using both approach, But for project level you may choose state management like riverpod/bloc

    import 'package:flutter/cupertino.dart';
    import 'package:flutter/material.dart';
    import 'dart:math' as math;
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({super.key});
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter layout demo',
          home: HomePage(),
        );
      }
    }
    
    class HomePage extends StatefulWidget {
      @override
      HomePageState createState() => HomePageState();
    }
    
    class HomePageState extends State<HomePage> {
      String TestoADestra = 'TestoInizialeADestra';
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Row(
            children: [
              ColonnaSx(
                onButtonTapA: () {
                  setState(() {
                    TestoADestra = "update value";
                  });
                },
                onButtonTapB: (data) {
                  setState(() {
                    TestoADestra = "update value ${data}";
                  });
                },
              ),
              ColonnaDx(data: TestoADestra),
            ],
          ),
        );
      }
    }
    
    class ColonnaDx extends StatefulWidget {
      const ColonnaDx({super.key, required this.data});
    
      final String data;
    
      @override
      ColonnaDxState createState() => ColonnaDxState();
    }
    
    class ColonnaDxState extends State<ColonnaDx> {
      @override
      Widget build(BuildContext context) {
        return Expanded(
          flex: 4,
          child: Container(
            decoration: const BoxDecoration(
              color: Colors.blue,
            ),
            child: Column(
              children: [
                Expanded(
                  child: Center(
                    child: Text(widget.data),
                  ),
                ),
              ],
            ),
          ),
        );
      }
    }
    
    class ColonnaSx extends StatelessWidget {
      final VoidCallback onButtonTapA;
      final Function(int data) onButtonTapB;
    
      const ColonnaSx({
        super.key,
        required this.onButtonTapA,
        required this.onButtonTapB,
      });
      @override
      Widget build(BuildContext context) {
        return Expanded(
          flex: 1,
          child: Container(
            decoration: BoxDecoration(
              color: Colors.red,
            ),
            alignment: Alignment.center,
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                BottoneA(onButtonTap: onButtonTapA),
                BottoneB(onButtonTap: onButtonTapB),
              ],
            ),
          ),
        );
      }
    }
    
    class BottoneA extends StatelessWidget {
      final VoidCallback onButtonTap;
    
      const BottoneA({super.key, required this.onButtonTap});
      @override
      Widget build(BuildContext context) {
        return TextButton(
          style: ButtonStyle(
            foregroundColor:
                MaterialStateProperty.all<Color>(Color.fromARGB(255, 72, 3, 201)),
          ),
          onPressed: onButtonTap,
          child: Text('Press here'),
        );
      }
    }
    
    class BottoneB extends StatelessWidget {
      final Function(int data) onButtonTap;
    
      const BottoneB({super.key, required this.onButtonTap});
      @override
      Widget build(BuildContext context) {
        return ElevatedButton(
          onPressed: () {
            onButtonTap(math.Random().nextInt(55555));
          },
          child: Text('Press to pass int'),
        );
      }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search