Flutter:商品搜索,本地存值,取值,更新

发布于:2025-02-11 ⋅ 阅读:(24) ⋅ 点赞:(0)

view

import 'package:demo/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 SearchKeywordPage extends GetView<SearchKeywordController> {
  const SearchKeywordPage({super.key});

  // 搜索
  Widget _buildSearch() {
    return <Widget>[
      TDImage(
        assetUrl: 'assets/img/search.png',
        width: 32.w,
        height: 32.w,
      ),
      SizedBox(
        width: 20.w,
      ),
      Container(
        width: 1.w,
        height: 28.w,
        color: const Color(0xffe9e9e9),
      ),
      SizedBox(
        width: 20.w,
      ),

      /// 输入框
      TDInput(
        leftLabel: '',
        leftLabelSpace: 0,
        textStyle: TextStyle(fontSize: 28.sp, color: const Color(0xff181818)),
        hintText: '搜索心仪的商品',
        hintTextStyle:
            TextStyle(fontSize: 28.sp, color: const Color(0xff181818)),
        backgroundColor: Colors.white,
        showBottomDivider: false,
        controller: controller.searchKeyController,
        inputType: TextInputType.text,
        contentPadding: EdgeInsets.only(top: 12.w),
        onChanged: (value) {
          controller.changeSearchKey(value);
        },
        onClearTap: () {
          controller.searchKeyController.text = '';
          controller.changeSearchKey('');
        },
        onSubmitted: (value) {
          if (value.isNotEmpty) {
            controller.onTapSearch(value);
          }
        },
      ).expanded(),
    ]
        .toRow()
        .paddingHorizontal(30.w)
        .card(
            color: Colors.white,
            shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(35.w)))
        .tight(width: 690.w, height: 70.w)
        .marginOnly(top: 30.w, right: 0);
  }

  // 搜索历史标题
  Widget _buildSearchHistoryTitle(BuildContext context) {
    return <Widget>[
      const TextWidget.body('搜索历史', color: Color(0xff999999)),
      TDImage(
        assetUrl: 'assets/img/del.png',
        width: 30.w,
        height: 30.w,
      ).onTap(() {
        showGeneralDialog(
          context: context,
          pageBuilder: (BuildContext buildContext, Animation<double> animation,
              Animation<double> secondaryAnimation) {
            return TDAlertDialog(
              title: '清空搜索历史',
              content: '请确定清空搜索历史?',
              buttonWidget: <Widget>[
                <Widget>[const TextWidget.body('取消')]
                    .toRow(mainAxisAlignment: MainAxisAlignment.center)
                    .card(color: const Color(0xffeeeeee))
                    .tight(width: 240.w, height: 80.w)
                    .onTap(() => Navigator.of(context).pop()),
                <Widget>[
                  const TextWidget.body(
                    '确定',
                    color: Colors.white,
                  )
                ]
                    .toRow(mainAxisAlignment: MainAxisAlignment.center)
                    .card(color: const Color(0xffE93323))
                    .tight(width: 240.w, height: 80.w)
                    .onTap(() {
                  controller.clearSearchHistory();
                  Navigator.of(context).pop();
                }),
              ]
                  .toRow(mainAxisAlignment: MainAxisAlignment.spaceBetween)
                  .paddingOnly(left: 30.w, right: 30.w, bottom: 40.w),
            );
          },
        );
      })
    ]
        .toRow(mainAxisAlignment: MainAxisAlignment.spaceBetween)
        .marginOnly(top: 30.w, bottom: 20.w);
  }

  // 搜索历史
  Widget _buildSearchHistory() {
    return SizedBox(
        // 添加一个固定宽度的容器
        width: double.infinity, // 让Wrap占满父容器宽度
        child: <Widget>[
          for (var i = 0; i < controller.searchHistory.length; i++)
            IntrinsicWidth(
              child: <Widget>[
                TextWidget.body(controller.searchHistory[i],
                    size: 26.sp, color: const Color(0xff666666)),
              ].toRow().paddingHorizontal(30.w).card().onTap(() {
                controller.onTapSearchValue(controller.searchHistory[i]);
              }),
            ),
        ].toWrap(
          spacing: 15.w, // 添加水平间距
          runSpacing: 15.w,
          alignment: WrapAlignment.start, // 添加左对齐
          crossAxisAlignment: WrapCrossAlignment.start,
        ));
  }

  // 主视图
  Widget _buildView(BuildContext context) {
    return <Widget>[
      _buildSearch(),
      _buildSearchHistoryTitle(context),
      const Divider(
        height: 1,
        color: Color(0xff666666),
      ),
      SizedBox(
        height: 30.w,
      ),
      _buildSearchHistory(),
    ].toColumn().paddingHorizontal(30.w);
  }

  @override
  Widget build(BuildContext context) {
    return GetBuilder<SearchKeywordController>(
      init: SearchKeywordController(),
      id: "search_keyword",
      builder: (_) {
        return Scaffold(
          backgroundColor: const Color(0xffF5F6FA),
          appBar: const TDNavBar(
            height: 45,
            title: '搜索',
            titleFontWeight: FontWeight.w600,
            backgroundColor: Colors.white,
            screenAdaptation: true,
            useDefaultBack: true,
          ),
          body: SafeArea(
            child: _buildView(context),
          ),
        );
      },
    );
  }
}

controller

import 'package:demo/common/index.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';

class SearchKeywordController extends GetxController {
  SearchKeywordController();

  // 搜索控制器
  final searchKeyController = TextEditingController();
  // 搜索关键词
  String searchKey = '';
  // 搜索历史
  List<String> searchHistory = [];

  // 点击搜索时
  void onTapSearch(String value) {
    // 查找是否存在该搜索词
    final index = searchHistory.indexOf(value);
    // 如果已存在,删除旧值
    if (index != -1) {
      searchHistory.removeAt(index);
    }
    // 将新搜索词添加到数组开头
    searchHistory.insert(0, value);
    // 限制历史记录条数
    if (searchHistory.length > 20) {
      searchHistory = searchHistory.sublist(0, 20);
    }
    // 保存更新后的搜索历史
    Storage().setList('search_history', searchHistory);
    searchKeyController.text = '';
    // 使用 Get.toNamed 的返回回调来刷新数据
    Get.toNamed('/search_list_page', arguments: {'searchKey': value})?.then((_) {
      _initData(); // 返回时重新加载数据
    });
  }

  // 点击搜索值跳转搜索列表
  void onTapSearchValue(String value) {
    Get.toNamed('/search_list_page', arguments: {'searchKey': value})?.then((_) {
      _initData(); // 返回时重新加载数据
    });
  }

  // 清空搜索历史
  void clearSearchHistory() {
    searchHistory = [];
    Storage().setList('search_history', searchHistory);
    update(["search_keyword"]);
  }

  // 输入框内容发生改变
  void changeSearchKey(String value) {
    searchKey = value;
    update(["search_keyword"]);
  }

  // 初始化数据
  void _initData() {
    searchHistory = Storage().getList('search_history');
    update(["search_keyword"]);
  }


  @override
  void onReady() {
    super.onReady();
    _initData();
  }

  @override
  void onClose() {
    super.onClose();
    searchKeyController.dispose();
  }
}

在这里插入图片描述
在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到