skip to Main Content

i have designed an appbar and invoked it in my home screen as follows:

return Scaffold(
      body: Container(
        color: const Color(0xFF191919),
        child: Column(
          children: [
            CustomAppBar(userEmail: userEmail),
          ],
        ),
      ),
    );

it always throw bottom overflow, here is the Appbar design:

return AppBar(
      backgroundColor: Colors.black,
      elevation: 0,
      leading: Padding(
        padding: const EdgeInsets.all(8.0),
        child: Image.asset('assets/logo.png'), // Your logo here
      ),
      title: Container(
        height: 40,
        decoration: BoxDecoration(
          color: Colors.grey[850],
          borderRadius: BorderRadius.circular(30),
        ),
        child: TextField(
          style: const TextStyle(color: Colors.white),
          decoration: InputDecoration(
            hintText: 'Search News, Teams, Players ...',
            hintStyle: const TextStyle(color: Colors.grey),
            prefixIcon: const Icon(Icons.search, color: Colors.grey),
            filled: true,
            fillColor: Colors.grey[850],
            border: OutlineInputBorder(
              borderRadius: BorderRadius.circular(30),
              borderSide: BorderSide.none,
            ),
          ),
        ),
      ),
      actions: [
        Padding(
          padding: const EdgeInsets.all(8.0),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              CircleAvatar(
                radius: 20,
                backgroundColor: Colors.grey[600],
                child: Icon(
                  Icons.person,
                  color: Colors.white,
                  size: 24,
                ),
              ),
              const SizedBox(height: 4),
              Text(
                userName, // Display the fetched user name
                style: const TextStyle(color: Colors.white, fontSize: 12),
              ),
            ],
          ),
        ),
      ],
    );

The overflow happens at the actions section exactly. i tried to add PrefferedSize() for both places my home screen and the file i designed the appbar in but nothing solved the problem. Thank you

2

Answers


  1. Actions at the trailing of the AppBar are intended to comport icons or icon buttons, not big components. Your column with CirleAvatar, SizedBox and Text was too much to the AppBar height. If you try increasing your title container, it won’t overflow, but will hide content without expanding your bar. I recommend your 3 approaches:

    1. Reducing elements size:
      appbar with reduced size actions
      I’ve also implemented your AppBar as an extended Widget, so you can use it in Scaffold(appBar: ...)
    import 'package:flutter/material.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({super.key});
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(debugShowCheckedModeBanner: false, home: Home());
      }
    }
    
    class Home extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: CustomAppBar(userEmail: "[email protected]"),
          body: Container(
              color: Colors.grey, child: Center(child: Text("Hello world!"))),
        );
      }
    }
    
    class CustomAppBar extends AppBar {
      final String userEmail;
      final imagePath =
          'https://0.gravatar.com/avatar/33252cd1f33526af53580fcb1736172f06e6716f32afdd1be19ec3096d15dea5';
    
      CustomAppBar({required this.userEmail});
    
      @override
      Color? get backgroundColor => Colors.black;
    
      @override
      Widget? get leading => Padding(
            padding: const EdgeInsets.all(8.0),
            child: Image.network(imagePath), // Your logo here
          );
    
      @override
      Widget? get title => Container(
            height: 40,
            decoration: BoxDecoration(
              color: Colors.grey[850],
              borderRadius: BorderRadius.circular(30),
            ),
            child: TextField(
              style: const TextStyle(color: Colors.white),
              decoration: InputDecoration(
                hintText: 'Search News, Teams, Players ...',
                hintStyle: const TextStyle(color: Colors.grey),
                prefixIcon: const Icon(Icons.search, color: Colors.grey),
                filled: true,
                fillColor: Colors.grey[850],
                border: OutlineInputBorder(
                  borderRadius: BorderRadius.circular(30),
                  borderSide: BorderSide.none,
                ),
              ),
            ),
          );
    
      @override
      List<Widget>? get actions => [
            Padding(
              padding: const EdgeInsets.all(8.0),
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  CircleAvatar(
                    radius: 10,
                    backgroundColor: Colors.grey[600],
                    child: Icon(
                      Icons.person,
                      color: Colors.white,
                      size: 12,
                    ),
                  ),
                  const SizedBox(height: 2),
                  Text(
                    userEmail, // Display the fetched user name
                    style: const TextStyle(color: Colors.white, fontSize: 12),
                  ),
                ],
              ),
            )
          ];
    }
    
    1. Making actions inline:
      appbar with actions inline
    @override
    List<Widget>? get actions => [
          Text(
            userEmail, // Display the fetched user name
            style: const TextStyle(color: Colors.white, fontSize: 12),
          ),
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: Column(
               mainAxisAlignment: MainAxisAlignment.center,
              children: [
                 CircleAvatar(
                  radius: 16,
                  backgroundColor: Colors.grey[600],
                  child: Icon(
                    Icons.person,
                    color: Colors.white,
                    size: 12,
                  ),
                ),
              ],
            ),
          )
        ];
    
    1. Create a fake AppBar
      Just use a full width Row at the top of a Column at the body of Scaffold.
    Login or Signup to reply.
  2. The bottom overflow occurs because the Column inside your AppBar’s actions exceeds the available vertical space. To fix this while keeping the Column, you can use the flexibleSpace property and adjust the AppBar’s height.

    Here’s how you can modify your code:

    1. Implement PreferredSizeWidget and adjust the AppBar height:
    class CustomAppBar extends StatelessWidget implements PreferredSizeWidget {
      final String userEmail;
    
      CustomAppBar({required this.userEmail});
    
      @override
      Size get preferredSize => const Size.fromHeight(kToolbarHeight * 1.5); // Adjust height as needed
    
      @override
      Widget build(BuildContext context) {
        return AppBar(
          // AppBar properties
        );
      }
    }
    
    • Explanation: By implementing PreferredSizeWidget and adjusting preferredSize, you set a custom height for the AppBar that can accommodate your content.
    1. Use flexibleSpace to customize the AppBar layout:
    @override
    Widget build(BuildContext context) {
      return AppBar(
        backgroundColor: Colors.black,
        elevation: 0,
        flexibleSpace: Padding(
          padding: const EdgeInsets.only(top: 40.0, left: 8.0, right: 8.0),
          child: Row(
            children: [
              // Leading Widget
              Image.asset('assets/logo2.png', height: 40.0),
              const SizedBox(width: 8.0),
              // Expanded Search Field
              Expanded(
                child: Container(
                  height: 40,
                  decoration: BoxDecoration(
                    color: Colors.grey[850],
                    borderRadius: BorderRadius.circular(30),
                  ),
                  child: TextField(
                    style: const TextStyle(color: Colors.white),
                    decoration: InputDecoration(
                      hintText: 'Search News, Teams, Players ...',
                      hintStyle: const TextStyle(color: Colors.grey),
                      prefixIcon: const Icon(Icons.search, color: Colors.grey),
                      filled: true,
                      fillColor: Colors.grey[850],
                      border: OutlineInputBorder(
                        borderRadius: BorderRadius.circular(30),
                        borderSide: BorderSide.none,
                      ),
                    ),
                  ),
                ),
              ),
              const SizedBox(width: 8.0),
              // Actions Widget
              Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  CircleAvatar(
                    radius: 20,
                    backgroundColor: Colors.grey[600],
                    child: Icon(
                      Icons.person,
                      color: Colors.white,
                      size: 24,
                    ),
                  ),
                  const SizedBox(height: 4),
                  Text(
                    userEmail,
                    style: const TextStyle(color: Colors.white, fontSize: 12),
                  ),
                ],
              ),
            ],
          ),
        ),
      );
    }
    
    • Explanation: By moving your content to the flexibleSpace property, you gain more control over the layout and avoid the constraints of the actions property. This allows you to include a Column without causing an overflow.

    Complete Code:

    class CustomAppBar extends StatelessWidget implements PreferredSizeWidget {
      final String userEmail;
    
      CustomAppBar({required this.userEmail});
    
      @override
      Size get preferredSize => const Size.fromHeight(kToolbarHeight * 1.5); // Adjust height as needed
    
      @override
      Widget build(BuildContext context) {
        return AppBar(
          backgroundColor: Colors.black,
          elevation: 0,
          flexibleSpace: Padding(
            padding: const EdgeInsets.only(top: 40.0, left: 8.0, right: 8.0),
            child: Row(
              children: [
                // Leading Widget
                Image.asset('assets/logo2.png', height: 40.0),
                const SizedBox(width: 8.0),
                // Expanded Search Field
                Expanded(
                  child: Container(
                    height: 40,
                    decoration: BoxDecoration(
                      color: Colors.grey[850],
                      borderRadius: BorderRadius.circular(30),
                    ),
                    child: TextField(
                      style: const TextStyle(color: Colors.white),
                      decoration: InputDecoration(
                        hintText: 'Search News, Teams, Players ...',
                        hintStyle: const TextStyle(color: Colors.grey),
                        prefixIcon: const Icon(Icons.search, color: Colors.grey),
                        filled: true,
                        fillColor: Colors.grey[850],
                        border: OutlineInputBorder(
                          borderRadius: BorderRadius.circular(30),
                          borderSide: BorderSide.none,
                        ),
                      ),
                    ),
                  ),
                ),
                const SizedBox(width: 8.0),
                // Actions Widget
                Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    CircleAvatar(
                      radius: 20,
                      backgroundColor: Colors.grey[600],
                      child: Icon(
                        Icons.person,
                        color: Colors.white,
                        size: 24,
                      ),
                    ),
                    const SizedBox(height: 4),
                    Text(
                      userEmail,
                      style: const TextStyle(color: Colors.white, fontSize: 12),
                    ),
                  ],
                ),
              ],
            ),
          ),
        );
      }
    }
    

    Usage in Scaffold:

    return Scaffold(
      appBar: CustomAppBar(userEmail: userEmail),
      body: Container(
        color: const Color(0xFF191919),
        // Your body content
      ),
    );
    

    Why This Works:

    • Custom Height: Increasing the AppBar height using preferredSize ensures all content fits without overflow.

    • flexibleSpace: Allows you to design a custom layout within the AppBar that isn’t restricted by the default height constraints.

    • Row Layout: Placing your widgets inside a Row within flexibleSpace aligns them horizontally, and you can still use a Column where needed.

    • Centering Content: Using mainAxisAlignment: MainAxisAlignment.center in the Column vertically centers your avatar and username.

    Note:

    • Adjust the multiplier in kToolbarHeight * 1.5 based on how much vertical space you need.
    • Ensure that all widgets are properly aligned and sized to fit within the new AppBar height.

    Summary:

    To fix the bottom overflow while keeping your Column, move your content to the flexibleSpace property of the AppBar and adjust its height using PreferredSizeWidget. This approach provides more flexibility and resolves the overflow issue.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search