最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

flutter - How to start PopupMenuItem below the selected item that is shown? - Stack Overflow

programmeradmin2浏览0评论

I have this code:

PopupMenuButton<Guru>(
  onSelected: _onSelectGuru,
  itemBuilder: (context) => [
    ...widget.wisdomData.gurus.map(
      (guru) => PopupMenuItem<Guru>(
        value: guru,
        child: Text(
          guru.name,
          style: const TextStyle(color: Colors.white),
        ),
      ),
    ),
    const PopupMenuItem<Guru>(
      value: null,
      child: Text(
        'Random',
        style: TextStyle(color: Colors.white),
      ),
    ),
  ],
  position: PopupMenuPosition.under,
  color: Colors.transparent,
  elevation: 0,
  child: Container(
    decoration: const BoxDecoration(color: Colors.transparent),
    padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
    child: Row(
      mainAxisSize: MainAxisSize.min,
      children: [
        Text(
          selectedGuru.name,
          style: const TextStyle(color: Colors.white),
        ),
        const Icon(
          Icons.arrow_drop_down,
          color: Colors.white,
        ),
      ],
    ),
  ),
)

The issue is that if the number of PopupMenuItem's is small (e.g., 2 to 7–9), it starts from the correct position. However, when the number of items is large (more than 10), it starts from the top of the screen instead of below the selected item. How can I ensure that it always starts below the selected item and scrolls to display all the items?

I have this code:

PopupMenuButton<Guru>(
  onSelected: _onSelectGuru,
  itemBuilder: (context) => [
    ...widget.wisdomData.gurus.map(
      (guru) => PopupMenuItem<Guru>(
        value: guru,
        child: Text(
          guru.name,
          style: const TextStyle(color: Colors.white),
        ),
      ),
    ),
    const PopupMenuItem<Guru>(
      value: null,
      child: Text(
        'Random',
        style: TextStyle(color: Colors.white),
      ),
    ),
  ],
  position: PopupMenuPosition.under,
  color: Colors.transparent,
  elevation: 0,
  child: Container(
    decoration: const BoxDecoration(color: Colors.transparent),
    padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
    child: Row(
      mainAxisSize: MainAxisSize.min,
      children: [
        Text(
          selectedGuru.name,
          style: const TextStyle(color: Colors.white),
        ),
        const Icon(
          Icons.arrow_drop_down,
          color: Colors.white,
        ),
      ],
    ),
  ),
)

The issue is that if the number of PopupMenuItem's is small (e.g., 2 to 7–9), it starts from the correct position. However, when the number of items is large (more than 10), it starts from the top of the screen instead of below the selected item. How can I ensure that it always starts below the selected item and scrolls to display all the items?

Share Improve this question edited Mar 19 at 20:53 President James K. Polk 42.1k29 gold badges109 silver badges145 bronze badges asked Mar 17 at 8:39 Sahil SinghSahil Singh 2411 gold badge6 silver badges18 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 1

Use the constraints property inside SingleChildScrollView to limit the height of the menu so it does not expand beyond a certain size.

PopupMenuButton<Guru>(
  onSelected: _onSelectGuru,
  itemBuilder: (context) => [
    
    PopupMenuItem(
      enabled: false, 
      child: ConstrainedBox(
        constraints: BoxConstraints(
          maxHeight: 300, // Adjust height as needed
        ),
        child: SingleChildScrollView(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              ...widget.wisdomData.gurus.map(
                (guru) => PopupMenuItem<Guru>(
                  value: guru,
                  child: Text(guru.name, style: const TextStyle(color: Colors.white)),
                ),
              ),
              const PopupMenuItem<Guru>(
                value: null,
                child: Text('Random', style: TextStyle(color: Colors.white)),
              ),
            ],
          ),
        ),
      ),
    ),
  ],
  position: PopupMenuPosition.under,
  color: Colors.black, 
  elevation: 4, 
  child: Container(
    decoration: const BoxDecoration(
      color: Colors.transparent,
    ),
    padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
    child: Row(
      mainAxisSize: MainAxisSize.min,
      children: [
        Text(selectedGuru.name, style: const TextStyle(color: Colors.white)),
        const Icon(Icons.arrow_drop_down, color: Colors.white),
      ],
    ),
  ),
)

To make the PopupMenuButton in your code always start below the selected item and scroll when there are many items, add the constraints property to limit its height

PopupMenuButton<Guru>(
  onSelected: _onSelectGuru,
  itemBuilder: (context) => [
    ...widget.wisdomData.gurus.map(
      (guru) => PopupMenuItem<Guru>(
        value: guru,
        child: Text(guru.name, style: const TextStyle(color: Colors.white)),
      ),
    ),
    const PopupMenuItem<Guru>(
      value: null,
      child: Text('Random', style: TextStyle(color: Colors.white)),
    ),
  ],
  position: PopupMenuPosition.under,
  constraints: BoxConstraints(maxHeight: 300), // Adjust height as needed
  color: Colors.transparent,
  elevation: 0,
  child: Container(
    decoration: const BoxDecoration(color: Colors.transparent),
    padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
    child: Row(
      mainAxisSize: MainAxisSize.min,
      children: [
        Text(selectedGuru.name, style: const TextStyle(color: Colors.white)),
        const Icon(Icons.arrow_drop_down, color: Colors.white),
      ],
    ),
  ),
),

This ensures the menu stays below the selected item and scrolls if the item count exceeds the specified maxHeight.

发布评论

评论列表(0)

  1. 暂无评论