Related
I'm making a Pomodoro app and I don't know how to implement Get and Obx if the timer is over and make that the tab bar change automatically.
This is my code:
Tab bar:
#override
Widget build(BuildContext context) {
return SizedBox(
height: MediaQuery.of(context).size.height,
width: double.infinity,
child: AnimatedBuilder(
animation: _countDownController.controller,
builder: (context, child) {
return DefaultTabController(
length: 3,
child: Scaffold(
appBar: AppBar(
elevation: 0,
backgroundColor: Colors.transparent,
bottom: PreferredSize(
preferredSize: const Size.fromHeight(22),
child: Container(
color: Colors.transparent,
child: SafeArea(
child: ResponsiveWeb(
child: Column(children: [
TabBar(
controller: _tabController,
indicator: const UnderlineTabIndicator(
borderSide: BorderSide(
color: Color(0xff3B3B3B), width: 2.0),
insets: EdgeInsets.fromLTRB(
12.0, 12.0, 12.0, 12.0)),
indicatorWeight: 5,
indicatorSize: TabBarIndicatorSize.label,
labelColor: const Color(0xff3B3B3B),
labelStyle: GoogleFonts.nunito(
fontSize: 16.0,
// letterSpacing: 1,
fontWeight: FontWeight.w500),
unselectedLabelColor: const Color(0xffD7D7D7),
tabs: const [
Tab(
text: "Pomodoro",
icon: Icon(Icons.work_history_outlined,
size: 24),
),
Tab(
text: "Short break",
icon: Icon(Icons.ramen_dining_outlined,
size: 24),
),
Tab(
text: "Long break",
icon: Icon(
Icons.battery_charging_full_outlined,
size: 24),
),
]),
]),
),
),
),
),
),
),
);
},
),
);
}
}
And my timer:
This is an example from an animation which means that if the timer starts the animation starts as well
createAnimationController(TickerProvider ticker) {
currentRoundType = typeRound.pomodoro;
_changeCurrentRoundTypeString();
tickerProvider = ticker;
currentRoundSeconds.value = currentRoundType == typeRound.pomodoro
? _settingsController.secondsWork.value
: currentRoundNumber.value < _settingsController.rounds.value
? _settingsController.secondsBreak.value
: _settingsController.secondsBreakAfterRound.value;
restartTimers();
controller = AnimationController(
vsync: tickerProvider,
duration: currentDuration,
);
logger.d(controller.value);
painter = CustomTimePainter(
backgroundColor: const Color.fromARGB(0, 33, 149, 243),
color: const Color(0xffD94530),
animation: controller,
);
timerString.value =
'${(currentDuration.inHours).toString().padLeft(2, '0')}:${(currentDuration.inMinutes % 60).toString().padLeft(2, '0')}:${(currentDuration.inSeconds % 60).toString().padLeft(2, '0')}';
listRounds.value = List.generate(
_settingsController.rounds.value + 1, (index) => Rx(stateRound.undone));
}
This is another example, which means that if the timer ends the empty image is colored with red color
import 'package:flutter/material.dart';
import 'package:get/get.dart%20';
import 'package:pomodoro/3.tomatoes_interval_UI/countdown_controller.dart';
import 'package:pomodoro/3.tomatoes_interval_UI/tomato_icon.dart';
class TomatoesIcons extends StatefulWidget {
const TomatoesIcons({super.key});
#override
State<TomatoesIcons> createState() => _TomatoesIconsState();
}
class _TomatoesIconsState extends State<TomatoesIcons>
with TickerProviderStateMixin {
final CountDownController _countDownController = Get.find();
final ScrollController _horizontal = ScrollController();
#override
void initState() {
super.initState();
_countDownController.createAnimationController(this);
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: AnimatedBuilder(
animation: _countDownController.controller,
builder: (context, child) {
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
color: const Color.fromARGB(255, 255, 202, 55),
height: 65,
width: MediaQuery.of(context).size.width,
child: Center(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Obx(
() => Scrollbar(
controller: _horizontal,
child: SingleChildScrollView(
controller: _horizontal,
scrollDirection: Axis.horizontal,
child: Row(
children: _countDownController.listRounds
.map(
(e) => MouseRegion(
cursor: SystemMouseCursors.click,
child: TomatoIcon(e),
),
)
.toList(),
),
),
),
),
),
),
),
],
);
},
),
),
);
}
}
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:pomodoro/3.tomatoes_interval_UI/countdown_controller.dart';
class TomatoIcon extends StatefulWidget {
final Rx<stateRound> state;
const TomatoIcon(this.state, {Key? key}) : super(key: key);
#override
State<TomatoIcon> createState() => _TomatoIconState();
}
class _TomatoIconState extends State<TomatoIcon> {
#override
Widget build(BuildContext context) {
return Obx(
() => IconButton(
onPressed: null,
icon: widget.state.value == stateRound.done
? Image.asset('assets/icons/tomatoDone.png')
: Image.asset('assets/icons/tomatoUndone.png')),
);
}
}
With these examples, I would like to create a function or " if statement" which triggers the timer is over, select automatically a tab bar.
Thanks for any help you can provide
I am creating an app and I am working on the profile setup and am using a tabcontroller. I have my tabcontroller working to navigate my first 3 screens, but for some reason I get a "late initializtion" error for my last screen. I have a custom button that I use for each screen, and the error gets shown once I add the custom button to my last acrren. Could someone explain to me what I need to do to get it working for my last screen? I've attached my code for the tabcontroller, custom button, and my last screen:
Tabcontroller onboarding model:
class AccountOnboarding extends StatefulWidget {
const AccountOnboarding({Key? key}) : super(key: key);
#override
State<AccountOnboarding> createState() => _AccountOnboardingState();
}
class _AccountOnboardingState extends State<AccountOnboarding> {
static const List<Tab> tabs = <Tab>[
Tab(text: 'Name'),
Tab(text: 'Age and Profile'),
Tab(text: 'Bio and Interests'),
Tab(text: 'Selection')
];
#override
Widget build(BuildContext context) {
return DefaultTabController(
length: tabs.length,
child: Builder(builder: (BuildContext context) {
final TabController tabController = DefaultTabController.of(context)!;
tabController.addListener(() {
if (!tabController.indexIsChanging) {}
});
return Scaffold(
resizeToAvoidBottomInset: false,
backgroundColor: const Color(0xff31708c),
appBar: AppBar(
automaticallyImplyLeading: false,
backgroundColor: Colors.transparent,
elevation: 0,
title: Row(
children: [
Expanded(
child: Image.asset('assets/images/Logo_Strength.png',
height: 50),
),
Expanded(
flex: 2,
child: RichText(
text: TextSpan(
style: GoogleFonts.montserrat(
fontSize: 30),
children: <TextSpan> [
TextSpan(text: 'Stren',
style: GoogleFonts.montserrat(
color: Colors.white,
fontWeight: FontWeight.bold,
letterSpacing: 1,
shadows: [
Shadow(
color: Colors.black.withOpacity(0.7),
offset: const Offset(1.5, 0.0))
])),
TextSpan(text: ';',
style: GoogleFonts.montserrat(
color: const Color(0xffef6a7a), fontWeight: FontWeight.bold,
letterSpacing: 1,
shadows: [
Shadow(
color: Colors.black.withOpacity(0.7),
offset: const Offset(1.5, 0.0))
])),
TextSpan(text: 'th',
style: GoogleFonts.montserrat(
color: Colors.white,
fontWeight: FontWeight.bold,
letterSpacing: 1,
shadows: [
Shadow(
color: Colors.black.withOpacity(0.7),
offset: const Offset(1.5, 0.0))
]))
],
),
),
),
],
)
),
body: TabBarView(
// physics: const NeverScrollableScrollPhysics(),
children: [
NamePage(tabController: tabController,),
ageAndPicture(tabController: tabController,),
bioAndInterests(tabController: tabController,),
SelectionPage(tabController: tabController,)
],
),
);
}));
}}
Custom Button:
class CustomButton extends StatelessWidget {
final TabController tabController;
const CustomButton({Key? key,
required this.tabController})
: super(key: key);
#override
Widget build(BuildContext context) {
return DecoratedBox(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50),
color: Colors.white
),
child: ElevatedButton(
style: ElevatedButton.styleFrom(
padding: const EdgeInsets.symmetric(
vertical: 16),
elevation: 0,
primary: Colors.transparent
),
onPressed: () {
tabController.animateTo(tabController.index + 1);
},
child: Container(
width: double.infinity,
child: Center(
child: Text('Continue',
style: GoogleFonts.montserrat(
color: const Color.fromARGB(255, 20, 83, 106),
fontSize: 19,
fontWeight: FontWeight.w600
),),
),
)
),
);
}
}
Last Screen code:
class SelectionPage extends StatefulWidget {
final TabController tabController;
const SelectionPage({Key? key,
required this.tabController}) : super(key: key);
#override
_SelectionPageState createState() => _SelectionPageState();
}
class _SelectionPageState extends State<SelectionPage>{
List <Item>listOfModel = [];
late TabController tabController;
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
String retrieveString;
final data = ModalRoute.of(context)!.settings;
if (data.arguments == null) {
retrieveString = "empty";
} else {
retrieveString = data.arguments as String;
}
listOfModel.add(Item(title: "Maintaining healthy relationships"));
listOfModel.add(Item(title: "Stress and anxiety management"));
listOfModel.add(Item(title: "Maintaing a better work-life balance"));
listOfModel.add(Item(title: "Personal growth and development"));
listOfModel.add(Item(title: "Being happier and more content in life"));
listOfModel.add(Item(title: "Mental and emotional well-being"));
double _height = MediaQuery.of(context).size.height;
return Scaffold(
resizeToAvoidBottomInset: false,
backgroundColor: const Color(0xff31708c),
body: Padding(
padding: EdgeInsets.only(
left: 30,
right: 30,
top: _height * 0.07,
bottom: _height * 0.05),
child: Column(
children: [
Column(
children: [
Column(
children: <Widget>[
Text('Hello there $retrieveString! What all would you like to focus on?',
style: GoogleFonts.montserrat(
color: Colors.white70,
fontSize: 19,
fontWeight: FontWeight.w600
),
textAlign: TextAlign.center,),
const SizedBox(height: 10),
Text("You can pick all that apply:",
style: GoogleFonts.montserrat(
color: Colors.white70,
fontSize: 14.5,
fontWeight: FontWeight.w600
),),
const SizedBox(height: 15,),
GridView.count(
primary: true,
shrinkWrap: true,
padding: const EdgeInsets.all(10),
childAspectRatio: 1.15,
crossAxisCount: 2,
crossAxisSpacing: 25,
mainAxisSpacing: 25,
children: [
gridItem(listOfModel[0],MyFlutterApp.relationships),
gridItem(listOfModel[1],MyFlutterApp2.meditate),
gridItem(listOfModel[2],MyFlutterApp.balance),
gridItem(listOfModel[3],MyFlutterApp2.personal_growth),
gridItem(listOfModel[4],MyFlutterApp.happy),
gridItem(listOfModel[5],MyFlutterApp3.well_rounded),
],
),
const SizedBox(height: 18,),
],
),
CustomButton(tabController: tabController)
],
),
],
),
),
);
}
Widget gridItem(Item item, IconData icon){
return GestureDetector(
onTap: () {
setState(() {
item.isSelected = !item.isSelected;
});
},
child: Stack(
children: [Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
border: Border.all(
color: const Color.fromARGB(255, 20, 83, 106),
width: 2.5),
color: item.isSelected ? Color.fromARGB(255, 234, 188, 193) : Colors.white
),
child: Column(
children: [
Align(alignment: Alignment.topCenter,
child: Icon(
icon,
color: const Color(0xff31708c),
size: 45,
),
),
const SizedBox(height: 4,),
Text(item.title,
style: GoogleFonts.montserrat(
fontSize: 14,
fontWeight: FontWeight.w500,
color: const Color(0xff31708c)
),
textAlign: TextAlign.center,),
],
),
),
Positioned(
top: 0,
right: 0,
child: Offstage(
offstage: !item.isSelected,
child: Container(
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(width: 2.5),
shape: BoxShape.circle),
child: const Icon(
Icons.check,
color: Colors.green,
),
),
),
)
],
)
);
}
}
class Item{
String title;
bool isSelected;
Item({required this.title, this.isSelected = false});
}
Remove
late TabController tabController;
in SelectionPage and change
CustomButton(tabController: tabController)
in SelectionPage to
CustomButton(tabController: widget.tabController)
I am building an online bottle store app using flutter and I am having an issue where if I add a product to favorites the selected product's button won't stay selected on the home page if I switch pages. I have categorized the products using a Tabbar and Tabbarview. I have tried using AutomaticKeepAliveClientMxin to keep the page alive but with no success. Please can anyone assist.
Here's what happens:
I click on the selected product
then it is added to Favorites
Come back to the home page and the selected item is no longer showing that it is selected
Here's my code:
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
#override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage>
with AutomaticKeepAliveClientMixin, TickerProviderStateMixin {
ProductProvider productProvider = ProductProvider();
late TabController tabController;
#override
void initState() {
super.initState();
tabController = TabController(length: 4, vsync: this);
}
#override
void dispose() {
tabController.dispose();
super.dispose();
}
#override
bool get wantKeepAlive => true;
#override
Widget build(BuildContext context) {
super.build(context);
var cart = Provider.of<ShoppingCartProvider>(context);
var favoriteProvider = Provider.of<FavoriteProvider>(context);
Size _screenSize = MediaQuery.of(context).size;
final double itemHeight = (_screenSize.height - kToolbarHeight - 24) / 2;
final double itemWidth = _screenSize.width / 2;
return Scaffold(
body: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Padding(
padding: EdgeInsets.all(8.0),
child: Text(
'Categories',
style: TextStyle(
fontSize: 20.0,
fontFamily: 'Montserrat-ExtraBold',
fontWeight: FontWeight.bold),
),
),
Container(
child: Align(
alignment: Alignment.centerLeft,
child: TabBar(
controller: tabController,
indicator:
CircleTabIndicator(color: Colors.redAccent, radius: 4.0),
isScrollable: true,
labelColor: Colors.redAccent,
labelStyle: const TextStyle(
fontWeight: FontWeight.bold, fontSize: 20.0),
unselectedLabelColor: Colors.black,
unselectedLabelStyle: const TextStyle(
fontWeight: FontWeight.bold, fontSize: 20.0),
tabs: const [
Tab(text: 'Brandy'),
Tab(text: 'Gin'),
Tab(text: 'Soft drinks'),
Tab(text: 'Whiskey')
],
),
),
),
Container(
height: 400,
width: double.maxFinite,
child: TabBarView(
controller: tabController,
children: productProvider.categories.map((bottleCategory) {
return GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: itemWidth / itemHeight,
),
itemCount: bottleCategory.bottleList.length,
itemBuilder: (context, index) {
return Card(
shadowColor: Colors.grey,
surfaceTintColor: Colors.amber,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20)),
child: Stack(
children: [
Positioned(
right: 0,
child: InkWell(
onTap: () {
favoriteProvider.toggleFavorites(
bottleCategory.bottleList[index]);
if (favoriteProvider.isExist(
bottleCategory.bottleList[index])) {
ScaffoldMessenger.of(context)
.hideCurrentSnackBar();
ScaffoldMessenger.of(context)
.showSnackBar(
const SnackBar(
content: Text(
"Product Added to Favorite!",
style: TextStyle(fontSize: 16),
),
backgroundColor: Colors.green,
duration: Duration(seconds: 1),
),
);
} else {
ScaffoldMessenger.of(context)
.hideCurrentSnackBar();
ScaffoldMessenger.of(context)
.showSnackBar(
const SnackBar(
content: Text(
"Product Removed from Favorite!",
style: TextStyle(fontSize: 16),
),
backgroundColor: Colors.red,
duration: Duration(seconds: 1),
),
);
}
},
child: favoriteProvider.isExist(
bottleCategory.bottleList[index])
? const Icon(
Icons.favorite,
color: Colors.redAccent,
)
: const Icon(Icons.favorite_border),
),
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Center(
child: Image.asset(
bottleCategory.bottleList[index].image,
height: 200.0,
),
),
Center(
child: Text(
bottleCategory
.bottleList[index].bottleName,
style: const TextStyle(
fontSize: 20.0,
fontWeight: FontWeight.bold))),
Center(
child: Text(
'R${bottleCategory.bottleList[index].price}'),
)
],
),
Positioned(
bottom: 0,
right: 10,
child: IconButton(
icon: const Icon(Icons.add_circle),
iconSize: 40.0,
onPressed: () {
cart.addToCart(
bottleCategory.bottleList[index].id,
bottleCategory
.bottleList[index].bottleName,
bottleCategory
.bottleList[index].price,
bottleCategory
.bottleList[index].image);
},
))
],
),
);
},
);
}).toList()),
),
],
),
),
);
}
}
class FavoriteProvider with ChangeNotifier {
List<Bottle> _favItems = [];
List<Bottle> get favItems {
return [..._favItems];
}
void toggleFavorites(Bottle favBottle) {
final isExist = _favItems.contains(favBottle);
if (isExist) {
_favItems.remove(favBottle);
} else {
_favItems.add(favBottle);
}
notifyListeners();
}
bool isExist(Bottle favBottle) {
final isExist = _favItems.contains(favBottle);
return isExist;
}
void clearFavorite() {
_favItems = [];
notifyListeners();
}
}
Try using Consumer widget. Like so:
Consumer<favoriteProvider>(
builder: (BuildContext context, favorite, _){
return Icon(
Icons.favorite,
color: favorite.isExist(bottleCategory.bottleList[index])? Colors.redAccent : null,
);
},
),
Consumer widget will refresh or change the state whenever the ChangeNotifier of that model, in this case, FavoriteProvider is triggered, this should allows your widget to change and check itself anytime. So you shouldn't need to keep your state or screen alive all the time.
If that doesn't work, please change your Business Logic in the FavoriteProvider. Instead of using contains, I suggest to use any and identifies each instances with its own id or any of its unique variable. Like so:
bool isExist(Bottle favBottle) {
final isExist = _favItems.any((e) =>e.bottleName == favBottle.bottleName);
return isExist;
}
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'),
),
],
),
),
),
);
}
}
Here is my main class with pageview
class EditInvoice extends StatefulWidget {
#override
_EditInvoiceState createState() => _EditInvoiceState();
}
class _EditInvoiceState extends State<EditInvoice> {
String strTotal = '0';
#override
void initState() {
super.initState();
}
PageController pageController = PageController(
initialPage: 0,
keepPage: true,
);
Widget buildPageView() {
return PageView(
controller: pageController,
children: <Widget>[
AddItems(),
],
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
floatingActionButton: FloatingActionButton(
onPressed: () {},
backgroundColor: Colors.orange[600],
elevation: 2.0,
child: Icon(
Icons.check,
color: Colors.white,
),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
appBar: AppBar(
iconTheme: IconThemeData(
color: Colors.black, //change your color here
),
automaticallyImplyLeading: false,
toolbarHeight: 140.0,
centerTitle: true,
title: Column(
children: <Widget>[
Row(
children: <Widget>[
IconButton(
onPressed: () {
Navigator.pop(context);
},
icon: Icon(Icons.arrow_back)),
Padding(padding: EdgeInsets.only(left: 30.0)),
Align(
alignment: Alignment.center,
child: Text(
strTotal,
style: TextStyle(color: Colors.black),
),
)
],
),
],
),
backgroundColor: Colors.white,
),
body: buildPageView(),
);
}
}
class AddItems extends StatefulWidget {
#override
_AddItemsState createState() => _AddItemsState();
}
class _AddItemsState extends State<AddItems> {
#override
Widget build(BuildContext context) {
var items = Padding(
padding: EdgeInsets.only(left: 20.0, right: 20.0),
child: TextFormField(
decoration: InputDecoration(
labelText: 'Amount',
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(5)),
),
),
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 15,
),
cursorColor: Colors.black,
keyboardType: TextInputType.phone,
));
return Container(
child: Card(
child: Padding(
padding: EdgeInsets.only(top: 10, bottom: 5.0, left: 10.0, right: 10.0),
child: SingleChildScrollView(
child: Column(mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[
Text(
'Add Items',
style: TextStyle(fontWeight: FontWeight.bold, color: Colors.black),
),
items,
])))),
);
}
}
I am implementing pageview in my Flutter application. I want to update the amount in main class whenever user entered value in TextFormField from pageview.
Here AddItems is the page added with pageview and EditInvoice is the main class.
I am new to Flutter application development.
You can use the Provider Pattern:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class ProviderTest with ChangeNotifier {
String amount = '';
void updateAmount(String newAmount) {
amount = newAmount;
notifyListeners();
}
}
class EditInvoice extends StatefulWidget {
#override
_EditInvoiceState createState() => _EditInvoiceState();
}
class _EditInvoiceState extends State<EditInvoice> {
#override
void initState() {
super.initState();
}
PageController pageController = PageController(
initialPage: 0,
keepPage: true,
);
Widget buildPageView() {
return PageView(
controller: pageController,
children: <Widget>[
AddItems(),
],
);
}
#override
Widget build(BuildContext context) {
var providerTest = Provider.of<ProviderTest>(context);
return Scaffold(
backgroundColor: Colors.white,
floatingActionButton: FloatingActionButton(
onPressed: () {},
backgroundColor: Colors.orange[600],
elevation: 2.0,
child: Icon(
Icons.check,
color: Colors.white,
),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
appBar: AppBar(
iconTheme: IconThemeData(
color: Colors.black, //change your color here
),
automaticallyImplyLeading: false,
toolbarHeight: 140.0,
centerTitle: true,
title: Column(
children: <Widget>[
Row(
children: <Widget>[
IconButton(
onPressed: () {
Navigator.pop(context);
},
icon: Icon(Icons.arrow_back)),
Padding(padding: EdgeInsets.only(left: 30.0)),
Align(
alignment: Alignment.center,
child: Text(
providerTest.amount.toString(),
style: TextStyle(color: Colors.black),
),
)
],
),
],
),
backgroundColor: Colors.white,
),
body: buildPageView(),
);
}
}
class AddItems extends StatefulWidget {
#override
_AddItemsState createState() => _AddItemsState();
}
class _AddItemsState extends State<AddItems> {
#override
Widget build(BuildContext context) {
var providerTest = Provider.of<ProviderTest>(context, listen: false);
var items = Padding(
padding: EdgeInsets.only(left: 20.0, right: 20.0),
child: TextFormField(
onChanged: (value) {
providerTest.updateAmount(value);
},
decoration: InputDecoration(
labelText: 'Amount',
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(5)),
),
),
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 15,
),
cursorColor: Colors.black,
keyboardType: TextInputType.phone,
));
return Container(
child: Card(
child: Padding(
padding: EdgeInsets.only(top: 10, bottom: 5.0, left: 10.0, right: 10.0),
child: SingleChildScrollView(
child: Column(mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[
Text(
'Add Items',
style: TextStyle(fontWeight: FontWeight.bold, color: Colors.black),
),
items,
])))),
);
}
}
And at main.dart
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (context) => ProviderTest(),
child: MaterialApp(
home: EditInvoice(),
),
);
}
}
More info about Provider Pattern here:
Provider Pattern
you can give callback to from child widget to parent widget to update data,
you can use inherited widget or provider