Flutter inherited widget inside ListView item

Nov 20 2019 10:26 PM
When i click qty plus on each item, Qty should plus on that item (But qty plus for all item)
who have good idea please help me please
thank you so much
 
 
inherited_widget.dart
  1. import 'package:flutter/material.dart';  
  2. import 'inherited_widget_data.dart';  
  3. class MyInheritedWidget extends InheritedWidget {  
  4. final Widget child;  
  5. final MyInheritedWidgetDataState state;  
  6. MyInheritedWidget({Key key, @required this.child, @required this.state})  
  7. super(key: key, child: child);  
  8. @override  
  9. bool updateShouldNotify(MyInheritedWidget oldWidget) {  
  10. return true;  
  11. }  
  12. }  
  13. inherited_widget_data.dart  
  14. import 'package:flutter/material.dart';  
import 'inherited_widget.dart';
  1. class MyInheritedWidgetData extends StatefulWidget {  
  2. final Widget child;  
  3. MyInheritedWidgetData({@required this.child});  
  4. @override  
  5. MyInheritedWidgetDataState createState() => MyInheritedWidgetDataState();  
  6. static MyInheritedWidgetDataState of(  
  7. [BuildContext context, bool rebuild = true]) {  
  8. return (rebuild  
  9. ? context.inheritFromWidgetOfExactType(MyInheritedWidget)  
  10. as MyInheritedWidget  
  11. : context.ancestorWidgetOfExactType(MyInheritedWidget)  
  12. as MyInheritedWidget)  
  13. .state;  
  14. }  
  15. }  
  16. class MyInheritedWidgetDataState extends State<MyInheritedWidgetData> {  
  17. int badgeNumer = 0, qty = 1, i = 0;  
  18. @override  
  19. void initState() {  
  20. super.initState();  
  21. }  
  22. setbadgeNumer(int newbadgeNumer) {  
  23. setState(  
  24. () {  
  25. badgeNumer = newbadgeNumer;  
  26. },  
  27. );  
  28. }  
  29. setQty(int newQty) {  
  30. setState(  
  31. () {  
  32. qty += newQty;  
  33. i += 1;  
  34. },  
  35. );  
  36. }  
  37. @override  
  38. Widget build(BuildContext context) {  
  39. return MyInheritedWidget(child: widget.child, state: this);  
  40. }  
  41. }  
main.dart
  1. //*******************Dart System package*******************  
  2. import 'dart:convert';  
  3. import 'dart:io';  
  4. import 'dart:typed_data';  
  5. import 'package:device_info/device_info.dart';  
  6. import 'package:flutter/material.dart';  
  7. //*******************pub.dev package*******************  
  8. import 'package:flutter_secure_storage/flutter_secure_storage.dart';  
  9. import 'package:get_ip/get_ip.dart';  
  10. import 'package:http/http.dart' as http;  
  11. import 'package:carousel_slider/carousel_slider.dart' as carouse;  
  12.   
  13. //*******************Model package*******************  
  14. import 'mainpage/hometab/inherited_widget_data.dart';  
  15. import 'models/Viewproduct.dart';  
  16. import 'services/fn.dart';  
  17. //*******************Pages package*******************  
  18.   
  19. void main() => runApp(MyApp());  
  20.   
  21. class MyApp extends StatelessWidget {  
  22. @override  
  23. Widget build(BuildContext context) {  
  24. return MaterialApp(  
  25. title: 'Flutter Demo',  
  26. theme: ThemeData(  
  27. primarySwatch: Colors.blue,  
  28. ),  
  29. home: HomePage(),  
  30. debugShowCheckedModeBanner: false,  
  31. );  
  32. }  
  33. }  
  34.   
  35. class HomePage extends StatefulWidget {  
  36. HomePage({Key key}) : super(key: key);  
  37. @override  
  38. _HomePageState createState() => new _HomePageState();  
  39. }  
  40.   
  41. class _HomePageState extends State<HomePage>  
  42. with SingleTickerProviderStateMixin {  
  43. bool isBackButtonActivated = false;  
  44. //Event on page load  
  45. @override  
  46. void initState() {  
  47. try {  
  48. super.initState();  
  49. _tabController = TabController(vsync: this, length: myTabs.length);  
  50. _tabController.addListener(() {  
  51. print(_tabController.index);  
  52. });  
  53. WidgetsBinding.instance.addPostFrameCallback((_) async {  
  54. DeviceInfoPlugin deviceInfo = DeviceInfoPlugin();  
  55. AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo;  
  56. Fn.deviceID = androidInfo.id;  
  57. Fn.deviceName = androidInfo.model;  
  58. Fn.ipaddress = await GetIp.ipAddress;  
  59. countrycode = await storage.read(key: 'countrycode') ?? "+856";  
  60. username = await storage.read(key: 'username');  
  61. loginResultID = await storage.read(key: 'loginResultID');  
  62. _refreshData();  
  63. //_asyncCheckAnotherLogin();  
  64. });  
  65. setState(() {});  
  66. catch (e) {  
  67. print(e.toString());  
  68. }  
  69. }  
  70.   
  71. //**************************** Variable for toolbar ****************************  
  72. static String appName = Fn.company_name + ' \u00a9 2019';  
  73. Widget appBarTitle = new Text(appName);  
  74. Icon actionIcon = new Icon(Icons.search);  
  75. static Color colorToolbar = Colors.deepOrange;  
  76. int badgeNumer = 0;  
  77. //**************************** Variable for login ****************************  
  78. String countrycode,  
  79. username,  
  80. password,  
  81. loginResultID = "",  
  82. isAnotherLoginResultID = "";  
  83. var txtusername = TextEditingController();  
  84. var txtpassword = TextEditingController();  
  85. final txtusername_focus = FocusNode();  
  86. final txtpassword_focus = FocusNode();  
  87. bool emailValid = false,  
  88. firstLoad = true,  
  89. isLogin = false,  
  90. password_visibility = false,  
  91. loadhometabeFail = false,  
  92. isAnotherLogin = false;  
  93. //**************************** Variable for home tabe ****************************  
  94. final List<Tab> myTabs = <Tab>[  
  95. Tab(  
  96. icon: Icon(IconData(0xe88a, fontFamily: 'MaterialIcons')),  
  97. //text: 'Home',  
  98. ),  
  99. Tab(  
  100. icon: Icon(  
  101. IconData(57573, fontFamily: 'MaterialIcons'),  
  102. ),  
  103. //text: 'Feed',  
  104. ),  
  105. Tab(  
  106. icon: Icon(IconData(59638, fontFamily: 'MaterialIcons')),  
  107. //text: 'Promotion',  
  108. ),  
  109. ];  
  110. TabController _tabController;  
  111. ScrollController _scrollController;  
  112. final GlobalKey<RefreshIndicatorState> _refreshIndicatorKey =  
  113. new GlobalKey<RefreshIndicatorState>();  
  114. final storage = new FlutterSecureStorage();  
  115. List<RegViewproduct> homeTabdata;  
  116. Uint8List _bytes(String b64) {  
  117. try {  
  118. return base64.decode(b64);  
  119. catch (e) {  
  120. print(e.toString());  
  121. }  
  122. }  
  123.   
  124. Future<List<RegViewproduct>> _getData() async {  
  125. try {  
  126. var photo = RegViewproduct();  
  127. //photo.albumId = '1';  
  128. String js = regViewproductToJson([photo]);  
  129. //print(js);  
  130. var rsp = await http.post(Fn.ihost.host + '/sale/vw_product.php',  
  131. body: js,  
  132. headers: {HttpHeaders.contentTypeHeader: 'application/json'});  
  133. //print(rsp.body);  
  134. return regViewproductFromJson(rsp.body);  
  135. catch (e) {  
  136. print(e.toString());  
  137. loadhometabeFail = e.toString() != null;  
  138. }  
  139. }  
  140.   
  141. Future<Null> _refreshData() {  
  142. try {  
  143. return _getData().then((onValue) {  
  144. //print(onValue);  
  145. setState(() {  
  146. homeTabdata = onValue;  
  147. });  
  148. });  
  149. catch (e) {  
  150. print(e.toString());  
  151. }  
  152. }  
  153.   
  154. @override  
  155. Widget build(BuildContext context) {  
  156. return MyInheritedWidgetData(  
  157. child: MaterialApp(  
  158. theme: ThemeData(  
  159. primarySwatch: colorToolbar,  
  160. //primaryColor: Colors.deepOrange, //Changing this will change the color of the TabBar  
  161. brightness: Brightness.light,  
  162. accentColor: Colors.green,  
  163. ),  
  164. debugShowCheckedModeBanner: false,  
  165. home: DefaultTabController(  
  166. length: 1,  
  167. child: WillPopScope(  
  168. onWillPop: () async => false,  
  169. child: Scaffold(  
  170. appBar: AppBar(  
  171. centerTitle: true,  
  172. title: appBarTitle,  
  173. actions: <Widget>[  
  174. new IconButton(  
  175. icon: actionIcon,  
  176. onPressed: () {  
  177. setState(() {  
  178. if (this.actionIcon.icon == Icons.search) {  
  179. this.actionIcon = new Icon(Icons.close);  
  180. this.appBarTitle = new TextField(  
  181. autofocus: true,  
  182. style: new TextStyle(  
  183. color: Colors.white,  
  184. ),  
  185. decoration: new InputDecoration(  
  186. prefixIcon:  
  187. new Icon(Icons.search, color: Colors.white),  
  188. hintText: 'Search in ' + Fn.company_name + ' ...',  
  189. hintStyle: new TextStyle(color: Colors.white),  
  190. ),  
  191. );  
  192. else {  
  193. this.actionIcon = new Icon(Icons.search);  
  194. this.appBarTitle = new Text(appName);  
  195. }  
  196. });  
  197. },  
  198. ),  
  199. WidgetCartBadge(),  
  200. ],  
  201. ),  
  202. body: TabBarView(  
  203. controller: _tabController,  
  204. children: <Widget>[  
  205. homeTabdata != null  
  206. ? RefreshIndicator(  
  207. key: _refreshIndicatorKey,  
  208. onRefresh: _refreshData,  
  209. child: ListView(  
  210. controller: _scrollController,  
  211. children: <Widget>[  
  212. //************************* Image slider *************************  
  213. Container(  
  214. decoration: const BoxDecoration(  
  215. border: Border(  
  216. top: BorderSide(  
  217. width: 1.0, color: Color(0xFFFFFFFFFF)),  
  218. left: BorderSide(  
  219. width: 1.0, color: Color(0xFFFFFFFFFF)),  
  220. right: BorderSide(  
  221. width: 1.0, color: Color(0xFFFF000000)),  
  222. bottom: BorderSide(  
  223. width: 5.0,  
  224. color: Colors.grey,  
  225. ),  
  226. ),  
  227. ),  
  228. child: Padding(  
  229. padding:  
  230. const EdgeInsets.fromLTRB(0204),  
  231. child: carouse.CarouselSlider(  
  232. height: 150.0,  
  233. aspectRatio: 16 / 9,  
  234. viewportFraction: 0.9,  
  235. initialPage: 0,  
  236. enableInfiniteScroll: true,  
  237. reverse: false,  
  238. autoPlay: true,  
  239. autoPlayInterval: Duration(seconds: 7),  
  240. autoPlayAnimationDuration:  
  241. Duration(seconds: 3),  
  242. //autoPlayCurve: Curve.fastOutSlowIn,  
  243. pauseAutoPlayOnTouch: Duration(seconds: 7),  
  244. enlargeCenterPage: true,  
  245. //onPageChanged: callbackFunction,  
  246. scrollDirection: Axis.horizontal,  
  247. items: homeTabdata.map(  
  248. (i) {  
  249. return Builder(  
  250. builder: (BuildContext context) {  
  251. return Container(  
  252. alignment: Alignment.bottomCenter,  
  253. width: MediaQuery.of(context)  
  254. .size  
  255. .width,  
  256. margin: EdgeInsets.symmetric(  
  257. horizontal: 5.0),  
  258. decoration: BoxDecoration(  
  259. image: new DecorationImage(  
  260. image: i.productImgBase64  
  261. .trim() !=  
  262. null  
  263. ? MemoryImage(_bytes(i  
  264. .productImgBase64))  
  265. : Container(),  
  266. fit: BoxFit.cover),  
  267. color: Colors.amber),  
  268. child: Padding(  
  269. padding:  
  270. const EdgeInsets.all(8.0),  
  271. child: new Text(  
  272. i.productBillName,  
  273. style: new TextStyle(  
  274. fontSize: 16.0),  
  275. ),  
  276. ),  
  277. );  
  278. },  
  279. );  
  280. },  
  281. ).toList(),  
  282. ),  
  283. ),  
  284. ),  
  285. //************************* Product menu *************************  
  286. Container(  
  287. child: ListView(  
  288. shrinkWrap: true,  
  289. //crossAxisCount: 2,  
  290. physics: ScrollPhysics(),  
  291. children: homeTabdata  
  292. .getRange(0, homeTabdata.length)  
  293. .map(  
  294. (f) {  
  295. return Container(  
  296. key: UniqueKey(),  
  297. decoration: const BoxDecoration(  
  298. border: Border(  
  299. bottom: BorderSide(  
  300. width: 5.0,  
  301. color: Colors.grey,  
  302. ),  
  303. ),  
  304. ),  
  305. child: Column(  
  306. key: UniqueKey(),  
  307. children: <Widget>[  
  308. Card(  
  309. key: UniqueKey(),  
  310. elevation: 0.0,  
  311. shape: RoundedRectangleBorder(  
  312. borderRadius:  
  313. BorderRadius.all(  
  314. Radius.circular(  
  315. 5.0))),  
  316. child: Image.memory(  
  317. _bytes(f.productImgBase64),  
  318. fit: BoxFit.cover,  
  319. height: 250.0,  
  320. width: MediaQuery.of(context)  
  321. .size  
  322. .width,  
  323. ),  
  324. clipBehavior: Clip.antiAlias,  
  325. margin: EdgeInsets.all(0.0),  
  326. ),  
  327. Text(  
  328. f.productBillName,  
  329. style: TextStyle(fontSize: 16),  
  330. textAlign: TextAlign.center,  
  331. ),  
  332. Container(  
  333. decoration: const BoxDecoration(  
  334. border: Border(  
  335. top: BorderSide(  
  336. width: 1.0,  
  337. color: Colors.grey)),  
  338. ),  
  339. child: Row(  
  340. key: UniqueKey(),  
  341. mainAxisAlignment:  
  342. MainAxisAlignment.end,  
  343. children: <Widget>[  
  344. ButtonTheme.bar(  
  345. key: UniqueKey(),  
  346. child: ButtonBar(  
  347. key: UniqueKey(),  
  348. children: <Widget>[  
  349. FlatButton(  
  350. key: UniqueKey(),  
  351. shape:  
  352. new RoundedRectangleBorder(  
  353. borderRadius:  
  354. new BorderRadius  
  355. .circular(  
  356. Fn.btnRadius),  
  357. ),  
  358. child: IconButton(  
  359. onPressed: () {  
  360. setState(() {  
  361. f.reqqty = (int.parse(f.reqqty) >  
  362. 1  
  363. int.parse(f.reqqty) -  
  364. 1  
  365. 1)  
  366. .toString();  
  367. });  
  368. },  
  369. icon: Icon(Icons  
  370. .remove_circle_outline),  
  371. ),  
  372. onPressed: () {},  
  373. ),  
  374. WidgetQty(),  
  375. // Container(  
  376. // decoration: BoxDecoration(  
  377. // color: new Color(  
  378. // 0x000000)),  
  379. // child: Text(  
  380. // f.reqqty,  
  381. // style: TextStyle(  
  382. // fontSize: 30,  
  383. // ),  
  384. // ),  
  385. // ),  
  386. WidgetbtnQtyMore(),  
  387. // FlatButton(  
  388. // shape: new RoundedRectangleBorder(  
  389. // borderRadius:  
  390. // new BorderRadius  
  391. // .circular(  
  392. // Fn.btnRadius)),  
  393. // child: IconButton(  
  394. // onPressed: () {  
  395. // setState(() {  
  396. // f.reqqty = (int.parse(  
  397. // f.reqqty) +  
  398. // 1)  
  399. // .toString();  
  400. // });  
  401. // },  
  402. // icon: Icon(Icons  
  403. // .add_circle_outline),  
  404. // ),  
  405. // onPressed: () {},  
  406. // ),  
  407. WidgetbtnAddToCart(),  
  408. ],  
  409. ),  
  410. )  
  411. ],  
  412. ),  
  413. ),  
  414. ],  
  415. ),  
  416. );  
  417. },  
  418. ).toList(),  
  419. ),  
  420. ),  
  421. ],  
  422. ),  
  423. )  
  424. : !loadhometabeFail  
  425. ? Container(  
  426. color: Colors.blue[700],  
  427. child: Column(  
  428. mainAxisAlignment: MainAxisAlignment.center,  
  429. children: <Widget>[  
  430. CircularProgressIndicator(  
  431. valueColor:  
  432. new AlwaysStoppedAnimation<Color>(  
  433. Colors.green),  
  434. ),  
  435. Padding(  
  436. padding: const EdgeInsets.only(top: 20.0),  
  437. ),  
  438. Text(  
  439. 'Loading......',  
  440. style: TextStyle(  
  441. color: Colors.white,  
  442. ),  
  443. ),  
  444. ],  
  445. ),  
  446. )  
  447. : Container(  
  448. child: Column(  
  449. mainAxisAlignment: MainAxisAlignment.center,  
  450. children: <Widget>[  
  451. Icon(Icons.warning),  
  452. Padding(  
  453. padding: const EdgeInsets.fromLTRB(  
  454. 0.020.000),  
  455. child:  
  456. Text(':) Problem with connection....!'),  
  457. ),  
  458. Padding(  
  459. padding:  
  460. const EdgeInsets.fromLTRB(102000),  
  461. child: ListTile(  
  462. title: Text(  
  463. 'Try again',  
  464. style: TextStyle(  
  465. decoration: TextDecoration.underline,  
  466. ),  
  467. textAlign: TextAlign.center,  
  468. ),  
  469. onTap: () {  
  470. setState(() {  
  471. loadhometabeFail = false;  
  472. });  
  473. _refreshData();  
  474. },  
  475. ),  
  476. ),  
  477. ],  
  478. ),  
  479. ),  
  480. Column(  
  481. children: <Widget>[  
  482. Icon(IconData(57573, fontFamily: 'MaterialIcons')),  
  483. ],  
  484. ),  
  485. Column(  
  486. children: <Widget>[  
  487. Icon(IconData(59638, fontFamily: 'MaterialIcons')),  
  488. ],  
  489. ),  
  490. ],  
  491. ),  
  492. //************************* Bottom Toolbar *************************  
  493. bottomNavigationBar: Container(  
  494. decoration: const BoxDecoration(  
  495. //color: Colors.deepOrange,  
  496. border: Border(  
  497. left: BorderSide(width: 0.0, color: Color(0xFFFFFFFFFF)),  
  498. right: BorderSide(width: 0.0, color: Color(0xFFFF000000)),  
  499. top: BorderSide(  
  500. width: 2.0,  
  501. color: Colors.grey,  
  502. ),  
  503. bottom: BorderSide(width: 0.0, color: Color(0xFFFFFFFFFF)),  
  504. ),  
  505. ),  
  506. child: TabBar(  
  507. controller: _tabController,  
  508. tabs: myTabs,  
  509. labelColor: Colors.grey[700],  
  510. //unselectedLabelColor: colorToolbar,  
  511. indicatorSize: TabBarIndicatorSize.label,  
  512. indicatorPadding: EdgeInsets.all(5.0),  
  513. indicatorColor: Colors.red,  
  514. indicatorWeight: 0.1,  
  515. onTap: (index) {  
  516. // print(index);  
  517. // Toast.show(  
  518. // 'msg : ' + index.toString(),  
  519. // context,  
  520. // duration: Toast.TOP,  
  521. // gravity: Toast.LENGTH_LONG,  
  522. // );  
  523. },  
  524. //controller: Text('data'),  
  525. ),  
  526. ),  
  527. ),  
  528. ),  
  529. ),  
  530. ),  
  531. );  
  532. }  
  533. }  
  534.   
  535. class WidgetQty extends StatelessWidget {  
  536. @override  
  537. Widget build(BuildContext context) {  
  538. final MyInheritedWidgetDataState state = MyInheritedWidgetData.of(context);  
  539. print("build Widget WidgetQty" + state.i.toString());  
  540. return Container(  
  541. key: UniqueKey(),  
  542. decoration: BoxDecoration(color: new Color(0x000000)),  
  543. child: Text(  
  544. state.qty.toString(),  
  545. style: TextStyle(  
  546. fontSize: 30,  
  547. ),  
  548. ),  
  549. );  
  550. }  
  551. }  
  552.   
  553. class WidgetbtnQtyMore extends StatelessWidget {  
  554. @override  
  555. Widget build(BuildContext context) {  
  556. print("build Widget WidgetQtyMore");  
  557. final MyInheritedWidgetDataState state =  
  558. MyInheritedWidgetData.of(context, false);  
  559. return FlatButton(  
  560. key: UniqueKey(),  
  561. shape: new RoundedRectangleBorder(  
  562. borderRadius: new BorderRadius.circular(Fn.btnRadius)),  
  563. child: IconButton(  
  564. key: UniqueKey(),  
  565. onPressed: () {  
  566. state.setQty(1);  
  567. return;  
  568. },  
  569. icon: Icon(Icons.add_circle_outline),  
  570. ),  
  571. onPressed: () {},  
  572. );  
  573. }  
  574. }  
  575.   
  576. class WidgetCartBadge extends StatelessWidget {  
  577. @override  
  578. Widget build(BuildContext context) {  
  579. final MyInheritedWidgetDataState widget = MyInheritedWidgetData.of(context);  
  580. return Stack(  
  581. children: <Widget>[  
  582. IconButton(  
  583. onPressed: () {},  
  584. icon: Icon(Icons.shopping_cart),  
  585. ),  
  586. widget.badgeNumer > 0  
  587. ? Positioned(  
  588. right: 1,  
  589. top: 11,  
  590. child: new Container(  
  591. padding: EdgeInsets.all(2),  
  592. decoration: new BoxDecoration(  
  593. color: Colors.green,  
  594. borderRadius: BorderRadius.circular(6),  
  595. ),  
  596. constraints: BoxConstraints(  
  597. minWidth: 14,  
  598. minHeight: 14,  
  599. ),  
  600. child: Text(  
  601. widget.badgeNumer.toString(),  
  602. style: TextStyle(  
  603. color: Colors.white,  
  604. fontSize: 8,  
  605. ),  
  606. textAlign: TextAlign.center,  
  607. ),  
  608. ),  
  609. )  
  610. : Container(),  
  611. ],  
  612. );  
  613. }  
  614. }  
  615.   
  616. class WidgetbtnAddToCart extends StatelessWidget {  
  617. @override  
  618. Widget build(BuildContext context) {  
  619. final _HomePageState _homePageState = _HomePageState();  
  620. final MyInheritedWidgetDataState state =  
  621. MyInheritedWidgetData.of(context, false);  
  622. return FlatButton(  
  623. shape: new RoundedRectangleBorder(  
  624. borderRadius: new BorderRadius.circular(Fn.btnRadius)),  
  625. child: IconButton(  
  626. onPressed: () {  
  627. state.setbadgeNumer(2);  
  628. _homePageState.badgeNumer = state.badgeNumer;  
  629. print(_homePageState.badgeNumer);  
  630. },  
  631. icon: Icon(Icons.shopping_cart),  
  632. ),  
  633. onPressed: () {},  
  634. );  
  635. }  
  636. }  

Answers (2)