使用滚动控制器提取数据页不会使用更新的列表更新 GridView



首次呈现Artworks屏幕时,它会进行异步调用,获取第一页数据,然后将其显示在网格中。在initState((函数中,我还添加了一个滚动监听器,当用户到达屏幕底部时,它会获取下一个可用的数据页。获取逻辑工作得很好,但尽管调用了setState((,GridView似乎并没有用新增强的列表重建。有什么想法吗?

艺术品屏幕:

class Artworks extends StatefulWidget {
const Artworks({
Key? key,
}) : super(key: key);
@override
State<StatefulWidget> createState() => _ArtworksState();
}
class _ArtworksState extends State<Artworks> {
AlbumCubit get _cubit => context.read<AlbumCubit>();
List<Photo> get artworks => _cubit.artworks;
final ArtworkRepository _artworkRepository = getIt<ArtworkRepository>();
final ScrollController _controller = ScrollController();
int _totalArtworkPages = 0;
int _currentPage = 0;
bool fetchedFirstPage = false;
@override
void initState() {
super.initState();
_controller.addListener(() async {
if (_controller.position.atEdge) {
final bool isTop = _controller.position.pixels == 0;
if (!isTop) {
// scrolled to the bottom, fetch new page if available
if (_currentPage < _totalArtworkPages - 1) {
await _artworkRepository.getSavedArtworks(page: ++_currentPage);
setState(() {});
}
}
}
});
initData();
}
Future<void> initData() async {
_totalArtworkPages =
await _artworkRepository.getSavedArtworks(page: _currentPage);
setState(() {
fetchedFirstPage = true;
});
}
@override
Widget build(BuildContext context) {
return (!fetchedFirstPage)
? Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: const <Widget>[
CircularProgressIndicator(color: AppColors.red),
SizedBox(
height: 10,
),
Text(
'Loading artworks',
style: montserratMedium14,
)
],
),
)
: GridView.builder(
controller: _controller,
itemCount: _artworkRepository.savedArtworks.length,
padding: const EdgeInsets.symmetric(horizontal: 16),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
crossAxisSpacing: 4,
mainAxisSpacing: 4,
),
itemBuilder: (BuildContext context, int index) {
final Photo artwork = _artworkRepository.savedArtworks[index];
return ArtworkItem(artwork: artwork);
},
);
}
}
class ArtworkItem extends StatelessWidget {
const ArtworkItem({Key? key, required this.artwork}) : super(key: key);
final Photo artwork;
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () =>
NavigatorUtils.goToArtworkViewScreen(context, artworkId: artwork.id),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16),
color: AppColors.grey,
),
child: ClipRRect(
borderRadius: BorderRadius.circular(16),
child: CachedNetworkImage(
placeholder: (context, url) => const Center(
child: CircularProgressIndicator(
color: AppColors.red,
),
),
errorWidget: (context, url, dynamic error) =>
const Icon(Icons.error),
imageUrl: artwork.thumbnailPhoto ?? artwork.firebasePhoto,
fit: BoxFit.cover,
),
),
),
);
}
}

Artworks存储库Impl:

class ArtworkRepositoryImpl implements ArtworkRepository {
ArtworkRepositoryImpl({required DioClient dioClient}) : _client = dioClient;
final DioClient _client;
final String baseUrl = getIt<AppRepository>().env == Env.staging //
? stagingUrl
: productionUrl;
final ArtistRepository artistRepository = getIt<ArtistRepository>();
@override
String? token;
@override
List<Photo> savedArtworks = [];
@override
Future<int> getSavedArtworks(
{int page = 0, int pageSize = 20, bool ascendent = true}) async {
try {
final ApiResponse response = await _client.httpCall(
baseUrl: baseUrl,
path: '/mobile/artwork/list',
httpMethod: HttpMethod.GET,
headers: <String, dynamic>{'x-auth-token': token},
queryParameters: <String, dynamic>{
'p': page,
'size': pageSize,
'asc': ascendent
},
);
final Map<String, dynamic> data = response.data;
final List<dynamic> artworksJson = data['results'] as List<dynamic>;
savedArtworks.addAll(
artworksJson.map((dynamic json) => Photo.fromJson(json)).toList(),
);
savedArtworks = savedArtworks.toSet().toList(); // remove duplicates
return data['totalPages'] as int;
} catch (e) {
rethrow;
}
}
}

也许它有效,如果你没有尝试,你可以创建一个函数并在你的监听器中替换wit,比如:

_controller.addListener(_onScroll);

然后创建_滚动

Future _onScroll() async{
if (_controller.position.atEdge) {
final bool isTop = _controller.position.pixels == 0;
if (!isTop) {
// scrolled to the bottom, fetch new page if available
if (_currentPage < _totalArtworkPages - 1) {
await _artworkRepository.getSavedArtworks(page: ++_currentPage);
setState(() {});
}
}
}
}

并检查下方的链接

https://www.youtube.com/watch?v=eENDlIgadr4

最新更新