当前位置: 首页 > article >正文

Flutter:搜索页,搜索bar封装

在这里插入图片描述

view
使用内置的Chip简化布局

import 'package:chenyanzhenxuan/common/index.dart';
import 'package:ducafe_ui_core/ducafe_ui_core.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:tdesign_flutter/tdesign_flutter.dart';

import 'index.dart';

class SearchGoodsPage extends GetView<SearchGoodsController> {
  const SearchGoodsPage({super.key});

  // 搜索
  Widget _buildSearch() {
    return <Widget>[
      SearchWidget(
        type: 'input',
        inputBgColor: AppTheme.pageBgColor,
        controller: controller.searchController,
        onChange: (value) {
          controller.onSearchChange(value);
        },
      ),
    ].toRow()
    .paddingAll(30.w)
    .card(shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(0)));
  }

  // 热门搜索
  Widget _buildHotSearch() { 
    return <Widget>[
      <Widget>[
        TDImage(assetUrl: 'assets/img/hot.png',width: 34.w,height: 34.w,),
        SizedBox(width: 10.w,),
        TextWidget.body('热门搜索',size: 28.sp,),
      ].toRow().paddingHorizontal(30.w),

      <Widget>[
        for(var i = 0; i < 6; i++)
        Chip(
          label: TextWidget.body('热门搜索$i',size: 24.sp,color: AppTheme.color999,),
          backgroundColor: AppTheme.blockBgColor,
          shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10.w)),
        )
      ].toWrap(spacing: 20.w,runSpacing: 0,).paddingLeft(30.w),
    ].toColumn(crossAxisAlignment: CrossAxisAlignment.start);
  }

  // 历史记录
  Widget _buildHistory() {
    return <Widget>[
      <Widget>[
        TextWidget.body('历史记录',size: 28.sp,),
        TDImage(assetUrl: 'assets/img/hot-del.png',width: 28.w,height: 32.w,),
      ].toRow(mainAxisAlignment: MainAxisAlignment.spaceBetween).paddingHorizontal(30.w),


      <Widget>[
        Chip(
          label: TextWidget.body('精品专精品专区区',size: 24.sp,color: AppTheme.color999,),
          backgroundColor: AppTheme.blockBgColor,
          shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10.w)),
          deleteIconColor: AppTheme.color999,
          onDeleted: () {
            print('删除');
          },
        ),
        for(var i = 0; i < 6; i++)
        Chip(
          label: TextWidget.body('精品专区',size: 24.sp,color: AppTheme.color999,),
          backgroundColor: AppTheme.blockBgColor,
          shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10.w)),
          deleteIconColor: AppTheme.color999,
          onDeleted: () {
            print('删除');
          },
        )
      ].toWrap(spacing: 20.w,runSpacing: 0,).paddingLeft(30.w),
    ].toColumn(crossAxisAlignment: CrossAxisAlignment.start);
  }

  // 主视图
  Widget _buildView() {
    return <Widget>[
      _buildSearch(),
      SizedBox(height: 30.w,),
      _buildHotSearch(),
      SizedBox(height: 30.w,),
      _buildHistory(),
      const EmptyState()
    ].toColumn();
  }

  @override
  Widget build(BuildContext context) {
    return GetBuilder<SearchGoodsController>(
      init: SearchGoodsController(),
      id: "search_goods",
      builder: (_) {
        return Scaffold(
          backgroundColor: AppTheme.pageBgColor, // 自定义颜色
          appBar: const TDNavBar(
            height: 44,
            title: "搜索",
            titleFontWeight: FontWeight.w600,
            backgroundColor: Colors.white,
            screenAdaptation: true,
            useDefaultBack: true,
          ),
          body: SingleChildScrollView(
            child: _buildView(),
          ),
        );
      },
    );
  }
}

controller

import 'package:get/get.dart';
import 'package:flutter/material.dart';
class SearchGoodsController extends GetxController {
  SearchGoodsController();
  // 搜索框
  final searchController = TextEditingController();
  
  @override
  void onReady() {
    super.onReady();
    _initData();
  }

  @override
  void onClose() {
    super.onClose();
    searchController.dispose();
  }
  
  // 初始化数据
  _initData() {
    update(["search_goods"]);
  }

  // 搜索框发送改变
  void onSearchChange(String value) {
    print('搜索内容: $value');
    searchController.text = value;
    update(["search_goods"]);
  }
}

SearchWidget

import 'package:ducafe_ui_core/ducafe_ui_core.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:tdesign_flutter/tdesign_flutter.dart';
import 'package:chenyanzhenxuan/common/index.dart';


class SearchWidget extends StatelessWidget {
  // 类型
  final String type;
  // 搜索框控制器
  final TextEditingController? controller;
  // 输入框背景色
  final Color? inputBgColor;
  // 搜索框发送改变
  final Function(String value)? onChange;



  const SearchWidget({
    super.key,
    required this.type,
    this.controller,
    this.inputBgColor,
    this.onChange,
  });


  @override
  Widget build(BuildContext context) {
    return <Widget>[
      <Widget>[
        TDImage(
          assetUrl: type == 'text' ? 'assets/img/search.png' : 'assets/img/search.png',
          width: 32.w,
          height: 32.w,
        ),
        SizedBox(width: 20.w),
        type == 'text' ? TextWidget.body('搜索您要找的商品名称', size: 28.sp, color: AppTheme.color999) 
        : InputWidget(
          placeholder: "搜索您要找的商品名称",
          controller: controller,
        ).width(450.w),
      ].toRow(),
      <Widget>[
        TextWidget.body('搜索', size: 26.sp, color: AppTheme.colorfff),
      ].toRow(mainAxisAlignment: MainAxisAlignment.center)
      .card(color: AppTheme.error,shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(30.w)))
      .tight(width: 120.w,height: 60.w)
      .onTap(() {
        if(type == 'input' && controller?.text != null){
          onChange!(controller!.text);
        }
      }),
    ]
    .toRow(mainAxisAlignment: MainAxisAlignment.spaceBetween)
    .paddingOnly(left: 30.w,right: 4.w)
    .card(
      color: inputBgColor,
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.circular(30.w)
      )
    )
    .tight(width: 690.w, height: 68.w)
    .onTap(() {
      if(type == 'text'){
        Get.toNamed('/search_goods_page');
      }
    });
  }
}

http://www.kler.cn/a/519143.html

相关文章:

  • mysql_use_result的概念和使用案例
  • OpenCV:二值化与自适应阈值
  • Chameleon(变色龙) 跨平台编译C文件,并一次性生成多个平台的可执行文件
  • JavaScript系列(43)--依赖注入系统实现详解
  • [极客大挑战 2019]BuyFlag1
  • vue高级组件封装 element组件二次封装
  • Maui学习笔记- SQLite简单使用案例
  • 基于ESP32的桌面小屏幕实战[6]:环境搭建和软件基础
  • 一次StarRocks分析的经历
  • 第25章 测试驱动开发模式深度剖析
  • unity 粒子系统实现碰撞检测(collision)且使粒子不受力
  • tcp/ip协议和ip协议,tcp/ip协议 ip协议
  • 探索JavaScript:网页设计中的创意与实践
  • leetcode——翻转链表(java)
  • (回溯分割)leetcode93 复原IP地址
  • AI学习(vscode+deepseek+cline)
  • INMP441一款微型电容式麦克风(MEMS麦克风)
  • Zookeeper(28)Zookeeper的线性化写入和顺序一致性读是什么?
  • 代码随想录day4
  • 【论文推荐|深度学习,滑坡检测,多光谱影像,自然灾害,遥感】2022年Landslide4Sense竞赛成果:基于多源卫星影像的先进滑坡检测算法研究(一)