I trying to change view from grid to list view.
I used StaggeredGridView for first view but after click change view button it should change into vertical list view .just like instagram gallery view.
Piece of code:
view changing button:
InkWell(
child:view
?Image.asset('assets/icons/view_by1.png')
:Image.asset('assets/icons/view_by3.png'),
onTap: (){
setState(() {
view = !view;
});
}
)
widget for changing view:
Widget sliverGridWidget(BuildContext context, List<Photos> listPhotoDetail){
return StaggeredGridView.countBuilder(
padding: const EdgeInsets.all(8.0),
crossAxisCount: view?2:6, //if view true make it vertical view otherwise grid view
itemCount: listPhotoDetail.length,
itemBuilder: (context, index){
return InkWell(
onLongPress: (){
setState(() {
enable = true;
});
},
child: Container(
decoration: BoxDecoration(
color:Colors.grey[100],
image: DecorationImage(
image: NetworkImage(listPhotoDetail[index].photoDetail.image.fileUrl),
fit: BoxFit.cover
)
),
child:enable? Stack(
children: <Widget>[
Positioned(
bottom: 5,
right: 3,
child: InkWell(
child: listPhotoDetail[index].isSelected
?Image.asset('assets/icons/selected.png')
:Image.asset('assets/icons/select_on_image.png'),
onTap: (){
setState(() {
listPhotoDetail[index].isSelected = !listPhotoDetail[index].isSelected;
count= listPhotoDetail[index].isSelected ?count+1:count-1;
if(listPhotoDetail[index].isSelected){
selectedPhotostList.add(
Photos(
photoDetail:listPhotoDetail[index].photoDetail ,
// contact:contactList[index].contact ,
isSelected:listPhotoDetail[index].isSelected)
);
} else{
selectedPhotostList.removeAt(index);
}
// listPhotoDetail[index].isSelected = ! listPhotoDetail[index].isSelected;
// count = listPhotoDetail[index].isSelected ?count+1:count-1;
});
},
)
)
],
)
:Container()
),
);
},
staggeredTileBuilder: (index)
=> StaggeredTile.count(2, 2), //Make size as you want.
mainAxisSpacing: 8.0,
crossAxisSpacing:8.0,
);
}
}
this does not give me satisfied view
means i have total14 images
and gridview looks perfect and shows all 14 images but when pressed changing view button, it
shows only 3 to 4 images as listview.
see :
Here short video
you can take help of this to solve your problem, click on the floating action button to change the view.
import 'package:flutter/material.dart';
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
void main(){
runApp(MaterialApp(home: Example01()));
}
List<Widget> _tiles = const <Widget>[
const _Example01Tile(Colors.green, Icons.widgets),
const _Example01Tile(Colors.lightBlue, Icons.wifi),
const _Example01Tile(Colors.amber, Icons.panorama_wide_angle),
const _Example01Tile(Colors.brown, Icons.map),
const _Example01Tile(Colors.deepOrange, Icons.send),
const _Example01Tile(Colors.indigo, Icons.airline_seat_flat),
const _Example01Tile(Colors.red, Icons.bluetooth),
const _Example01Tile(Colors.pink, Icons.battery_alert),
const _Example01Tile(Colors.purple, Icons.desktop_windows),
const _Example01Tile(Colors.blue, Icons.radio),
const _Example01Tile(Colors.pink, Icons.radio),
const _Example01Tile(Colors.yellow, Icons.radio),
const _Example01Tile(Colors.brown, Icons.map),
const _Example01Tile(Colors.deepOrange, Icons.send),
const _Example01Tile(Colors.indigo, Icons.airline_seat_flat),
];
class Example01 extends StatefulWidget {
#override
_Example01State createState() => _Example01State();
}
class _Example01State extends State<Example01> {
bool isList= false;
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('Example 01'),
),
body: new Padding(
padding: const EdgeInsets.only(top: 12.0),
child: new StaggeredGridView.countBuilder(
crossAxisCount: 6,
itemCount: _tiles.length,
itemBuilder: (context,i){
return _tiles[i];
},
staggeredTileBuilder: (i)=> isList ?StaggeredTile.count(6,1):StaggeredTile.count(2,2),
mainAxisSpacing: 1.0,
crossAxisSpacing: 1.0,
padding: const EdgeInsets.all(4.0),
)),
floatingActionButton: FloatingActionButton(
child: isList ?Icon(Icons.grid_on):Icon(Icons.list),
onPressed:(){
setState(() {
isList = !isList;
});
},
),
);
}
}
class _Example01Tile extends StatelessWidget {
const _Example01Tile(this.backgroundColor, this.iconData);
final Color backgroundColor;
final IconData iconData;
#override
Widget build(BuildContext context) {
return new Card(
color: backgroundColor,
child: new InkWell(
onTap: () {},
child: new Center(
child: new Padding(
padding: const EdgeInsets.all(4.0),
child: new Icon(
iconData,
color: Colors.white,
),
),
),
),
);
}
}
Related
I have a custom Text widget Named Dynamic_Game_Preview , and also a TextField.
I want the Dynamic_Game_Preview to be changed with the change of the TextField.
I used onChanged method for the TextField but all the letters are shown separately in the Dynamic_Game_Preview. How can I handle this changes to be applied in the same Dynamic_Game_Preview simultaneously with changing the TextField?
Here is my code:
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:pet_store/widgets/dynamic_game_preview.dart';
import 'main.dart';
class Dynamic_Game extends StatefulWidget {
const Dynamic_Game({Key? key}) : super(key: key);
#override
State<Dynamic_Game> createState() => _Dynamic_GameState();
}
class _Dynamic_GameState extends State<Dynamic_Game> {
TextEditingController nameController = TextEditingController();
List<String> names = [];
bool isLoading = false;
List<Dynamic_Game_Preview> dynamicList = [];
void initState() {
super.initState();
dynamicList = [];
names = [];
}
void addNames() {
if (names.length == 1) {
names = [];
}
names.add(nameController.text);
nameController.clear();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.indigo,
title: const Text('Dynamic Game'),
leading: GestureDetector(
child: const Icon(
Icons.arrow_back_ios,
color: Colors.white,
),
onTap: () {
// Navigator.pop(context);
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(
builder: (BuildContext context) => const HomePage(),
),
(route) => false,
);
},
),
),
body: GestureDetector(
onTap: () {
FocusScope.of(context).requestFocus(FocusNode());
},
child: Center(
child: Column(
children: <Widget>[
SizedBox(height: 20),
Container(
margin: const EdgeInsets.symmetric(horizontal: 30),
child: TextField(
controller: nameController,
onChanged: (value) {
setState(() {
addNames();
});
},
decoration: const InputDecoration(
labelText: 'Enter a Pet Name',
),
),
),
SizedBox(height: 10),
Flexible(
fit: FlexFit.loose,
child: ListView.builder(
shrinkWrap: true,
itemCount: names.length,
itemBuilder: (_, index) {
return Padding(
padding: const EdgeInsets.symmetric(
horizontal: 5.0, vertical: 3.0),
child: Dynamic_Game_Preview(nameController.text),
);
},
),
),
],
),
),
),
);
}
}
Problem
Your code clears the nameController:
void addNames() {
...
nameController.clear();
}
Then the code is trying to display nameController.text, which just got cleared:
Dynamic_Game_Preview(nameController.text)
Solution
Something along these lines should work:
itemBuilder: (_, index) {
return Padding(
padding: const EdgeInsets.symmetric(
horizontal: 5.0, vertical: 3.0),
child: Dynamic_Game_Preview(names[index]),
);
},
Last but not least
This probably is not needed:
onTap: () {
FocusScope.of(context).requestFocus(FocusNode());
},
I want to add a new column after the end of the loop inside Gridview.
Right now in my code I add the append functionality in floatingActionButton but I want to add this append functionality in the column after every end of the column loop.
Like this:- need to add a new column after end of loop
Please see this image for a better understanding.
I hope you understand what I want to say.
Right now my output is like this:- see there is floatingActionButton where i add append functionality to add a new column
Here is my code:-
import 'package:flutter/material.dart';
import 'package:mindmatch/utils/widget_functions.dart';
import 'package:mindmatch/custom/BorderIcon.dart';
import 'package:mindmatch/screens/Relation.dart';
import 'package:flutter_svg/flutter_svg.dart';
void main() {
runApp(new MaterialApp(
home: new Photos(),
));
}
class Photos extends StatefulWidget {
var usrid;
Photos({Key? key, #required this.usrid}) : super(key: key);
#override
_Photos createState() => _Photos();
}
class _Photos extends State<Photos>{
int counter = 0;
//List<Widget> _list = List<Widget>();
List<Widget> _list = <Widget> [];
#override
void initState() {
for (int i = 0; i < 2; i++) {
Widget child = _newItem(i);
_list.add(child);
};
}
void on_Clicked() {
Widget child = _newItem(counter);
setState(
() => _list.add(child),
);
}
Widget _newItem(int i) {
Key key = new Key('item_${i}');
Column child = Column(
key: key,
children: [
Stack(
children: [
Card(
elevation: 0,
shape: RoundedRectangleBorder(
side: BorderSide(
color: Color(0xffa1a1a1),
),
borderRadius: BorderRadius.all(Radius.circular(12)),
),
child: SizedBox(
//width: 300,
height: 100,
child: Center(child:
Icon(
Icons.image,
color: Color(0xffcccccc),
size: 60,
),
),
),
),
Positioned(
top: 9,
right: 9,
child: InkWell(
onTap: () => _removeItem(i),
child: SvgPicture.asset(
width: 20,
'assets/images/close.svg',
height: 20,
),
),
)
]
),
]
);
counter++;
return child;
}
void _removeItem(int i) {
print("====remove $i");
print('===Removing $i');
setState(() => _list.removeAt(i));
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('Photo'),
backgroundColor: Colors.deepPurpleAccent,
),
floatingActionButton: new FloatingActionButton(onPressed: on_Clicked, child: new
Icon(Icons.add),),
body: new Container(
padding: new EdgeInsets.all(32.0),
child: Column(
children: [
Expanded(
child: GridView(
//padding: const EdgeInsets.all(8.0),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
crossAxisSpacing: 10.0,
mainAxisSpacing: 15,
//childAspectRatio: 2/1,
),
children: [
itemBuilder: List.generate(_list.length, (index) {
//generating tiles with people from list
return _newItem(index);
},
]
return Column(
)
),
)
)
],
),
),
);
}
}
Please help how I add a new Column after the end of the loop on that column i add onTap property where i add append functionality to add new column when click.
Here is the code of the new column with add icon
InkWell(
onTap: (){},
child: Column(
children: [
Stack(
children: const [
Card(
elevation: 0,
color: Color(0xff8f9df2),
shape: RoundedRectangleBorder(
side: BorderSide(
color: Color(0xff8f9df2),
),
borderRadius: BorderRadius.all(Radius.circular(12)),
),
child: SizedBox(
//width: 300,
height: 100,
child: Center(child:
Icon(
Icons.add,
color: Colors.white,
size: 80.0,
),
),
),
)
]
),
]
),
)
You can extend item-count (item Length) by one and use last index to show add widget.
children: List.generate(itemLength + 1,
(index) => index == itemLength ? Text("new Item") : _newItem(index)),
I have created sample demo. you can foloow this. Hope this you want this same.
import 'package:flutter/material.dart';
const Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class CustomObject{
String name;
bool isDummy;
CustomObject(this.name , this.isDummy);
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(
scaffoldBackgroundColor: darkBlue,
),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: MyClass(),
),
),
);
}
}
class MyClass extends StatefulWidget {
#override
State<MyClass> createState() => _MyClassState();
}
class _MyClassState extends State<MyClass> {
List<CustomObject> _list =[];
#override
void initState() {
_list =[
CustomObject('test',false),
CustomObject('test 2',false),
CustomObject('',true), ///this is extra item to achieve
];
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body : Padding(
padding: const EdgeInsets.all(8.00),
child : GridView.builder(
gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 200,
childAspectRatio: 3 / 2,
crossAxisSpacing: 20,
mainAxisSpacing: 20),
itemCount: _list.length,
itemBuilder: (BuildContext ctx, index) {
return Container(
alignment: Alignment.center,
child: (!_list[index].isDummy) ? Text(_list[index].name) :
Icon(Icons.add,size: 40.00,),
decoration: BoxDecoration(
color: Colors.amber,
borderRadius: BorderRadius.circular(15)),
);
}),
),
);
}
}
Output :
Let me know if any query or anything.
I have a list of the button in my flutter app like the picture :enter image description here
and I need to select the container who I'm click on it
for example, change the container color
you can use container or button and GestureDetector like below example
import 'package:flutter/material.dart';
class SelectableGridView extends StatefulWidget {
const SelectableGridView({Key? key}) : super(key: key);
#override
State<SelectableGridView> createState() => _SelectableGridViewState();
}
class _SelectableGridViewState extends State<SelectableGridView> {
int selectedIndex = 0;
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.blueGrey,
body: Padding(
padding: const EdgeInsets.all(16.0),
child: GridView.builder(
physics: const ClampingScrollPhysics(),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
crossAxisSpacing: 16.0,
mainAxisSpacing: 16.0,
),
itemCount: 18,
itemBuilder: (context, index) {
return GestureDetector(
onTap: () => setState(() {
selectedIndex = index;
}),
child: Container(
color: selectedIndex == index ? Colors.pink : Colors.white,
),
);
},
),
),
);
}
}
TBH I'm not sure what your asking exactly, but this may or may not help you:
GestureDetector
This will let you respond to clicks on whatever it surrounds, so for example
return
GestureDetector(
onTap: (){
//Do something here to respond to a tap on the child Container()
},
child: Container(...) /// Your box
Now you can do something with it.
Hope this is what you were asking about
You can also use InkWell in this following way,
First you have to declare Color in your instances and after that you can use it in your onPress() widget.
Color _colorContainer = Colors.blue;
Now you can use it in your widget as follow:
Ink(
child: InkWell(
child: Container(
width: 200,
height: 200,
color: _colorContainer ,
),
onTap: () {
setState(() {
_colorContainer = _colorContainer == Colors.red ?
Colors.blue :
Colors.red;
});
},
)),
Header pull to refresh can be pulled up when I want to drag it up.
Tabbar sticky.
ListView can swipe to another page.
100% Custom Widget. It supports to change the header value and also support swipe opeartions.
It is not actually a TabBar Widget but it Works exactly like that
import 'package:flutter/material.dart';
import 'dart:math';
class NestedScrolls extends StatefulWidget {
static const listHeader = ['Pakistan', 'China','Iran','Turkey'];
#override
_NestedScrollsState createState() => _NestedScrollsState();
}
class _NestedScrollsState extends State<NestedScrolls> {
var position=0;
var topHeader;
Widget? applyWidget() {
switch(position){
case 0:
setState(() {
topHeader = NestedScrolls.listHeader[0];
});
// return widget if user click over pakistan in tab bar
return grid();
case 1:
setState(() {
topHeader = NestedScrolls.listHeader[1];
});
return list();
case 2:
setState(() {
topHeader = NestedScrolls.listHeader[2];
});
return Container(color: Colors.blue,
child: Center(child: Text(topHeader),),);
case 3:
setState(() {
topHeader = NestedScrolls.listHeader[3];
});
return Container(color: Colors.orange,
child: Center(child: Text(topHeader),),);
}
}
#override
void initState() {
// TODO: implement initState
super.initState();
//initial header name when activity start first time
topHeader = NestedScrolls.listHeader[0];
}
#override
Widget build(BuildContext context) {
topHeader = topHeader;
return Scaffold(
// Persistent AppBar that never scrolls
appBar: AppBar(
title: Text('AppBar'),
elevation: 0.0,
),
body:
Column(
children: <Widget>[
///header
Container(
alignment: Alignment.center,
color: Colors.blueGrey,
height: 90,
child: Text(NestedScrolls.listHeader[position]),
),
/// tabBar
Container(
height: 60,
width: MediaQuery.of(context).size.width,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: NestedScrolls.listHeader.length,
itemBuilder: (con, index) {
return GestureDetector(
onTap: () => setState(() {
position=index;
topHeader = NestedScrolls.listHeader[index];
}),
child: Padding(
padding: const EdgeInsets.symmetric(
vertical: 2.0, horizontal: 10),
child: Container(alignment: Alignment.center,
width: 100,
color: topHeader==NestedScrolls.listHeader[index]?Colors.black26:Colors.transparent,
child: Text(NestedScrolls.listHeader[index])),
),
);
}),
),
///Widget
Expanded(
child: GestureDetector(
// onHorizontalDragStart: (left){
// print('left : ${left.localPosition.direction}');
// // left.globalPosition.dx
//
// },
onHorizontalDragEnd: (start){
print('start : ${start.velocity.pixelsPerSecond.dx}');
if((start.velocity.pixelsPerSecond.dx)<-700){
if(position<NestedScrolls.listHeader.length-1 && position>=0)
setState(() {
position=position+1;
});
}else{}
if((start.velocity.pixelsPerSecond.dx)>900){
if(position<=NestedScrolls.listHeader.length-1 && position>0)
setState(() {
position=position-1;
});
}
print(position);
},
child: applyWidget()),
),
],
),
);
}
list() {
return SingleChildScrollView(scrollDirection: Axis.vertical,
child: Container(
child: Column(children: [
for(var color in Colors.primaries)
Container(color: color, height: 100.0)
],),
),
);
}
grid() {
return GridView.count(
padding: EdgeInsets.zero,
crossAxisCount: 3,
children: Colors.primaries.map((color) {
return Container(color: color, height: 100.0);
}).toList(),
);
}
}
I have the following Flutter BottomNavigationBar, I have 3 children page widgets. As soon as the user writes a review and press the submit button, I am calling the void _clear() which resets the values in the textfield widgets. This method is inside and called from the WriteReview widget but is not working, the screen is not refreshing. The data it self is being reset but the UI has not be refreshed. I tried with and without setState(){ _clear()}; but no results.
I have similar issue with the TabBarView. What I would expect as a result would be the selected widget page to be refreshed.
I assume is something different on how the widgets are being handled in the TabBarView and BottomNavigationBar that I am missing.
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class HomeView extends StatefulWidget {
#override
_HomeViewState createState() => _HomeViewState();
}
class _HomeViewState extends State<HomeView> {
final String _writeReviewLabel = 'Write review';
final String _searchLabel = 'Search';
final String _accountLabel = 'Account';
var _currentIndex = 0;
final List<Widget> _bottomBarItems = [
WriteReviewView(),
SearchView(),
UserAccountView()
];
#override
Widget build(BuildContext context) {
final accentColor = Theme.of(context).accentColor;
final primaryColor = Theme.of(context).primaryColor;
return BaseView<HomePresenter>(
createPresenter: () => HomePresenter(),
onInitialize: (presenter) {
_currentIndex = ModalRoute.of(context).settings.arguments;
},
builder: (context, child, presenter) => Scaffold(
bottomNavigationBar: BottomNavigationBar(
backgroundColor: primaryColor,
selectedItemColor: accentColor,
unselectedItemColor: Colors.white,
elevation: 0,
currentIndex: _currentIndex,
onTap: (index) {
onTabTapped(index, presenter);
},
items: [
BottomNavigationBarItem(
activeIcon: Icon(Icons.rate_review),
icon: Icon(Icons.rate_review),
title: Text(_writeReviewLabel),
),
BottomNavigationBarItem(
activeIcon: Icon(Icons.search),
icon: Icon(Icons.search),
title: Text(_searchLabel),
),
BottomNavigationBarItem(
activeIcon: Icon(Icons.person),
icon: Icon(Icons.person),
title: Text(_accountLabel)),
],
),
body: _bottomBarItems[_currentIndex]),
);
}
void onTabTapped(int index, HomePresenter presenter) {
if (index == _currentIndex) {
return;
}
if (presenter.isAuthenticated) {
setState(() {
_currentIndex = index;
});
} else {
presenter.pushNamed(context, Routes.login, arguments: () {
if (presenter.isAuthenticated) {
Future.delayed(const Duration(microseconds: 500), () {
setState(() {
_currentIndex = index;
});
});
}
});
}
}
}
Write Review View
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'base/BaseView.dart';
class WriteReviewView extends StatefulWidget {
#override
_WriteReviewViewState createState() => _WriteReviewViewState();
}
class _WriteReviewViewState extends State<WriteReviewView> {
final String _locationLabel = 'Location';
final String _reviewLabel = 'Review';
#override
Widget build(BuildContext context) {
return BaseView<WriteReviewPresenter>(
createPresenter: () => WriteReviewPresenter(),
onInitialize: (presenter) {
presenter.init();
},
builder: (context, child, presenter) => Container(
color: Theme.of(context).backgroundColor,
child: _body(presenter),
));
}
Widget _body(WriteReviewPresenter presenter) {
final height = MediaQuery.of(context).size.height;
return LayoutBuilder(builder: (context, constraint) {
return SingleChildScrollView(
child: ConstrainedBox(
constraints: BoxConstraints(minHeight: constraint.maxHeight),
child: IntrinsicHeight(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Card(
margin: EdgeInsets.fromLTRB(4.0, 4.0, 4.0, 8.0),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Padding(
padding: EdgeInsets.only(top: 10, bottom: 20),
child: Row(
children: [
Icon(Icons.location_on,
color: Theme.of(context).cursorColor),
SectionTitle(_locationLabel),
],
),
),
ChooseAddressButton(presenter.addressContainer.address, () {
presenter.navigateNewAddress(context);
}),
SizedBoxes.medium,
],
),
),
),
Card(
margin: EdgeInsets.fromLTRB(4.0, 4.0, 4.0, 8.0),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: Column(
children: [
Padding(
padding: EdgeInsets.only(top: 10),
child: Row(
children: [
Icon(Icons.star, color: Theme.of(context).indicatorColor),
SectionTitle(_reviewLabel),
],
),
),
SizedBoxes.medium,
CustomTextFormField(
data: presenter.reviewContainer.review,
showMinimum: true,
characterLimit: 50,
maxLines: 4,
height: 100),
ModifyRatingBar(50.0, presenter.reviewContainer.rating, false),
Padding(
padding: EdgeInsets.symmetric(vertical: 5),
child: Divider(indent: 40, endIndent: 40)),
],
),
),
),
Padding(
padding: EdgeInsets.symmetric(horizontal: 10),
child: Card(
color: Theme.of(context).accentColor,
child: FlatButton(
onPressed: () {
_submit(context, presenter);
},
child: Text('Submit',style:TextStyle(fontWeight: FontWeight.bold,fontSize: 18,color: Colors.white)),
),
),
),
],
),
),
),
);
});
}
void _submit(BuildContext context, WriteReviewPresenter presenter) async {
LoadingPopup.show(context);
final status = await presenter.submit(context);
LoadingPopup.hide(context);
if (status == ReviewStatus.successful) {
PostCompletePopup.show(context);
setState(() {
presenter.clear();
});
} else {
presenter.showError(context, status);
}
}
}
setState() only refreshes the widget that called it, and all the widgets under it.
When calling setState()from WriteReview widget, it will not update the HomeView widget. Try moving the setState()call to the HomeView widget using some sort of callback.