import 'dart:async'; import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:shared_preferences/shared_preferences.dart'; import '../../beans/search_bean.dart'; import 'my_home_model.dart'; class SearchPage extends StatefulWidget { const SearchPage({super.key}); @override State createState() => _SearchPageState(); } class _SearchPageState extends State { final TextEditingController _searchController = TextEditingController(); bool isContent = true; late StreamSubscription subscription; final MyHomeModel _viewModel = MyHomeModel(); List searchList = []; List searchHistoryList = []; List gameHotSearch = []; @override void initState() { // TODO: implement initState super.initState(); subscription = _viewModel.streamController.stream.listen((event) { String code = event['code']; if (code.isNotEmpty) { switch (code) { case "gameSearch": searchList = event['data']; if (searchList.isEmpty) { EasyLoading.showToast("未搜索到相关游戏"); } break; case "gameHotSearch": gameHotSearch = event['data']; print("gameHotSearch == $gameHotSearch"); break; } setState(() {}); } }); loadData(); } loadData() async { searchHistoryList = await readArrayFromSharedPrefs(); _viewModel.gameHotSearch(); setState(() {}); } @override void dispose() { // TODO: implement dispose subscription.cancel(); super.dispose(); } void _searchChanged(String str) { if (str != "") { isContent = false; } else { isContent = true; } setState(() {}); } // 保存数组到SharedPreferences Future saveArrayToSharedPrefs(List array) async { final prefs = await SharedPreferences.getInstance(); // 将数组转换为字符串列表,并使用逗号分隔 final String arrayString = array.join(','); prefs.setString('searchList', arrayString); } // 从SharedPreferences读取数组 Future> readArrayFromSharedPrefs() async { final prefs = await SharedPreferences.getInstance(); final String arrayString = prefs.getString('searchList') ?? ''; // 将字符串列表转换回数组 return arrayString.split(','); } @override Widget build(BuildContext context) { final size = MediaQuery.of(context).size; return Scaffold( backgroundColor: Color(0xFF17181A), body: Column( children: [ Container( margin: EdgeInsets.only(top: MediaQuery.of(context).padding.top + 10), child: Row( children: [ GestureDetector( onTap: () { Navigator.pop(context); }, child: Container( margin: EdgeInsets.symmetric(horizontal: 15), child: Image( width: 19, height: 26, image: AssetImage('assets/images/btn_fanhui.png'), ), ), ), Expanded( child: Container( height: 36, decoration: BoxDecoration( color: Color(0xFF202530), borderRadius: BorderRadius.all(Radius.circular(19)), ), child: Row( children: [ Container( padding: EdgeInsets.only(left: 10), child: Image(width: 16, height: 16, image: AssetImage('assets/images/ic_search.png')), ), Expanded( child: Container( alignment: Alignment.center, padding: EdgeInsets.only(left: 10, right: 10, bottom: 5), child: TextField( controller: _searchController, style: TextStyle(fontSize: 13, color: Colors.white), decoration: InputDecoration( border: InputBorder.none, ), onChanged: _searchChanged, onSubmitted: (value) { print("object"); }, ), ), ), ///清空输入内 !isContent ? GestureDetector( onTap: () { setState(() { _searchController.text = ""; searchList.clear(); isContent = true; }); }, child: Container( padding: EdgeInsets.only(right: 10), child: Image( width: 16, height: 16, image: AssetImage('assets/images/ic_clear.png'), ), ), ) : Container(), ], ), )), GestureDetector( onTap: () { if (_searchController.text == "") { EasyLoading.showToast("请输入内容"); return; } searchHistoryList.add(_searchController.text); saveArrayToSharedPrefs(searchHistoryList); //搜索 _viewModel.gameSearch(_searchController.text); setState(() {}); }, child: Container( margin: EdgeInsets.symmetric(horizontal: 15), child: Text( "搜索", style: TextStyle(fontSize: 13, color: Color(0xFF626262)), ), ), ) ], ), ), ///搜索历史 searchList.isEmpty ? Container( margin: EdgeInsets.only(left: 14, right: 14, top: 36), child: Column( children: [ Container( child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( "历史搜索", style: TextStyle(fontSize: 16, color: Color(0xFFD6D6D7)), ), GestureDetector( onTap: () { searchHistoryList.clear(); saveArrayToSharedPrefs(searchHistoryList); setState(() {}); }, child: Image( width: 14, height: 14, image: AssetImage('assets/images/ic_del.png'), ), ), ], ), ), ///搜索历史列表 Container( width: size.width, margin: EdgeInsets.only(top: 18), child: Wrap( children: List.generate( searchHistoryList.length, (index) => GestureDetector( onTap: () { //搜索 _viewModel.gameSearch(searchHistoryList[index]); _searchController.text = searchHistoryList[index]; isContent = false; }, child: Container( padding: EdgeInsets.symmetric(horizontal: 13, vertical: 4), margin: EdgeInsets.only(right: 10), decoration: BoxDecoration( color: Color(0xFF202530), borderRadius: BorderRadius.all(Radius.circular(4)), ), child: Text( searchHistoryList[index], style: TextStyle(fontSize: 13, color: Color(0xFFB6B6B6)), ), ), )), ), ), Container( alignment: Alignment.centerLeft, margin: EdgeInsets.only(top: 36), child: Text( "热门搜索", style: TextStyle(fontSize: 16, color: Color(0xFFD6D6D7)), ), ), Container( margin: EdgeInsets.only(top: 18), child: Wrap( children: List.generate( gameHotSearch.length, (index) => Container( width: 155, margin: EdgeInsets.only(right: 10, top: 10), child: Text( "${gameHotSearch[index]}", overflow: TextOverflow.ellipsis, style: TextStyle(fontSize: 14, color: Color(0xFF939394)), ), ), ), ), ) ], ), ) : Expanded( child: Container( margin: EdgeInsets.only(left: 14, right: 14, top: 36), child: ListView.builder( padding: EdgeInsets.zero, itemCount: searchList.length, itemBuilder: (context, index) { return _searchItem(searchList[index]); }), )), ], ), ); } _searchItem(SearchBean data) { return Container( margin: EdgeInsets.only(top: 18), child: Row( children: [ CachedNetworkImage( width: 57, height: 57, imageUrl: '${data.gameIconImage}', errorWidget: (context, url, error) => const Icon(Icons.error), ), Container( margin: EdgeInsets.only(left: 11), child: Text( "${data.gameName}", style: TextStyle(fontSize: 14, color: Color(0xFFD6D6D7)), ), ), ], ), ); } }