Состояние не обновляется после удаления элемента из массива в PageView
У меня есть массив объектов Character, который обрабатывается поставщиком и устанавливается с помощью запроса SQL. Когда я выполняю действие INSERT, новый персонаж успешно добавляется к просмотру страницы. Но когда я выполняю действие DELETE и удаляю символ из просмотра страницы, он удаляет его из списка, но не обновляет пользовательский интерфейс для отображения следующего символа в массиве - он продолжает отображать информацию об удаленном персонаже, пока не будет принудительно перестроен переходя прочь и обратно. Я знаю, что он успешно удаляется из базы данных и массива, потому что индикатор моей страницы уменьшается на 1. Текущий символ обрабатывается другим провайдером и устанавливается путем передачи его в уведомитель 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();
}
}