How to center a widget inside a column inside of a SingleChildScrollView - flutter

I have this screen with a searchWidget on top and a list below it. But the list data comes after querying in the searchWidget, and while waiting for the data to be fetched i want to render a ActivityIndicator at the center of the screen. But the progress indicator doesn't seem to take the rest of the space of the screen and it's directly below the searchWidget, and if i wrap it inside an Expanded it gives an error
body: SingleChildScrollView(
physics: BouncingScrollPhysics(),
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
SearchWidget(
hintText: 'Search',
textEditingController: _textEditingController,
onCancel: () {
setState(() {
_textEditingController.text = '';
data = [];
});
},
onSubmitted: (val) {
onSubmitted(val);
}),
_isLoading
? (Container(
child: Center(
child: CupertinoActivityIndicator(
radius: 15,
),
),
))
: (data.length == 0
? SizedBox()
: Padding(
padding:
const EdgeInsets.only(top: 8, right: 8, left: 8),
child: ListView.builder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemCount: data.length,
itemBuilder: (ctx, i) =>
ListItem(item: data[i]),
),
))
],
),
),

Try Expanded:
_isLoading
? (Expanded(
child: Center(
child: CupertinoActivityIndicator(
radius: 15,
),
),
))

Put your CupertinoActivityIndicator inside a Column and use Spacer to put it in the middle of the screen. Just like this:
Column(
children: [
Spacer(),
Container(
child: Center(
child: CupertinoActivityIndicator(
radius: 15,
),
),
),
Spacer()
]
)

Related

Flutter: Put textField at bottom of scaffold

This has been giving me a headache, im just trying to put a Textfield on the bottom of my screen. I have the following code, trying to wrap it in a Positioned:
return Scaffold(
//set a textField to add a reply
appBar: TopAppBar(title: 'bruh'),
body: SingleChildScrollView(
controller: _scrollController,
child: Column(
children: [
FocalWaveTile(
wave: widget.waveTile.wave,
user: profileState.user,
poster: widget.waveTile.poster,
),
ListView.builder(
shrinkWrap: true,
itemCount: waves.length,
itemBuilder: (BuildContext context, int index) {
},
),
//poisition on the bottom
Positioned(
bottom: MediaQuery.of(context).viewInsets.bottom,
child: Container(
height: 50,
width: MediaQuery.of(context).size.width,
color: Colors.white,
child: Row(
children: [
Expanded(
child: Container(
margin: EdgeInsets.only(left: 10),
child: TextField(
decoration: InputDecoration(
hintText: 'Reply to this wave'),
onChanged: (value) {
if (value.length > 0) {
setState(() {
isTyping = true;
});
} else {
setState(() {
isTyping = false;
});
}
},
),
),
),
],
),
),
)
],
),
));
And it looks like this:
Any idea what im doing wrong? Ive tried a few things like a bottomnavbar and adding a spacer, but neither of these work in the way i would like them too. Thanks!
try this:
return Scaffold(
//set a textField to add a reply
appBar: TopAppBar(title: 'bruh'),
body: Stack(
children: [
SingleChildScrollView(
controller: _scrollController,
child: Column(
children: [
FocalWaveTile(
wave: widget.waveTile.wave,
user: profileState.user,
poster: widget.waveTile.poster,
),
ListView.builder(
shrinkWrap: true,
itemCount: waves.length,
itemBuilder: (BuildContext context, int index) {},
),
//poisition on the bottom
],
),
),
Positioned(
bottom: MediaQuery.of(context).viewInsets.bottom,
child: Container(
height: 50,
width: MediaQuery.of(context).size.width,
color: Colors.white,
child: Row(
children: [
Expanded(
child: Container(
margin: EdgeInsets.only(left: 10),
child: TextField(
decoration:
InputDecoration(hintText: 'Reply to this wave'),
onChanged: (value) {
if (value.length > 0) {
setState(() {
isTyping = true;
});
} else {
setState(() {
isTyping = false;
});
}
},
),
),
),
],
),
),
)
],
),
);
You can use bottomNavigationBar from Scaffold.
Scaffold(
bottomNavigationBar: TextFormField(),
Appreciate everyone's help, but for some reason just replacing the singleChildScrollView with Listview solved it

Wrapping a ListView Builder Output with small bubble text boxes that wrap

I'm trying to produce a wrapping list of button text boxes. I cannot find a way to wrap this properly. I've included 2 images, one of the current output and another of the desired output.
return Wrap(
children: [
ListView.builder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemCount: _filteredHashTags.isEmpty
? hashTagWigetsList.length
: _filteredHashTags.length,
itemBuilder: (context, index) {
return _buildHashTagList(hashTagWigetsList[index]);
}),
This is what is looks like:
This is what I'd like it to look like:
Demo
final items = List.generate(4, (i) => " item $i"); // response
return Scaffold(
body: Column(
children: [
Container(
child: Text("Search Field"),
),
Wrap(
children: [
...items.map(
(e) => Padding(
padding: EdgeInsets.all(4),
child: Container(
padding: EdgeInsets.all(4),
decoration: BoxDecoration(
color: Colors.blue,
),
child: Text(e)),
),
),
///or
...List.generate(
items.length,
(index) => Text(
items[index],
style: TextStyle(
backgroundColor: Colors.blue,
),
),
)
],
)
],
));
}

set left widget as focused one in flutter

I am using card_swiper widget in my project. It is a good library, but there is a problem: the focused widget always stays on centre but I want the focused item to be the one on the left. How can I accomplish this with this library?
In the below picture, focused item is on centre, but yellow item, in my case, should be on the left.
I found the answer which could be useful for others. The example is for 4 items on view but you can customise it to as many as you want:
Scaffold(
backgroundColor: AppColors.purpleDark,
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: [
Flexible(
child: Swiper(
index: chosenIndex,
layout: SwiperLayout.CUSTOM,
physics: BouncingScrollPhysics(),
customLayoutOption: CustomLayoutOption(
startIndex: 0,
stateCount: math.min(4, listSize),
).addScale(
[3, 1, 1, 1], // there should be 4 widgets in view with the first 3 times larger
Alignment.topRight,
).addTranslate( // place the 4 items as I want
[
Offset(-35.toResizableWidth(), 0),
Offset(30.toResizableWidth(), 0.0),
Offset(118.toResizableWidth(), 0.0),
Offset(200.toResizableWidth(), 0.0),
],
),
itemWidth: 51.toResizableWidth(),
itemHeight: 51.toResizableHeight(),
controller: controller,
itemCount: listSize,
onIndexChanged: (newIndex) => setState(() => chosenIndex = newIndex),
itemBuilder: (context, index) {
return GestureDetector(
onTap: () => controller.next(),
child: Container(
width: 51.toResizableWidth(),
height: 51.toResizableHeight(),
color: Colors.grey,
child: Center(
child: Text(
'$index',
style: AppTextStyles.styleS16W600.copyWith(color: Colors.white),
),
),
),
);
},
),
),
Padding(
padding: EdgeInsets.symmetric(
vertical: 10.toResizableHeight(),
horizontal: 20.toResizableWidth(),
),
child: Text(
LocaleKeys.rewards_day.tr(args: <String>[chosenIndex.toString()]),
style: AppTextStyles.styleS20W600
.copyWith(color: true ? AppColors.greenPositive : AppColors.redNegative),
),
),
Padding(
padding: EdgeInsets.symmetric(
horizontal: 20.toResizableWidth(),
),
child: Text(
longText,
style: AppTextStyles.styleS16W400.copyWith(color: AppColors.white100),
),
),
Expanded(child: Container()),
],
),
);

Getting error "Incorrect use of ParentDataWidget." on flutter

The following assertion was thrown while applying parent data.:
Incorrect use of ParentDataWidget.
The ParentDataWidget Flexible(flex: 1) wants to apply ParentData of type FlexParentData to a RenderObject, which has been set up to accept ParentData of incompatible type ParentData.
Usually, this means that the Flexible widget has the wrong ancestor RenderObjectWidget. Typically, Flexible widgets are placed directly inside Flex widgets.
The offending Flexible is currently placed inside a RepaintBoundary widget.
My Code is
class Search extends StatelessWidget {
//final homeProvider;
final HomeProvider homeProvider;
Search(this.homeProvider);
#override
Widget build(BuildContext context) {
return Container(
child: SmartRefresher(
controller: homeProvider.getSearchRefreshControllerLook(),
enablePullDown: true,
enablePullUp: true,
onRefresh: () {
debugPrint('on pull to refresh ');
//modistaboxApplicationProvider.getTrendingLooksWithLoginStatus();
homeProvider.getAllLooks();
},
onLoading: () {
debugPrint('next loading --------- ');
homeProvider.getAllNextLooks();
},
child: ListView(
controller: homeProvider.controllerLooksList,
children: [
Selector<HomeProvider, NetWorkResponseStatus>(
builder: (context, data, child) {
Widget lookWidget;
switch (data) {
case NetWorkResponseStatus.ResponseError:
lookWidget = Column(
children: <Widget>[
SizedBox(
height: MediaQuery.of(context).size.height / 3,
),
const ModistaboxErrorWidget(
error: 'No Internet',
visible: true,
)
],
);
break;
case NetWorkResponseStatus.ResponseEmpty:
lookWidget = const EmptyWidget(
visible: true,
);
break;
case NetWorkResponseStatus.NetworkError:
lookWidget = const EmptyWidget(
visible: true,
);
break;
case NetWorkResponseStatus.ResponseData:
lookWidget = getLooksWidget(context, homeProvider);
break;
default:
lookWidget = Column(
children: <Widget>[
SizedBox(
height: MediaQuery.of(context).size.height / 3,
),
Center(child: CustomProgressIndicator())
],
);
break;
}
return Padding(
padding: const EdgeInsets.only(left: 5, right: 5),
child: lookWidget,
);
},
selector: (buildContext, provider) => homeProvider.lookResponseStatus),
],
),
),
);
}
Widget getLooksWidget(context, HomeProvider homeProvider) {
return homeProvider.lookListResponce != null &&
homeProvider.lookListResponce.results.length > 0
? GridView.builder(
shrinkWrap: true,
itemCount: homeProvider.lookListResponce.results.length,
scrollDirection: Axis.vertical,
physics: const ScrollPhysics(),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
crossAxisSpacing: 5,
mainAxisSpacing: 5,
childAspectRatio: 2 / 3,
),
itemBuilder: (BuildContext context, int index) {
return lookWidget(index, context,
homeProvider.lookListResponce.results[index], homeProvider);
},
)
: const EmptyWidget(
visible: true,
);
}
Widget lookWidget(int index, context, ResultsLook look,
HomeProvider homeProvider) {
return Stack(
children: <Widget>[
InkWell(
onTap: () {
debugPrint('look data --- $look');
Navigator.pushNamed(context,TagrankRoutes.lookTagging,arguments:
look.image);
},
child: CachedNetworkImage(
imageUrl: look.image,
fit: BoxFit.fitHeight,
height: (MediaQuery.of(context).size.height) - 80),
),
Positioned(
left: 5,
bottom: 5,
child: InkWell(
onTap: () {
//debugPrint("this is inkwell");
if (TagRankPreferences().getLoginStatus()) {
} else {
Fluttertoast.showToast(msg: 'Please login to see user profile');
}
},
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
SizedBox(
width: 5,
),
Text(
look.username ?? '',
style: textStyle12White,
),
],
),
),
),
Positioned(
child: Container(
height: 16,
width: 16,
child: Checkbox(
checkColor: Colors.red ,
activeColor: Colors.white
//checkColor: dividerColor,
onChanged:(newValue){
homeProvider.onClickCheckBox(look);
},
value: true,
),
),
/*child: Row(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
*//* InkWell(
child: Icon(
Icons.share,
color: white,
),
),*//*
],
),*/
right: 5,
bottom: 5,
)
],
);
}
}
Apparently, you forgot to post the actual code with Flexible.
It seems that you provide the only Flexible widget in the container, so it does not understand what space it should allocate. To fix that, add another Flexible in a Row or a Column so that Flutter knows the proportion of the space you want to dedicate to your widget.
Here is the example of the code:
Row(
children: [
Flexible(
flex: 1,
child: Container() // your widget here
),
Flexible(
flex: 2,
child: Container() // another widget or an empty container to allocate the space
),
],
);
See also: Flutter Flexible.
Your code is missing the flexible widget which you are trying to explain.
If you are trying to use ListView inside a Flexible or Expanded widget this kind of error is shown. Because it can accept only row, column, or flex.
Try to use a ConstrainedBox or container with a fixed height/width
ConstrainedBox(
constraints: BoxConstraints(minHeight: 50, maxHeight: 500),
child: ListView(...),
)

ExpansionTile or ExpansionPanel with horizontal scrolling using flutter

I'm trying to implement expansionTile with horizontal scrolling Listview not vertical . So in this below image I want make this enter image description here.
Answer is to use scrollDirection: Axis.horizontal, in your ListView
UPDATE
Column(
children: <Widget>[
Flexible(
child: ListView(
children: [
Container(
width: 100,
child: ListTile(
title: Text('No1'),
onTap: () {
setState(() {
selected = 0;
});
},
),
),
Container(
width: 100,
child: ListTile(
title: Text('No2'),
onTap: () {
setState(() {
selected = 1;
});
},
),
)
],
scrollDirection: Axis.horizontal,
),
),
Container(
height: 150,
color: selected == 0 ? Colors.red : Colors.green,
)
],
);