4

I have two widgets, widget1 and widget2. Widget1: I have added one Drop-down in this widget. now I want to update widget2's views properties (like color and name) on drop-down item changes event.

So, Can I use interface to fulfill the above requirements? or Is there any other way to perform the same things?

Widget1
 - Text
 - DropdownButton
     - OnChange(){
        // Update widget2 (change txt1 & color1 values)
       }


Widget2
 - Text
 - Container
     - Card
         - Text (txt1, color1...)
Samet ÖZTOPRAK
  • 3,112
  • 3
  • 32
  • 33
Akash Patel
  • 3,091
  • 3
  • 15
  • 23

2 Answers2

6

The trick is to have a common ancestor widget that is stateful:

WidgetParent (StatefulWidget)
- Widget1 (displays the dropdown)
- Widget2 (displays the text/color)

The selection of Widget1 is passed up to the parent (using a callback). The selection is stored in the state of the parent widget, and passed down to Widget2 through constructor parameters. The parent calls setState, which causes all children to be rebuilt.

Example code:

import 'package:flutter/material.dart';

class ParentWidget extends StatefulWidget {
  @override
  _ParentWidgetState createState() => _ParentWidgetState();
}

class _ParentWidgetState extends State<ParentWidget> {
  String _text = 'hello world';
  Color _color = Colors.red;

  void _onSelectionChanged(int value) {
    if (value == 0) {
      setState(() {
        _text = "0 selected";
        _color = Colors.blue;
      });
    } else if (value == 1) {
      setState(() {
        _text = "1 selected";
        _color = Colors.yellow;
      });
    } else {
      setState(() {
        _text = "unknown value selected";
        _color = Colors.black;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        Widget1(
          onChanged: _onSelectionChanged,
        ),
        Widget2(
          text: _text,
          color: _color,
        )
      ],
    );
  }
}

class Widget1 extends StatelessWidget {
  final ValueChanged<int> onChanged;

  const Widget1({Key key, this.onChanged}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return DropdownButton<int>(
      items: [
        DropdownMenuItem(child: Text("Zero"), value: 0),
        DropdownMenuItem(child: Text("One"), value: 1),
      ],
      onChanged: onChanged,
    );
  }
}

class Widget2 extends StatelessWidget {
  final String text;
  final Color color;

  const Widget2({Key key, this.text, this.color}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      color: color,
      child: Text(text),
    );
  }
}
boformer
  • 28,207
  • 10
  • 81
  • 66
0

I think what you want to do is pass the Function that needs to be executed Something like this

Widget1 (this._onChangeFunction); // get a ref to the Function needed later

final Function _onChangeFunction; 

 - Text
 - DropdownButton
     - OnChange(){
        // Update widget2 (change txt1 & color1 values)
        _onChangeFunction(txt, color);
      }


Widget2

fun _changeText(String txt, String color) {
   // called by Widget1, change the Text... in this private function
}

// some reference to Widget1, nested in your Card perhaps?
Widget1(_changeText);

 - Text
 - Container
     - Card
         - Text (txt1, color1...)
aaronvargas
  • 12,189
  • 3
  • 52
  • 52