skip to Main Content

I use the following function to check and display the content either in Dialog or Bottom Sheet, but when executing it does not work properly, as it displays both together, what is the reason and how can the problem be solved?

Content function:


content(BuildContext context, dynamic dialog, dynamic bottomSheet) {
  (MediaQuery.of(context).orientation == Orientation.landscape) ? dialog : bottomSheet;
}

Implementation:

ElevatedButton(
    child: Text('Button'),
    onPressed: () {
        content(context, dialog(context), bottomSheet(context));
    }, 
),

How can this be solved?

4

Answers


  1. The reason the function is not working properly is because you’re not actually showing the dialog or bottom sheet. To show the dialog or bottom sheet, you need to call showDialog or showModalBottomSheet, respectively, and pass them the result of calling dialog or bottomSheet.

    try this

    void revealContent(BuildContext context, Widget dialog, Widget bottomSheet) {
      (MediaQuery.of(context).orientation == Orientation.landscape)
          ? showDialog(context: context, builder: (context) => dialog)
          : showModalBottomSheet(context: context, builder: (context) => bottomSheet);
    
    }
    Login or Signup to reply.
  2. In order to determine the Orientation of the screen, we can use the OrientationBuilder Widget. The OrientationBuilder will determine the current Orientation and rebuild when the Orientation changes.

     void main() async {
      runApp(const Home(
      ));
    }
    
    class Home extends StatefulWidget {
      const Home({Key key}) : super(key: key);
    
      @override
      State<Home> createState() => _HomeState();
    }
    
    class _HomeState extends State<Home> {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(home:  Scaffold(
          body: Center(
            child:  OrientationBuilder(
              builder: (context, orientation) {
                return ElevatedButton(
                  child: Text('Button'),
                  onPressed: () {
                    revealContent(orientation,context);
                  },
                );
              },
            )
          ),
        ));
      }
      revealContent(Orientation orientation, BuildContext context) {
         orientation == Orientation.landscape ? dialog(context) : bottomSheet(context);
      }
      dialog(BuildContext context){
        showDialog(
            context: context,
            builder: (context) => const Dialog(
              child: Padding(
                padding: EdgeInsets.all(20.0),
                child: Text('test'),
              ),
            )
        );
      }
      bottomSheet(final BuildContext context)  {
        return showModalBottomSheet(
          context: context,
          isScrollControlled: true,
          builder: (builder) => const Padding(
            padding: EdgeInsets.all(20.0),
            child: Text('test'),
          ),
        );
      }
    }
    

    here are screenshots:

    Bottom Sheet in portrait mode

    Dialog in landscape mode

    happy coding…

    Login or Signup to reply.
  3. You have a fundamental misunderstanding as to what your code is doing.

    Take your "Implementation" and revealContent code, for example:

    ElevatedButton(
        child: Text('Button'),
        onPressed: () {
            revealContent(context, dialog(context), bottomSheet(context));
        }, 
    ),
    
    revealContent(BuildContext context, dynamic dialog, dynamic bottomSheet) {
      (MediaQuery.of(context).orientation == Orientation.landscape) ? dialog : bottomSheet;
    }
    

    You think that revealContent will invoke either dialog or bottomSheet based on the orientation of the screen. What you are actually doing, however, is you are invoking both of them and then passing the result of the invocations to revealContent, which isn’t actually doing anything with them.

    What you need to be doing is passing the functions as callbacks to revealContent and then invoking the callbacks within the function:

    ElevatedButton(
        child: Text('Button'),
        onPressed: () {
            revealContent(context, () => dialog(context), () => bottomSheet(context));
        }, 
    ),
    
    revealContent(BuildContext context, void Function() dialog, void Function() bottomSheet) {
      if (MediaQuery.of(context).orientation == Orientation.landscape) {
        dialog()
      } else {
        bottomSheet();
      }
    }
    
    Login or Signup to reply.
  4. You should be calling showDialog and showModalBottomSheet inside revealContent.

    Dialog

    dialog(BuildContext context){
     return Dialog( //.. );
    }
    

    BottomSheet

    bottomSheet(final BuildContext context)  {
      return Widget( /.. );
    }
    

    Reveal Content

    void revealContent(BuildContext context, Widget dialog, Widget bottomSheet) {
      if (MediaQuery.of(context).orientation == Orientation.landscape) {
          return showDialog(context: context, builder: (context) => dialog);
      } else {
          return showModalBottomSheet(context: context, builder: (context) => bottomSheet);
      } 
    
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search