In flutter I need to hide button after 1 mins - flutter

I need to hide button after 1 mins but while reloading and again restarting application it will not show again once it hide it will not repeated

Use shared_preferences (or any persist memory) to persist the state of the button over restarts.
See Store key-value data on disk for details.

You need to use db to handle restarting application case.
You can use shared_preferences to store a flag about visibility.
class _GState extends State<G> {
static const String _buttonVisibilityKey = "DoneWIthButtonX";
bool showButton = false;
#override
void initState() {
super.initState();
_buttonActionChecker().then((value) async {
// return false if button never showed up, activate the timer to hide
print(value);
if (!value) {
showButton = true;
setState(() {});
Future.delayed(Duration(minutes: 1)).then((value) async {
showButton = false;
SharedPreferences.getInstance()
.then((value) => value.setBool(_buttonVisibilityKey, true));
setState(() {});
});
}
});
}
#override
void dispose() {
super.dispose();
}
/// is the button have been shown already return true
Future<bool> _buttonActionChecker() async {
return SharedPreferences.getInstance().then((value) {
return value.getBool(_buttonVisibilityKey) ?? false;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: showButton
? FloatingActionButton(
onPressed: () {
setState(() {});
},
)
: null,
);
}
}

Related

ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: dependOnInheritedWidgetOfExactType<_InheritedProviderSco

i am trying to load api data in init state with provider ,but this error is throwing,i wrapped parent widget with multiprovider and added changenotifier provider also, seems like some error with context of provider but i coudnt find the issue
bool isPostdataloading = false;
bool iscommentsLoading = false;
List<CommentsModelData> commentsCollections = [];
List<SingleUserPostModelData> userPostCollections = [];
#override
void initState() {
super.initState();
getpostdata();
getComments();
}
getpostdata() async {
setState(() {
isPostdataloading = true;
});
userPostCollections =
await SingleUserPostService().getSingleuserPost(postid: widget.postid);
print(userPostCollections[0].commentCount);
setState(() {
isPostdataloading = false;
});
}
getComments() async {
setState(() {
iscommentsLoading = true;
});
commentsCollections =
Provider.of<CommentPageProvider>(context).loadComments(widget.postid);
// commentsCollections =
// await CommentService().getCommentsdata(post_id: widget.postid);
// print(commentsCollections[0].status);
setState(() {
iscommentsLoading = false;
});
}
#override
Widget build(BuildContext context) {
TextEditingController commentTextEditingController =
TextEditingController();
return ChangeNotifierProvider<CommentPageProvider>(
create: (context) => CommentPageProvider(),
child: Scaffold(
bottomNavigationBar: postcomment(widget.postid),
This error happened because you used context that related to the parents of ChangeNotifierProvider, try put your functions inside addPostFrameCallback:
#override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
getpostdata();
getComments();
});
}

Flutter How can I use setState and only change one area and leave the other as it is?

I want a page that has a timer and also displays math problems. and whenever the correct answer has been entered, a new task should appear. But the problem is that whenever a new task appears, the timer is reset. How can I prevent this ?
late Timer timer;
double value = 45;
void startTimer() {
timer = Timer.periodic(const Duration(seconds: 1), (timer) {
if (value > 0) {
setState(() {
value--;
});
} else {
setState(() {
timer.cancel();
});
}
});
}
#override
void initState() {
// TODO: implement initState
super.initState();
startTimer();
}
#override
void dispose() {
controller.dispose();
super.dispose();
}
void userTextFieldInput() {
controller.addListener(
() {
String rightResult = (firstIntValue + secondIntValue).toString();
String userResult = controller.text;
if (rightResult == userResult) {
setState(() {
DatabaseHelper(
firstUserValue: firstIntValue,
secondUserValue: secondIntValue,
finalUserResult: int.parse(controller.text),
).setDB();
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => const CalculatePage(),
),
);
});
} else if (controller.text.length >= 2) {
controller.clear();
}
},
);
}
You should create two different state, one for timer and another one for the problems.
You can use the package flutter bloc to manage these state easily.

setState is not calling when Navigating to another page

I am checking the connectivity using Connectivity().checkConnectivity() it is working but the setState() is not calling when I navigate to this page.
To navigate to main page to another page I am using Navigator.push(context, MaterialPageRoute(builder: (context) => search()));
and here is my next page
class search extends StatefulWidget {
#override
_searchState createState() => _searchState();
}
class _searchState extends State<search> {
List<filter> _list = [];
List<filter> to_display = [];
bool isoffline;
Future<void> connectivity() async {
var connectivityResult = await (Connectivity().checkConnectivity());
if (connectivityResult == ConnectivityResult.mobile) {
// I am connected to a mobile network.
setState(() {
isoffline = true;
});
print("connected");
} else if (connectivityResult == ConnectivityResult.wifi) {
setState(() {
isoffline = true;
});
// I am connected to a wifi network.
print("connected");
} else {
setState(() {
isoffline = false;
});
print(
"dissconneteddsfffffffffffffffffffffffffffffffffffffffffffffffffffffffdsfsd");
}
}
Future _future;
#override
void initState() {
mylist().then((value) {
setState(() {
_list = to_display = value;
});
});
connectivity();
print("value${isoffline}"); // this value is on null
_future = data();
super.initState();
}
print("value${isoffline}"); // this value is on null
The function connectivity is an asynchronous function. You are calling the function and immediately checking the boolean value, that's why you are getting null. You have to wait till the execution, either by using await or then syntax.
connectivity().then((value) {
print("value ${isoffline}");
});
In your code connectivity(); method is async which mean it will require some time to complete.
Now when init method is called it executes connectivity(); and then immediately executes print("value${isoffline}"); now the value for isoffline initially is null, hence null printed
solution is either you put print("value${isoffline}"); in connectivity(); method or try to add it after build method.
#override
Widget build(BuildContext context) {
connectivity();
print("value${isoffline}");
return YourWidget();
}

getting code to run upon widget creation flutter

I have a flutter camera app and am able to get a recorded video to play. The problem is, I am only able to get it to play when a button is pressed. How do I get the code to run when the widget(screen) is created instead of when the button is pressed so I don't have to press a button to get it to play? Here is my code:
Here is the code for when the button is pressed:
//raised button
RaisedButton(
onPressed: () {stopButtonPressed();},
//stopButtonPressed
void stopButtonPressed() {
print('stopButtonPressed hit');
stopVideoRecording().then((_) {
print('StopVideoRecording complete');
});
}
//stopVideoRecording
Future<void> stopVideoRecording() async {
print('stopVideoRecording hit');
await _startVideoPlayer();
}
//_startVideoPlayer
Future<void> _startVideoPlayer() async {
print('_startVideoPlayer hit');
print(Provider.of<SendDataModel>(context, listen: false).displayImageVideo());
final VideoPlayerController vcontroller =
VideoPlayerController.file(File(Provider.of<SendDataModel>(context, listen: false).displayImageVideo()));
videoPlayerListener = () {
if (videoController != null && videoController.value.size != null) {
if (mounted) setState(() {});
videoController.removeListener(videoPlayerListener);
}
};
vcontroller.addListener(videoPlayerListener);
await vcontroller.setLooping(true);
await vcontroller.initialize();
await videoController?.dispose();
if (mounted) {
setState(() {
//saveImagePath = null;
videoController = vcontroller;
});
}
await vcontroller.play();
} //startVideoPlayer
Thanks!
You can call the function from initState(). initState() is called only once when the StatefulWidget is inserted into the Widget tree, so it's a good place to initialize variables or do what you're trying to do.
class _MyHomePageState extends State<MyHomePage> {
#override
void initState() {
super.initState();
// Do anything you need done here
_startVideoPlayer();
// If you want a slight delay, use Future.delayed
Future.delayed(Duration(seconds: 1), (){
_startVideoPlayer();
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
// rest of app

flutter - Avoiding whole widget rebuild

Trying a 'like button' within a Future builder with many other widgets as below ,
onPressed: () {
if (aleadyLiked.length > 0) {
unlike(profileId);
} else {
like(profileId);
}
setState(() {});
},
And this is how my future builder starts,
#override
Widget build(BuildContext context) {
return FutureBuilder(
future: getProfile(profileId),
builder: (context, snapshot) {
=======Other widgets here======
}
Issue is onPressed of the like icon-button I am doing the setState() which is causing the whole Future builder to reload , Is there a way just to update the Like Button and the Like count , I was thinking to use some client side counter logic which callbacks to actual DB updates .Please help.
Loading Profile part on initState() can be achieved, but how to handle updating and reflecting 'Likes' , can that Like-button region alone be reloaded ?
You should not get this User Profile like this, but what you can do rather, you can get the user profile inside the initState, and before data is not loaded you can show either loader of something.
Something like this...
User _user;
Future<User> getUserProfile(profileId) async{
///Todo : Implementation of get User Profile
}
#override
void initState() {
// TODO: implement initState
super.initState();
getUserProfile("userId").then((user){
setState(() {
_user =user;
});
})
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: this._user == null ? CircularProgressIndicator() : UserWidget(),
);
}
So this is how I finally achieved it ,
void initState() {
getProfile(profileId).then((user){
setState(() {
_profile =user;
_counter =_profile.profilelikes.length;
_isAlreadyLiked=_profile.allreadyliked.length > 0;
});
});
super.initState();
}
And OnPressed() is
onPressed: () {
if (_isAlreadyLiked) {
unlike(profileId);
setState(() {
_counter--;
_isAlreadyLiked=false;
});
} else {
like(profileId);
setState(() {
_counter++;
_isAlreadyLiked=true;
});
}
},
Downside : The likes by other users will reflect on Wiget reload only, which is fine for me , for now.