Skip to content

Instantly share code, notes, and snippets.

@shriharip
Created November 22, 2019 21:53
Show Gist options
  • Save shriharip/d2113fd4eab1a922919c281a903d759d to your computer and use it in GitHub Desktop.
Save shriharip/d2113fd4eab1a922919c281a903d759d to your computer and use it in GitHub Desktop.
listfeed.dart
class NewsListFollowing extends StatefulWidget {
static final PageStorageKey<String> pageKey =
PageStorageKey<String>('newsListFollowing');
final scrollcontroller;
NewsListFollowing({this.scrollcontroller, Key key}) : super(key: key);
@override
_NewsListFollowingState createState() => _NewsListFollowingState();
}
class _NewsListFollowingState extends State<NewsListFollowing> {
Offset imagepressLocation;
VideoPlayerController videoController;
OverlayEntry _overlayEntry;
VoidCallback listener;
@override
void initState() {
super.initState();
listener = () {
setState(() {});
};
}
videoInit(news) {
if (news.videoUrl == null) {
return;
}
videoController = VideoPlayerController.network(news.videoUrl)
..setVolume(1.0)
..initialize().then((_) {
print('inside the videoInit ${videoController.value.initialized}');
videoController.addListener(listener);
// Ensure the first frame is shown after the video is initialized, even before the play button has been pressed.
// setState(() {});
});
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Consumer<NewsModel>(
builder: (context, model, child) => model.busy
? Center(
child: CircularProgressIndicator(),
)
: SmartRefresher(
key: NewsListFollowing.pageKey,
controller: model.refreshController,
enablePullDown: true,
header: WaterDropMaterialHeader(
backgroundColor: Theme.of(context).primaryColor,
),
enablePullUp: true,
onRefresh: model.onRefresh,
onLoading: model.onLoading,
child: buildList(model, context)),
),
);
}
gethasVideo(News news) {
if (news.videoUrl != null) {
if (news.videoUrl.length > 0) {
return true;
}
}
return false;
}
buildList(NewsModel model, BuildContext context) {
return ListView.builder(
shrinkWrap: true,
padding: const EdgeInsets.all(8.0),
itemBuilder: (
BuildContext context,
int ind,
) {
News news = model.newsItems[ind];
var herotag = news.id;
// var imgurl = getImage(news);
videoInit(news);
bool hasVideo = gethasVideo(news);
return Card(
elevation: 3.0,
child: Material(
color: Colors.transparent,
child: InkWell(
child: Column(
// mainAxisSize: MainAxisSize.min,
children: <Widget>[
// GestureDetector(
// child: CachedNetworkImage(
// imageUrl: imageURL,
// imageBuilder: (context, imageProvider) => Container(
// decoration: BoxDecoration(
// color: Theme.of(context).backgroundColor),
// width: MediaQuery.of(context).size.width,
// child: Hero(
// tag: herotag,
// // child: Image.network(imageURL),
// child: FadeInImage.memoryNetwork(
// placeholder: kTransparentImage,
// image: imageURL,
// ),
// ),
// ),
// ),
// child: Hero(
// tag: herotag,
// child: Container(
// width: MediaQuery.of(context).size.width,
// decoration: BoxDecoration(
// color: Theme.of(context).backgroundColor),
// // child: Image.network(imageURL),
// child: FadeInImage.memoryNetwork(
// placeholder: kTransparentImage,
// image: imgurl,
// fit: BoxFit.cover),
// ),
// ),
hasVideo
? AspectRatio(
aspectRatio: 16 / 9,
child: GestureDetector(
child: VideoPlayer(videoController),
onTap: () {
setState(() {
videoController.value.isPlaying
? videoController.pause()
: videoController.play();
});
},
),
)
: getImage(news) < 1
? Container()
: AspectRatio(
aspectRatio: 1.0,
child: Swiper(
// shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemBuilder:
(BuildContext context, int index) {
return Hero(
tag: herotag,
// child: Container(
// width: MediaQuery.of(context).size.width,
// decoration: BoxDecoration(
// color:
// Theme.of(context).backgroundColor),
// child: Image.network(imageURL),
// child: FadeInImage.memoryNetwork(
// placeholder: kTransparentImage,
// image: news.media[index],
// fit: BoxFit.contain),
child: Image.network(news.media[index],
fit: BoxFit.contain)
// ),
);
},
loop: false,
itemCount: getImage(news),
pagination:
//SwiperPagination(),
SwiperCustomPagination(
builder: (BuildContext context,
SwiperPluginConfig config) {
buildDots() {
List<Widget> listDots = [];
for (int i = 0;
i < config.itemCount;
i++) {
if (i == config.activeIndex) {
listDots.add(Container(
width: 16.0,
height: 16.0,
decoration: ShapeDecoration(
color: Theme.of(context)
.primaryColor,
shape: CircleBorder(),
),
));
} else {
listDots.add(Container(
width: 16.0,
height: 16.0,
decoration: ShapeDecoration(
color: Theme.of(context)
.buttonColor,
shape: CircleBorder(),
),
));
}
}
return listDots;
}
if (getImage(news) <= 1) {
return SizedBox();
}
return Align(
alignment: Alignment.bottomCenter,
child: Wrap(
spacing: 8.0,
children: buildDots()),
);
},
)
//control: SwiperControl(),
),
),
// onTap: () {
// var newsn = model.increaseView(news, ind);
// Navigator.pushNamed(context, RoutePaths.NewsDetail,
// arguments: ind);
// }
// //),
// ),
GestureDetector(
child: Container(
width: MediaQuery.of(context).size.width,
padding: EdgeInsets.all(8.0),
child: Text(news.title,
style: Theme.of(context).textTheme.title),
),
onTap: () {
var newsn = model.increaseView(news, ind);
Navigator.pushNamed(context, RoutePaths.NewsDetail,
arguments: ind);
}),
Row(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(left: 8.0),
child: Icon(Icons.home, size: 18.0),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 4.0),
child: GestureDetector(
child: Text(news.villageName,
style: Theme.of(context)
.textTheme
.body2
.copyWith(fontSize: 12.0)),
onTap: () {
Navigator.pushNamed(
context, RoutePaths.VillageMain);
}),
),
Spacer(),
Text(timeago.format(news.createdAt),
style: Theme.of(context)
.textTheme
.body2
.copyWith(fontSize: 10.0))
],
),
Container(
width: MediaQuery.of(context).size.width,
child: Padding(
padding: const EdgeInsets.fromLTRB(8.0, 8.0, 0, 0),
child: Wrap(
spacing: 8.0,
runSpacing: 8.0,
children: buildTags(news, context)),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
ReactionSection(
feature: news,
model: model,
userIsMember: true,
),
Row(children: <Widget>[
Padding(
padding:
const EdgeInsets.symmetric(horizontal: 8.0),
child: Icon(Icons.message, size: 18.0),
),
Text(news.commentsCount.toString(),
style: Theme.of(context).textTheme.subhead),
])
],
),
),
],
),
onLongPress: () {
showEmojiPicker(context, news, model);
},
),
),
);
},
itemCount: model.newsItems != null ? model.newsItems.length : 0,
);
}
getImage(news) {
int mediaLength = 0;
if (news.media == null) {
return mediaLength;
}
mediaLength = news.media.length;
return mediaLength;
}
List<Widget> buildTags(News news, BuildContext context) {
List<Widget> widgetList = [];
if (news.tags == null) {
return widgetList;
}
for (var tag in news.tags) {
widgetList.add(Text('#$tag',
style: Theme.of(context)
.textTheme
.body2
.copyWith(fontStyle: FontStyle.italic)));
}
return widgetList;
}
getVideoThumbnail(news) async {
if (news.videoUrl == null) {
return '';
}
final uint8list = await VideoThumbnail.thumbnailFile(
video: news.videoUrl,
thumbnailPath: (await getTemporaryDirectory()).path,
imageFormat: ImageFormat.WEBP,
maxHeightOrWidth: 0, // the original resolution of the video
quality: 75,
);
return uint8list;
}
@override
void dispose() {
super.dispose();
videoController.dispose();
}
}
@shriharip
Copy link
Author

hi, i had done the following to make sure the initialization works properly,

inside initState method

 _controller = VideoPlayerController.network(widget.url)
        ..initialize().then((_) {
          print('inside the videoInit ${_controller.value.initialized}');
          // Ensure the first frame is shown after the video is initialized, even before the play button has been pressed.
          setState(() {});
        });

and then in the build method

 @override
  Widget build(BuildContext context) {
    if (_controller == null) {
      return CircularProgressIndicator();
    } else {
      return GestureDetector(
        child: _controller.value.initialized
            ? AspectRatio(
                aspectRatio: _controller.value.aspectRatio,
                child: Stack(children: [
                  VideoPlayer(_controller),
                  Align(
                    alignment: Alignment.center,
                    child: Container(
                      color: _controller.value.isPlaying
                          ? Colors.transparent
                          : Colors.black,
                      child: AnimatedOpacity(
                        opacity: _controller.value.isPlaying ? 0 : 1,
                        duration: Duration(milliseconds: 500),
                        child: AnimatedIcon(
                          icon: AnimatedIcons.pause_play,
                          color: Colors.white,
                          size: 64.0,
                          progress: aniController,
                        ),
                      ),
                    ),
                  )
                ]),
              )
            : CircularProgressIndicator(),
        onTap: () {
          setState(() {
            _controller.value.isPlaying
                ? _controller.pause()
                : _controller.play();
          });
        },
      );
    }
  }


don't forget to dispose the controller .
however, sometimes I face the issue of video not showing up and it is a blank container. This sometimes happen on ios

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment