我的数据来自主要来自队列和当前队列mediaItem
的流。因此mediaItem
总是在变化。
我使用了
index = queue.indexOf(mediaItem);
现在我想将轮播的当前页面设置为我的索引,我在轮播的initialPage
上添加了索引,但是该索引仅在索引更改时起作用一次,并且不会更改当前页面。
我的流看起来像这样
//this stream is initialized inside initState()
stream = Rx.combineLatest3<List<MediaItem>, MediaItem, PlaybackState, ScreenState>(
AudioService.queueStream,
AudioService.currentMediaItemStream,
AudioService.playbackStateStream,
(queue, mediaItem, playbackState) => ScreenState(queue, mediaItem, playbackState)
);
Scaffold(
body: new Center(
child: StreamBuilder<ScreenState>(
stream: stream,
builder: (context, snapshot) {
final screenState = snapshot.data;
final queue = screenState?.queue;
final mediaItem = screenState?.mediaItem;
final state = screenState?.playbackState;
final basicState = state?.basicState ?? BasicPlaybackState.none;
int index = queue?.indexWhere((MediaItem mediaItemX){return (mediaItem?.id == mediaItemX.id);});
return (queue!=null&& mediaItem!=null && basicState != null && index != null)
? mainView(queue, mediaItem, basicState, state, index)
: Container(
child: Center(
child: SpinKitWave(
color: Colors.white70,
),
),
);
},
),
),
),
主视图
Widget mainView(List<MediaItem> queue, MediaItem mediaItemX, BasicPlaybackState basicState, PlaybackState state, int index){
return CarouselSlider.builder(
itemCount: queue.length,
initialPage: queue.indexOf(mediaItemX),//only works first time
itemBuilder: (BuildContext context, int itemIndex) {
Stack(
children: <Widget>[
ClipRRect(
borderRadius: BorderRadius.circular(8.0),
child: Container(
padding: EdgeInsets.fromLTRB(0,0,0,0),
child: CachedNetworkImage(
height: ScreenUtil().setWidth(1200),
width: ScreenUtil().setWidth(1200),
imageUrl: queue[itemIndex].artUri,
fit: BoxFit.cover,
placeholder: (context, url) => new SpinKitWave(color: Colors.white30, size: 30.0,),
errorWidget: (context, url, error) => new Image.asset(
'images/addplaylist.png',
color: Colors.white30,
),
),
)
)
],
),
}
);
}
问题是当mediaItem
从另一个地方更改时,需要轮播根据数据流的变化来更改其索引,换句话说,该功能与Carousel内部的currentPage几乎相同,因此每次索引进行更改,然后将currentPage
设置为流中的新数据,或控制流中的轮播。
高度赞赏具有示例的解决方案或提示。
其他信息:我正在使用carousel_slider: ^1.4.1
答案 0 :(得分:3)
initialPage可以在空容器中正常工作(请参见下面的代码),在我看来似乎缺少一些key
,可能是在缓存的图像网络或您的容器中,请尝试放置UniqueKey()
以确保小部件树将在新的snapthos出现时检测到更改...
使用StreamBuilder
和滑块的示例:
import 'dart:async';
import 'dart:math';
import 'package:carousel_slider/carousel_slider.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(body: MyHomePage()),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final StreamController sc = StreamController();
final rng = Random();
final containers = [
Container(color: Colors.pink),
Container(color: Colors.black),
Container(color: Colors.yellow),
Container(color: Colors.brown),
];
@override
void initState() {
super.initState();
Timer.periodic(
Duration(seconds: 5),
(t) {
sc.add(rng.nextInt(containers.length));
},
);
}
@override
Widget build(BuildContext context) {
return StreamBuilder(
stream: sc.stream,
builder: (context, snapshot) {
if (snapshot.hasData == false) {
return CircularProgressIndicator();
}
return Container(
child: mainView(containers, containers[snapshot.data]),
);
},
);
}
Widget mainView(
List<Container> queue,
Container mediaItemX,
) {
return CarouselSlider.builder(
itemCount: queue.length,
initialPage: queue.indexOf(mediaItemX), //only works first time
itemBuilder: (BuildContext context, int itemIndex) {
print('changed');
return mediaItemX;
},
);
}
}