#flutter #dart #flutter-layout
#flutter #dart #флаттер-макет
Вопрос:
Я получаю изображения из API и показываю их в виде сетки, но требуется, чтобы я долго нажимал на любой индекс изображения, выбранный значок должен быть виден на этом индексном изображении. но проблема в том, что когда я долго нажимаю на любой индекс, выбранный значок отображается на всех индексах.
Скриншот:
чтобы решить эту проблему, я создал класс model, в котором для каждого индекса есть тип данных: первая — логическая переменная (IsSelected), другая — для PhotoDetails, которая извлекается из API, но не может обработать ее с помощью FutureBuilder
, потому что она перестраивает метод сборки, когда я выполняю setState
и IsSelected становится false.
Код:
Класс модели:
class Photos{
PhotoDetail photoDetail;
bool isSelected;
Photos({this.photoDetail, this.isSelected});
}
FutureBuilder:
Expanded(
child: FutureBuilder<PhotoModel>(
future: _photoApi.getPhotosByUserList(
token: widget.tokenId,
contactId: widget.userContent.id,
),
builder:(BuildContext context, AsyncSnapshot<PhotoModel> snapshot){
if (!snapshot.hasData) {
return Center(child: CircularProgressIndicator());
}
if (snapshot.hasError){
return Center(child: new Text('Error: ${snapshot.error}'));
}
List<Photos> photos =[];
snapshot.data.content.forEach((element) {
photos.add(
Photos(
isSelected: false,
photoDetail: element
)
);
});
print("photos photos photos length:${photos.length}");
return photos.length>0?
sliverGridWidget(context,photos)
:Container(
alignment: Alignment.center,
child: Text("Empty"),
);
}
)
)
Изображения в виде сетки:
Widget sliverGridWidget(BuildContext context, List<Photos> listPhotoDetail){
return StaggeredGridView.countBuilder(
padding: const EdgeInsets.all(8.0),
crossAxisCount: 6,
itemCount: listPhotoDetail.length,
itemBuilder: (context, index){
return InkWell(
onLongPress: (){
setState(() {
enable = true;
print("iinnndexxxxxxx:$index");
// listPhotoDetail[index].isSelected = true;
});
},
child: Container(
alignment: Alignment.bottomRight,
decoration: BoxDecoration(
color:Colors.grey[100],
image: DecorationImage(
image: NetworkImage(listPhotoDetail[index].photoDetail.image.fileUrl),
fit: BoxFit.cover
)
),
child:enable?
Image.asset('assets/icons/selected.png')
:Container()
),
);
},
staggeredTileBuilder: (index)=> view ?StaggeredTile.count(6,6):StaggeredTile.count(2,2),
mainAxisSpacing: 8.0,
crossAxisSpacing:8.0,
);
}
Комментарии:
1. Где вы объявили
enable
. Попробуйте объявить это вsliverGridWidget
методе.2. Ничего плохого в том, чтобы включить переменную. Пожалуйста, прочитайте вопрос правильно, вы поймете.
3. Проблема в области видимости вашей
enable
переменной. Он охватывает всю сетку, а не отдельный элемент в вашей сетке. Вы можете решить эту проблему, взяв свойInkWell
виджет и его дочерние элементы и переместив их в свои собственные,StatefulWidget
чтобы длительное нажатие обновляло толькоenable
переменную одного элемента, а не все сразу.4. Не могли бы вы, пожалуйста, внедрить это в код?
Ответ №1:
Чтобы решить эту проблему, попробуйте использовать определенный ключ для каждого изображения