панель поиска флаттера с блоком c с пожарным депо - PullRequest
0 голосов
/ 11 апреля 2020

Я выполняю поиск в панели приложений. Я ищу данные по названию (подстроке) и возвращаю элементы. У меня есть Ui, blo c, классы обслуживания. Я не знаю, как передать '$ searchQuery' в приемник blo c. Я возвращаю список потоков (в пользовательском интерфейсе), но сначала мне нужно отфильтровать мой список по заголовку (элементу) и поместить в сток. Не могли бы вы дать мне несколько советов или примеров? Должен ли я исправить свой класс blo c?

class Search extends StatefulWidget {
  @override
  _Search createState() => _Search();
}

class _Search extends State<Search> {

  static final GlobalKey<ScaffoldState> scaffoldKey =
      new GlobalKey<ScaffoldState>();
  TextEditingController _searchQuery;
  bool _isSearching = false;
  String searchQuery = "Search query";

  @override
  void initState() {
    super.initState();
    _searchQuery = new TextEditingController();
  }

  void _startSearch() {
    print("open search box");
    ModalRoute.of(context)
        .addLocalHistoryEntry(new LocalHistoryEntry(onRemove: _stopSearching));

    setState(() {
      _isSearching = true;
    });
  }

  void _stopSearching() {
    _clearSearchQuery();

    setState(() {
      _isSearching = false;
    });
  }

  void _clearSearchQuery() {
    print("close search box");
    setState(() {
      _searchQuery.clear();
      updateSearchQuery("Search query");
    });
  }

  Widget _buildTitle(BuildContext context) {
    var horizontalTitleAlignment =
        Platform.isIOS ? CrossAxisAlignment.center : CrossAxisAlignment.start;

    return new InkWell(
      onTap: () => scaffoldKey.currentState.openDrawer(),
      child: new Padding(
        padding: const EdgeInsets.symmetric(horizontal: 12.0),
        child: new Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: horizontalTitleAlignment,
          children: <Widget>[
            const Text('Seach box'),
          ],
        ),
      ),
    );
  }

  Widget _buildSearchField() {
    return new TextField(
      controller: _searchQuery,
      autofocus: true,
      decoration: const InputDecoration(
        hintText: 'Search...',
        border: InputBorder.none,
        hintStyle: const TextStyle(color: Colors.white30),
      ),
      style: const TextStyle(color: Colors.white, fontSize: 16.0),
      onChanged: updateSearchQuery,
    );
  }

  void updateSearchQuery(String newQuery) {
    setState(() {
      searchQuery = newQuery;
    });
    print("search query " + newQuery);
  }

  List<Widget> _buildActions() {
    if (_isSearching) {
      return <Widget>[
        new IconButton(
          icon: const Icon(Icons.clear),
          onPressed: () {
            if (_searchQuery == null || _searchQuery.text.isEmpty) {
              Navigator.pop(context);
              return;
            }
            _clearSearchQuery();
          },
        ),
      ];
    }

    return <Widget>[
      new IconButton(
        icon: const Icon(Icons.search),
        onPressed: _startSearch,
      ),
    ];
  }

  @override
  Widget build(BuildContext context) {
    return SafeArea(
        child: Scaffold(
      key: scaffoldKey,
      appBar: new AppBar(
        leading: _isSearching ? const BackButton() : null,
        title: _isSearching ? _buildSearchField() : _buildTitle(context),
        actions: _buildActions(),
      ),
      body: new Center(
        child: new Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            new Text(
              '$searchQuery',
              style: Theme.of(context).textTheme.display1,
            )
          ],
        ),
      ),
    ));
  }
}

class MovieService {
  static final String _baseUrl = 'xxxx';

  final CollectionReference _db;

  MovieService() : _db = Firestore.instance.collection(_baseUrl);

  Future<List<MovieEntity>> searchByString(String stringSearch) async {
    final CollectionReference _dbs = Firestore.instance.collection(_baseUrl);
    QuerySnapshot query =
    await _dbs.where("Title", isEqualTo: stringSearch.substring(0, 1).toUpperCase()).getDocuments();
    List<MovieEntity> products = query.documents
        .map((doc) => MovieEntity.fromSnapshotJson(doc))
        .toList();
    return products;
  }
}


class MovieBloc extends BlocBase {

  String nameFilmSearchQuery;
  final MovieService _productService;

  MovieBloc(this._productService) {
    _loadMovies();
  }

  final BehaviorSubject<List<MovieEntity>> _controllerSearch =
      new BehaviorSubject<List<MovieEntity>>.seeded(List<MovieEntity>());

  Observable<List<MovieEntity>> get listMoviesFluxSearch =>
      _controllerSearch.stream;

  Sink<List<MovieEntity>> get listMoviesEventSearch => _controllerSearch.sink;

  _loadMovies() async {
    listMoviesEventSearch.add(await _productService.searchByString(nameFilmSearchQuery));// i should pass '$searchQuery' here from Ui
  }

  @override
  void dispose() {
    _controllerSearch.close();
    super.dispose();
  }
}
...