База данных MOOR во флаттере не переключает иконку IconButton при вставке / удалении элемента - PullRequest
0 голосов
/ 17 октября 2019

Вчера я внедрил базу данных мавров в мое приложение по флаттеру автомобиля, я следил за показом разработки скучного флаттера.

База данных работает нормально, когда я нажимаю сердце IconButton, машина будет вставлена ​​в базу данных мавра, а когда янажмите еще раз кнопку, если автомобиль находится внутри базы данных, он будет удален, также, если я закрою приложение и вновь открою элемент, он останется любимым. Основная проблема заключается в том, что когда я нажимаю значок кнопки, она остается прежней, в моем случае сердце с рамкой и не переключается в полном объеме;но это меняется только тогда, когда я прокручиваю вверх и вниз просмотр списка и перестраиваю домашнюю страницу. Я также пытался переместить .watch () после select () в запросах, но ничего не изменилось.

В ui.dart я использую streambuilder для базы данных.

большое спасибомного кто хочет мне помочь

Вот мой код:

main.dart

FirebaseUtils databaseUtils;
  PageController _pageController;
  var _page = 0;
  List<Car> carList = new List<Car>();

  Query _carQuery;

  StreamSubscription<Event> _onAddedSubscription;
  StreamSubscription<Event> _onChangedSubscription;

  @override
  void initState() {
    databaseUtils = new FirebaseUtils();
    databaseUtils.initState();
    _pageController = PageController();

    _carQuery = databaseUtils.getRef();
    _onAddedSubscription = _carQuery.onChildAdded.listen(_onEntryAdded);
    _onChangedSubscription = _carQuery.onChildChanged.listen(_onEntryChanged);

    // _scrollController = ScrollController()..addListener(() => setState(() {}));

    super.initState();
  }

  @override
  void dispose() {
    databaseUtils.dispose();
    _pageController.dispose();

    _onAddedSubscription.cancel();
    _onChangedSubscription.cancel();
    super.dispose();
  }

  void navigationTapped(int page) {
    _pageController.animateToPage(
      page,
      duration: Duration(milliseconds: 300),
      curve: Curves.easeIn,
    );
  }

  void onPageChanged(int page) {
    setState(() {
      this._page = page;
    });
  }

  _onEntryChanged(Event event) {
    var oldEntry = carList.singleWhere((entry) {
      print(entry.key);
      print(event.snapshot.key);
      return entry.key == event.snapshot.key;
    });

    setState(() {
      carList[carList.indexOf(oldEntry)] = Car.fromSnapshot(event.snapshot);
    });
  }

  _onEntryAdded(Event event) {
    setState(() {
      carList.add(Car.fromSnapshot(event.snapshot));
    });
  }

  Widget _showListView() {
    if (carList.length > 0) {
      return ListView.builder(
          shrinkWrap: true,
          itemCount: carList.length,
          itemBuilder: (BuildContext context, int index) {
            return HomePageUi(carList[index]);
          });
    } else {
      return new Center(
          child:
              CircularProgressIndicator() //new Text("Nessun veicolo presente"),
          );
    }
  }

Widget _showList() {
    return new SafeArea(
      child: Column(
        children: <Widget>[
          new Container(
            margin: EdgeInsets.symmetric(horizontal: 16.0),
              width: MediaQuery.of(context).size.width,
              height: kExpandedHeight,
              child: MyFlexiableAppBar()),
          new Expanded(child: _showListView())
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    List<Widget> _myPages = [
      _showList(),
      Container(),
      FavoritesScreen(carList)
    ];

    return Scaffold(
      bottomNavigationBar: BottomNavigationBar(
        type: BottomNavigationBarType.fixed,
        backgroundColor: AppTheme.darkerBlue,
        fixedColor: AppTheme.orangeText,
        unselectedItemColor: Colors.white,
        showSelectedLabels: false,
        showUnselectedLabels: false,
        onTap: navigationTapped,
        currentIndex: _page,
        items: [
          new BottomNavigationBarItem(
              title: new Text(''), icon: new Icon(Icons.home)),
          new BottomNavigationBarItem(
              title: new Text(''),
              icon: IconButton(
                icon: Icon(Icons.search),
                onPressed: () async {
                  final Car searchRes = await showSearch<Car>(
                      context: context, delegate: searchPage(carList));
                  if (searchRes != null)
                    Navigator.of(context).push(new PageRouteBuilder(
                        pageBuilder: (_, __, ___) => new CarPage(searchRes)));
                },
              )),
          new BottomNavigationBarItem(
              title: new Text(''), icon: new Icon(Icons.favorite_border))
        ],
      ),
      body: new PageView.builder(
          controller: _pageController,
          onPageChanged: onPageChanged,
          scrollDirection: Axis.horizontal,
          physics: BouncingScrollPhysics(),
          itemCount: _myPages.length,
          itemBuilder: (BuildContext context, int position) =>
              _myPages[position]),
    );

ui.dart

    final _favoriteButton = StreamBuilder<bool>(
        stream: MyDatabase().isFavorite(int.parse(car.key)),
        builder: (context, snapshot) {
          print("rebuilding");

          if (snapshot.hasData && snapshot.data) {
            return IconButton(
                onPressed: () =>
                    MyDatabase().removeFavorite(int.parse(car.key)),
                icon: Icon(Icons.favorite, color: AppTheme.orangeText));
          }

          return IconButton(
              onPressed: () => MyDatabase().addFavorite(car),
              icon: Icon(Icons.favorite_border, color: AppTheme.darkBlue));
        });

    final carCardContent = new Padding(
      padding: EdgeInsets.all(10.0),
      child: new Column(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: <Widget>[
          new Text(car.title,
              style: headerTextStyle, textAlign: TextAlign.center),
          new SizedBox(height: 5.0),
          new Row(
            mainAxisAlignment: MainAxisAlignment.end,
            children: <Widget>[
              new Text(
                car.price,
                style: headerTextStyle,
              ),
              new Text(" - ", style: regularTextStyle),
              new Text("Iva Esclusa",
                  style: regularTextStyle.copyWith(
                      decoration: TextDecoration.underline))
            ],
          ),
          new SizedBox(height: 5.0),
          new Row(
            crossAxisAlignment: CrossAxisAlignment.center,
            children: <Widget>[
              carThumb,
              SizedBox(width: 10.0),
              carDetails,
            ],
          ),
          SizedBox(height: 5.0),
          new Row(
            crossAxisAlignment: CrossAxisAlignment.center,
            mainAxisAlignment: MainAxisAlignment.end,
            children: <Widget>[
              new Text("Aggiungimi ai prefereriti ", style: subHeaderTextStyle),
              _favoriteButton
            ],
          ),

        ],
      ),
    );

    final carCard = Container(
      child: carCardContent,
      decoration: new BoxDecoration(
          color: AppTheme.nearlyWhite,
          shape: BoxShape.rectangle,
          borderRadius: new BorderRadius.circular(8.0),
          boxShadow: <BoxShadow>[
            new BoxShadow(
                color: Colors.black12,
                blurRadius: 5.0,
                offset: new Offset(0.0, 6.0))
          ]),
    );

Favorites_database.dart

import 'package:moor_flutter/moor_flutter.dart';
import 'package:moor/moor.dart';
import 'package:pastore_app/car.dart';

// assuming that your file is called filename.dart. This will give an error at first,
// but it's needed for moor to know about the generated code
part 'favorites_database.g.dart';

// this will generate a table called "Favorites" for us. The rows of that table will
// be represented by a class called "Favorites".
class Favorites extends Table {
  IntColumn get id => integer().customConstraint('UNIQUE')();
  TextColumn get rif => text()();
  TextColumn get title => text()();
}

// this annotation tells moor to prepare a database class that uses both of the
// tables we just defined. We'll see how to use that database class in a moment.
@UseMoor(tables: [Favorites])
class MyDatabase extends _$MyDatabase {
  MyDatabase()
      // Specify the location of the database file
      : super((FlutterQueryExecutor.inDatabaseFolder(
          path: 'db1.sqlite',
          // Good for debugging - prints SQL in the console
          logStatements: true,
        )));

  // Bump this when changing tables and columns.
  // Migrations will be covered in the next part.
  @override
  int get schemaVersion => 1;

  Future<List<Favorite>> get allFavoritesEntries => select(favorites).get();

  Stream<List<Favorite>> get allFavoritesWatch => select(favorites).watch();

  // watches all Favorites entries in a given category. The stream will automatically
  // emit new items whenever the underlying data changes.
/*
  Stream<bool> isFavorite(int rifId) {
    return (select(favorites)..where((favorite) => favorite.id.equals(rifId)))
        .watch()
        .map((favoritesList) => favoritesList.length >= 1);
  }
*/
  void addFavorite(Car car) {
    var favorite =
        Favorite(id: int.parse(car.key), rif: car.rif, title: car.title);

    into(favorites).insert(favorite);
  }

  void removeFavorite(int keyId) =>
      (delete(favorites)..where((t) => t.id.equals(keyId))).go();

  Stream<bool> isFavorite(int keyId) {
    return (select(favorites).watch().map((favoritesList) =>
        favoritesList.where((favorite) => favorite.id == keyId).length >= 1));
  }
}
...