dennbagas
dennbagas

Reputation: 2993

How to change background color of PopupMenuItem in Flutter

How to change the background color of PopupMenuItem in flutter?

Right now I just change the color of the child of PopupMenuItem, and the result is this:

image

Here is the code:

PopupMenuButton<int>(
        onSelected: (value) {
          // TODO: Implement onSelect
        },
        offset: Offset(50, 50),
        itemBuilder: (context) => [
          PopupMenuItem(
            value: 1,
            child: Container(
              height: double.infinity,
              width: double.infinity,
              color: Colors.greenAccent,  // i use this to change the bgColor color right now
              child: Row(
                mainAxisAlignment: MainAxisAlignment.end,
                children: <Widget>[
                  Icon(Icons.check),
                  SizedBox(width: 10.0),
                  Text("Konfirmasi Update"),
                  SizedBox(width: 10.0),
                ],
              ),
            ),
          ),

What I want is to change the background color of the "Konfirmasi Update" option, as you can see on the picture above the color is leaving white area outside the option.

How to fully change the PopupMenuItem background color, without leaving the white area on the outside of the PopupMenuItem?

Upvotes: 9

Views: 13342

Answers (6)

Sina Najdi Hejazi
Sina Najdi Hejazi

Reputation: 11

You must wrap your widget with Theme and change "highlightColor" to color you want:

Center(
        child: Theme(
            data: Theme.of(context).copyWith(
              highlightColor: Colors.greenAccent, // <--------- here
            ),
            child: PopupMenuButton<int>(
                onSelected: (value) {
                },
                offset: Offset(50, 50),
                itemBuilder: (context) => [
                  PopupMenuItem(
                    value: 1,
                    child: Container(
                      height: double.infinity,
                      width: double.infinity,
                      color: Colors.greenAccent,  // i use this to change the bgColor color right now
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.end,
                        children: <Widget>[
                          Icon(Icons.check),
                          SizedBox(width: 10.0),
                          Text("Konfirmasi Update"),
                          SizedBox(width: 10.0),
                        ],
                      ),
                    ),
                  )
                ]
            )
        )
    )

Upvotes: 1

Adam Smaka
Adam Smaka

Reputation: 6403

For Flutter 3.7 i have modified @erli proposition to such version:

class CustomPopupMenuItem<T> extends PopupMenuItem<T> {
  const CustomPopupMenuItem({
    super.key,
    super.value,
    super.onTap,
    super.height,
    super.enabled,
    super.child,
    this.color,
  });
  final Color? color;

  @override
  CustomPopupMenuItemState<T> createState() => CustomPopupMenuItemState<T>();
}

class CustomPopupMenuItemState<T>
    extends PopupMenuItemState<T, CustomPopupMenuItem<T>> {
  @override
  Widget build(BuildContext context) {
    return Material(
      color: widget.color,
      child: super.build(context),
    );
  }
}

Upvotes: 0

PasPro
PasPro

Reputation: 75

It is very easy to change the color of the whole menu or just its children.

Use the regular color expression. color: Colors.red or whatever color you like.

You can use it in PopupMenuButton() or in PopupMenuItem().

Upvotes: -2

Erli
Erli

Reputation: 518

Another alternative is inheriting from PopupMenuItem.

To use only change the PopupMenuButton for CustomPopupMenuItem and set the color.

import 'package:flutter/material.dart';

class CustomPopupMenuItem<T> extends PopupMenuItem<T> {
  final Color color;

  const CustomPopupMenuItem({
    Key key,
    T value,
    bool enabled = true,
    Widget child,
    this.color,
  }) : super(key: key, value: value, enabled: enabled, child: child);

  @override
  _CustomPopupMenuItemState<T> createState() => _CustomPopupMenuItemState<T>();
}

class _CustomPopupMenuItemState<T> extends PopupMenuItemState<T, CustomPopupMenuItem<T>> {
  @override
  Widget build(BuildContext context) {
    return Container(
      child: super.build(context),
      color: widget.color,
    );
  }
}

Upvotes: 16

diegoveloper
diegoveloper

Reputation: 103541

There is no way using PopupMenuButton and PopupMenuItem widget out of the box, because if you check the source code, there are hardcode values for vertical and horizontal padding.

I modified the code of the popup_menu.dart file, specifically these values:

const double _kMenuVerticalPadding = 0.0;//8.0;
const double _kMenuHorizontalPadding = 0.0;//16.0;

If you want to make it work, download this file to your project: https://gist.github.com/diegoveloper/995f1e03ef225edc64e06525dc024b01

import that file in your project and add an alias :

import 'your_project/my_popup_menu.dart' as mypopup;

Usage:

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: mypopup.PopupMenuButton<int>(
          elevation: 20,
          onSelected: (value) {
            // TODO: Implement onSelect
          },
          offset: Offset(50, 50),
          itemBuilder: (context) => [
            mypopup.PopupMenuItem(
              value: 1,
              child: Container(
                height: double.infinity,
                width: double.infinity,
                color: Colors
                    .greenAccent, // i use this to change the bgColor color right now
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.end,
                  children: <Widget>[
                    Icon(Icons.check),
                    SizedBox(width: 10.0),
                    Text("Konfirmasi Update"),
                    SizedBox(width: 10.0),
                  ],
                ),
              ),
            ),
            mypopup.PopupMenuItem(
              value: 1,
              child: Container(
                height: double.infinity,
                width: double.infinity,
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.end,
                  children: <Widget>[
                    Icon(Icons.check),
                    SizedBox(width: 10.0),
                    Text("Revisi Update"),
                    SizedBox(width: 10.0),
                  ],
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }

Result

enter image description here

Upvotes: 5

Luis Miguel Mantilla
Luis Miguel Mantilla

Reputation: 1748

You can put the PopupMenuButton inside a Theme, in your Theme you have to update the cardColor for the background color that you want, as you see below:

Center(
        child: Theme(
            data: Theme.of(context).copyWith(
              cardColor: Colors.greenAccent,
            ),
            child: PopupMenuButton<int>(
                onSelected: (value) {
                },
                offset: Offset(50, 50),
                itemBuilder: (context) => [
                  PopupMenuItem(
                    value: 1,
                    child: Container(
                      height: double.infinity,
                      width: double.infinity,
                      color: Colors.greenAccent,  // i use this to change the bgColor color right now
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.end,
                        children: <Widget>[
                          Icon(Icons.check),
                          SizedBox(width: 10.0),
                          Text("Konfirmasi Update"),
                          SizedBox(width: 10.0),
                        ],
                      ),
                    ),
                  )
                ]
            )
        )
    )

Upvotes: 4

Related Questions