Flutter: FlatButton not changing child on onPressed - flutter

I wanted to change a value in firestore by a button onPressed. I know there might be seconds delay and I wanted to show a CircularProgressIndicator widget while waiting. But It's not not working.
Here is my widget:
Widget save(String id) {
return new FutureBuilder(
future: PostController().isAlreadySaved(id),
builder: (BuildContext context, AsyncSnapshot<bool> snapshot) {
if (snapshot.hasData) {
if (snapshot.data) {
return FlatButton(
onPressed: () {
setState(() {
isSaveLoading = true;
});
PostController().deleteSaved(id);
setState(() {
isSaveLoading = false;
});
},
child: !isSaveLoading
? Icon(
MyFlutterApp.star,
size: 30,
color: Colors.redAccent,
)
: SizedBox(
height: 15,
width: 15,
child: CircularProgressIndicator(
strokeWidth: 1,
),
),
);
} else {
return FlatButton(
onPressed: () {
setState(() {
isSaveLoading = true;
});
PostController().save(context, id);
setState(() {
isSaveLoading = false;
});
},
child: !isSaveLoading
? Icon(
MyFlutterApp.star,
size: 30,
color: Colors.grey,
)
: SizedBox(
height: 15,
width: 15,
child: CircularProgressIndicator(
strokeWidth: 1,
),
),
);
}
} else {
return Container(
//color: Colors.white,
width: Adapt.screenW(),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Flexible(
child: Shimmer.fromColors(
baseColor: Colors.grey[400],
highlightColor: Colors.grey[50],
enabled: true,
child: Row(
children: <Widget>[
Padding(
padding: const EdgeInsets.fromLTRB(5, 0, 0, 0),
child: new Icon(
MyFlutterApp.star,
size: 30,
color: Colors.white,
),
),
],
),
),
),
],
),
);
}
},
);
}
Here is my isAlreadySaved() function:
Future<bool> isAlreadySaved(String id) async {
bool isSaved = false;
QuerySnapshot snapshot =
await databaseReference.collection('saved').getDocuments();
snapshot.documents.forEach((a) async {
if (a.data['postID'] == id&&
a.data['saver'] == globals.currentUser.uid) {
isSaved = true;
}
});
return isSaved;
}
The delete function actually deletes the document from my saved collection in firestore and the save function creates a document and saves.
Thank you in advance!

I think the problem is because you update the widget tree too fastly, or the flutter UI thread is locked by waiting the PostController job to finish...
In these lines:
onPressed: () {
setState(() {
isSaveLoading = true;
});
PostController().deleteSaved(id);
setState(() {
isSaveLoading = false;
});
},
Here I see that you want to update the loading state of the button. But the problem is that when you set isSaveLoading to true you don't wait for the PostController().deleteSaved(id) to finish before resetting isSaveLoading to false.
On another side, if PostController().deleteSaved() is doing a long job, since it's not async, it can lock the UI thread for a time, so you will never see your circular progress bar.
You can make the onPressed callback async and await for the PostController job.
onPressed: () async {
setState(() {
isSaveLoading = true;
});
// The deleteSaved function have to be async too
await PostController().deleteSaved(id);
setState(() {
isSaveLoading = false;
});
},
Hope this will help!

Related

Flutter - Want to show camera Tabbarview in full screen

I am building WhatsApp clone for demo. I want to hide AppBar and Tabbar when I click on Camera tab and I want CameraScreen in full screen. I hope, I could made very clear. I have also included whole code of the CameraScreen page thus you can understand(just edited to add whole code).
Sorry for uploading code late.
Thank you in advance.
Here is scree shot:Click here
class _CameraScreenState extends State<CameraScreen> {
CameraController? _cameraController;
// bool _isvideoRecording = false;
Future<void>? cameravalue;
bool isrecording = false;
String videopath = '';
XFile? videorecording;
bool flash = false;
bool isCameraFront = false;
double trasform = 0;
#override
void initState() {
// TODO: implement initState
super.initState();
_cameraController = CameraController(camera![0], ResolutionPreset.high);
cameravalue = _cameraController!.initialize();
}
#override
void dispose() {
// TODO: implement dispose
super.dispose();
_cameraController!.dispose();
}
#override
Widget build(BuildContext context) {
return Stack(
children: [
FutureBuilder(
future: cameravalue,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return CameraPreview(_cameraController!);
} else {
return const Center(
child: CircularProgressIndicator(),
);
}
},
),
Positioned(
bottom: 0,
child: Container(
padding: const EdgeInsets.only(
top: 5,
bottom: 5,
),
color: Colors.black,
width: MediaQuery.of(context).size.width,
child: Column(
children: [
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
IconButton(
onPressed: () {
setState(() {
flash = !flash;
});
flash
? _cameraController!.setFlashMode(FlashMode.torch)
: _cameraController!.setFlashMode(FlashMode.off);
},
icon: Icon(
flash ? Icons.flash_on : Icons.flash_off,
color: Colors.white,
size: 28,
),
),
GestureDetector(
onLongPress: () async {
await _cameraController!.startVideoRecording();
setState(() {
isrecording = true;
});
},
onLongPressUp: () async {
XFile videopath =
await _cameraController!.stopVideoRecording();
setState(() {
isrecording = false;
});
Navigator.push(
context,
MaterialPageRoute(
builder: (builder) => VideoView(
path: videopath.path,
)));
},
onTap: () {
if (!isrecording) {
takePhoto(context);
}
},
child: isrecording
? const Icon(
Icons.radio_button_on,
color: Colors.red,
size: 80,
)
: const Icon(
Icons.panorama_fish_eye,
color: Colors.white,
size: 70,
),
),
IconButton(
onPressed: () async {
setState(() {
isCameraFront = !isCameraFront;
trasform = trasform + pi;
});
int cameraPos = isCameraFront ? 0 : 1;
_cameraController = CameraController(
camera![cameraPos], ResolutionPreset.high);
cameravalue = _cameraController!.initialize();
},
icon: Transform.rotate(
angle: trasform,
child: const Icon(
Icons.flip_camera_ios,
color: Colors.white,
size: 30,
),
),
),
],
),
const SizedBox(
height: 4,
),
const Text(
'Hold for Video, tap for photo',
style: TextStyle(color: Colors.white),
textAlign: TextAlign.center,
),
],
),
),
)
],
);
}
void takePhoto(BuildContext context) async {
final path =
join((await getTemporaryDirectory()).path, "${DateTime.now()}.png");
XFile picture = await _cameraController!.takePicture();
picture.saveTo(path);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => CameraView(
path: path,
),
),
);
}
You can implement this features by doing the following simple steps. There will be another possible solutions.
First of all, create a new route ( new widget ) that contains camera view in fullscreen.
When you tap the camera tab, go to that route with fade-in or scale animation with faster duration that will make UI more realistic.

How to implement objectbox into flutter appilcation

I am working on an app, and need help trying to change my save method to object box. I have been using path_provider to save data but want to switch it to the object box database but I am struggling to do it. The goal is to have each timer button be clicked to record a time and present them back to the user to see how long each task/button took. Below is my code for my ViewModel and my timer_page dart files.
#Entity()
class StudyViewModel {
static List<Study> studies = [];
static List<ValueChanged<ElapsedTime>> timerListeners =
<ValueChanged<ElapsedTime>>[];
static Stopwatch stopwatch = new Stopwatch();
/// load from file...
static Future load() async {
try {
File file = await getFile();
String studiesJson = await file.readAsString();
if (studiesJson.isNotEmpty) {
List studiesParsed = json.decode(studiesJson);
studies = studiesParsed.map((i) => Study.fromJson(i)).toList();
}
} catch (e) {
print(e);
}
}
static Future<File> getFile() async {
final directory = await getApplicationDocumentsDirectory();
final path = directory.path;
return File('$path/studies.json');
}
static Future saveFile() async {
File file = await getFile();
file.writeAsString(json.encode(studies));
}
SizedBox(
height: 600,
child: GridView.count(
primary: false,
padding: const EdgeInsets.all(20),
crossAxisSpacing: 10,
mainAxisSpacing: 10,
crossAxisCount: 3,
children: widget.tasks.map((element) {
final isActive = activeTask != null && activeTask == element;
return GestureDetector(
onTap: () {
// set active task or toggle is active
if (isActive) {
setState(() {
activeTask = null;
StudyViewModel.stopwatch.start();
disable = true;
});
} else {
setState(() {
activeTask = element;
StudyViewModel.stopwatch.stop();
disable = false;
});
}
},
child: Container(
color: isActive ? Colors.amber : Colors.green,
padding: EdgeInsets.all(8),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
element.name,
style: TextStyle(color: Colors.white, fontSize: 25),
textAlign: TextAlign.center,
),
Text(
element.elapsedTime
)
]
),
),
);
}).toList(),
),
),
Expanded(
child: timerText,
),
Expanded(
flex: 0,
child: Padding(
padding: const EdgeInsets.only(bottom: 24.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
RaisedButton(
onPressed: disable
? null
: () {
setState(() {
StudyViewModel.stopwatch.reset();
});
},
color: Colors.red,
padding: EdgeInsets.symmetric(
horizontal: 60.0,
vertical: 20.0,
),
child: Text(
"Reset",
style: TextStyle(fontSize: 20.0, color: Colors.white),
),
),
RaisedButton(
onPressed: disable
? null
: () async {
await showDialog(
context: context,
builder: (context) {
return AlertDialog(
content: Text('Do you wish to save a time study?'),
actions: <Widget>[
FlatButton(
child: Text('Accept'),
onPressed: () async {
StudyViewModel.saveFile();
Navigator.of(context).pop();
},
),
FlatButton(
child: Text('Cancel'),
onPressed: () {
Navigator.of(context).pop();
},
),
]
);
}
);

Local camera in first video call is not working in Flutter app with Agora (using agora_rtc_engine 4.0.7)

I integrated Agora in Flutter Application with the help of agora_rtc_engine 4.0.7, but upon making a video call for the very first time the local camera view is not working. When we disconnect the call and call back again then everything works fine, the local camera view started working.
Again when we kill the application from Phone memory and rerun it then also the same problem occurs for the first time.
VideoCallingScreen.dart file
class VideoCallingScreen extends StatefulWidget {
String doctorId;
String bookingId;
VideoCallingScreen(this.doctorId, this.bookingId);
#override
_VideoCallingScreenState createState() => _VideoCallingScreenState();
}
class _VideoCallingScreenState extends State<VideoCallingScreen> {
int? _remoteUid;
RtcEngine? _engine;
bool isJoined = false,
switchCamera = true,
switchRender = true,
muteAudio = false,
muteVideo = false;
bool remoteUserMicMute = false, remoteUserVideoMute = false;
bool resizeVideo = false;
ServerHandler _serverHandler = ServerHandler();
String? token;
String? channelName;
String? channelId;
late user.Details userDetails;
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
#override
void initState() {
super.initState();
getAgoraToken().then((value) {
if (value) {
initForAgora();
} else {
_showMyDialog();
}
});
// initForAgora();
}
Future<void> _showMyDialog() async {
return showDialog<void>(
context: context,
barrierDismissible: false, // user must tap button!
builder: (BuildContext context) {
return AlertDialog(
title: const Text('No Channel Found'),
content: SingleChildScrollView(
child: ListBody(
children: const <Widget>[
Text('No video channel has been created by the Doctor'),
],
),
),
actions: <Widget>[
TextButton(
child: const Text('Ok'),
onPressed: () async {
// int count = 0;
Navigator.pop(context);
Navigator.pop(_scaffoldKey.currentContext!);
},
),
],
);
},
);
}
Future<bool> getAgoraToken() async {
await Screen.keepOn(true);
var tokenBody = await _serverHandler.joinAgoraChannel(
widget.doctorId, widget.bookingId);
print('token Body from videoPage' + tokenBody.toString());
if (tokenBody['success'] == 1) {
setState(() {
token = tokenBody['channel']['access_token_patient'];
channelName = tokenBody['channel']['channel_name'];
print('**********Token Set********' + token!);
channelId = tokenBody['channel']['id'].toString();
});
return true;
} else {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(
"Unable to get Video Call Token, Please check your internet Connection and try again."),
));
return false;
}
}
Future<void> initForAgora() async {
// retrieve permissions
await [Permission.microphone, Permission.camera].request();
userDetails = await _serverHandler.getUserProfile();
//create the engine
_engine = await RtcEngine.create(appId);
await _engine?.enableVideo();
_engine?.setEventHandler(
RtcEngineEventHandler(
joinChannelSuccess: (String channel, int uid, int elapsed) async {
print("local user $uid joined");
// await _engine!.enableVideo();
},
userJoined: (int uid, int elapsed) {
print("remote user $uid joined");
setState(() {
_remoteUid = uid;
});
},
tokenPrivilegeWillExpire: (token) async {
await getAgoraToken();
await _engine?.renewToken(token);
},
userOffline: (int uid, UserOfflineReason reason) {
print("remote user $uid left channel");
// _engine!.enableVideo();
setState(() {
_remoteUid = null;
});
_userLeftTheCall();
},
userMuteVideo: (int uid, bool isMute) {
print('Audio Mutted');
setState(() {
remoteUserVideoMute = isMute;
});
},
userMuteAudio: (int uid, bool isMute) {
print('Audio Mutted');
setState(() {
remoteUserMicMute = isMute;
});
},
),
);
await getAgoraToken();
await _engine?.joinChannel(token, channelName!, null, userDetails.id!);
}
// Create UI with local view and remote view
#override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: _onWillPop,
child: Scaffold(
key: _scaffoldKey,
body: SafeArea(
child: Stack(
children: [
Center(
child:
resizeVideo ? _renderLocalPreview() : _renderRemoteVideo(),
),
if (remoteUserVideoMute)
BackdropFilter(
filter: ImageFilter.blur(
sigmaX: 10,
sigmaY: 10,
),
child: Padding(
padding: const EdgeInsets.only(bottom: 32),
child: Center(
child: Text(
'Doctor video Paused',
style: TextStyle(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.bold),
textAlign: TextAlign.center,
),
),
),
),
if (remoteUserMicMute)
Padding(
padding: const EdgeInsets.only(top: 32),
child: Center(
child: Text(
'Doctor Mic Muted',
style: TextStyle(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.bold),
textAlign: TextAlign.center,
),
),
),
Positioned(
top: 8,
left: 8,
child: InkWell(
//Uncomment it to unable resize
// onTap: () {
// setState(() {
// resizeVideo = !resizeVideo;
// });
// },
child: Container(
width: 100,
height: 120,
child: Stack(
children: [
ImageFiltered(
imageFilter: muteVideo
? ImageFilter.blur(sigmaX: 3.0, sigmaY: 3.0)
: ImageFilter.blur(sigmaX: 0, sigmaY: 0),
child: resizeVideo
? _renderRemoteVideo()
: _renderLocalPreview(), // Widget that is blurred
),
if (muteVideo)
Positioned(
top: 4,
left: 4,
child: Icon(
Icons.videocam_off_outlined,
color: Colors.white,
size: 32,
),
),
if (muteAudio)
Positioned(
bottom: 4,
right: 4,
child: Icon(
Icons.mic_off_outlined,
color: Colors.white,
size: 32,
),
),
],
),
),
),
),
Positioned(
bottom: 32,
right: 8,
left: 8,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
InkWell(
onTap: () async {
await Screen.keepOn(false);
await _engine?.leaveChannel();
await _serverHandler.leaveChannel(channelId!);
Navigator.pop(_scaffoldKey.currentContext!);
},
child: Container(
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50),
color: Colors.red),
child: Icon(
Icons.call_end,
color: Colors.white,
),
),
),
InkWell(
onTap: this._switchCamera,
child: Container(
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50),
color: Colors.white),
child: Icon(
Icons.flip_camera_android_rounded,
color: Colors.black87,
),
),
),
InkWell(
onTap: this._onToggleMuteVideo,
child: Container(
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50),
color: Colors.white),
child: Icon(
muteVideo
? Icons.videocam_off_outlined
: Icons.videocam_outlined,
color: Colors.black87,
),
),
),
InkWell(
onTap: this._onToggleMute,
child: Container(
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50),
color: Colors.white),
child: Icon(
muteAudio
? Icons.mic_off_outlined
: Icons.mic_none_outlined,
color: Colors.black87,
),
),
),
],
),
)
],
),
),
),
);
}
// current user video
Widget _renderLocalPreview() {
return RtcLocalView.SurfaceView();
}
// remote user video
Widget _renderRemoteVideo() {
// return RtcRemoteView.SurfaceView(uid: 70);
if (_remoteUid != null) {
return RtcRemoteView.SurfaceView(uid: _remoteUid!);
} else {
return Text(
'Please wait, doctor is joining shortly',
style: TextStyle(
color: Colors.white, fontSize: 16, fontWeight: FontWeight.bold),
textAlign: TextAlign.center,
);
}
}
_switchCamera() {
_engine?.switchCamera().then((value) {
setState(() {
switchCamera = !switchCamera;
});
}).catchError((err) {
log('switchCamera $err');
});
}
void _onToggleMute() {
setState(() {
muteAudio = !muteAudio;
});
_engine!.muteLocalAudioStream(muteAudio);
}
void _onToggleMuteVideo() {
setState(() {
muteVideo = !muteVideo;
});
_engine!.muteLocalVideoStream(muteVideo);
}
Future<bool> _onWillPop() async {
return (await showDialog(
context: _scaffoldKey.currentContext!,
builder: (context) => new AlertDialog(
title: new Text('Are you sure?'),
content: new Text('Do you want to exit exit Video Call?'),
actions: <Widget>[
TextButton(
onPressed: () => Navigator.pop(_scaffoldKey.currentContext!),
child: new Text('No'),
),
TextButton(
onPressed: () async {
await Screen.keepOn(false);
await _serverHandler.leaveChannel(channelId!);
await _engine?.leaveChannel();
Navigator.pop(_scaffoldKey.currentContext!);
Navigator.pop(_scaffoldKey.currentContext!);
},
child: new Text('Yes'),
),
],
),
)) ??
false;
}
_userLeftTheCall() async {
return (await showDialog(
context: _scaffoldKey.currentContext!,
builder: (context) => new AlertDialog(
title: new Text('Doctor Left'),
content: new Text('Doctor left this call please join Again'),
actions: <Widget>[
TextButton(
onPressed: () async {
// await _serverHandler.leaveChannel(channelId!);
await Screen.keepOn(false);
await _engine?.leaveChannel();
Navigator.pop(_scaffoldKey.currentContext!);
Navigator.pop(_scaffoldKey.currentContext!);
// Navigator.of(context).pop(true);
},
child: new Text('Okay'),
),
],
),
)) ?? false;
}
}
Please ignore things which are not relevent. Also the log is too long to share, the log keeps on running during the entire video call.
Mobile Screenshot
Thank You

Show circular indicator while getting the current location in Flutter?

I have trying to get current location with Location.when i call the function in button it will ask for enable location but after enable location it take some time to fetch location data instead of that after i press the button a circular indicator should show with in button.This is is what i did.the problem is the circular indicator doesn't show
Submit button
Flexible(
flex: 0,
child: Padding(
padding: EdgeInsets.symmetric(vertical: 160),
child: GestureDetector(
child: Container(
height: 60,
width: double.infinity,
color: Color.fromRGBO(34, 83, 148, 1),
child: ProgressButton(),//Progress Widget
),
onTap: () {
//getLocation function
_getLocation();
},
),
),
)
_getLocation function
Future _getLocation() async {
Location location = new Location();
LocationData _currentPosition = await location.getLocation();
setState(() {
SharedPrefrence().setLatitude(_currentPosition.latitude.toString());
SharedPrefrence().setLongitude(_currentPosition.longitude.toString());
islocateCompelete = true;
});
Future loginstatus = SharedPrefrence().getLogedIn();
Future gust_status = SharedPrefrence().getGustLogedIn();
gust_status.then((gustdata) {
loginstatus.then((data) {
if (data == true || gustdata == true) {
Navigator.pop(context, true);
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(builder: (context) => HomeScreen()),
ModalRoute.withName("/login"));
} else {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => LoginScreen(),
),
);
}
});
});
}
ProgressButton Widget
Widget ProgressButton() {
if (islocateCompelete == true) {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(Colors.white)),
],
);
} else {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(
Icons.location_searching,
color: Colors.white,
size: 20,
),
Text(
"Locate Me",
style: TextStyle(
color: Colors.white, fontSize: 15, fontWeight: FontWeight.bold),
),
],
);
}
}
You need to call setState() with isLocateCompelete = false before you start fetching location.
Future _getLocation() async {
setState(() {
islocateCompelete = false;
});
Location location = new Location();
var _permissionGranted = await location.hasPermission();
if (_permissionGranted == PermissionStatus.denied) {
_permissionGranted = await location.requestPermission();
if (_permissionGranted != PermissionStatus.granted) {
setState(() {
islocateCompelete = true;
});
return;
}
}
LocationData _currentPosition = await location.getLocation();
//...
//...
//rest of the code
}

Flutter A RenderFlex overflowed by 99469 pixels on the bottom

I am new to flutter and trying to solve the below issue, in the first screenshot I have labelStart line 127 value as 1.21, when i pass that value using the variable i get renderflex error, if i am using hardcoded i don't get any error. Not sure what i am doing wrong. I tried adding Expanded after reading few posts online but that didn't help. Can someone please guide me on what mistake i am doing here?
class _ListPageState extends State<ListPage> with SingleTickerProviderStateMixin {
List<MusicModel> _list;
var _value;
int _playId;
String _playURL;
bool isPlaying = false;
String _startTime;
String _endTime;
AnimationController _controller;
AudioPlayer _audioPlayer = AudioPlayer();
#override
void initState() {
_playId = 0;
_list = MusicModel.list;
_controller = AnimationController(vsync: this,duration: Duration(microseconds: 250));
_value = 0.0;
_startTime="0.0";
_endTime="0.0";
super.initState();
_audioPlayer.onAudioPositionChanged.listen((Duration duration) {
setState(() {
_startTime = duration.toString().split(".")[0];
});
});
_audioPlayer.onDurationChanged.listen((Duration duration) {
setState(() {
_endTime = duration.toString().split(".")[0];
});
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
elevation: 0,
backgroundColor: AppColors.mainColor,
centerTitle: true,
title: Text("Skin - Flume",
style: TextStyle(color: AppColors.styleColor),),
),
backgroundColor: AppColors.mainColor,
body: Stack(
children: <Widget>[
Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(24.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
CustomButtonWidget(
child: Icon(
Icons.favorite,
color: AppColors.styleColor,
),
size: 50,
onTap: (){
},
),
CustomButtonWidget(
image: 'assets/logo.jpg',
size: 100,
borderWidth: 5,
onTap: (){
Navigator.of(context).push(
MaterialPageRoute(builder: (_) => DetailPage(),
),
);
},
),
CustomButtonWidget(
child: Icon(
Icons.menu,
color: AppColors.styleColor,
),
size: 50,
onTap: (){
Navigator.of(context).push(
MaterialPageRoute(builder: (_) => HomePage(),
),
);
},
)
],
),
),
//Progress bar section
// Expanded(child: SizedBox()),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 24),
child: CustomProgressWidget(
value: _value,
labelStart: "1.21",
labelend: "2.34",
),
),
// Expanded(child: SizedBox()),
Expanded( //This is added so we can see overlay else this will be over button
child: ListView.builder(
physics: BouncingScrollPhysics(),//This line removes the dark flash when you are at the begining or end of list menu. Just uncomment for
itemCount: _list.length,
padding: EdgeInsets.all(12),
itemBuilder: (context,index){
return GestureDetector(
onTap: (){
Navigator.of(context).push(
MaterialPageRoute(builder: (_) => DetailPage(),
),
);
},
child: AnimatedContainer(
duration: Duration(milliseconds: 500),
//This below code will change the color of sected area or song being played.
decoration: BoxDecoration(
color: _list[index].id == _playId
? AppColors.activeColor
: AppColors.mainColor,
borderRadius: BorderRadius.all(
Radius.circular(20),
),
),
//End of row color change
child: Padding(
padding: const EdgeInsets.all(16), //This will all padding around all size
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, //This will allign button to left, else button will be infront of name
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
_list[index].title,
style: TextStyle(
color: AppColors.styleColor,
fontSize: 16,
),
),
Text(
_list[index].album,
style: TextStyle(
color: AppColors.styleColor.withAlpha(90),
fontSize: 16,
),
),
],
),
CustomButtonWidget( //This is Play button functionality on list page.
child: Icon(
_list[index].id == _playId
? Icons.pause
: Icons.play_arrow,
color: _list[index].id == _playId
? Colors.white
: AppColors.styleColor,
),
size: 50,
isActive: _list[index].id == _playId,
onTap: () async {
if (isPlaying){
if (_playId == _list[index].id){
int status = await _audioPlayer.pause();
if (status == 1){
setState(() {
isPlaying = false;
});
}
} else {
_playId = _list[index].id;
_playURL = _list[index].songURL;
_audioPlayer.stop();
int status = await _audioPlayer.play(_playURL);
if (status == 1){
setState(() {
isPlaying = true;
});
}
}
// int status = await _audioPlayer.pause();
// if (status == 1){
// setState(() {
// isPlaying = false;
// });
// }
} else {
_playId = _list[index].id;
_playURL = _list[index].songURL;
int status = await _audioPlayer.play(_playURL);
if (status == 1){
setState(() {
isPlaying = true;
});
}
} // String filePath = await FilePicker.getFilePath();
},
// onTap: (){
// setState(() {
// _playId = _list[index].id;
// });
// },
)
],
),
),
),
);
},
),
)
],
),
Align(
alignment: Alignment.bottomCenter,
child: Container(
height: 50,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
AppColors.mainColor.withAlpha(0),
AppColors.mainColor,
],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
)
),
),
)
],
),
);
}
}
After changing line 1.27 with a dynamic value variable.
You have to wrap you Column in a scrollview like SingleChildScrollView or ListView. This error occurs when the items in column take more space than available.
I had the same problem, and my problem was my variable extracted of my state it took too long in show and showed first the widget after the variable.
In my case use Getx, and fixed for this way:
My old code:
GetX<UserController>(
builder: (_){
return Text(_.user.name);
}
},
),
My new code
GetX<UserController>(
builder: (_){
if(_.user.email != null){
return Text(_.user.name);
}else{
return Text('Loading....');
}
},
),