flutter实现一行三个筛选文本【仅静态】

点击出现对应的option,一行展示四个标签

import 'package:flutter/material.dart';

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

  
  State<TemplateFilter> createState() => _TemplateFilterState();
}

class _TemplateFilterState extends State<TemplateFilter> {
  
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 28.0, vertical: 6.0),
      child: const Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: [
          FilterOption(title: '排序规则', options: ['最新', '最热', '最新', '最热']),
          FilterOption(title: '主题风格', options: ['全网爆款', '男', '女', '大片', '是', '职场', '最美证件照']),
          FilterOption(title: '是否可用', options: ['免费', '收费']),
        ],
      ),
    );
  }
}

class FilterOption extends StatefulWidget {
  final String title;
  final List<String> options;

  const FilterOption({Key? key, required this.title, required this.options})
      : super(key: key);

  
  State<FilterOption> createState() => _FilterOptionState();
}

class _FilterOptionState extends State<FilterOption> {
  
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () => showFilterOptions(context),
      child: Row(
        children: [
          Text(widget.title, style: const TextStyle(color: Color(0xffaaaaaa))),
          const Icon(Icons.keyboard_arrow_down_sharp, color: Color(0xffaaaaaa)),
        ],
      ),
    );
  }

  void showFilterOptions(BuildContext context) {
    final RenderBox button = context.findRenderObject()! as RenderBox;
    final RenderBox overlay =
    Navigator.of(context).overlay!.context.findRenderObject()! as RenderBox;

    Offset offset = Offset(0.0, button.size.height);

    RelativeRect position = RelativeRect.fromRect(
      Rect.fromPoints(
        button.localToGlobal(offset, ancestor: overlay),
        button.localToGlobal(button.size.bottomRight(Offset.zero) + offset, ancestor: overlay),
      ),
      Offset.zero & overlay.size,
    );

    double screenWidth = MediaQuery.of(context).size.width;

    showMenu(
      color: const Color(0xff1c1c1c),
      context: context,
      position: position,
      constraints: BoxConstraints(maxWidth: screenWidth),
      items: [
        PopupMenuItem(
          child: Container(
            width: screenWidth,
            alignment: AlignmentDirectional.topStart,
            child: Wrap(
              alignment: WrapAlignment.start, // 从左侧开始排列
              spacing: 8.0, // 控制按钮之间的间距
              children: widget.options.map((option) => SizedBox(
                width: 80.0, // 固定按钮宽度
                child: TextButton(
                  onPressed: () => print('Button 1'),
                  style: TextButton.styleFrom(
                    shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(20.0),
                    ),
                    backgroundColor: const Color(0xff2c2c2c),
                  ),
                  child: Text(
                    option,
                    style: const TextStyle(color: Colors.white, fontSize: 12),
                  ),
                ),
              )).toList(),
            ),
          ),
        ),

      ],
    );
  }
}

参考:https://blog.csdn.net/gzx110304/article/details/134069921

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值