Flutter setState not updating values - flutter

Hi there a Flutter newbie here.
I have a project to be submitted via flutter. This is my main code and it's not updating text to stop when button was clicked.
import 'package:assets_audio_player/assets_audio_player.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:url_launcher/url_launcher_string.dart';
import 'firebase_options.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'FM Mahanama',
theme: ThemeData(
primaryColor: const Color(0xfffbc02d),
primarySwatch: Colors.amber,
useMaterial3: true,
),
darkTheme: ThemeData(
primaryColor: const Color(0xfffbc02d),
primarySwatch: Colors.amber,
brightness: Brightness.dark,
useMaterial3: true,
),
themeMode: ThemeMode.system,
debugShowCheckedModeBanner: false,
home: const MyHomePage(title: 'FM Mahanama'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _selectedAppIndex = 0;
IconData iconPlayStop = Icons.play_arrow_rounded;
String txtPlayStop = "Play";
static final assetsAudioPlayer = AssetsAudioPlayer();
#override
void initState() {
WidgetsFlutterBinding.ensureInitialized();
initFirebaseActivities();
}
void initFirebaseActivities() {
Firebase.initializeApp();
}
static Future<void> initRadioPlayer(param0) async {
try {
await assetsAudioPlayer.open(
Audio.liveStream(param0),
showNotification: true,
autoStart: true,
);
} catch (t) {
AlertDialog(title: const Text("Error"), content: Text(t.toString()),);
}
}
void updateButtonText(String txt, IconData iconData){
setState(() {
txtPlayStop = txt;
iconPlayStop = iconData;
});
}
#override
void dispose() {
if(assetsAudioPlayer.isPlaying.value){
assetsAudioPlayer.stop();
}
}
static void _openFacebookPage() async {
String fbProtocolUrl = "fb://page/865683116816630";
String fallbackUrl = "https://www.facebook.com/mcrcofficial/";
try {
bool launched = await launchUrlString(fbProtocolUrl);
if (!launched) {
await launchUrlString(fallbackUrl);
}
} catch (e) {
await launchUrlString(fallbackUrl);
}
}
late final Set<Widget> _appPages = <Widget>{
Center(
child: StreamBuilder<DocumentSnapshot<Map<String, dynamic>>>(
stream: FirebaseFirestore.instance
.collection("public")
.doc("stream")
.snapshots(),
builder: (BuildContext context,
AsyncSnapshot<DocumentSnapshot<Map<String, dynamic>>> data) {
if (data.hasData) {
if (!data.data?.get("onair")) {
if (assetsAudioPlayer.isPlaying.value) {
assetsAudioPlayer.stop();
}
}
return Visibility(
replacement: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Padding(
padding: const EdgeInsets.fromLTRB(0.0, 0.0, 0.0, 20.0),
child: Image.asset(
"assets/images/app_logo.png",
width: 200.0,
fit: BoxFit.cover,
),
),
const Text(
"FM Mahanama is currently offline!",
style: TextStyle(fontSize: 18.0),
),
const Padding(
padding: EdgeInsets.fromLTRB(0.0, 20.0, 0.0, 20.0),
child: Text(
"Checkout our Facebook for page more information"),
),
Padding(
padding: const EdgeInsets.fromLTRB(0.0, 0.0, 0.0, 20.0),
child: TextButton.icon(
onPressed: () {
_openFacebookPage();
},
icon: const Icon(Icons.link_rounded),
label: const Text("Facebook Page"),
),
),
],
),
),
visible: data.data?.get("onair"),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Padding(
padding: const EdgeInsets.fromLTRB(0.0, 0.0, 0.0, 30.0),
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30.0)),
elevation: 10.0,
child: ClipRRect(
borderRadius: BorderRadius.circular(30.0),
child: Image.network(
data.data?.get("cover_img"),
width: 300.0,
height: 300.0,
fit: BoxFit.fitHeight,
),
),
),
),
const Padding(
padding: EdgeInsets.fromLTRB(0.0, 0.0, 0.0, 5.0),
child: Text(
"Now Playing",
style: TextStyle(fontSize: 22.0),
),
),
Padding(
padding: const EdgeInsets.fromLTRB(0.0, 0.0, 0.0, 20.0),
child: Text(
data.data!.get("nowplaying").toString(),
style: const TextStyle(
fontSize: 24.0, fontWeight: FontWeight.w600),
),
),
const Padding(
padding: EdgeInsets.fromLTRB(0.0, 0.0, 0.0, 5.0),
child: Text(
"By",
style: TextStyle(fontSize: 18.0),
),
),
Padding(
padding: const EdgeInsets.fromLTRB(0.0, 0.0, 0.0, 30.0),
child: Text(
data.data!.get("by").toString(),
style: const TextStyle(
fontSize: 22.0, fontWeight: FontWeight.w600),
),
),
ElevatedButton.icon(
onPressed: () {
if(!assetsAudioPlayer.isPlaying.value) {
initRadioPlayer(data.data?.get("link"));
updateButtonText("Stop", Icons.stop_rounded);
}else{
assetsAudioPlayer.stop();
updateButtonText("Play", Icons.play_arrow_rounded);
}
},
label: Text(getButtonString(), style: const TextStyle(fontSize: 24.0),),
icon: Icon(iconPlayStop, size: 24.0,),
),
],
),
),
);
} else {
return const Text("There is a error loading data!");
}
},
),
),
const Center(
child: Text("Scoreboard"),
),
const Center(
child: Text("About"),
),
};
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Center(
child: Text(widget.title),
),
),
body: Center(
child: _appPages.elementAt(_selectedAppIndex),
),
bottomNavigationBar: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
backgroundColor: Colors.transparent,
elevation: 0,
currentIndex: _selectedAppIndex,
selectedFontSize: 14,
unselectedFontSize: 14,
showUnselectedLabels: false,
onTap: (value) {
setState(() {
_selectedAppIndex = value;
});
},
items: const [
BottomNavigationBarItem(
label: "Player",
icon: Icon(Icons.music_note_rounded),
),
BottomNavigationBarItem(
label: "Scoreboard",
icon: Icon(Icons.scoreboard_rounded),
),
BottomNavigationBarItem(
label: "About",
icon: Icon(Icons.info_rounded),
),
],
),
);
}
static String getButtonString() {
if(assetsAudioPlayer.isPlaying.value){
return "Stop";
}else{
return "Play";
}
}
}
What I want is to update the button text and icon stop text and icon to when the button is pressed and the player is playing and vice versa.
I am using the latest build of flutter with material design widgets. I am building for android and ios.

you need to tell your code when did you change the state by doing setState()
ElevatedButton.icon(
onPressed: () {
setState(() {// add this whenever you want to change the values and update your screen
if(!assetsAudioPlayer.isPlaying.value) {
initRadioPlayer(data.data?.get("link"));
updateButtonText("Stop", Icons.stop_rounded);
}else{
assetsAudioPlayer.stop();
updateButtonText("Play", Icons.play_arrow_rounded);
}
});
},
label: Text(getButtonString(), style: const
TextStyle(fontSize: 24.0),),
icon: Icon(iconPlayStop, size: 24.0,),
),

You can use like that:
ElevatedButton.icon(
onPressed: () async {
await getButtonString();
setState(() {
});
},
label: Text(getButtonString(), style: const
TextStyle(fontSize: 24.0),),
icon: Icon(iconPlayStop, size: 24.0,),
),
For more information https://dart.dev/codelabs/async-await

I found a solution for this. It seems that setState isn't working for my app. So I implemented ValueNotifier and ValueListenableBuilder to update the values.
First I initialised the variables
ValueNotifier<IconData> iconPlayStop = ValueNotifier(Icons.play_arrow_rounded);
ValueNotifier<String> txtPlayStop = ValueNotifier("Play");
Then in button on click I updated the code to change the values on both value notifiers.
onPressed: () {
if(!assetsAudioPlayer.isPlaying.value) {
initRadioPlayer(data.data?.get("link"));
txtPlayStop.value = "Stop";
iconPlayStop.value = Icons.stop_rounded;
iconPlayStop.notifyListeners();
}else{
assetsAudioPlayer.stop();
txtPlayStop.value = "Play";
iconPlayStop.value = Icons.play_arrow_rounded;
}
},
Then on both label and icon I added ValueListenableBuilders
label: ValueListenableBuilder(
valueListenable: txtPlayStop,
builder: (BuildContext context, String value, Widget? child) => Text(value, style: const TextStyle(fontSize: 24.0),),
),
icon: ValueListenableBuilder(
valueListenable: iconPlayStop,
builder: (BuildContext context, IconData value, Widget? child) => Icon(value, size: 24.0,),
),

Related

Problem in multilingualizing the app in flutter

I encountered a problem in making my app multilingual.
On the other pages of my app, when the code
S.of(context).myText is called, the code works correctly and And the text corresponding to the language chosen by the audience is displayed, but on the one class of my app named Home, by calling this program code, regardless of the selected language, only the English text is displayed shows even if I choose Malaysia or Arabic.
Interestingly, when I build the project with Chrome, there is no problem, but when I download the apk from it, it does not work on the mobile.
the problem is with S.of(context).Home_drawer_mainMenu, in below code:
my Home class:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:smooth_page_indicator/smooth_page_indicator.dart';
import 'package:untitled22/SignUp.dart';
import 'package:untitled22/TabBarViewHome.dart';
import 'package:untitled22/loginFile.dart';
import './Page_1.dart';
import './Page_2.dart';
import './Page_3.dart';
import './Page_4.dart';
import 'LanguageChangeProvider.dart';
import 'package:untitled22/generated/l10n.dart';
void main() {
runApp(const MaterialApp(
home: HomePage(),
debugShowCheckedModeBanner: false,
));
}
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
#override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
int pageNumb = 0;
late TabController _controller;
String _currentLanguage = 'ar';
bool rtl = false;
#override
void initState() {
_loadCounter();
super.initState();
}
_loadCounter() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
setState(() {
_currentLanguage = (prefs.getString('currentLang') ?? '');
rtl = (prefs.getBool('isRtl') ?? false);
});
}
#override
Widget build(BuildContext context) {
return MaterialApp(
locale: new Locale(_currentLanguage),
localizationsDelegates: [
S.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: S.delegate.supportedLocales,
home: BodyBody(),
debugShowCheckedModeBanner: false,
showSemanticsDebugger: false,
);
}
}
class BodyBody extends StatefulWidget {
const BodyBody({Key? key}) : super(key: key);
#override
State<BodyBody> createState() => _BodyBodyState();
}
class _BodyBodyState extends State<BodyBody> with SingleTickerProviderStateMixin {
int pageNumb = 0;
late TabController _controller;
String _currentLanguage = '';
bool rtl = false;
#override
void initState() {
_loadCounter();
super.initState();
_controller = TabController(vsync: this, length: 3, initialIndex: 1);
}
_loadCounter() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
setState(() {
_currentLanguage = (prefs.getString('currentLang') ?? 'ar');
rtl = (prefs.getBool('isRtl') ?? false);
});
}
#override
Widget build(BuildContext context) {
Size media = MediaQuery.of(context).size;
var height = AppBar().preferredSize.height;
TextEditingController textController = TextEditingController();
return DefaultTabController(
initialIndex: 1,
length: 3,
child: Scaffold(
appBar: AppBar(
titleSpacing: 0,
title: Text(
S.of(context).Home_drawer_mainMenu,
style: TextStyle(
color: Color(0xFF434343),
fontSize: rtl == true ? 16 : 14,
),
),
backgroundColor: const Color(0xff26c6da),
leading: Builder(
builder: (BuildContext context) {
return Container(
child: IconButton(
icon: const Icon(Icons.menu),
onPressed: () {
Scaffold.of(context).openDrawer();
},
color: const Color(0xFF434343),
),
);
},
),
actions: <Widget>[
IconButton(
onPressed: () {
print(height);
},
icon: Icon(Icons.search),
padding: rtl == false ? const EdgeInsets.only(right: 10) : const EdgeInsets.only(left: 10),
color: const Color(0xFF434343),
),
IconButton(
onPressed: () {},
icon: Icon(Icons.settings),
padding: rtl == false ? const EdgeInsets.only(right: 15) : const EdgeInsets.only(left: 15),
color: const Color(0xFF434343),
),
],
bottom: TabBar(
controller: _controller,
labelColor: Color(0xff434343),
unselectedLabelColor: Color(0xff434343),
indicatorColor: Color(0xff434343),
automaticIndicatorColorAdjustment: false,
tabs: <Widget>[
Tab(
icon: Icon(Icons.event_note_outlined),
),
Tab(
icon: Icon(Icons.home_rounded),
),
Tab(
icon: Icon(Icons.add_alert),
),
],
),
),
body: TabBarView(
controller: _controller,
children: [
TabBarHome(width: media.width, height: media.height),
TabBarHome(width: media.width, height: media.height),
TabBarHome(width: media.width, height: media.height),
],
),
drawer: Drawer(
child: ListView(
children: [
GestureDetector(
onTap: () {
print('hey');
},
child: InkWell(
onTap: () {},
child: Container(
color: Colors.grey.shade100,
height: media.height * 0.2,
child: Center(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 0.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Container(
height: 70,
width: 90,
decoration: BoxDecoration(
shape: BoxShape.circle,
image: DecorationImage(
fit: BoxFit.fitWidth,
image: AssetImage("images/aga.png"),
)),
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
"Text",
style: TextStyle(
fontSize: 17,
color: Colors.black87,
fontWeight: FontWeight.w600,
),
),
Text(
"The best leader",
textAlign: TextAlign.justify,
style: TextStyle(
fontSize: 15,
color: Colors.black87,
),
),
],
),
],
),
Container(
child: rtl == true ? Icon(Icons.keyboard_arrow_right_rounded) : Icon(Icons.keyboard_arrow_left_rounded),
),
],
),
),
),
),
),
),
Padding(
padding: EdgeInsets.all(10),
child: Text(
S.of(context).Home_drawer_mainMenu,
style: TextStyle(fontSize: 17, fontWeight: FontWeight.w600),
),
),
ListTile(
leading: Icon(Icons.home),
title: Text('data'),
),
ListTile(
leading: Icon(Icons.add_call),
title: Text('call with us'),
),
],
),
),
),
);
}
}

Could not find the correct Provider<CartItemCounter> above this HomeScreen Widget

I keep on getting this problem:
Unhandled Exception: Error: Could not find the correct Provider above this HomeScreen Widget
Since I am trying to implement Cart Item Counter, there is this bug.
Here is my code:
Main.dart
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
sharedPreferences = await SharedPreferences.getInstance();
await Firebase.initializeApp();
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(create: (c) => CartItemCounter()),
ChangeNotifierProvider(create: (c) => TotalAmount()),
],
child: MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Users App',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MySplashScreen(),
),
);
}
}
Below is my App Bar, This is where i send users to Cart:
class MyAppBar extends StatefulWidget with PreferredSizeWidget {
final PreferredSizeWidget? bottom;
final String? sellerUID;
MyAppBar({this.bottom, this.sellerUID});
#override
_MyAppBarState createState() => _MyAppBarState();
#override
Size get preferredSize => bottom == null
? Size(56, AppBar().preferredSize.height)
: Size(56, 80 + AppBar().preferredSize.height);
}
class _MyAppBarState extends State<MyAppBar> {
#override
Widget build(BuildContext context) {
return AppBar(
flexibleSpace: Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
colors: [
Colors.cyan,
Colors.amber,
],
begin: FractionalOffset(0.0, 0.0),
end: FractionalOffset(1.0, 0.0),
stops: [0.0, 1.0],
tileMode: TileMode.clamp,
)),
),
leading: IconButton(
icon: const Icon(Icons.arrow_back),
onPressed: () {
Navigator.pop(context);
},
),
title: const Text(
"iFood",
style: TextStyle(fontSize: 45, fontFamily: "Signatra"),
),
centerTitle: true,
automaticallyImplyLeading: true,
actions: [
Stack(
children: [
IconButton(
icon: const Icon(
Icons.shopping_cart,
color: Colors.cyan,
),
onPressed: () {
//send user to cart screen
Navigator.push(
context,
MaterialPageRoute(
builder: (c) =>
CartScreen(sellerUID: widget.sellerUID)));
},
),
Positioned(
child: Stack(
children: [
const Icon(
Icons.brightness_1,
size: 20.0,
color: Colors.green,
),
Positioned(
top: 3,
right: 4,
child: Center(
child: Consumer<CartItemCounter>(
builder: (context, counter, c) {
return Text(
counter.count.toString(),
style: const TextStyle(
color: Colors.white, fontSize: 12),
);
},
),
),
),
],
),
),
],
),
],
);
}
}
Following is My Cart Screen:
I want to display cart items with quantity number
class CartScreen extends StatefulWidget {
final String? sellerUID;
CartScreen({this.sellerUID});
#override
_CartScreenState createState() => _CartScreenState();
}
class _CartScreenState extends State<CartScreen> {
List<int>? separateItemQuantityList;
num totalAmount = 0;
#override
void initState() {
super.initState();
totalAmount = 0;
Provider.of<TotalAmount>(context, listen: false).displayTotalAmount(0);
separateItemQuantityList = separateItemQuantities();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
flexibleSpace: Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
colors: [
Colors.cyan,
Colors.amber,
],
begin: FractionalOffset(0.0, 0.0),
end: FractionalOffset(1.0, 0.0),
stops: [0.0, 1.0],
tileMode: TileMode.clamp,
)),
),
leading: IconButton(
icon: const Icon(Icons.clear_all),
onPressed: () {
clearCartNow(context);
},
),
title: const Text(
"iFood",
style: TextStyle(fontSize: 45, fontFamily: "Signatra"),
),
centerTitle: true,
automaticallyImplyLeading: true,
actions: [
Stack(
children: [
IconButton(
icon: const Icon(
Icons.shopping_cart,
color: Colors.cyan,
),
onPressed: () {
print("clicked");
},
),
Positioned(
child: Stack(
children: [
const Icon(
Icons.brightness_1,
size: 20.0,
color: Colors.green,
),
Positioned(
top: 3,
right: 4,
child: Center(
child: Consumer<CartItemCounter>(
builder: (context, counter, c) {
return Text(
counter.count.toString(),
style: const TextStyle(
color: Colors.white, fontSize: 12),
);
},
),
),
),
],
),
),
],
),
],
),
floatingActionButton: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
const SizedBox(
width: 10,
),
Align(
alignment: Alignment.bottomLeft,
child: FloatingActionButton.extended(
label: const Text(
"Clear Cart",
style: TextStyle(fontSize: 16),
),
backgroundColor: Colors.cyan,
icon: const Icon(Icons.clear_all),
onPressed: () {
clearCartNow(context);
Navigator.push(context,
MaterialPageRoute(builder: (c) => const MySplashScreen()));
Fluttertoast.showToast(msg: "Cart has been cleared.");
},
),
),
Align(
alignment: Alignment.bottomLeft,
child: FloatingActionButton.extended(
label: const Text(
"Check Out",
style: TextStyle(fontSize: 16),
),
backgroundColor: Colors.cyan,
icon: const Icon(Icons.navigate_next),
onPressed: () {
// Navigator.push(
// context,
// MaterialPageRoute(
// builder: (c) => AddressScreen(
// totalAmount: totalAmount.toDouble(),
// sellerUID: widget.sellerUID,
// ),
// ),
// );
},
),
),
],
),
body: CustomScrollView(
slivers: [
//overall total amount
SliverPersistentHeader(
pinned: true, delegate: TextWidgetHeader(title: "My Cart List")),
SliverToBoxAdapter(
child: Consumer2<TotalAmount, CartItemCounter>(
builder: (context, amountProvider, cartProvider, c) {
return Padding(
padding: const EdgeInsets.all(8),
child: Center(
child: cartProvider.count == 0
? Container()
: Text(
"Total Price: " + amountProvider.tAmount.toString(),
style: const TextStyle(
color: Colors.black,
fontSize: 18,
fontWeight: FontWeight.w500,
),
),
),
);
}),
),
//display cart items with quantity number
StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance
.collection("items")
.where("itemID", whereIn: separateItemIDs())
.orderBy("publishedDate", descending: true)
.snapshots(),
builder: (context, snapshot) {
return !snapshot.hasData
? SliverToBoxAdapter(
child: Center(
child: circularProgress(),
),
)
: snapshot.data!.docs.length == 0
? //startBuildingCart()
Container()
: SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) {
Items model = Items.fromJson(
snapshot.data!.docs[index].data()!
as Map<String, dynamic>,
);
if (index == 0) {
totalAmount = 0;
totalAmount = totalAmount +
(model.price! *
separateItemQuantityList![index]);
} else {
totalAmount = totalAmount +
(model.price! *
separateItemQuantityList![index]);
}
if (snapshot.data!.docs.length - 1 == index) {
WidgetsBinding.instance
.addPostFrameCallback((timeStamp) {
Provider.of<TotalAmount>(context,
listen: false)
.displayTotalAmount(
totalAmount.toDouble());
});
}
return CartItemDesign(
model: model,
context: context,
quanNumber: separateItemQuantityList![index],
);
},
childCount: snapshot.hasData
? snapshot.data!.docs.length
: 0,
),
);
},
),
],
),
);
}
}
It's hard to tell what is the problem without looking at the whole source code.
My guess is that you need to pass the ChangeNotifierProvider instance across routes (basically whenever you do Navigator.push()).
Check out this answer.
When passing ChangeNotifierProvider in main
Pass it like this
ChangeNotifierProvider(
create : (context) => CartItemCounter(),
child : CartScreen (), // screen where you want to access the Provider
),

How can I create this animation on select?

I need to make an animation, but I don't know how to do it. When the user clicks on one of the avatars, the avatar will have a blue outline and the camera icon will appear on the selected avatar, the text accompanies the blue color when the avatar is selected. Can you help me please :___.
This is the code:
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const SettingUser(),
);
}
}
class SettingUser extends StatefulWidget {
const SettingUser({Key? key}) : super(key: key);
#override
State<SettingUser> createState() => _SettingUserState();
}
class _SettingUserState extends State<SettingUser> {
bool saved = false;
ImagePicker imagePicker = ImagePicker();
XFile? imageSelect;
Future<bool?> showConfirmationDialog() {
return showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: const Text(
'Exit App',
style: TextStyle(fontWeight: FontWeight.bold),
),
content: const Text(
'Exit app'),
actions: [
TextButton(
onPressed: () => Navigator.pop(context, false),
child: const Text('CANCELAR'),
),
TextButton(
onPressed: () {},
child: const Text(
'EXIT',
style: TextStyle(color: Colors.red),
)),
],
);
});
}
imageGallery() async {
final XFile? imageTemp = await imagePicker.pickImage(
source: ImageSource.gallery,
);
setState(() {
imageSelect = imageTemp;
});
}
Widget _buildUserAvatar({
required ImageProvider image,
required String name,
}) {
return GestureDetector(
onTap: () {
imageGallery();
},
child: Padding(
padding: const EdgeInsets.only(left: 16, top: 10.0, right: 0.0, bottom: 5.0),
child: Column(
children: [
SizedBox(
child: CircleAvatar(
backgroundColor: Color(0xFFF3E0A6),
radius: 30.0,
backgroundImage: image, // if image is a Image
child: Align(
alignment: Alignment.bottomRight,
child: CircleAvatar(
backgroundColor: Colors.blue,
radius: 12.0,
child: Icon(
Icons.camera_alt,
size: 12.0,
color: Colors.white,
),
),
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
name,
style: TextStyle(fontSize: 14),
),
),
],
),
),
);
}
Widget _renderUserAvatar() {
if (imageSelect != null) {
return _buildUserAvatar(
name: 'Avatar 1',
image: FileImage(File(imageSelect!.path)),
);
}
return _buildUserAvatar(
name: 'Avatar 1',
image: AssetImage('assets/images/euQ.png'),
);
}
#override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async {
if (!saved) {
final confirmation = await showConfirmationDialog();
return confirmation ?? false;
}
return true;
},
child: Scaffold(
appBar: AppBar(
elevation: 0,
backgroundColor: Colors.transparent,
iconTheme: IconThemeData(color: Colors.blue),
actions: [
IconButton(
icon: Icon(Icons.help_outline,
),
onPressed: () {},
),
],
),
body: ListView(
children: [
Padding(
padding: EdgeInsets.only(left: 16, top: 5.0),
child: Text(
'Select Avatar:',
style: TextStyle(
color: Color(0xff8194A9),
fontWeight: FontWeight.bold,
fontSize: 14,
),
),
),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_renderUserAvatar(),
_buildUserAvatar(
name: 'Avatar 2',
image: AssetImage('assets/images/'),
),
_buildUserAvatar(
name: 'Avatar 3',
image: AssetImage('assets/images/'),
),
],
),
// ButtonConfig(),
Padding(
padding: const EdgeInsets.only(left: 15.0, top: 10.0, right: 180.0),
child: ElevatedButton(
onPressed: () {
showConfirmationDialog();
},
child: Text(
'Exit App',
style: TextStyle(color: Colors.blue),
),
style: ElevatedButton.styleFrom(
//elevation: 1,
primary: Colors.white,
padding:
EdgeInsets.symmetric(horizontal: 10.0, vertical: 10.0),
textStyle: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
),
side: BorderSide(
width: 1.0,
color: Colors.grey,
),
),
),
),
],
),
),
);
}
}
I managed to make it work only on the first avatar.
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const SettingUser(),
);
}
}
class SettingUser extends StatefulWidget {
const SettingUser({Key? key}) : super(key: key);
#override
State<SettingUser> createState() => _SettingUserState();
}
class _SettingUserState extends State<SettingUser> {
bool saved = false;
ImagePicker imagePicker = ImagePicker();
XFile? imageSelect;
Future<bool?> showConfirmationDialog() {
return showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: const Text(
'Exit App',
style: TextStyle(fontWeight: FontWeight.bold),
),
content: const Text(
'Exit app'),
actions: [
TextButton(
onPressed: () => Navigator.pop(context, false),
child: const Text('CANCELAR'),
),
TextButton(
onPressed: () {},
child: const Text(
'EXIT',
style: TextStyle(color: Colors.red),
)),
],
);
});
}
imageGallery() async {
final XFile? imageTemp = await imagePicker.pickImage(
source: ImageSource.gallery,
);
setState(() {
imageSelect = imageTemp;
});
}
Widget _buildUserAvatar(bool hasFocus, {
required ImageProvider image,
required String name,
}) {
return GestureDetector(
onTap: () {
imageGallery();
},
child: Padding(
padding: const EdgeInsets.only(left: 16, top: 10.0, right: 0.0, bottom: 5.0),
child: Column(
children: [
SizedBox(
child: AnimatedContainer(
duration: const Duration(milliseconds: 1000),
width: hasFocus ? 120 : 100,
height: hasFocus ? 120 : 100,
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(
width: hasFocus ? 4 : 3,
color: hasFocus ? Colors.black : Colors.blue,
),
),
child: CircleAvatar(
backgroundColor: Color(0xFFF3E0A6),
radius: 30.0,
backgroundImage: image, // if image is a Image
child: Align(
alignment: Alignment.bottomRight,
child: CircleAvatar(
backgroundColor: Colors.blue,
radius: 12.0,
child: Icon(
Icons.camera_alt,
size: 12.0,
color: Colors.white,
),
),
),
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
name,
style: const TextStyle(fontSize: 14),
),
),
],
),
),
);
}
Widget _renderUserAvatar(bool hasFocus) {
if (imageSelect != null) {
return _buildUserAvatar(
true,
name: "Avatar 1",
image: FileImage(File(imageSelect!.path)),
);
}
return _buildUserAvatar(
false,
name: 'Avatar 1',
image: AssetImage('assets/images/euQ.png'),
);
}
#override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async {
if (!saved) {
final confirmation = await showConfirmationDialog();
return confirmation ?? false;
}
return true;
},
child: Scaffold(
appBar: AppBar(
elevation: 0,
backgroundColor: Colors.transparent,
iconTheme: const IconThemeData(color: Colors.blue),
actions: [
IconButton(
icon: const Icon(Icons.help_outline,
),
onPressed: () {},
),
],
),
body: ListView(
children: [
const Padding(
padding: EdgeInsets.only(left: 16, top: 5.0),
child: Text(
'Select Avatar:',
style: TextStyle(
color: Color(0xff8194A9),
fontWeight: FontWeight.bold,
fontSize: 14,
),
),
),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_renderUserAvatar(true),
_buildUserAvatar(
false,
name: 'Avatar 2',
image: AssetImage('assets/images/euQ.png'),
),
_buildUserAvatar(
false,
name: 'Avatar 3',
image: AssetImage('assets/images/euQ.png'),
),
],
),
// ButtonConfig(),
Padding(
padding: const EdgeInsets.only(left: 15.0, top: 10.0, right: 180.0),
child: ElevatedButton(
onPressed: () {
showConfirmationDialog();
},
child: const Text(
'Exit App',
style: TextStyle(color: Colors.blue),
),
style: ElevatedButton.styleFrom(
//elevation: 1,
primary: Colors.white,
padding:
const EdgeInsets.symmetric(horizontal: 10.0, vertical: 10.0),
textStyle: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
),
side: const BorderSide(
width: 1.0,
color: Colors.grey,
),
),
),
),
],
),
),
);
}
}

I am getting two appBar in flutter app. I am trying to add Drawer widget and TabBar widget in flutter app

main.dart
import 'package:flutter/material.dart';
import 'package:stray_animal_emergencyrescue/signUpPage.dart';
import './commons/commonWidgets.dart';
import 'package:stray_animal_emergencyrescue/loggedIn.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 login UI',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
//String showPasswordText = "Show Password";
bool obscurePasswordText = true;
#override
Widget build(BuildContext context) {
final passwordField = TextField(
obscureText: obscurePasswordText,
decoration: InputDecoration(
//contentPadding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
hintText: "Password",
//border: OutlineInputBorder(borderRadius: BorderRadius.circular(32.0)),
suffixIcon: IconButton(
icon: new Icon(Icons.remove_red_eye),
onPressed: () {
setState(() {
this.obscurePasswordText = !obscurePasswordText;
});
},
)),
);
final loginButon = Material(
//elevation: 5.0,
//borderRadius: BorderRadius.circular(30.0),
color: Colors.blue,
child: MaterialButton(
//minWidth: MediaQuery.of(context).size.width,
//padding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
onPressed: () {
//print(MediaQuery.of(context).size.width);
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => LogIn()),
);
},
child: Text('Login', textAlign: TextAlign.center),
),
);
final facebookContinueButton = Material(
//borderRadius: BorderRadius.circular(30.0),
color: Colors.blue,
child: MaterialButton(
//minWidth: MediaQuery.of(context).size.width,
//padding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
onPressed: () {
//print(MediaQuery.of(context).size.width);
},
child: Text('Facebook', textAlign: TextAlign.center),
),
);
final googleContinueButton = Material(
//borderRadius: BorderRadius.circular(30.0),
color: Colors.blue,
child: MaterialButton(
//minWidth: MediaQuery.of(context).size.width,
//padding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
onPressed: () {
//print(MediaQuery.of(context).size.width);
},
child: Text('Google ', textAlign: TextAlign.center),
),
);
final signUpButton = Material(
//borderRadius: BorderRadius.circular(30.0),
color: Colors.blue,
child: MaterialButton(
//minWidth: MediaQuery.of(context).size.width,
//padding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => FormScreen()),
);
//print(MediaQuery.of(context).size.width);
},
child: Text('Sign Up ', textAlign: TextAlign.center),
),
);
return Scaffold(
appBar: AppBar(
title: Text("Animal Emergency App"),
),
body: Center(
child: Container(
//color: Colors.white,
child: Padding(
padding: const EdgeInsets.all(36.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
//SizedBox(height: 45.0),
getTextFieldWidget(),
SizedBox(height: 15.0),
passwordField,
sizedBoxWidget,
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
facebookContinueButton,
SizedBox(width: 5),
googleContinueButton,
SizedBox(width: 5),
loginButon
],
),
/*loginButon,
signUpButton,*/
sizedBoxWidget,
const Divider(
color: Colors.black,
height: 20,
thickness: 1,
indent: 20,
endIndent: 0,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
//crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
signUpButton
],
),
],
),
),
),
),
);
}
}
loggedIn.dart
import 'package:flutter/material.dart';
import './tabbarviews/emergencyresue/EmergencyHome.dart';
import './tabbarviews/animalcruelty/animalCrueltyHome.dart';
import './tabbarviews/bloodbank/bloodBankHome.dart';
class LogIn extends StatefulWidget {
#override
_LogInState createState() => _LogInState();
}
class _LogInState extends State<LogIn> {
int _selectedIndex = 0;
static const TextStyle optionStyle =
TextStyle(fontSize: 30, fontWeight: FontWeight.bold);
static List<Widget> _widgetOptions = <Widget>[
EmergencyHome(),
AnimalCrueltyHome(),
BloodBankHome()
];
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('First app bar appearing'),
actions: <Widget>[
GestureDetector(
onTap: () {},
child: CircleAvatar(
//child: Text("SC"),
backgroundImage: AssetImage('assets/images/760279.jpg'),
//backgroundImage: ,
),
),
IconButton(
icon: Icon(Icons.more_vert),
color: Colors.white,
onPressed: () {},
),
],
),
drawer: Drawer(
child: ListView(
children: <Widget>[
new ListTile(title: Text("Primary")),
MyListTile(
"Home",
false,
"Your customized News Feed about people you follow, ongoing rescues, nearby activities, adoptions etc.",
3,
Icons.home,
true,
() {}),
MyListTile(
"News & Media Coverage",
false,
"News about incidents which need immediate action, changing Laws",
3,
Icons.home,
false,
() {}),
MyListTile(
"Report",
true,
"Report cases with evidences anonymously",
3,
Icons.announcement,
false,
() {}),
MyListTile(
"Blood Bank",
true,
"Details to donate blood ",
3,
Icons.medical_services,
false,
() {}),
],
),
),
body: _widgetOptions[_selectedIndex],
bottomNavigationBar: BottomNavigationBar(
currentIndex: _selectedIndex,
selectedItemColor: Colors.blue,
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.pets),
label: 'Emergency Rescue',
),
BottomNavigationBarItem(
icon: Icon(Icons.add_alert),
label: 'Report Cruelty',
),
BottomNavigationBarItem(
icon: Icon(Icons.medical_services),
label: 'Blood Bank',
),
/*BottomNavigationBarItem(
icon: Icon(Icons.school),
label: 'Safe Hands',
backgroundColor: Colors.blue),*/
],
onTap: _onItemTapped,
),
);
}
}
//Safe Hands
class MyListTile extends StatelessWidget {
final String title;
final bool isThreeLine;
final String subtitle;
final int maxLines;
final IconData icon;
final bool selected;
final Function onTap;
MyListTile(this.title, this.isThreeLine, this.subtitle, this.maxLines,
this.icon, this.selected, this.onTap);
#override
Widget build(BuildContext context) {
return ListTile(
title: Text(title),
isThreeLine: isThreeLine,
subtitle:
Text(subtitle, maxLines: maxLines, style: TextStyle(fontSize: 12)),
leading: Icon(icon),
selected: selected,
onTap: onTap);
}
}
EmergencyHome.dart
import 'package:flutter/material.dart';
import './finishedAnimalEmergencies.dart';
import './reportAnimalEmergency.dart';
import './ongoingAnimalEmergencies.dart';
class EmergencyHome extends StatefulWidget {
#override
_EmergencyHomeState createState() => _EmergencyHomeState();
}
class _EmergencyHomeState extends State<EmergencyHome> {
#override
Widget build(BuildContext context) {
return DefaultTabController(
length: 3,
child: Scaffold(
appBar: AppBar(
title: Text("Second appBar appearing"),
bottom: TabBar(
tabs: [
Tab(
//icon: Icon(Icons.more_vert),
text: "Report",
),
Tab(
text: "Ongoing",
),
Tab(
text: "Finished",
)
],
),
),
body: TabBarView(
children: [
ReportAnimalEmergency(),
OngoingAnimalEmergencies(),
FinishedAnimalEmergencies(),
],
),
)
);
}
}
The issue I am facing is two appBar, I tried removing appBar from loggedIn.dart but Drawer hamburger icon is not showing, and I cannot remove appBar from emergencyHome.dart as I wont be able to add Tab bar. What is viable solution for this? Please help how to Structure by app and routes to easily manage navigation within app
Remove the appbar from EmergencyHome.dart
this will remove the second app title. But there will be that shadow from the first app bar so put elvation:0
so, this will look like one appbar now your drawer will also work.
you can use flexibleSpace in EmergencyHome.dart
DefaultTabController(
length: 3,
child: Scaffold(
appBar: AppBar(
flexibleSpace: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
TabBar(
tabs: [
Tab(
//icon: Icon(Icons.more_vert),
text: "Report",
),
Tab(
text: "Ongoing",
),
Tab(
text: "Finished",
)
],
)
],
),
),
body: TabBarView(
children: [
ReportAnimalEmergency(),
OngoingAnimalEmergencies(),
FinishedAnimalEmergencies(),
],
),
)
);
You don't want to make two appbar to get the drawer property. Use DefaultTabController then inside that you can use scaffold.so, you can have drawer: Drawer() inside that you can also get a appbar with it with TabBar as it's bottom.
This is most suitable for you according to your use case.
i will put the full code below so you can copy it.
void main() {
runApp(const TabBarDemo());
}
class TabBarDemo extends StatelessWidget {
const TabBarDemo({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
home: DefaultTabController(
length: 3,
child: Scaffold(
drawer: Drawer(),
appBar: AppBar(
bottom: const TabBar(
tabs: [
Tab(
text: "report",
),
Tab(text: "ongoing"),
Tab(text: "completed"),
],
),
title: const Text('Tabs Demo'),
),
body: const TabBarView(
children: [
Icon(Icons.directions_car),
Icon(Icons.directions_transit),
Icon(Icons.directions_bike),
],
),
),
),
);
}
}
OUTPUT

Flutter variable doesn't change background color when changed?

I'm new to flutter and am trying to update the background color of a scaffold when a variable is changed. the variable is declared in another file. The reason why it needs to change? I am trying to change the background of the app to grey, a dark mode option. Any advice on why the background doesn't change when the variable does? Any advice would be appreciated, thanks!
import 'package:flutter/material.dart';
import 'package:page_transition/page_transition.dart';
import 'package:share/share.dart';
import './Widgets/DrawerSettings.dart';
void main() {
runApp(MaterialApp(
title: 'Navigation Basics',
home: FirstRoute(),
));
}
class FirstRoute extends StatefulWidget {
#override
_FirstRouteState createState() => _FirstRouteState();
}
class _FirstRouteState extends State<FirstRoute> {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
drawer: Container(
width: 70,
child: ClipRRect(
borderRadius: BorderRadius.vertical(top: Radius.circular(.0)),
child: Drawer(
child: Padding(
padding: const EdgeInsets.fromLTRB(0, 30, 0, 0),
child: Column(
children: <Widget>[
IconButton(
icon: Icon(Icons.bookmark),
onPressed: () {
Navigator.push(
context,
PageTransition(
type: PageTransitionType.rightToLeft,
child: SavedRoute()));
},
),
IconButton(
icon: Icon(Icons.rate_review),
onPressed: () {
Navigator.push(
context,
PageTransition(
type: PageTransitionType.rightToLeft,
child: ReviewRoute()));
},
),
IconButton(
icon: Icon(Icons.share),
onPressed: () {
Share.share('Share');
},
),
IconButton(
icon: Icon(Icons.settings),
onPressed: () {
Navigator.push(
context,
PageTransition(
type: PageTransitionType.rightToLeft,
child: SettingsRoute()));
},
)
],
),
),
),
),
),
appBar: AppBar(
title: Text(
'Explore',
),
centerTitle: true,
backgroundColor: Colors.cyan[500],
),
body: Scaffold(
backgroundColor: DarkMode ? Colors.grey[800] : Colors.white, //Here is the code to change the background color when variable change.
body: Padding(
padding: const EdgeInsets.fromLTRB(2, 12, 2, 12),
child: Center(
child: ListView(
shrinkWrap: true,
padding: EdgeInsets.all(5.0),
children: <Widget>[
Column(
children: [
Container(
padding: EdgeInsets.fromLTRB(2, 10, 2, 0),
height: 150,
width: double.maxFinite,
child: InkWell(
onTap: () {
Navigator.push(
context,
PageTransition(
type: PageTransitionType.rightToLeft,
child: SecondRoute()));
},
child: Card(
elevation: 5,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
),
child: ClipRRect(
borderRadius: BorderRadius.circular(15.0),
child: Image.network(
'https://i.ytimg.com/vi/hlWiI4xVXKY/maxresdefault.jpg',
fit: BoxFit.cover,
height: 150.0,
width: 100.0,
),
),
),
),
),
],
),
),
),
),
),
);
}
}
Here is the second file
import 'package:flutter/material.dart';
class SettingsRoute extends StatefulWidget {
#override
_SettingsRouteState createState() => _SettingsRouteState();
}
bool DarkMode = false;
class _SettingsRouteState extends State<SettingsRoute> {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: DarkMode ? Colors.grey[800] : Colors.white,
appBar: AppBar(
title: Text(
'Settings',
),
centerTitle: true,
),
body: ListView(
children: <Widget>[
Container(
child: Padding(
padding: const EdgeInsets.fromLTRB(20, 20, 10, 20),
child: SwitchListTile(
title: Text(
'Dark Mode',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w400,
color: DarkMode ? Colors.white : Colors.grey[800],
),
),
value: DarkMode,
activeColor: Colors.white,
inactiveThumbColor: Colors.white,
onChanged: (bool value) {
setState(() {
DarkMode = !DarkMode;
});
},
),
),
),
],
),
),
);
}
}
You can copy paste run full code below
You can pass callback refresh to SettingsRoute and call with widget.callback()
You can see working demo below
code snippet
class _FirstRouteState extends State<FirstRoute> {
refresh() {
setState(() {});
}
...
onPressed: () {
Navigator.push(
context,
PageTransition(
type: PageTransitionType.rightToLeft,
child: SettingsRoute(
callback: refresh,
)));
},
...
class SettingsRoute extends StatefulWidget {
final VoidCallback callback;
SettingsRoute({this.callback});
...
onChanged: (bool value) {
setState(() {
DarkMode = !DarkMode;
});
widget.callback();
},
working demo
full code
import 'package:flutter/material.dart';
import 'package:page_transition/page_transition.dart';
import 'package:share/share.dart';
void main() {
runApp(MaterialApp(
title: 'Navigation Basics',
home: FirstRoute(),
));
}
class FirstRoute extends StatefulWidget {
#override
_FirstRouteState createState() => _FirstRouteState();
}
class _FirstRouteState extends State<FirstRoute> {
refresh() {
setState(() {});
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
drawer: Container(
width: 70,
child: ClipRRect(
borderRadius: BorderRadius.vertical(top: Radius.circular(.0)),
child: Drawer(
child: Padding(
padding: const EdgeInsets.fromLTRB(0, 30, 0, 0),
child: Column(
children: <Widget>[
IconButton(
icon: Icon(Icons.bookmark),
onPressed: () {
/* Navigator.push(
context,
PageTransition(
type: PageTransitionType.rightToLeft,
child: SavedRoute()));*/
},
),
IconButton(
icon: Icon(Icons.rate_review),
onPressed: () {
/* Navigator.push(
context,
PageTransition(
type: PageTransitionType.rightToLeft,
child: ReviewRoute()));*/
},
),
IconButton(
icon: Icon(Icons.share),
onPressed: () {
Share.share('Share');
},
),
IconButton(
icon: Icon(Icons.settings),
onPressed: () {
Navigator.push(
context,
PageTransition(
type: PageTransitionType.rightToLeft,
child: SettingsRoute(
callback: refresh,
)));
},
)
],
),
),
),
),
),
appBar: AppBar(
title: Text(
'Explore',
),
centerTitle: true,
backgroundColor: Colors.cyan[500],
),
body: Scaffold(
backgroundColor: DarkMode
? Colors.grey[800]
: Colors
.white, //Here is the code to change the background color when variable change.
body: Padding(
padding: const EdgeInsets.fromLTRB(2, 12, 2, 12),
child: Center(
child: ListView(
shrinkWrap: true,
padding: EdgeInsets.all(5.0),
children: <Widget>[
Column(
children: [
Container(
padding: EdgeInsets.fromLTRB(2, 10, 2, 0),
height: 150,
width: double.maxFinite,
child: InkWell(
onTap: () {
/* Navigator.push(
context,
PageTransition(
type: PageTransitionType.rightToLeft,
child: SecondRoute()));*/
},
child: Card(
elevation: 5,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
),
child: ClipRRect(
borderRadius: BorderRadius.circular(15.0),
child: Image.network(
'https://i.ytimg.com/vi/hlWiI4xVXKY/maxresdefault.jpg',
fit: BoxFit.cover,
height: 150.0,
width: 100.0,
),
),
),
),
),
],
),
]),
),
),
),
));
}
}
class SettingsRoute extends StatefulWidget {
final VoidCallback callback;
SettingsRoute({this.callback});
#override
_SettingsRouteState createState() => _SettingsRouteState();
}
bool DarkMode = false;
class _SettingsRouteState extends State<SettingsRoute> {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: DarkMode ? Colors.grey[800] : Colors.white,
appBar: AppBar(
title: Text(
'Settings',
),
centerTitle: true,
),
body: ListView(
children: <Widget>[
Container(
child: Padding(
padding: const EdgeInsets.fromLTRB(20, 20, 10, 20),
child: SwitchListTile(
title: Text(
'Dark Mode',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w400,
color: DarkMode ? Colors.white : Colors.grey[800],
),
),
value: DarkMode,
activeColor: Colors.white,
inactiveThumbColor: Colors.white,
onChanged: (bool value) {
setState(() {
DarkMode = !DarkMode;
});
widget.callback();
},
),
),
),
],
),
),
);
}
}
You need to get the value of the DarkMode variable from a global variable like using an app state provider. Or you can send the DarkMode value as a parameter to the next page. The first one is a better use-case.
Your provider will look like this:
import 'package:flutter/material.dart';
class AppStateProvider with ChangeNotifier {
bool _darkMode = false;
bool get darkMode => this._darkMode;
void setDarkMode(bool value) {
this._darkMode = value;
}
}
You can read more from here.