Horizontal viewport was given unbounded height while using PageView.Builder - flutter

I'm working on simple quiz app with BLoC pattern. Tried to implement swipe feature for each quiz with PageView.Builder, here is my code
class _QuizScreenState extends State<QuizScreen> {
#override
void initState() {
context.read<QuizInfoBloc>().add(GetQuizStat("1"));
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
extendBodyBehindAppBar: true,
backgroundColor: kSecondaryColor,
appBar: AppBar(
backgroundColor: Colors.transparent,
elevation: 0,
actions: [],
),
body: Container(
decoration: BoxDecoration(color: kSecondaryColor),
width: double.infinity,
height: double.infinity,
child: SafeArea(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 0),
child: Column(
children: [
Padding(
padding:
const EdgeInsets.symmetric(horizontal: kDefaultPadding / 2),
child: ProgressBar(),
),
Spacer(
flex: 1,
),
Padding(
padding:
const EdgeInsets.symmetric(horizontal: kDefaultPadding / 2),
child: BlocConsumer<QuizInfoBloc, QuizInfoState>(
listener: (context, state) {
// TODO: implement listener
},
builder: (context, state) {
if (state is QuizInfoLoaded) {
return PageView.builder(
itemCount: state.quiz.questions.length,
itemBuilder: (context, index) => QuestionCard(
question: state.quiz.questions[index]));
} else {
return Container(
height: 0,
width: 0,
);
}
},
),
),
Spacer(
flex: 4,
),
BottomButtons(),
SizedBox(
height: 20,
),
// AnswerExplanation(
// correctOrWrong: kGreenColor,
// ),
],
),
)),
),
);
}
}
I've tried with wrapping PageView.Builder with Expanded which was wrapped with Column. But still getting a different error
Padding(
padding:
const EdgeInsets.symmetric(horizontal: kDefaultPadding / 2),
child: BlocConsumer<QuizInfoBloc, QuizInfoState>(
listener: (context, state) {
// TODO: implement listener
},
builder: (context, state) {
if (state is QuizInfoLoaded) {
return Column(
children: [
Expanded(
child: PageView.builder(
itemCount: state.quiz.questions.length,
itemBuilder: (context, index) => QuestionCard(
question: state.quiz.questions[index])),
),
],
);
} else {
return Container(
height: 0,
width: 0,
);
}
},
),
),
RenderFlex children have non-zero flex but incoming height constraints
are unbounded.
QuestionCard
class _QuestionCardState extends State<QuestionCard> {
#override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(kDefaultPadding / 2),
child: Column(
children: [
Text(
this.widget.question.questionText,
style: Theme.of(context)
.textTheme
.headline5
?.copyWith(color: Colors.white, fontWeight: FontWeight.bold),
),
SizedBox(
height: 30,
),
ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: this.widget.question.options.length,
itemBuilder: (BuildContext context, int index) {
return OptionUI(option: this.widget.question.options[index]);
})
],
),
);
}
}

Since you already have a kSecondaryColor as backgroundColor of your Scaffold, you don't need a Container as body of your Scaffold:
Scaffold(
extendBodyBehindAppBar: true,
backgroundColor: kSecondaryColor,
appBar: AppBar(
backgroundColor: Colors.transparent,
elevation: 0,
actions: [],
),
body: SafeArea(
// child: ...
),
)
A SafeArea widget is meant to be used on the top-level widget tree:
SafeArea(
Scaffold(
extendBodyBehindAppBar: true,
backgroundColor: kSecondaryColor,
appBar: AppBar(
backgroundColor: Colors.transparent,
elevation: 0,
actions: [],
),
body: Padding(
// child: ...
),
)
)
Wrap an Expanded into the Padding of your BlocConsumer:
Column(
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: kDefaultPadding / 2),
child: ProgressBar(),
),
Spacer(flex: 1),
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: kDefaultPadding / 2),
child: BlocConsumer<QuizInfoBloc, QuizInfoState>(
listener: (context, state) {
// TODO: implement listener
},
builder: (context, state) {
if (state is QuizInfoLoaded) {
return PageView.builder(
itemCount: state.quiz.questions.length,
itemBuilder: (context, index) =>
QuestionCard(question: state.quiz.questions[index]));
} else {
return Container(height: 0, width: 0);
}
},
),
),
),
Spacer(flex: 4),
BottomButtons(),
SizedBox(height: 20),
// AnswerExplanation(correctOrWrong: kGreenColor),
],
);
You didn't provide the ProgressBar, QuestionCard and BottomButtons widgets, so if the error persists you should check them, but I think these changes should suffice.

Related

Flutter: Scroll view not responding

I am pretty new to flutter. I have build a landing page using grid view and added a bottom navigation bar. The navigation bar is called first after login in and I have added the screen to the navigation class. The issue am facing is that the navigation bar is on top of my grid items, when I try to scroll up, the grid items are sticky and not moving, what am I not doing right??
my home screen code
class GridDashboard extends StatelessWidget {
var services = [
"Home",
"Update",
"Bluetooth",
"Forms",
"Supervisor",
"Messages",
"Settings",
"App updates",
"Logout",
];
var images = [
"assets/home.png",
"assets/updated.png",
"assets/bluetooth.png",
"assets/todo.png",
"assets/supervisor.png",
"assets/message.png",
"assets/setting.png",
"assets/update.ico",
"assets/logout.png",
];
#override
Widget build(BuildContext context) {
List<Items> myList = [home, update, bluetooth, forms, supervisor, messages, settings, check, logout];
var color = 0xff453658;
return Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
height: 500,
// margin: EdgeInsets.only(top: 10),
// padding: EdgeInsets.all(20),
child: GridView.builder(
// add this
shrinkWrap: true,
itemCount: services.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
childAspectRatio: MediaQuery.of(context).size.width /
(MediaQuery.of(context).size.height / 1.4),
),
itemBuilder: (BuildContext context, int index) {
return GestureDetector(
onTap: () {
Navigator.push(context, new MaterialPageRoute<Widget>(
builder: (BuildContext context) {
if(myList != null){
return myList[index].screen;
}else{
return null;
}
}));
},
child: Padding(
padding: EdgeInsets.all(3),
child: Card(
elevation: 10,
child: ListView(
children: <Widget>[
SizedBox(
height: 20,
),
Image.asset(
images[index],
height: 50.0,
width: 50.0,
),
Padding(
padding: const EdgeInsets.all(20.0),
child: Text(
services[index],
style: TextStyle(
fontSize: 16.0,
height: 1.2,
color: Colors.white,
fontWeight: FontWeight.bold),
textAlign: TextAlign.center,
),
),
],
),
color: Color(color),
),
),
);
},
),
),
);
}
}
class Items {
String title;
String subtitle;
String event;
String img;
final Widget screen;
Items({this.title, this.subtitle, this.event, this.img, this.screen});
}
my Nav bar code
class _NavSCreenState extends State<NavSCreen> {
final List<Widget> _screens = [Home()];
final List<IconData> _icons = const [
Icons.home,
Icons.settings,
MdiIcons.accountCircleOutline,
MdiIcons.accountGroupOutline,
Icons.menu,
];
int _selectedIndex = 0;
#override
Widget build(BuildContext context) {
return DefaultTabController(
length: _icons.length,
child: Scaffold(
body: IndexedStack(index: _selectedIndex, children: _screens),
bottomNavigationBar: Padding(
padding: const EdgeInsets.only(bottom: 8.0),
child: CustomTabBar(
icons: _icons,
selectedIndex: _selectedIndex,
onTap: (index) => setState(() => _selectedIndex = index),
),
),
));
}
}
Try this by adding SingleChildScrollView. Hope this will solve your problem.
#override
Widget build(BuildContext context) {
List<Items> myList = [home, update, bluetooth, forms, supervisor, messages, settings, check, logout];
var color = 0xff453658;
return Scaffold(
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
height: 500,
// margin: EdgeInsets.only(top: 10),
// padding: EdgeInsets.all(20),
child: GridView.builder(
// add this
shrinkWrap: true,
itemCount: services.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
childAspectRatio: MediaQuery.of(context).size.width /
(MediaQuery.of(context).size.height / 1.4),
),
itemBuilder: (BuildContext context, int index) {
return GestureDetector(
onTap: () {
Navigator.push(context, new MaterialPageRoute<Widget>(
builder: (BuildContext context) {
if(myList != null){
return myList[index].screen;
}else{
return null;
}
}));
},
child: Padding(
padding: EdgeInsets.all(3),
child: Card(
elevation: 10,
child: ListView(
children: <Widget>[
SizedBox(
height: 20,
),
Image.asset(
images[index],
height: 50.0,
width: 50.0,
),
Padding(
padding: const EdgeInsets.all(20.0),
child: Text(
services[index],
style: TextStyle(
fontSize: 16.0,
height: 1.2,
color: Colors.white,
fontWeight: FontWeight.bold),
textAlign: TextAlign.center,
),
),
],
),
color: Color(color),
),
),
);
},
),
),
),
),
);
}
You need to embed the GridView into a SingleChildScrollView widget. This widget handles the scrolling for its child, which is in your case the GridView. The same applies to ListView.
See the links for detailed documentation.
// ...
child: Container(
height: 500,
child: SingleChildScrollView(
child: GridView.builder(
// ...
)
)
)
// ...
EDIT
I forgot, that you have to give a GridView a height to work inside a SingleChildScrollView. You can use a Container that wraps the GridView.
// ...
child: Container(
height: 500,
child: SingleChildScrollView(
child: Container(
height: 500,
child: GridView.builder(
// ...
)
)
)
)
// ...
But with that approach you have to give your GridView a predefined height. An alternative is the CustomScrollView but you have to use a SliverGrid for that.
CustomScrollView(
slivers: [
SliverGrid(
// ...
)
]
)

render slivergrid using bloc in flutter

Here is the case :-
i have a Bloc named XYZBloc which loads data from network. i need to render these lists into sliverGrid.
the same list goes pretty well with sliverList.
Store.dart
#override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => _xyzBloc,
child: AnnotatedRegion<SystemUiOverlayStyle>(
value: SystemUiOverlayStyle.light,
child: Container(
width: MediaQuery.of(context).copyWith().size.width,
height: MediaQuery.of(context).copyWith().size.height,
child: BlocBuilder<XyzBloc, XyzState>(
bloc: _xyzBloc,
builder: (context, state) {
if (state is XYZLoadingState) {
return buildLoading();
} else if (state is XYZErrorState) {
return buildErrorUi(state.message);
} else if (state is XYZLoadedState) {
return _buildPageView(state.lists, context);
} else {
return Container();
}
}),
),
),
);
}
_buildPageView(List<XYZModel> lists, BuildContext context) {
return SliverGrid(
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
delegate: SliverChildBuilderDelegate((BuildContext context, int index) {
return Container(
padding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 20.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
color: Colors.grey, height: 130.0, width: double.infinity),
Text(lists[index].name)
],
),
);
}, childCount: lists.length),
);
}
code to load sliverGrid data :-
Home.dart
#override
Widget build(BuildContext context) {
double cardWidth = MediaQuery.of(context).size.width / 3.3;
double cardHeight = MediaQuery.of(context).size.height / 3.6;
return Container(
color: AppTheme.nearlyWhite,
child: Scaffold(
backgroundColor: Colors.transparent,
body: Column(
children: <Widget>[
SizedBox(
height: MediaQuery.of(context).padding.top,
),
getAppBarUI(),
Expanded(
child: CustomScrollView(
slivers: <Widget>[
SliverList(
delegate: SliverChildListDelegate([
Padding(
padding: EdgeInsets.all(15),
child: Container(
width: MediaQuery.of(context).size.width,
height: 150,
child: BannerItems(),
),
),
])),
SliverList(
delegate: SliverChildListDelegate(
[
Padding(
padding: const EdgeInsets.fromLTRB(15, 0, 15, 0),
child: Container(
decoration: BoxDecoration(color: Colors.transparent),
height: 100,
child: Category(),
),
),
],
),
),
Stores(),
],
)),
],
),
),
);
}
i have tried all possible way to debug but my noob sense couldn't help me to understand how this sliverGrid works with network data.
any suggestion, reference will be highly appreciated.

How to create multiple horizontal `GridView` in the same screen using flutter

Is there's a way to create a lists of GridViews as the below image in one screen...
I have a some Screen as the below one:
class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
var _showOnlyFavorites = false;
AnimationController animationController;
bool multiple = true;
#override
void initState() {
animationController = AnimationController(
duration: const Duration(milliseconds: 2000), vsync: this);
super.initState();
}
Future<bool> getData() async {
await Future<dynamic>.delayed(const Duration(milliseconds: 0));
return true;
}
#override
void dispose() {
animationController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: AppTheme.white,
body: FutureBuilder<bool>(
future: getData(),
builder: (BuildContext context, AsyncSnapshot<bool> snapshot) {
if (!snapshot.hasData) {
return const SizedBox();
} else {
return Padding(
padding: EdgeInsets.only(top: MediaQuery.of(context).padding.top),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
appBar(),
Expanded(
child: FutureBuilder<bool>(
future: getData(),
builder:
(BuildContext context, AsyncSnapshot<bool> snapshot) {
if (!snapshot.hasData) {
return const SizedBox();
} else {
return PropertiesGrid(_showOnlyFavorites);
}
},
),
),
],
),
);
}
},
),
);
}
Widget appBar() {
return SizedBox(
height: AppBar().preferredSize.height,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 8, left: 8),
child: Container(
width: AppBar().preferredSize.height - 8,
height: AppBar().preferredSize.height - 8,
),
),
Expanded(
child: Center(
child: Padding(
padding: const EdgeInsets.only(top: 4),
child:
Image.asset('assets/images/logo.png', fit: BoxFit.contain),
),
),
),
Padding(
padding: const EdgeInsets.only(top: 8, right: 8),
child: Container(
width: AppBar().preferredSize.height - 8,
height: AppBar().preferredSize.height - 8,
color: Colors.white,
child: Material(
color: Colors.transparent,
child: InkWell(
borderRadius:
BorderRadius.circular(AppBar().preferredSize.height),
child: Icon(
multiple ? Icons.dashboard : Icons.view_agenda,
color: AppTheme.dark_grey,
),
onTap: () {
setState(() {
multiple = !multiple;
});
},
),
),
),
),
],
),
);
}
}
as I have a widget which have the GridView.builder as the below code:
import 'package:aradi_online_vtwo/providers/properties.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../providers/properties.dart';
import './property_item.dart';
class PropertiesGrid extends StatelessWidget {
final bool showFavs;
PropertiesGrid(this.showFavs);
#override
Widget build(BuildContext context) {
final productsData = Provider.of<Properties>(context);
final products = showFavs ? productsData.favoriteItems : productsData.items;
return GridView.builder(
padding: const EdgeInsets.all(10.0),
itemCount: products.length,
itemBuilder: (ctx, i) => ChangeNotifierProvider.value(
// builder: (c) => products[i],
value: products[i],
child: PropertyItem(
// products[i].id,
// products[i].title,
// products[i].imageUrl,
),
),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 1,
childAspectRatio: 3 / 2,
crossAxisSpacing: 10,
mainAxisSpacing: 10,
), scrollDirection: Axis.horizontal,
);
}
}
I tried to set the height of the grid by wrapping it with a Container and set the height of it as to add more grids but it doesn't work.
and here's my Grid Item widget code:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../providers/property.dart';
class PropertyItem extends StatelessWidget {
#override
Widget build(BuildContext context) {
final property = Provider.of<Property>(context, listen: false);
return InkWell(
onTap: () => {},
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15),
),
elevation: 7,
margin: EdgeInsets.all(2),
child: Stack(
children: <Widget>[
ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(15),
topRight: Radius.circular(15),
),
// color: Colors.transparent,
child: Image.asset(
property.image,
fit: BoxFit.fill,
),
),
Positioned(
top: 8,
right: 8,
child: Consumer<Property>(
builder: (ctx, property, _) => IconButton(
icon: Icon(
property.isFavorite ? Icons.favorite : Icons.favorite_border,
),
color: Colors.red,
onPressed: () {
property.toggleFavoriteStatus();
},
),
),
),
Positioned(
right: 20,
top: 100,
child: Container(
width: 300,
color: Colors.black54,
padding: EdgeInsets.symmetric(
vertical: 5,
horizontal: 20,
),
child: Text(
property.title,
style: TextStyle(
fontSize: 20,
color: Colors.white,
),
softWrap: true,
overflow: TextOverflow.fade,
),
),
)
],
),
),
);
}
}
You'll need a column where each ListView or GridView is wrapped inside a SizedBox (if you have a specific height) and you also can use Expanded to take whatever available space (like the last one in the given example):
You can post the code below in dartpad.dev and see how it works:
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyApp(),
));
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Column(
children: [
SizedBox(
height: 100,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: 10,
itemBuilder: (c, i) {
return Card(
child: Container(
height: 100,
width: 100,
child: Center(child: Text("$i")),
),
);
},
),
),
Padding(
padding: const EdgeInsets.all(16.0),
child: Align(
child: Text("The Second List"),
alignment: Alignment.centerRight,
),
),
SizedBox(
height: 100,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: 10,
itemBuilder: (c, i) {
return Card(
child: Container(
height: 100,
width: 100,
child: Center(child: Text("$i")),
),
);
},
),
),
Padding(
padding: const EdgeInsets.all(16.0),
child: Align(
child: Text("The Third List"),
alignment: Alignment.centerRight,
),
),
Expanded(
//height: 200,
child: GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 3 / 2,
crossAxisSpacing: 10,
mainAxisSpacing: 10,
),
scrollDirection: Axis.vertical,
itemCount: 20,
itemBuilder: (c, i) {
return Card(
child: Container(
height: 100,
width: 100,
child: Center(child: Text("$i")),
),
);
},
),
),
],
),
);
}
}

Flutter : Listview Builder Horizontal Inside Stack Widget

I have design like above, In that design I implement to app. I have Stack Widget inside container then inside Stack widget i have ListviewBuilder with Scroll direction Horizontal.
But the problem is, I cant scroll ListViewBuilder Horizontal inside Stack widget.
How can i fixed this ?
My Trial Fail
Source Code
class HomeScreen extends StatelessWidget {
static const routeName = "/home-screen";
#override
Widget build(BuildContext context) {
final mqHeight = MediaQuery.of(context).size.height;
final mqWidth = MediaQuery.of(context).size.width;
return SafeArea(
child: Scaffold(
appBar: AppBar(
elevation: 0,
title: Text('Good Morning'),
actions: <Widget>[
IconButton(
icon: Icon(Icons.settings),
onPressed: () => "",
)
],
),
body: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
color: Colors.blue,
height: mqHeight / 3,
child: Stack(
overflow: Overflow.visible,
children: <Widget>[
Container(
color: Colors.red,
),
Positioned(
top: mqHeight / 4.5,
child: SizedBox(
height: 100,
child: ListView.builder(
physics: ClampingScrollPhysics(),
scrollDirection: Axis.horizontal,
shrinkWrap: true,
itemCount: 20,
itemBuilder: (BuildContext context, int index) {
return Container(
width: 100,
child: Card(
elevation: 10,
child: Icon(Icons.card_giftcard)),
);
},
),
),
)
],
),
),
Container(
child: Text(
'data data data data data data data data data ',
style: Theme.of(context).textTheme.display4,
),
)
],
)),
),
);
}
}
You can copy paste run full code below
From https://github.com/flutter/flutter/issues/36584#issuecomment-554950474
Add top, right, bottom attribute
code snippet
Positioned(
top: mqHeight / 4.5,
left:0.0,
right:0.0,
bottom:0.0,
child: SizedBox(
height: 100,
child: ListView.builder(
working demo
full code
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: HomeScreen(),
);
}
}
class HomeScreen extends StatelessWidget {
static const routeName = "/home-screen";
#override
Widget build(BuildContext context) {
final mqHeight = MediaQuery.of(context).size.height;
final mqWidth = MediaQuery.of(context).size.width;
return SafeArea(
child: Scaffold(
appBar: AppBar(
elevation: 0,
title: Text('Good Morning'),
actions: <Widget>[
IconButton(
icon: Icon(Icons.settings),
onPressed: () => "",
)
],
),
body: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
color: Colors.blue,
height: mqHeight / 3,
child: Stack(
overflow: Overflow.visible,
children: <Widget>[
Container(
color: Colors.red,
),
Positioned(
top: mqHeight / 4.5,
left:0.0,
right:0.0,
bottom:0.0,
child: SizedBox(
height: 100,
child: ListView.builder(
physics: ClampingScrollPhysics(),
scrollDirection: Axis.horizontal,
shrinkWrap: true,
itemCount: 20,
itemBuilder: (BuildContext context, int index) {
return Container(
width: 100,
child: Card(
elevation: 10,
child: Icon(Icons.card_giftcard)),
);
},
),
),
)
],
),
),
Container(
child: Text(
'data data data data data data data data data ',
style: Theme.of(context).textTheme.display4,
),
)
],
)),
),
);
}
}
I have already fixed as below:
Positioned(
top: mqHeight / 4.5,
left: 0, /// <-- fixed here
right: 0, /// <-- fixed here
child: SizedBox(
height: 100,
child: ListView.builder(
physics: ClampingScrollPhysics(),
scrollDirection: Axis.horizontal,
shrinkWrap: true,
itemCount: 20,
itemBuilder: (BuildContext context, int index) {
return Container(
width: 100,
child: Card(
elevation: 10,
child: Icon(Icons.card_giftcard)),
);
},
),
),
)```

How to make ListView Items align at bottom of a container with a fixed height without using reverse in Flutter?

In my Flutter project, I have a container with a fixed height. Inside that container I have a Listview.
Here's the code-
return new Scaffold(
appBar: AppBar(
title: Text("All Values"),
),
body: new Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
Container(
height: isLoading ? 50.0 : 0,
color: Colors.white70,
child: Center(
child: new CircularProgressIndicator(),
),
),
Expanded(
child: Container(
height: 350,
color: Colors.red,
alignment: Alignment.bottomLeft,
child:
new ListView.builder(
itemCount: data.length-8,
itemBuilder: (BuildContext cxtx, int index) {
return Padding(
padding: const EdgeInsets.fromLTRB(10, 0.0, 10, 0),
child: Container(
child: showCard(index, radius),
),
);
},
controller: _scrollController,
),
),),
],
),
resizeToAvoidBottomPadding: false,
);
The code outputs like below-
So, the problem is I want to align these items at bottom left of the container. I could have done that using reverse: true but I need the list items with the same sequence. So, I need suggestion how can I do that?
You need those items in a row or a column? Follow with a row possibility:
Try this:
return new Scaffold(
appBar: AppBar(
title: Text("All Values"),
),
body: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
if(isLoading)
Container(
height: 50.0 ,
color: Colors.white70,
child: Center(
child: new CircularProgressIndicator(),
),
),
Expanded(
child: Container(
height: 350,
color: Colors.red,
alignment: Alignment.bottomLeft,
child: new ListView.builder(
itemCount: data.length - 8,
itemBuilder: (BuildContext cxtx, int index) {
return Padding(
padding: const EdgeInsets.fromLTRB(10, 0.0, 10, 0),
child: Container(
child: Text('asdf'),
),
);
},
controller: _scrollController,
),
),
),
],
),
resizeToAvoidBottomPadding: false,
);
StoreConnector<_ViewModel, List<Message>>(
converter: (store) {
// check mark ,reverse data list
if (isReverse) return store.state.dialogList;
return store.state.dialogList.reversed.toList();
},
builder: (context, dialogs) {
// Add a callback when UI render after. then change it direction;
WidgetsBinding.instance.addPostFrameCallback((t) {
// check it's items could be scroll
bool newMark = _listViewController.position.maxScrollExtent > 0;
if (isReverse != newMark) { // need
isReverse = newMark; // rebuild listview
setState(() {});
}
});
return ListView.builder(
reverse: isReverse, // 反转列表,insert数据时,刷新到0,加载更多时,滚动偏移不变
controller: _listViewController,
itemBuilder: (context, index) => _bubbleItem(context, dialogs[index], index),
itemCount: dialogs.length,
);
},
)