Home > Blockchain >  Call a Widget based on the result of an If statement Flutter
Call a Widget based on the result of an If statement Flutter

Time:02-11

I want to be able to call either one of two different widgets based on the result of an if statement. I am able to get a Text Widget to show two different answers based on the result of the first dropdown box, but I am not able to call another widget the same way ...

import 'package:flutter/material.dart';

class FilterPage extends StatefulWidget {
  const FilterPage({Key? key}) : super(key: key);

  @override
  State<FilterPage> createState() => _FilterPageState();
}

class _FilterPageState extends State<FilterPage> {
  String firstDropdownValue = 'Option A';
  String secondDropdownValue = 'Option B';

  @override
  void dispose() {
    super.dispose();
  }

  static const String _title = 'Filter Code Sample';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        actions: [
          Padding(
            padding: EdgeInsets.all(4),
          ),
        ],
        title: Column(
          children: [
            Text(
              'Filter',
              style: TextStyle(fontSize: 22, color: Colors.amberAccent),
            ),
          ],
        ),
      ),
      body: SingleChildScrollView(
        child: Padding(
          padding: const EdgeInsets.all(8.0),
          child: Column(
            children: [
              Text(
                'What are the Options ?',
                style: TextStyle(fontSize: 16, color: Colors.white),
              ),

              /*
              * This is the first dropdown that is called, This dropdown provides
              * two possible options,
              * */
              DropdownButton<String>(
                dropdownColor: Colors.blueGrey.shade700,
                value: firstDropdownValue,
                icon: const Icon(Icons.arrow_downward),
                elevation: 16,
                style: const TextStyle(color: Colors.white),
                underline: Container(
                  height: 2,
                  color: Colors.blueGrey.shade900,
                ),
                onChanged: (String? newValue) {
                  setState(() {
                    firstDropdownValue = newValue!;
                  });
                },
                items: <String>['Option A', 'Option B']
                    .map<DropdownMenuItem<String>>((String doaValue) {
                  return DropdownMenuItem<String>(
                    value: doaValue,
                    child: Text(doaValue),
                  );
                }).toList(),
              ),


              /*
              * So this is the if Statement that works based upon the first
              * drop down box's answer...
              *
              * The problem is I can not get the system to call another Drop down Butten
              * Widget based on the answer of the first DropdownBox,
              * However, i can get a Text Widget to print...
              * */
              Text((() {
                if (firstDropdownValue == 'Option A') {
                  return "Option is Option A";
                }
                return "Option is Option B";
              })()),


              /*
              * This is the second dropbox that I would like to be called if the
              * previous statement is met instead of the Text Widget above...
              *(DROPBOX 2)
              * */
              DropdownButton<String>(
                dropdownColor: Colors.blueGrey.shade700,
                value: secondDropdownValue,
                icon: const Icon(Icons.arrow_downward),
                elevation: 16,
                style: const TextStyle(color: Colors.white),
                underline: Container(
                  height: 2,
                  color: Colors.blueGrey.shade900,
                ),
                onChanged: (String? newValue) {
                  setState(() {
                    secondDropdownValue = newValue!;
                  });
                },
                items: <String>[
                  'Option 1',
                  'Option 2',
                  'Option 3',
                ].map<DropdownMenuItem<String>>((String doaValue) {
                  return DropdownMenuItem<String>(
                    value: doaValue,
                    child: Text(doaValue),
                  );
                }).toList(),
              ),


              /*
              * This is also drop box two, but this dropbox with these different
              * options should be called when the if statement is not met ..
              *(DROPBOX 2)
              * */
              DropdownButton<String>(
                dropdownColor: Colors.blueGrey.shade700,
                value: secondDropdownValue,
                icon: const Icon(Icons.arrow_downward),
                elevation: 16,
                style: const TextStyle(color: Colors.white),
                underline: Container(
                  height: 2,
                  color: Colors.blueGrey.shade900,
                ),
                onChanged: (String? newValue) {
                  setState(() {
                    secondDropdownValue = newValue!;
                  });
                },
                items: <String>[
                  'Option 4',
                  'Option 5',
                  'Option 6',
                ].map<DropdownMenuItem<String>>((String doaValue) {
                  return DropdownMenuItem<String>(
                    value: doaValue,
                    child: Text(doaValue),
                  );
                }).toList(),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

flow diagram for logic

The flow diagram is maybe easier to get the whole picture from.

CodePudding user response:

You can use a if(condition)...[widgetA] else...[WidgetB] structure:

    class _FilterPageState extends State<FilterPage> {
      String firstDropdownValue = 'Option A';
      String secondDropdownValue = 'Option B';
    
      @override
      void dispose() {
        super.dispose();
      }
    
      static const String _title = 'Filter Code Sample';
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            actions: [
              Padding(
                padding: EdgeInsets.all(4),
              ),
            ],
            title: Column(
              children: [
                Text(
                  'Filter',
                  style: TextStyle(fontSize: 22, color: Colors.amberAccent),
                ),
              ],
            ),
          ),
          body: SingleChildScrollView(
            child: Padding(
              padding: const EdgeInsets.all(8.0),
              child: Column(
                children: [
                  Text(
                    'What are the Options ?',
                    style: TextStyle(fontSize: 16, color: Colors.white),
                  ),
    
                  /*
                  * This is the first dropdown that is called, This dropdown provides
                  * two possible options,
                  * */
                  DropdownButton<String>(
                    dropdownColor: Colors.blueGrey.shade700,
                    value: firstDropdownValue,
                    icon: const Icon(Icons.arrow_downward),
                    elevation: 16,
                    style: const TextStyle(color: Colors.white),
                    underline: Container(
                      height: 2,
                      color: Colors.blueGrey.shade900,
                    ),
                    onChanged: (String? newValue) {
                      setState(() {
                        firstDropdownValue = newValue!;
                      });
                    },
                    items: <String>['Option A', 'Option B']
                        .map<DropdownMenuItem<String>>((String doaValue) {
                      return DropdownMenuItem<String>(
                        value: doaValue,
                        child: Text(doaValue),
                      );
                    }).toList(),
                  ),
    
    
                  if(firstDropDownValue)...[
                  DropdownButton<String>(
                    dropdownColor: Colors.blueGrey.shade700,
                    value: secondDropdownValue,
                    icon: const Icon(Icons.arrow_downward),
                    elevation: 16,
                    style: const TextStyle(color: Colors.white),
                    underline: Container(
                      height: 2,
                      color: Colors.blueGrey.shade900,
                    ),
                    onChanged: (String? newValue) {
                      setState(() {
                        secondDropdownValue = newValue!;
                      });
                    },
                    items: <String>[
                      'Option 1',
                      'Option 2',
                      'Option 3',
                    ].map<DropdownMenuItem<String>>((String doaValue) {
                      return DropdownMenuItem<String>(
                        value: doaValue,
                        child: Text(doaValue),
                      );
                    }).toList(),
                  ),
               ] else ...[
                 DropdownButton<String>(
                    dropdownColor: Colors.blueGrey.shade700,
                    value: secondDropdownValue,
                    icon: const Icon(Icons.arrow_downward),
                    elevation: 16,
                    style: const TextStyle(color: Colors.white),
                    underline: Container(
                      height: 2,
                      color: Colors.blueGrey.shade900,
                    ),
                    onChanged: (String? newValue) {
                      setState(() {
                        secondDropdownValue = newValue!;
                      });
                    },
                    items: <String>[
                      'Option 4',
                      'Option 5',
                      'Option 6',
                    ].map<DropdownMenuItem<String>>((String doaValue) {
                      return DropdownMenuItem<String>(
                        value: doaValue,
                        child: Text(doaValue),
                      );
                    }).toList(),
                  ),
                 ]
                ],
              ),
            ),
          ),
        );
      }
    }

CodePudding user response:

Not the best approach for this probably, but you can use a Builder widget, inside it put your if statement and if you don't want to show your widget there, return SizedBox.shrink() instead (don't forget to setState((){}) so that the widget containing them both rebuilds them. But a better answer may be using Bloc or some other state management package. Or even ValueNotifiers and ValueListenableBuilders to update your UI only where it's needed.

CodePudding user response:

One solution here is to use an inline if condition like this:

 DropdownButton<String>(
    dropdownColor: Colors.blueGrey.shade700,
    value: firstDropdownValue,
    icon: const Icon(Icons.arrow_downward),
    elevation: 16,
    style: const TextStyle(color: Colors.white),
    underline: Container(
      height: 2,
      color: Colors.blueGrey.shade900,
    ),
    onChanged: (String? newValue) {
      setState(() {
        firstDropdownValue = newValue!;
      });
    },
    items: <String>['Option A', 'Option B']
        .map<DropdownMenuItem<String>>((String doaValue) {
      return DropdownMenuItem<String>(
        value: doaValue,
        child: Text(doaValue),
      );
    }).toList(),
),
firstDropdownValue == 'Option A'? 
       DropdownButton(/*first dropdown*/) : 
       DropdownButton(/*second dropdown*/),

The other is creating a Widget variable at the beginning of the build method and giving it a value before returning the Scaffold, then put the created variable as one of the Column children:

@override
  Widget build(BuildContext context) {
    Widget bottomDropdown;
    if (firstDropdownValue == 'Option A'){
       bottomDropdown = DropdownButton(/*first dropdown*/);
    } else {
       bottomDropdown = DropdownButton(/*second dropdown*/);
    }
    return Scaffold(
      appBar: AppBar(
//...other code
    DropdownButton<String>(
      dropdownColor: Colors.blueGrey.shade700,
      value: firstDropdownValue,
      icon: const Icon(Icons.arrow_downward),
      elevation: 16,
      style: const TextStyle(color: Colors.white),
      underline: Container(
        height: 2,
        color: Colors.blueGrey.shade900,
      ),
      onChanged: (String? newValue) {
        setState(() {
          firstDropdownValue = newValue!;
        });
      },
      items: <String>['Option A', 'Option B']
          .map<DropdownMenuItem<String>>((String doaValue) {
        return DropdownMenuItem<String>(
          value: doaValue,
          child: Text(doaValue),
        );
      }).toList(),
   ),
   bottomDropdown,

CodePudding user response:

You can use the Dart short if form: if ? then : else. Since the only thing that changes are the dropdown options, you can dynamically change them without the need to use another widget.

import 'package:flutter/material.dart';

class FilterPage extends StatefulWidget {
  const FilterPage({Key? key}) : super(key: key);

  @override
  State<FilterPage> createState() => _FilterPageState();
}

class _FilterPageState extends State<FilterPage> {
  String firstDropdownValue = '';
  String secondDropdownValue = 'Option B';

  @override
  void dispose() {
    super.dispose();
  }

  static const String _title = 'Filter Code Sample';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        actions: [
          Padding(
            padding: EdgeInsets.all(4),
          ),
        ],
        title: Column(
          children: [
            Text(
              'Filter',
              style: TextStyle(fontSize: 22, color: Colors.amberAccent),
            ),
          ],
        ),
      ),
      body: SingleChildScrollView(
        child: Padding(
          padding: const EdgeInsets.all(8.0),
          child: Column(
            children: [
              Text(
                'What are the Options ?',
                style: TextStyle(fontSize: 16, color: Colors.white),
              ),
              DropdownButton<String>(
                dropdownColor: Colors.blueGrey.shade700,
                value: firstDropdownValue,
                icon: const Icon(Icons.arrow_downward),
                elevation: 16,
                style: const TextStyle(color: Colors.white),
                underline: Container(
                  height: 2,
                  color: Colors.blueGrey.shade900,
                ),
                onChanged: (String? newValue) {
                  setState(() {
                    firstDropdownValue = newValue!;
                  });
                },
                items: <String>['Option A', 'Option B']
                    .map<DropdownMenuItem<String>>((String doaValue) {
                  return DropdownMenuItem<String>(
                    value: doaValue,
                    child: Text(doaValue),
                  );
                }).toList(),
              ),
              if(firstDropdownValue.isNotEmpty)
               DropdownButton<String>(
                 dropdownColor: Colors.blueGrey.shade700,
                 value: secondDropdownValue,
                 icon: const Icon(Icons.arrow_downward),
                 elevation: 16,
                 style: const TextStyle(color: Colors.white),
                 underline: Container(
                   height: 2,
                   color: Colors.blueGrey.shade900,
                 ),
                 onChanged: (String? newValue) {
                   setState(() {
                     secondDropdownValue = newValue!;
                   });
                 },
                 items: <String>[
                   firstDropdownValue == 'Option A' ? 
                   ...['Option 1',
                   'Option 2',
                   'Option 3'] : ...['Option 5',
                   'Option 6',
                   'Option 7']
                 ].map<DropdownMenuItem<String>>((String doaValue) {
                   return DropdownMenuItem<String>(
                     value: doaValue,
                     child: Text(doaValue),
                   );
                 }).toList(),
               ),
            ],
          ),
        ),
      ),
    );
  }
}
  • Related