0

我有一个由提供者处理并通过 SQL 查询设置的字符对象数组。当我执行 INSERT 操作时,新角色已成功添加到网页浏览中。但是,当我执行 DELETE 操作并从网页浏览中删除字符时,它会将其从列表中删除,但不会更新 UI 以显示数组中的下一个字符 - 它会继续显示已删除字符的信息,直到强制重建导航离开和返回。我知道它已成功从数据库和数组中删除,因为我的页面指示器减少了 1。当前 Character 由另一个提供程序处理,并通过将其作为参数传递给 CharacterState 通知程序来设置。

我想要的是 CharacterState 在执行 DELETE 操作后显示来自数组中下一个字符的信息。我认为问题在于 Character 对象如何从 CharacterListState 传递到 CharacterState。当用户在页面之间滑动或删除数组中的最后一项时,它可以正常工作,但否则 CharacterState 只会继续显示旧信息,直到通过离开页面并返回手动重建整个状态。

请在下面找到相关代码:

class CharacterListPage extends StatefulWidget {
  @override
  _CharacterListPageState createState() => _CharacterListPageState();
}

class _CharacterListPageState extends State<CharacterListPage> {
  PageController _pageController = PageController();

  @override
  Widget build(BuildContext context) {
    final AppState appState = Provider.of<AppState>(context);
    final CharacterListState characterListState =
        Provider.of<CharacterListState>(context);
    // _pageController.jumpToPage(appState.position);
    return Scaffold(
      resizeToAvoidBottomPadding: true,
      body: FutureBuilder<bool>(
          future: characterListState.setCharacterList(),
          builder: (context, AsyncSnapshot<bool> _snapshot) {
            return _snapshot.hasError
                ? Container(child: Text(_snapshot.error.toString()))
                : !_snapshot.hasData
                    ? Container(
                        child: Center(child: CircularProgressIndicator()),
                        height: MediaQuery.of(context).size.height,
                      )
                    : PageIndicatorContainer(
                        child: PageView.builder(
                          controller: _pageController =
                              PageController(initialPage: appState.position),
                          onPageChanged: (_index) async {
                            var prefs = await SharedPreferences.getInstance();
                            appState.position = _index;
                            prefs.setInt('position', _index);
                            appState.setTheme(characterListState
                                .characterList[_index].classColor);
                            prefs.setString(
                                'themeColor',
                                characterListState
                                    .characterList[_index].classColor);
                          },
                          itemCount: characterListState.characterList.length,
                          itemBuilder: (BuildContext context, int index) {
                            return Container(
                              padding: EdgeInsets.all(smallPadding),
                              child: Card(
                                child: Stack(
                                  children: <Widget>[
                                    Container(
                                      decoration: BoxDecoration(
                                        color: Colors.white.withOpacity(0.9),
                                        image: DecorationImage(
                                          image: AssetImage(
                                              'images/class_icons/${characterListState.characterList[index].classIcon}'),
                                          colorFilter: ColorFilter.mode(
                                              Colors.white.withOpacity(0.9),
                                              BlendMode.lighten),
                                        ),
                                      ),
                                    ),
                                    Container(
                                        color: Color(int.parse(
                                                characterListState
                                                    .characterList[index]
                                                    .classColor))
                                            .withOpacity(0.2)),
                                    SingleChildScrollView(
                                      child: ChangeNotifierProvider<
                                          CharacterState>(
                                        builder: (context) => CharacterState(
                                          characterListState
                                              .characterList[index].id,
                                        ),
                                        child: Container(
                                          padding: EdgeInsets.all(smallPadding),
                                          child: CharacterPage(),
                                        ),
                                      ),
                                    )
                                  ],
                                ),
                              ),
                            );
                          },
                        ),
                        align: IndicatorAlign.top,
                        length: characterListState.characterList.length,
                        indicatorSpace: smallPadding,
                        padding: const EdgeInsets.only(top: 20),
                        indicatorColor: Colors.white,
                        indicatorSelectorColor: appState.accentColor,
                        shape: IndicatorShape.circle(size: 12),
                      );
            // shape: IndicatorShape.roundRectangleShape(size: Size.square(12),cornerSize: Size.square(3)),
            // shape: IndicatorShape.oval(size: Size(12, 8)),
          }),
      floatingActionButton: SpeedDial(
        animatedIcon: AnimatedIcons.menu_close,
        animatedIconTheme: IconThemeData(size: 22.0),
        closeManually: false,
        curve: Curves.bounceIn,
        overlayColor: Colors.black,
        overlayOpacity: 0.5,
        elevation: 8.0,
        shape: CircleBorder(),
        children: [
          SpeedDialChild(
              child: Icon(Icons.add),
              backgroundColor: Theme.of(context).accentColor,
              label: 'Import Legacy Character',
              labelStyle: TextStyle(fontSize: 18.0),
              onTap: () async => await characterListState.addLegacyCharacter()),
          SpeedDialChild(
            child: Icon(Icons.add),
            backgroundColor: Colors.green,
            label: 'Add New Character',
            labelStyle: TextStyle(fontSize: 18.0),
            onTap: () async {
              await showDialog(
                context: context,
                builder: (BuildContext context) {
                  return NewCharacterDialog(characterListState: characterListState);
                },
              );
              _pageController
                  .jumpToPage(characterListState.characterList.length + 1);
            },
          ),
          SpeedDialChild(
              child: Icon(Icons.add),
              backgroundColor: Colors.green,
              label: 'OPEN OLD CHAR SHEET',
              labelStyle: TextStyle(fontSize: 18.0),
              onTap: () {
                Navigator.push(
                  context,
                  MaterialPageRoute(builder: (context) => CharacterSheetPage()),
                );
              })
        ],
      ),
    );
  }
}

CharacterListState 类

class CharacterListState with ChangeNotifier {
  List<Character> _characterList = [];
  List<bool> _legacyPerks = [];
  DatabaseHelper db = DatabaseHelper.instance;

  List<Character> get characterList => _characterList;

  Future<bool> setCharacterList() async {
    // List _list = [];
    _characterList = await db.queryAllCharacters();
    // _list.forEach((_result) => _result.))
    // await db.queryPlayerClass(_classCode)
    return true;
  }

  Future addCharacter(String _name, PlayerClass _playerClass) async {
    Character _character = Character();
    List<bool> _perks = [];
    perkList.forEach((_perk) {
      for (var x = 0; x < _perk.numOfPerks; x++) {
        _perks.add(false);
      }
    });
    _character.name = _name;
    // _character.playerClass = _playerClass;
    _character.classCode = _playerClass.classCode;
    _character.classColor = _playerClass.classColor;
    _character.classIcon = _playerClass.classIconUrl;
    _character.classRace = _playerClass.race;
    _character.className = _playerClass.className;
    _character.xp = 0;
    _character.gold = 0;
    _character.notes = 'Add notes here';
    _character.checkMarks = 0;
    _character.isRetired = false;
    int id = await db.insertCharacter(_character, _perks);
    _character.id = id;
    print('inserted row: $id');
    print(_character.name);
    print(_character.classCode);
    notifyListeners();
  }

  Future deleteCharacter(int _characterId) async {
    await db.deleteCharacter(_characterId);
    // _characterList.removeWhere((value) => value.id == _characterId);
    notifyListeners();
  }
}
4

0 回答 0