Flutter: использование SQFLite с моделью с ограниченной областью видимости - PullRequest
0 голосов
/ 09 мая 2020

Я создавал приложение, в котором есть разные списки дел, и я использую для него модель с ограниченным объемом. Я искал в inte rnet хороший пример того, как использовать SQFlite с моделью с осциллографом, но пока без сигары. Я в значительной степени застрял.

Итак, мой вопрос: как я могу получить и сохранить элементы, используя приведенный ниже код?

Модель TodoItem (todos.dart)

Я хотел бы получить список дел из базы данных с помощью функции fetchAll. Из базы данных необходимы только идентификатор, метка и проверенные данные. Остальные значения всегда false и new FocusNode () при инициализации.

import 'package:flutter/material.dart';

class TodoItem {
  int id;
  String label;
  bool checked;
  bool isNew;
  var focusNode;

  TodoItem(this.id, this.label, this.checked, this.isNew, this.focusNode);

  static List<TodoItem> fetchAll() {
    return [
      TodoItem(1, 'Walk dog', false, false, new FocusNode()),
      TodoItem(2, 'Draw', false, false, new FocusNode()),
      TodoItem(3, 'Buy milk', false, false, new FocusNode()),
      TodoItem(4, 'Code an awesome app', false, false, new FocusNode()),
      TodoItem(5, 'Dentist', true, false, new FocusNode()),
    ];
  }
}

Глобальная модель (global.dart)

Здесь я вызываю TodoItem.fetchAll () чтобы добавить элементы в глобальную модель. И обработайте изменения в списке дел. Я хочу сохранить изменения в базе данных.

import 'package:flutter/material.dart';
import 'package:scoped_model/scoped_model.dart';
import '../models/scores.dart';
import '../models/todos.dart';

class ScopedGlobalModel extends Model {
  // Scores
  final dayScore = DayScore();
  final weekScore = WeekScore();
  final monthScore = MonthScore();
  final totalScore = TotalScore();

  addToDayScore(int value) {
    dayScore.value += value;
    weekScore.value += value;
    monthScore.value += value;
    totalScore.value += value;
    notifyListeners();
  }

  addToWeekScore(int value) {
    weekScore.value += value;
    monthScore.value += value;
    totalScore.value += value;
    notifyListeners();
  }

  addToMonthScore(int value) {
    monthScore.value += value;
    totalScore.value += value;
    notifyListeners();
  }

  addToTotalScore(int value) {
    totalScore.value += value;
    notifyListeners();
  }

  // Tabs
  ScrollPhysics tabBarViewPhysics = AlwaysScrollableScrollPhysics();

  // Lists
  final todoItems = TodoItem.fetchAll();

  getList(String type) {
    if (type == 'todo') return todoItems;
  }

  reorderListItems(String type, int from, int to) {
    var list = getList(type);
    list.insert(to, list.removeAt(from));
  }

  setListItemChecked(String type, int id, bool checked) {
    var list = getList(type);

    for (var i = 0; i < list.length; i++) {
      if (id == list[i].id) {
        list[i].checked = checked;
        break;
      }
    }

    if (type == 'todo') {
      if (checked == true) {
        addToDayScore(1);
      } else {
        addToDayScore(-1);
      }
    }
  }

  setListItemLabel(String type, int id, String label) {
    var list = getList(type);

    for (var i = 0; i < list.length; i++) {
      if (id == list[i].id) {
        list[i].label = label;
        print(list[i].label);
        break;
      }
    }
  }

  addListItem(String type) {
    var list = getList(type);
    int _id = 0;

    for (var i = 0; i < list.length; i++) {
      if (list[i].id > _id) _id = list[i].id;
    }
    _id++;

    if (type == 'todo') {
      todoItems.insert(
          todoItems.length, TodoItem(_id, '', false, true, new FocusNode()));
    }

    notifyListeners();
  }

  addListItemInBetween(String type, int id) {
    addListItem(type);

    var list = getList(type);
    int from = list.length - 1;
    int to = 0;
    for (var i = 0; i < list.length; i++) {
      if (list[i].id == id) to = i;
    }
    to++;
    reorderListItems(type, from, to);
    notifyListeners();
  }

  setListItemFocus(String type, int id, BuildContext context) {
    var list = getList(type);

    for (var i = 0; i < list.length; i++) {
      if (id == list[i].id && list[i].isNew) {
        FocusScope.of(context).requestFocus(list[i].focusNode);
        list[i].isNew = false;
      }
    }
  }

  removeListItem(String type, int id) {
    var list = getList(type);

    for (var i = 0; i < list.length; i++) {
      if (id == list[i].id) {
        list.removeAt(i);
      }
    }

    notifyListeners();
  }
}

Основной код приложения (app.dart)

Здесь я создаю вкладки и вызываю HomeScreen (), где Я показываю список дел.

import 'package:flutter/material.dart';
import 'package:scoped_model/scoped_model.dart';
import 'style.dart';

import 'screens/home/home.dart';
import 'screens/day/day.dart';
import 'screens/week/week.dart';
import 'screens/month/month.dart';

import 'scoped_models/global.dart';

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'To do app',
      theme: ThemeData.dark().copyWith(
        primaryColor: ColorStyles.primary,
        accentColor: ColorStyles.accent,
        cursorColor: ColorStyles.accent,
        textSelectionColor: ColorStyles.accent,
        textSelectionHandleColor: ColorStyles.accent,
        floatingActionButtonTheme: FloatingActionButtonThemeData(
          backgroundColor: ColorStyles.accent,
        ),
        textTheme: TextTheme(
          body1: TextStyles.textFont,
        ),
        unselectedWidgetColor: ColorStyles.icon,
        toggleableActiveColor: ColorStyles.iconDark,
      ),
      home: AppHome(),
    );
  }
}

class AppHome extends StatelessWidget {
  final ScopedGlobalModel scopedGlobalModel = ScopedGlobalModel();

  @override
  Widget build(BuildContext context) {
    return ScopedModel<ScopedGlobalModel>(
      model: scopedGlobalModel,
      child: DefaultTabController(
        length: 5,
        child: Scaffold(
          appBar: PreferredSize(
            preferredSize: AppBarStyles.height,
            child: AppBar(
              bottom: TabBar(
                labelStyle: TabStyles.labelFont,
                unselectedLabelColor: TabStyles.unselectedLabelColor,
                indicatorColor: TabStyles.indicatorColor,
                tabs: [
                  Tab(icon: Icon(Icons.home)),
                  Tab(text: 'Day'),
                  Tab(text: 'Week'),
                  Tab(text: 'Month'),
                  Tab(text: 'Test'),
                ],
              ),
              title: Container(
                padding: AppBarStyles.titlePadding,
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.start,
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text('App name', style: AppBarStyles.titleText),
                    ScopedModelDescendant<ScopedGlobalModel>(
                      builder: (context, child, model) => Text(
                          'Total score: ${model.totalScore.value}',
                          style: AppBarStyles.subTitleText),
                    ),
                  ],
                ),
              ),
            ),
          ),
          body: TabBarView(
            physics: scopedGlobalModel.tabBarViewPhysics,
            children: [
              HomeScreen(),
              DayScreen(),
              WeekScreen(),
              MonthScreen(),
              TestScreen(),
            ],
          ),
        ),
      ),
    );
  }
}

Вкладка главного экрана (home.dart)

Здесь я использую ScopedModelDescendant для передачи элементов списка дел в мой ListComponent widget

import 'package:flutter/material.dart';
import 'package:scoped_model/scoped_model.dart';
import '../../scoped_models/global.dart';
import '../../scoped_models/home.dart';
import '../../style.dart';
import '../../components/list.dart';
import '../../components/text.dart';

class HomeScreen extends StatelessWidget {
  final ScopedHomeModel homeModel = ScopedHomeModel();

  @override
  Widget build(BuildContext context) {
    return ScopedModelDescendant<ScopedGlobalModel>(
      builder: (context, child, globalModel) => ScopedModel<ScopedHomeModel>(
        model: homeModel,
        child: Scaffold(
          backgroundColor: ColorStyles.background,
          body: GestureDetector(
            onTap: () {
              FocusScope.of(context).requestFocus(new FocusNode());
            },
            child: SingleChildScrollView(
              child: Column(
                mainAxisSize: MainAxisSize.min,
                mainAxisAlignment: MainAxisAlignment.start,
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Container(
                    padding: ContainerStyles.padding,
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.start,
                      crossAxisAlignment: CrossAxisAlignment.start,
                       children: [
                         Text('Day: ${globalModel.dayScore.value}'),
                         Text('Week: ${globalModel.weekScore.value}'),
                         Text('Month: ${globalModel.monthScore.value}'),
                         Text('Total: ${globalModel.totalScore.value}'),
                       ],
                    ),
                  ),
                  ListTitleComponent('To do list'),
                  ListComponent('todo', globalModel.todoItems, globalModel),
                  Title1Component('Notes'),
                  TextAreaComponent(homeModel.notes, homeModel.saveNotes),
                ],
              ),
            ),
          ),
          floatingActionButton: FloatingActionButton(
            onPressed: () => globalModel.addListItem('todo'),
            tooltip: 'Add',
            child: Icon(Icons.add),
          ),
        ),
      ),
    );
  }
}

Я добавил большую часть своего кода, чтобы вы получили полную картину того, что я делаю. Любая помощь будет высоко ценится! Я также открыт для альтернативы SQFLite. В основном я выбрал его, потому что знаком с SQL

...