Matt123
Matt123

Reputation: 303

Flutter passing data up through stateless widget

I am working on a flutter app, and I have some data stored in the state of a widget. In this case it is the string title. I am wondering if I can pass this data through a parent stateless widget and into this stateless widgets parent, which is a stateful widget. If working correctly, I could pass title into the state of MyHomePage and save it into title2. Is there a way to do this or do I have to convert Widget1 into a stateful widget. The only issue with that is that I already wrote the widget, but I am curious. Here is my code. Thanks!

//main.dart
import 'package:flutter/material.dart';
import 'Widget1.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(

        primarySwatch: Colors.blue,
      ),

        home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {

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

class _MyHomePageState extends State<MyHomePage> {
String title2;
  @override
  Widget build(BuildContext context) {

    return Scaffold(
      appBar: AppBar(
        title: Text("Hello"),
      ),
      body: Center(
        child: Widget1(),
      ),
    );
  }
}
/////////////////////////////////////////////
//Widget1.dart

Widget Widget1() {
  return Widget2();
}
/////////////////////////////////
//Widget2.dart

import 'package:flutter/material.dart';

class Widget2 extends StatefulWidget {

  final String title = "Hello from Widget2";


  _Widget2State createState() => _Widget2State();
}

class _Widget2State extends State<Widget2> {
String title = "Hello from Widget2";


  @override
  Widget build(BuildContext context) {
    return Text('${title}');

  }
}

Thanks again!

Upvotes: 1

Views: 3358

Answers (2)

Crazy Lazy Cat
Crazy Lazy Cat

Reputation: 15103

I assume you just want to pass data from StatelessWidget to StatefulWidget and want to access it in its State. Then try this,

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: "Flutter Demo",),
    );
  }
}

class MyHomePage extends StatefulWidget {
  final String title;

  const MyHomePage({Key key, this.title}) : super(key: key);

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

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title), //TODO: use `widget` to access properties
      ),
      body: Center(
        child: MyWidget(title: widget.title,),
      ),
    );
  }
}

class MyWidget extends StatefulWidget {
  final String title;

  const MyWidget({Key key, this.title}) : super(key: key);

  _MyWidgetState createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  @override
  Widget build(BuildContext context) {
    return Text('${widget.title}');
  }
}

Upvotes: 0

Antonio Valentic
Antonio Valentic

Reputation: 380

If you are not using any state management except default one then you can pass data between widgets using Navigator. Here is the code example of how to pass String from child Stateless widget (can be stateful too) to its parent widget.

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  String title = "";

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("FIRST WIDGET"),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text("Title from child Stateless widget: $title"),
            FlatButton(
              onPressed: () => _openSecondWidget(),
              child: Text("OPEN SECOND WIDGET"),
            )
          ],
        ),
      ),
    );
  }

  void _openSecondWidget() async {
    var newTitle = await Navigator.of(context).push(
      MaterialPageRoute(
        builder: (context) => SecondWidget(),
      ),
    );
    setState(() {
      title = newTitle;
    });
  }
}

class SecondWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("SECOND WIDGET"),
      ),
      body: Center(
        child: FlatButton(
          onPressed: () {
            Navigator.of(context).pop("Hi from Second Widget");
          },
          child: Text("GO BACK"),
        ),
      ),
    );
  }
}

So the button on the first widget is pushing new widget on the screen and awaits for its result. When it gets the result from the second widget I'm using setState updating display of the title variable. And second widget has just one button which removes this widget from the back stack with some parameter which is in this case String, but it can be anything else.

Upvotes: 1

Related Questions