You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Stream Builder结合按钮实现Firebase数据排序与筛选

Flutter实现Firebase房源价格与位置筛选功能

修复现有问题并实现完整筛选逻辑

以下是修改后的完整代码,解决了原代码的数据流返回、UI刷新问题,并添加了价格范围和位置筛选的完整功能:

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:realstate/home%20page/addingpage.dart';
import '../account page/account page.dart';

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

  @override
  State<Home> createState() => _HomeState();
}

class _HomeState extends State<Home> {
  // 筛选状态变量
  double? _minPrice;
  double? _maxPrice;
  String? _selectedLocation;
  bool _isFilterActive = false;

  // Firestore集合引用
  final CollectionReference _database = FirebaseFirestore.instance.collection('Detabase');

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        backgroundColor: Colors.white,
        appBar: AppBar(
          centerTitle: true,
          title: const Text(
            "Home",
            style: TextStyle(
              color: Colors.black,
              fontFamily: 'Montserrat',
              fontWeight: FontWeight.bold,
              fontSize: 32,
            ),
          ),
          leading: IconButton(
            icon: const Icon(Icons.add_business_sharp, color: Colors.black, size: 26),
            onPressed: () => Navigator.of(context).push(MaterialPageRoute(builder: (context) => const Addingpage())),
          ),
          backgroundColor: Colors.white,
          actions: [
            IconButton(
              onPressed: () => Navigator.of(context).push(MaterialPageRoute(builder: (context) => const AccountPage())),
              icon: const Icon(Icons.account_circle, color: Colors.black),
              highlightColor: Colors.transparent,
              focusColor: Colors.transparent,
              hoverColor: Colors.transparent,
              splashColor: Colors.transparent,
            )
          ],
        ),
        body: SingleChildScrollView(
          padding: const EdgeInsets.all(16),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              // 筛选栏
              _buildFilterBar(),
              const SizedBox(height: 20),
              // 房源列表
              _buildPropertyList(),
            ],
          ),
        ),
      ),
    );
  }

  // 构建筛选栏UI
  Widget _buildFilterBar() {
    return Column(
      children: [
        Row(
          children: [
            Expanded(
              child: TextField(
                keyboardType: TextInputType.number,
                decoration: const InputDecoration(labelText: "最低价格"),
                onChanged: (value) => setState(() => _minPrice = double.tryParse(value)),
              ),
            ),
            const SizedBox(width: 10),
            Expanded(
              child: TextField(
                keyboardType: TextInputType.number,
                decoration: const InputDecoration(labelText: "最高价格"),
                onChanged: (value) => setState(() => _maxPrice = double.tryParse(value)),
              ),
            ),
          ],
        ),
        const SizedBox(height: 10),
        TextField(
          decoration: const InputDecoration(labelText: "位置"),
          onChanged: (value) => setState(() => _selectedLocation = value.trim()),
        ),
        const SizedBox(height: 10),
        Row(
          mainAxisAlignment: MainAxisAlignment.end,
          children: [
            TextButton(
              onPressed: () {
                setState(() {
                  _minPrice = null;
                  _maxPrice = null;
                  _selectedLocation = null;
                  _isFilterActive = false;
                });
              },
              child: const Text("重置筛选"),
            ),
            ElevatedButton(
              onPressed: () => setState(() => _isFilterActive = true),
              child: const Text("应用筛选"),
            ),
          ],
        ),
      ],
    );
  }

  // 构建房源列表
  Widget _buildPropertyList() {
    return SizedBox(
      height: MediaQuery.of(context).size.height - 300, // 固定高度避免滚动冲突
      child: StreamBuilder<QuerySnapshot>(
        stream: _getFilteredStream(),
        builder: (context, snapshot) {
          if (snapshot.hasError) return const Text('加载出错');
          if (snapshot.connectionState == ConnectionState.waiting) return const Text("加载中...");

          return ListView.builder(
            shrinkWrap: true,
            physics: const AlwaysScrollableScrollPhysics(),
            itemCount: snapshot.data!.docs.length,
            itemBuilder: (context, index) {
              final data = snapshot.data!.docs[index].data() as Map<String, dynamic>;
              return ListTile(
                title: Text("位置: ${data['location']}"),
                subtitle: Text("租金: ${data['expectedrent']} | 详情: ${data['detals']}"),
              );
            },
          );
        },
      ),
    );
  }

  // 获取筛选后的Firestore数据流
  Stream<QuerySnapshot> _getFilteredStream() {
    Query query = _database.orderBy('expectedrent', descending: false);

    // 添加价格范围筛选
    if (_minPrice != null) query = query.where('expectedrent', isGreaterThanOrEqualTo: _minPrice);
    if (_maxPrice != null) query = query.where('expectedrent', isLessThanOrEqualTo: _maxPrice);

    // 添加位置筛选(精确匹配,若需模糊搜索需提前处理数据)
    if (_selectedLocation != null && _selectedLocation!.isNotEmpty) {
      query = query.where('location', isEqualTo: _selectedLocation);
    }

    return query.snapshots();
  }
}

关键修改说明

  1. 筛选状态管理:新增_minPrice、_maxPrice、_selectedLocation变量记录筛选条件,_isFilterActive标记筛选状态
  2. 动态查询构建:_getFilteredStream()根据当前筛选条件动态组合Firestore的where子句,支持多条件叠加
  3. 布局优化:给嵌套的ListView设置固定高度,添加shrinkWrap: true避免布局溢出,同时保留滚动功能
  4. 交互逻辑:筛选栏输入实时更新状态,点击"应用筛选"触发数据流刷新,"重置筛选"清空所有条件

注意事项

  • 若需要位置模糊搜索,需提前在Firestore文档中存储位置关键词数组,使用arrayContains或Firebase全文检索服务
  • 确保Firestore已为expectedrent和location字段创建复合索引,避免多条件查询报错

内容的提问来源于stack exchange,提问作者ISLAM IS LIFE

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 22:57:55