i need too array prouducts from higher to lower id (products on firebase) - flutter

class WildWidget extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Obx(()=>GridView.count(
crossAxisCount: 3,
childAspectRatio: .48,
padding: const EdgeInsets.all(15),
mainAxisSpacing: 4.0,
crossAxisSpacing: 10,
children: productController.wild.map((ProductModel product) {
return SingleProductWidget(product: product,);
}).toList())
);
}
}
class SingleProductWidget extends StatelessWidget {
final ProductModel product;
const SingleProductWidget({Key key, this.product}) : super(key: key);
#override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(5)),
child:
Column(
children: [
GestureDetector(
onTap: () {
showDialog(
context: context,
builder: (_) =>Material(
type: MaterialType.transparency,
child: Center(
child:
Padding(
padding:
EdgeInsets.symmetric(vertical:(60)),
child:
CachedNetworkImage(
imageUrl: product.image,
fit: BoxFit.fill,
placeholder: (context, url) => new SpinKitWave(color: Color.fromARGB(255, 0, 53, 145), size: 30,),
errorWidget: (context, url, error) => new Icon(Icons.error),// Fixes border issues
height: double.infinity,
width: double.infinity,
),
),
),
),
);
}, // Image tapped
child:
CachedNetworkImage(
//height: 220,
//width: 140,
imageUrl: product.image,
placeholder: (context, url) => new SpinKitWave(color: Color.fromARGB(255, 0, 53, 145), size: 30,),
errorWidget: (context, url, error) => new Icon(Icons.error),
),
),
Padding(
padding:
const EdgeInsets.symmetric(horizontal:(0)),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: CustomText(
text: "\$${product.price}",
size: 11,
weight: FontWeight.bold,),),
Expanded(
child:SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: CustomText(
text: product.id,
color: kPrimaryColor,
size: 14,
weight: FontWeight.bold,
),
)
),
IconButton(
icon: Icon(Icons.add_shopping_cart),
onPressed: () {
cartController.addProductToCart(product);
})
],
),
),
],
),
);
}
}
this is products , its shown from lower to higher

Related

How to sort functionality & filter data got from restapi

starting my carrer in flutter development for 2 months
while doing this project based in flutter,i get data from rest api with bloc state management & listed it with listvieww builder, but want add sort & filter functionality to it,, can you please explain how to do with an example, excepting valuable suggestions from you guys
search and filter functionilty
class Upcoming extends StatefulWidget {
Upcoming({Key? key}) : super(key: key);
#override
State<Upcoming> createState() => _UpcomingState();
}
class _UpcomingState extends State<Upcoming> {
#override
Widget build(BuildContext context) {
return BlocBuilder<MOdelBloc, MOdelState>(
builder: (context, state) {
if (state is MOdelInitial) {
context.read<MOdelBloc>().add(LoadEVENT());
return const Center(
child: CircularProgressIndicator(),
);
} else if (state is ModelLoading) {
return const Center(
child: CircularProgressIndicator(),
);
} else if (state is ModelLoadedstate) {
return buildupcoming(state.fakestore);
} else if (state is ErrorSatte) {
return const Center(
child: Text('errorstate'),
);
}
return const Center(child: Text('error'));
},
);
}
}
Widget buildupcoming(List<CryptoCurrency> currency) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.yellow.shade400,
leading: const Icon(
Icons.portrait_rounded,
),
title: const Center(
child: Text(
'Upcoming Matches',
style: TextStyle(fontWeight: FontWeight.bold),
),
),
actions: const [
Icon(
Icons.headset,
),
SizedBox(
width: 5,
),
Icon(Icons.message)
],
),
body: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Container(
height: double.maxFinite,
margin: const EdgeInsets.all(10),
child:
Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {}, child: const Text('CRICKET')),
const SizedBox(
width: 15,
),
ElevatedButton(
onPressed: () {},
child: const Icon(Icons.sports_football))
],
),
const SizedBox(
height: 10,
),
Row(
children: const [
TextWidget(text: 'My Rooms', size: 20),
Spacer(),
Text(
'View all',
style: TextStyle(color: Colors.black45),
)
],
),
const SizedBox(
height: 5,
),
Container(
height: 170,
child: PageView.builder(
scrollDirection: Axis.horizontal,
itemCount: 3,
itemBuilder: (context, index) {
return Container(
margin: const EdgeInsets.only(left: 5),
child: Column(children: [
SliderCARD(
text1: currency[2].fullname.toString(),
text2: currency[3].fullname,
minitext1: currency[2].price.toString(),
minitext2: currency[4].price.toString(),
color: Colors.indigo,
height: 100,
),
Row(children: [IconButton(onPressed: ( ){},
icon: Icon(Icons.arrow_back)),IconButton(onPressed: (){}, icon: Icon(Icons.arrow_back_outlined))],)]));
})),
ListView.builder(
physics:const NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: currency.length,
itemBuilder: (context, index) {
final CryptoCurrency cryptoCurrency = currency[index];
return Container(
margin: const EdgeInsets.only(bottom: 10),
height: 100,
child: SliderCARD(
text1: cryptoCurrency.fullname,
text2: currency[3].fullname,
minitext1: cryptoCurrency.price.toString(),
minitext2: currency[4].price.toString(),
color: Colors.white,
height: 100,
));
})
])),
));
}

Flutter: RenderFlex children have non-zero flex but incoming height constraints are unbounded. Using Expandable listview

I want to design this layout:
I am using a expandable listview inside a column. I was add ListView.builder inside Expanded but still problem continue.
What is the wrong?
This is my code:
Parent page:
class LearningCoursePage extends StatefulWidget {
String courseId;
LearningCoursePage({Key? key, required this.courseId}) : super(key: key);
#override
State<LearningCoursePage> createState() => _LearningCoursePageState();
}
class _LearningCoursePageState extends State<LearningCoursePage> {
CourseModel? courseModel;
Future<void> _loadResource() async {
courseModel = await Get.find<CourseController>().getCourseById(widget.courseId);
}
#override
Widget build(BuildContext context) {
return FutureBuilder(
future: _loadResource(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
backgroundColor: AppColors.yellowColor,
title: courseModel != null ? Text(courseModel!.name.toString()) : Text("Loading..."),
leading: IconButton(
icon: Icon(Icons.close),
onPressed: () {},
),
),
body: GetBuilder<AuthController>(builder: (authController) {
return authController.userLoggedIn() ? Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(Dimensions.radius20),
boxShadow: [
BoxShadow(
color: Color(0xFFe8e8e8),
blurRadius: 5.0,
offset: Offset(0, 5)
),
BoxShadow(
color: Colors.white,
offset: Offset(-5, 0)
),
BoxShadow(
color: Colors.white,
offset: Offset(5, 0)
),
]
),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(height: 40,),
BigText(text: "Vui lòng đăng nhập để xác minh tài khoản"),
SizedBox(height: 20,),
SizedBox(height: 20,),
GestureDetector(
onTap: (){
Get.toNamed(RouteHelper.getSignInPage());
},
child: Container(
width: Dimensions.screenWidth/2,
height: Dimensions.screenHeight/13,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(Dimensions.radius15),
color: AppColors.yellowColor
),
child: Center(
child: BigText(
text: "ĐĂNG NHẬP",
size: Dimensions.font20+Dimensions.font20/2,
color: Colors.white,
),
),
),
),
SizedBox(height: 40,),
],
),
),
) :
SingleChildScrollView(
child: Container(
child: Column(
children: [
Container(
height: 400,
decoration: BoxDecoration(
image: DecorationImage(
fit: BoxFit.cover,
image: AssetImage("assets/image/test.jpg")
)
),
),
Container(
width: double.infinity,
color: AppColors.mainBlackColor,
child: Container(
margin: EdgeInsets.only(left: Dimensions.width20, right: Dimensions.width20),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: 30,),
BigText(text: (courseModel != null ? courseModel!.name.toString().toUpperCase() : "Loading..."), size: 20, color: AppColors.whiteColor,),
SizedBox(height: 30,),
BigText(text: "Bạn hoàn thành 3 trong 59 bài giảng", size: 16, color: AppColors.whiteColor,),
SizedBox(height: 30,),
LinearPercentIndicator(
animation: true,
animationDuration: 1000,
lineHeight: 40.0,
backgroundColor: Colors.white,
percent: 0.2,
padding: EdgeInsets.only(right: 0),
center: Text("20.0%"),
trailing: Container(
color: AppColors.yellowColor,
padding: EdgeInsets.only(left: 10, right: 10),
alignment: Alignment.center,
height: 40,
child: SmallText(text: "hoàn thành", size: 16, color: AppColors.whiteColor,),
),
linearStrokeCap: LinearStrokeCap.butt,
progressColor: AppColors.yellowColor,
),
SizedBox(height: 30,),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SelectButtonWidget(text: 'Vào học ngay', isSelect: true, width: Dimensions.screenWidth/2.5,),
SelectButtonWidget(text: 'Hướng dẫn học', width: Dimensions.screenWidth/2.5,),
],
),
SizedBox(height: 30,),
SelectButtonWidget(text: 'Xem mẫu chứng chỉ hoàn thành',),
SizedBox(height: 60,),
],
),
)
),
Container(
width: double.infinity,
color: AppColors.greyColor,
child: Container(
margin: EdgeInsets.only(left: Dimensions.width20, right: Dimensions.width20),
child: Column(
children: [
SizedBox(height: 30,),
LearningCourseBody(courseModel: courseModel,)
],
),
),
)
],
),
),
);
}),
);
},
);
}
}
The body page (cluster layout with gray background color):
class LearningCourseBody extends StatefulWidget {
CourseModel? courseModel;
LearningCourseBody({Key? key, this.courseModel}) : super(key: key);
#override
State<LearningCourseBody> createState() => _LearningCourseBodyState();
}
class _LearningCourseBodyState extends State<LearningCourseBody> {
#override
Widget build(BuildContext context) {
return Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SelectButtonWidget(text: 'Tổng quan', isSelect: true, width: Dimensions.screenWidth/3.5,),
SelectButtonWidget(text: 'Bài học', textColor: AppColors.mainBlackColor, width: Dimensions.screenWidth/3.5,),
SelectButtonWidget(text: 'Tài liệu', textColor: AppColors.mainBlackColor, width: Dimensions.screenWidth/3.5,),
],
),
SizedBox(height: 30,),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SizedBox(width: 5,),
SelectButtonWidget(text: 'Hỏi & đáp', textColor: AppColors.mainBlackColor, width: Dimensions.screenWidth/3.5,),
SizedBox(width: 5,),
SelectButtonWidget(text: 'Ghi chép', textColor: AppColors.mainBlackColor, width: Dimensions.screenWidth/3.5,),
SizedBox(width: 5,),
],
),
SizedBox(height: 60,),
// OverviewCourse(courseModel: widget.courseModel, rating: 5,)
(widget.courseModel != null && widget.courseModel!.particalsCourse != null) ? Expanded(child: ExpandableListViewWidget(courseModel: widget.courseModel!,)) : Text('Loading....'),
],
);
}
}
And this is the expandable lisview:
class ExpandableListViewWidget extends StatefulWidget {
CourseModel courseModel;
ExpandableListViewWidget({Key? key, required this.courseModel}) : super(key: key);
#override
State<ExpandableListViewWidget> createState() => _ExpandableListViewWidgetState();
}
class _ExpandableListViewWidgetState extends State<ExpandableListViewWidget> {
List<Widget> _buildExpandList(int index) {
List<Widget> res = [];
if (widget.courseModel.particalsCourse![index].lessons == null) return res;
for (var sub in widget.courseModel.particalsCourse![index].lessons!) {
var s = ListTile(
title: Text(sub.title!),
leading: Icon(Icons.play_circle),
trailing: sub.isTrial! ? SmallText(text: 'học thử', color: AppColors.yellowColor,) : Text(sub.timeLearning!.toString()),
);
res.add(s);
}
return res;
}
#override
Widget build(BuildContext context) {
List<bool> tileExpanded = List<bool>.generate(widget.courseModel.particalsCourse!.length, (index) => false);
return ListView.builder(
itemCount: widget.courseModel.particalsCourse!.length,
itemBuilder: (context, index) {
return Container(
child: ExpansionTile(
title: Text(widget.courseModel.particalsCourse![index].title!),
controlAffinity: ListTileControlAffinity.leading,
leading: Icon(
tileExpanded[index] ? Icons.arrow_drop_up : Icons.arrow_drop_down
),
children: _buildExpandList(index),
onExpansionChanged: (bool expanded) {
setState(() => tileExpanded[index] = expanded);
},
),
);
}
);
}
}
Hope your help? Thanks!!!
Finally, I was resolve this problem. This is my step:
Step 1: Column use mainAxisSize: MainAxisSize.min
Step 2: Change Expanded to Flexible
Step 3: Adding this two lines in ExpandableListViewWidget
ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
...

large image when clicking - flutter

I have an algorithm working, and I need to click on the image to show it on the entire screen, I have not succeeded, I send all the code, add a comment "// THIS IS THE IMAGE I NEED TO LOOK BIG WHEN I CLICK" which is the image that I want to make it look large when I click it, I have tried in several ways but I have not been able to solve it, and the only thing I am missing is this functionality.
import 'dart:async';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:tienda/models/productos_model.dart';
import 'package:tienda/pages/otra_pagina.dart';
import 'package:tienda/pages/crear_productos.dart';
import 'package:tienda/pages/pedido_lista.dart';
import 'package:tienda/services/firebase_services.dart';
import 'package:tienda/widgets/header.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
//title: 'Flutter Demo',
theme: ThemeData(
//primarySwatch: Colors.yellow,
primaryColor: Colors.yellow[800],
),
home: MyHomePage(title: 'RETO SAN JOSE CHAPARRAL'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
List<ProductosModel> _productosModel = List<ProductosModel>();
List<ProductosModel> _listaCarro = [];
FirebaseService db = new FirebaseService();
StreamSubscription<QuerySnapshot> productSub;
#override
void initState() {
super.initState();
_productosModel = new List();
productSub?.cancel();
productSub = db.getProductList().listen((QuerySnapshot snapshot) {
final List<ProductosModel> products = snapshot.documents
.map((documentSnapshot) =>
ProductosModel.fromMap(documentSnapshot.data))
.toList();
setState(() {
this._productosModel = products;
});
});
}
#override
void dispose() {
productSub?.cancel();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
actions: <Widget>[
Padding(
padding: const EdgeInsets.only(right: 16.0, top: 8.0),
child: GestureDetector(
child: Stack(
alignment: Alignment.topCenter,
children: <Widget>[
Icon(
Icons.shopping_cart,
size: 38,
),
if (_listaCarro.length > 0)
Padding(
padding: const EdgeInsets.only(left: 2.0),
child: CircleAvatar(
radius: 8.0,
backgroundColor: Colors.red,
foregroundColor: Colors.white,
child: Text(
_listaCarro.length.toString(),
style: TextStyle(
fontWeight: FontWeight.bold, fontSize: 12.0),
),
),
),
],
),
onTap: () {
if (_listaCarro.isNotEmpty)
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => Cart(_listaCarro),
),
);
},
),
)
],
),
drawer: Container(
width: 170.0,
child: Drawer(
child: Container(
width: MediaQuery.of(context).size.width * 0.5,
//color: Colors.black, //color de menu principal
color: Colors.yellow[800],
child: new ListView(
padding: EdgeInsets.only(top: 30.0),
children: <Widget>[
Container(
height: 120,
child: new UserAccountsDrawerHeader(
accountName: new Text(''),
accountEmail: new Text(''),
decoration: new BoxDecoration(
image: new DecorationImage(
fit: BoxFit.fill,
image: AssetImage('assets/images/food1x.png'),
),
),
),
),
new Divider(),
new ListTile(
title: new Text(
'productos',
style: TextStyle(color: Colors.white),
),
trailing: new Icon(
Icons.fastfood,
size: 30.0,
color: Colors.white,
),
onTap: () =>
Navigator.of(context).push(new MaterialPageRoute(
builder: (BuildContext context) => CrearProductos(),
)),
),
new Divider(),
],
),
),
),
),
body: SafeArea(
child: SingleChildScrollView(
child: Container(
child: Column(
children: <Widget>[
Stack(
children: <Widget>[
WaveClip(),
Container(
color: Colors.transparent,
padding: const EdgeInsets.only(left: 24, top: 48),
height: 170,
child: ListView.builder(
itemCount: _productosModel.length,
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
return Row(
children: <Widget>[
Container(
height: 300,
padding: new EdgeInsets.only(
left: 10.0, bottom: 10.0),
child: Card(
elevation: 7.0,
clipBehavior: Clip.antiAlias,
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(24)),
child: AspectRatio(
aspectRatio: 1,
child: CachedNetworkImage(
imageUrl:
'${_productosModel[index].image}' +
'?alt=media',
fit: BoxFit.cover,
placeholder: (_, __) {
return Center(
child:
CupertinoActivityIndicator(
radius: 15,
));
}),
),
),
),
],
);
},
))
],
),
Container(height: 3.0, color: Colors.grey),
SizedBox(
height: 5.0,
),
Container(
color: Colors.grey[300],
height: MediaQuery.of(context).size.height / 1.5,
child: GridView.builder(
padding: const EdgeInsets.all(4.0),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2),
itemCount: _productosModel.length,
itemBuilder: (context, index) {
final String imagen = _productosModel[index].image;
var item = _productosModel[index];
return Card(
elevation: 4.0,
child: Stack(
fit: StackFit.loose,
alignment: Alignment.center,
children: <Widget>[
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(
child: CachedNetworkImage(
// THIS IS THE IMAGE I NEED TO LOOK BIG WHEN I CLICK
imageUrl:
'${_productosModel[index].image}' +
'?alt=media',
fit: BoxFit.cover,
placeholder: (_, __) {
return Center(
child:
CupertinoActivityIndicator(
radius: 15,
));
}),
),
Text(
'${_productosModel[index].name}',
textAlign: TextAlign.center,
style: TextStyle(fontSize: 20.0),
),
SizedBox(
height: 15,
),
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: <Widget>[
SizedBox(
height: 25,
),
Text(
'${_productosModel[index].price.toString()}COP',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20.0,
color: Colors.black),
),
Padding(
padding: const EdgeInsets.only(
right: 8.0,
bottom: 8.0,
),
child: Align(
alignment: Alignment.bottomRight,
child: GestureDetector(
child: (!_listaCarro
.contains(item))
? Icon(
Icons.shopping_cart,
color: Colors.yellow[800],
size: 38,
)
: Icon(
Icons.shopping_cart,
color: Colors.red,
size: 38,
),
onTap: () {
setState(() {
if (!_listaCarro
.contains(item))
_listaCarro.add(item);
else
_listaCarro.remove(item);
});
},
),
),
),
],
)
],
),
],
));
},
)),
],
),
)),
));
}
}
Another solution is to show the larger image on the same screen using the dialog below.
InkWell(
onTap: () => showDialog(
builder: (BuildContext context) => AlertDialog(
backgroundColor: Colors.transparent,
insetPadding: EdgeInsets.all(2),
title: Container(
decoration: BoxDecoration(),
width: MediaQuery.of(context).size.width,
child: Expanded(
child: Image.network(
'${_productosModel[index].image}' +
'?alt=media',
fit: BoxFit.fitWidth,
),
),
),
),
context: context),
child: ClipRRect(
borderRadius: BorderRadius.circular(8),
child: Image.network(
BaseUrl.host + posts!.imageUrl!,
fit: BoxFit.cover,
),
),
)
You can create a new page, wrap the image widget in a InkWell widget, and when tapped navigate to the new page showing the image.
EDIT:
Your widget image would become:
// THIS IS THE IMAGE I NEED TO LOOK BIG WHEN I CLICK
return InkWell(
onTap: () => Navigator.push(
context,
MaterialPageRoute(
builder: (BuildContext context) => ImageScreen(
url: '${_productosModel[index].image}' + '?alt=media',
),
),
),
child: Expanded(
child: CachedNetworkImage(
imageUrl: '${_productosModel[index].image}' + '?alt=media',
fit: BoxFit.cover,
placeholder: (_, __) {
return Center(
child: CupertinoActivityIndicator(
radius: 15,
),
);
},
),
),
),
And then you create a new stateless widget which it builds a:
import 'package:flutter/material.dart';
class ImageScreen extends StatelessWidget {
final String? url;
ImageScreen({
Key? key,
#required this.url,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child: Expanded(
child: CachedNetworkImage(
imageUrl: '${this.url}',
// Ajust the image changing the box fit attributte
fit: BoxFit.cover,
placeholder: (_, __) {
return Center(
child: CupertinoActivityIndicator(
radius: 15,
),
);
},
),
),
);
}
}
After that when you click the app navigates to a new screen rendering only the image. You can add a back button later.

How to make infinity scroll layout in flutter? (Updated)

I'm trying to make listview using data from REST API, the position is below my image , but the layout reach its limit, so i can't create it , and showing this error
here my code, (Updated Code)
import 'package:http/http.dart' as http;
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:schoolofparentingalfa/assets/color/color.dart';
class Home extends StatefulWidget {
#override
Home2 createState() => Home2();
}
class Home2 extends State<Home> {
var colorsop = new Colorsop();
var apiconfig = new ApiConfig();
var apiClient = new ApiClient();
#override
void initState() {
super.initState();
}
//To call list from api
Future<List<Artikel>> getNews() async {
// future is used to handle the error when calling api > Future + async or await
var data = await http.get(
'https://newsapi.org/v2/top-headlines?country=us&category=business&apiKey=c4349a84570648eaa7be3cd673cc262b');
var jsonData = json.decode(data.body);
var newsData =
jsonData['articles']; //to retrieve data from articles array of api
List<Artikel> news = []; // create array
for (var data in newsData) {
//assign data into News model array list from articles array of api
Artikel newsItem = Artikel(
data['title'], data['description'], data['urlToImage']);
news.add(newsItem);
}
return news;
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(children: <Widget>[
Positioned(
top: 0,
child: Container(
height: 100,
width: MediaQuery.of(context).size.width,
color: Colors.yellow[800],
child: Align(
alignment: Alignment.center,
child: Text("Halo, Selamat Datang", style: TextStyle(color: Colors.white, fontSize: 25),))),
),
Positioned(
top: 90,
bottom: 0,
right: 0,
left: 0,
child: Container(
width: MediaQuery.of(context).size.width,
height: 600,
decoration: BoxDecoration(
color: Colors.white,
),
child: GridView.count(
crossAxisCount: 1,
children: [
Container( // Container 1
child: Row(
children: <Widget>[
Image.asset(
'lib/assets/image/kelas_online.png',
height: 120,
width: 150,
),
Image.asset(
'lib/assets/image/tanyaahli.png',
height: 120,
width: 150,
),
],
),
),
Container( // Container 2
child: Row(
children: <Widget>[
Image.asset(
'lib/assets/image/workshop_online.png',
height: 120,
width: 150,
),
Image.asset(
'lib/assets/image/MitraSekolah.png',
height: 120,
width: 150,
),
],
),
),
Container( //Container 3
margin: EdgeInsets.only(top: 15, bottom: 30, left: 20),
padding: EdgeInsets.symmetric(horizontal: 15),
child: FutureBuilder(
future: getNews(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
//snapshot is same with response
if (snapshot.data == null) {
return Container(
child: Center(
child: CircularProgressIndicator(),
),
);
} else {
return ListView.builder(
itemCount: snapshot.data.length,
// to retrieve data as all array indexes
itemBuilder: (BuildContext context, int index) {
// is same with holder
return InkWell(
// Inkwell is used to apply card view
onTap: () {
Artikel news = new Artikel(snapshot.data[index].post_link, snapshot.data[index].description, snapshot.data[index].post_image);//is used to onclick
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => new Details(news: news)
));
},
child: Card(
child: Row(
children: <Widget>[
Container(
width: 120.0,
height: 110.0,
child: ClipRRect(
//for corner radius
borderRadius:
BorderRadius.all(Radius.circular(8)),
//to retrieve image from array
child: snapshot.data[index].post_image == null
? Image.network(
'https://cdn2.vectorstock.com/i/1000x1000/70/71/loading-icon-load-icon-wait-for-a-wait-please-wait-vector-24247071.jpg')
: Image.network(
snapshot.data[index].post_image,
width: 100,
fit: BoxFit.fill,
),
),
),
Expanded(
child: ListTile(
//include title and subtitle
title: Text(snapshot.data[index].post_title),
subtitle: Text(snapshot.data[index].post_link == null
? 'Unknown Author'
: snapshot.data[index].post_link),
),
)
],
),
),
);
},
);
}
},
),
),
],
),
)
)
],),
);
}
}
}
class Details extends StatelessWidget{
final Artikel news;
Details({this.news}); // create constructor
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: Column(
children: <Widget>[
Stack( //little same with expanded
children: <Widget>[
Container(
height: 400,
child: Image.network('${this.news.post_image}',
fit: BoxFit.fill,),
),
AppBar(
backgroundColor: Colors.transparent,
leading: InkWell(
child: Icon(Icons.arrow_back_ios),
onTap: () => Navigator.pop(context),
),
elevation: 0,
)
],
),
Padding(
padding: const EdgeInsets.all(8),
child: Column(
children: <Widget>[
SizedBox( // for title
height: 10,
),
Text(
'${this.news.post_title}',
style: TextStyle(
color: Colors.black87,
fontWeight: FontWeight.bold,
fontSize: 20,
letterSpacing: 0.2,
wordSpacing: 0.6
),
),
SizedBox( // for description
height: 20,
),
Text(
this.news.post_link,
style: TextStyle(
color: Colors.black54,
fontSize: 16,
letterSpacing: 0.2,
wordSpacing: 0.3
),
)
],
),
)
],
),
),
),
);
}
}
class Artikel {
final String post_title;
final String post_link;
final String post_image;
//Alt+insert > constructor
Artikel(this.post_title, this.post_link, this.post_image);
}
Can anyone help me?
Updated Screenshot .............................................................................
you can replace the code and check
return Scaffold(
body: Stack(children: <Widget>[
Positioned(
top: 0,
child: Container(
height: 100,
width: MediaQuery.of(context).size.width,
color: Colors.yellow[800],
child: Align(
alignment: Alignment.center,
child: Text("Halo, Selamat Datang", style: TextStyle(color: Colors.white, fontSize: 25),))),
),
Positioned(
top: 90,
bottom: 0,
right: 0,
left: 0,
child: Container(
width: MediaQuery.of(context).size.width,
height: 600,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(topLeft:Radius.circular(20), topRight:Radius.circular(20)) ),
child:
GridView.count(
crossAxisCount: 2,
children: List.generate(5, (index) {
return Padding(
padding: const EdgeInsets.all(24.0),
child: GridTile(child: Image.network("https://upload.wikimedia.org/wikipedia/commons/6/6d/Good_Food_Display_-_NCI_Visuals_Online.jpg"),),
);
}) ,),)
)
],),
);

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")),
),
);
},
),
),
],
),
);
}
}