I have a DashboardScreen which is accessed from bottom navbar , and another screen called CollectionScreen also is accessed from bottom navbar, when i create a collection on collection screen i need to update the dashboard screen to have that collection, as well as if i download a video in a collection i need to update the dashboard to have the latest video downloaded, the problem when i have a new collection and a video in it, and navigate to dashboard screen through bottom navbar, there is no update of new collection and video in dashboard until i hit hot reload, also the back button on appbar in collection screen does not allow the pop context. anybody to help on this.
i have tried to use setstate to update the widget but nothing work, also i have used future build but the collections are updated but no video is updated.
BottomNavigation page file (LandingPage):
import 'package:demo/components/setting.dart';
import 'package:demo/screens/collectionScreen.dart';
import 'package:demo/screens/dashboardScreen.dart';
import 'package:icony/icony_ikonate.dart';
import 'package:flutter/material.dart';
List<BottomNavigationBarItem> bottomNavItems = const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Ikonate(
Ikonate.home_alt2,
color: Colors.white,
),
label: "Home",
backgroundColor: Colors.black),
BottomNavigationBarItem(
icon: Ikonate(
Ikonate.grid,
color: Colors.white,
),
label: "Collections",
backgroundColor: Colors.black),
BottomNavigationBarItem(
icon: Icon(Icons.add_box), label: "", backgroundColor: Colors.black),
BottomNavigationBarItem(
icon: Ikonate(
Ikonate.settings,
color: Colors.white,
),
label: "Settings",
backgroundColor: Colors.black),
];
class LandingPage extends StatefulWidget {
const LandingPage({super.key});
@override
State<LandingPage> createState() => _LandingPageState();
}
class _LandingPageState extends State<LandingPage> with SingleTickerProviderStateMixin {
late TabController _pageController;
var _selectedPageIndex;
List<Widget> _screenOptions = <Widget>[
DashboardScreen(),
CollectionsScreen(),
Setting(),
Setting()
];
@override
void initState() {
// TODO: implement initState
super.initState();
_selectedPageIndex = 0;
_screenOptions;
_pageController = TabController(length: 4, vsync: this);
}
@override
void dispose() {
// TODO: implement dispose
super.dispose();
_pageController.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: TabBarView(
controller: _pageController,
children:_screenOptions,
),
bottomNavigationBar: BottomNavigationBar(
items: bottomNavItems,
currentIndex: _selectedPageIndex,
selectedItemColor: Colors.white,
iconSize: 40,
onTap: (selectedPageIndex) {
setState(() {
_selectedPageIndex = selectedPageIndex;
_pageController.index=selectedPageIndex;
});
},
elevation: 5,
),
);
}
}
my Dashboard Screen
import 'dart:io';
import 'dart:typed_data';
import 'package:demo/components/ravVideoPlay.dart';
import 'package:demo/model/storage.dart';
import 'package:demo/model/video.dart';
import 'package:flutter/material.dart';
import 'package:video_thumbnail/video_thumbnail.dart';
class DashboardScreen extends StatefulWidget {
const DashboardScreen({super.key});
@override
State<DashboardScreen> createState() => _DashboardScreenState();
}
class _DashboardScreenState extends State<DashboardScreen> {
List<String> collections = [];
List<Video> _videos = [];
List<Uint8List> collectionThumbnails = [];
late Video lastVideo = Video(videoUrl: "", music_url: "", filepath: "", thumbnailpath: "", collection: "");
Future<void> _getLatestColl() async {
try {
List<String> latestCollections =
await DatabaseHelper.getLatestCollections();
List<Video> videos = await DatabaseHelper.getAllVideos();
List<Uint8List> thumbnails =
await generateThumbnailsForCollections(latestCollections);
// Find the latest video
Video latestVideo = videos.isNotEmpty
? videos.last
: Video(
videoUrl: "",
music_url: "",
filepath: "",
thumbnailpath: "",
collection: "");
collections = latestCollections;
_videos = videos;
lastVideo = latestVideo;
collectionThumbnails = thumbnails;
} catch (e) {
print("Error loading latest collection and videos: $e");
// Handle error here
}
}
Future<List<Uint8List>> generateThumbnailsForCollections(
List<String> collections) async {
final List<Uint8List> thumbnails = [];
for (final collectionName in collections) {
final videosInCollection =
await DatabaseHelper.getVideosInCollection(collectionName);
// Generate a thumbnail for the first video in the collection (customize as needed)
if (videosInCollection.isNotEmpty) {
final videoPath =
videosInCollection[0].filepath; // Adjust this to get the video path
final thumbnailData = await VideoThumbnail.thumbnailData(
video: videoPath,
imageFormat: ImageFormat.JPEG,
quality: 30,
);
thumbnails.add(thumbnailData!);
} else {
// Add a placeholder thumbnail if no videos are in the collection
thumbnails
.add(Uint8List(0)); // Replace with a default placeholder image path
}
}
return thumbnails;
}
Widget TitleLabel(var text) {
return Padding(
padding: EdgeInsets.all(16.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
text,
style: TextStyle(fontSize: 20, color: Colors.white),
),
RichText(
text: TextSpan(children: [
TextSpan(
text: "View All",
style: TextStyle(fontSize: 14, color: Colors.white)),
WidgetSpan(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 4.0),
child: Icon(
Icons.keyboard_arrow_right,
color: Colors.white,
size: 16,
),
))
]))
],
),
);
}
@override
void initState(){
super.initState();
_getLatestColl();
}
@override
Widget build(BuildContext context) {
double expandHeight = MediaQuery.of(context).size.height*0.33;
return Scaffold(
appBar: AppBar(
title: Text('Home'),
leading: BackButton(
color: Colors.white,
),
),
body: FutureBuilder(
future: _getLatestColl(),
builder: (context,snapshot){
if( snapshot.connectionState == ConnectionState.waiting ){
return Center(child: CircularProgressIndicator(),);
}else {
if (snapshot.hasError) {
return Center(child: Text('Error: ${snapshot.error}'));
}else{
return NestedScrollView(
headerSliverBuilder:
(BuildContext context, bool innerBoxIsScrolled) {
return [
SliverAppBar(
expandedHeight: expandHeight,
floating: true,
forceElevated: innerBoxIsScrolled,
pinned: true,
titleSpacing: 0,
backgroundColor: Color(0x232728),
flexibleSpace: FlexibleSpaceBar(
background: Container(
height: expandHeight,
child: Stack(
children: [
if (lastVideo.thumbnailpath.isNotEmpty)
Container(
margin: EdgeInsets.all(20),
child: ClipRRect(
borderRadius:
BorderRadius.all(Radius.circular(8)),
child: PageView(
children: [
RecentVideo(
img: lastVideo.thumbnailpath,
callback: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => VideoPlay(
videoPath:
lastVideo.filepath),
),
);
},
)
],
),
),
)
else
Center(child: Text('No Latest Video')),
],
),
),
),
),
];
},
body: SingleChildScrollView(
child: Column(
children: [
TitleLabel("New Collections"),
if (collections.isEmpty)
Center(child: Text('No Collections'))
else
SizedBox(
height: 220,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: collections.length,
shrinkWrap: true,
itemBuilder: (context, index) {
return RecentCollection(
video: collections[index],
thumbnail: collectionThumbnails[index]);
}),
),
TitleLabel("Recently Edited"),
SizedBox(
height: 220,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: _videos.length,
shrinkWrap: true,
itemBuilder: (context, index) {
return RecentEdited(
video: _videos[index],
);
}),
)
],
),
));
}
}
}
),
);
}
}
class RecentVideo extends StatelessWidget {
final String img;
final Function callback;
const RecentVideo({super.key,required this.img, required this.callback});
@override
Widget build(BuildContext context) {
return Stack(
children: [
Container(
width: double.infinity,
height: double.infinity,
// width: MediaQuery.of(context).size.width,
child: GestureDetector(
onTap:() {
callback();
},
child: Stack(
fit: StackFit.expand,
children: [
Image.memory(File(img).readAsBytesSync(),fit: BoxFit.cover,),
Center(
child: Icon(Icons.play_circle_fill, size:30)
),
],
),
),
),
],
);
}
}
// ignore: must_be_immutable
class RecentCollection extends StatelessWidget {
late String video;
late Uint8List thumbnail;
RecentCollection({
super.key,
required this.video,
required this.thumbnail,
});
@override
Widget build(BuildContext context) {
return Container(
width: MediaQuery.of(context).size.width * 0.35,
margin: EdgeInsets.only(left:16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ClipRRect(
borderRadius: BorderRadius.circular(8.0),
child: Image.memory(
thumbnail, // Use the thumbnail data here
fit: BoxFit.cover,
height: 160,
width: MediaQuery.of(context).size.width,
),
),
SizedBox(height: 4,),
Padding(
padding: EdgeInsets.only(left: 4, right: 4),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(video, style: TextStyle(color: Colors.white),)
],
),
)
],
),
);
}
}
// ignore: must_be_immutable
class RecentEdited extends StatelessWidget {
late Video video;
RecentEdited({
super.key,
required this.video,
});
@override
Widget build(BuildContext context) {
return Container(
width: MediaQuery.of(context).size.width * 0.35,
margin: EdgeInsets.only(left: 16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ClipRRect(
borderRadius: BorderRadius.circular(8.0),
child: Image.asset(
video.thumbnailpath,
fit: BoxFit.cover,
height: 160,
width: MediaQuery.of(context).size.width,
),
),
SizedBox(
height: 4,
),
Padding(
padding: EdgeInsets.only(left: 4, right: 4),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
video.collection,
style: TextStyle(color: Colors.white),
)
],
),
)
],
),
);
}
}