Flutter: responsive height and width - flutter

in my flutter code below i'm suffering from height and width problem which appears different on each device, for ex in my below code i set a background image and it appears on half screen if i didn't set a height, and ofc this height appears different on each device.
also in child: Image.asset( object["placeImage"], fit: BoxFit.cover,width: 280,height: 180,) i wanted the image to appear one size on all devices without setting a specific height and width.. is there a way to do this in flutter?
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:hexcolor/hexcolor.dart';
import 'package:localize_and_translate/localize_and_translate.dart';
import 'package:menu_app/About.dart';
import 'package:menu_app/Drinks.dart';
import 'package:flutter/gestures.dart';
class FoodDetailsPage extends StatefulWidget {
final String pageId;
//The string of each meal will be passed when calling this page.
FoodDetailsPage({required this.pageId});
#override
_FoodDetailsPageState createState() => _FoodDetailsPageState();
}
class _FoodDetailsPageState extends State<FoodDetailsPage> {
late Future<List<Widget>> myCreateList;
#override
void initState() {
super.initState();
myCreateList = createList();
//THIS IS NECESSARY TO AVOID THE FUTUREBUILDER FROM FIRING EVERYTIME THE PAGE REBUILDS.
// You can check more at
// https://stackoverflow.com/questions/57793479/flutter-futurebuilder-gets-constantly-called
}
Future<List<Widget>> createList() async {
List<Widget> items = <Widget>[];
String dataString = await rootBundle.loadString(translator.translate(
"assets/${widget.pageId}.json")); //view JSON file depending on pageId
List<dynamic> dataJSON = jsonDecode(dataString);
dataJSON.forEach((object) {
String finalString = "";
List<dynamic> dataList = object["placeItems"];
dataList.forEach((item) {
finalString = finalString + item + " | ";
});
items.add(Padding(
padding: EdgeInsets.all(2.0),
child: Container(
decoration: BoxDecoration(
color: Color.fromRGBO(255, 255, 255, 0.7),
borderRadius: BorderRadius.all(Radius.circular(10.0)),
boxShadow: [
BoxShadow(
color: Colors.black12, spreadRadius: 2.0, blurRadius: 5.0),
]),
margin: EdgeInsets.all(5.0),
child: Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
child: Image.asset(
object["placeImage"], // also here i need to set a astatic height and width on each device
fit: BoxFit.cover,
width: 280,
height: 180,
),
),
SizedBox(
width: 250,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
translator.translate(object["placeName"]),
style: GoogleFonts.elMessiri(
textStyle: TextStyle(
fontSize: 15.0, color: Colors.black54)),
),
// Padding(
// padding: const EdgeInsets.only(top: 2.0, bottom: 2.0),
// child: Text(
// finalString,
// overflow: TextOverflow.ellipsis,
// style: TextStyle(
// fontSize: 12.0,
// color: Colors.black54,
// ),
// maxLines: 1,
// ),
// ),
Text(
translator.translate(" ${object["minOrder"]} IQD"),
style: TextStyle(fontSize: 12.0, color: Colors.black54),
)
],
),
),
)
],
),
),
));
});
return items;
}
Widget build(BuildContext context) {
// ignore: unused_local_variable
var size = MediaQuery.of(context).size;
var screenHeight = MediaQuery.of(context).size.height;
var screenWidth = MediaQuery.of(context).size.width;
return Scaffold(
appBar: AppBar(
backgroundColor: HexColor("#242424"),
leading: IconButton(
icon: Icon(Icons.arrow_back_ios),
iconSize: 20.0,
onPressed: () {
Navigator.pop(context);
},
),
title: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
"assets/images/logo.png",
fit: BoxFit.contain,
height: 40,
),
],
),
),
body: SafeArea(
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min, // set min
children: <Widget>[
Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(
"assets/images/backg.png", // i have to set a static height for each device to get the full backfround
),
fit: BoxFit.fill)),
height: 3000,
width: screenWidth,
child: FutureBuilder<List<Widget>>(
initialData: [Text("")],
future: myCreateList,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting)
return Text(translator.translate("Loading"));
if (snapshot.hasError) {
return Text("Error ${snapshot.error}");
}
if (snapshot.hasData) {
return Padding(
padding: EdgeInsets.all(8.0),
child: GridView.count(
childAspectRatio: 1, // items' width/height
crossAxisCount: 2,
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
children: [
// ignore: sdk_version_ui_as_code
...?snapshot.data,
],
));
} else {
return CircularProgressIndicator();
}
}),
)
],
),
)),
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => About()),
);
},
backgroundColor: Colors.black,
child: Icon(
MdiIcons.information,
color: Colors.white,
)),
);
}
}

if you want you image to same size in every device wrap it with a container and give static height and width use the fit property according to your needs but if you want the size of the image should change according to device height and width you can use media query for that ....for eg
Container(
color: Colors.yellow,
height: MediaQuery.of(context).size.height * 0.65,
width: MediaQuery.of(context).size.width,
)
put your image in child parameter ......
let me know if this help

Related

How can i achieve 'add photo' logic in flutter?

Hey guys i am trying to achieve this image logic in flutter as i am new to flutter.
First off...
Images from the user gallery are being rendered in the 'Recent' Grid view UI (Should be in the UI provided and not come out as an overlay page as different pub.dev image picker packages does)
Images are selectable, both multiple selection and single selection.
Any image selected should be rendered inn the big container that has a round hole and an overlay, which can be cropped and zoomed.
any image selected would then be rendered in the sized boxes with the 'x'. when the 'x' is tapped, the image should be unselected.
This is what i am trying to achieve in a picture, the UI is not a problem but the logic has been giving me sleepless nights.
I tried using photo_manager
and it helped me to render the user's gallery image in the 'recent' but i am stuck at the rest logic.
Please help me :(
This is what i tried.
class AddPhotosView extends StatefulWidget {
#override
State<AddPhotosView> createState() => _AddPhotosView();
}
class _AddPhotosView extends State<AddPhotosView> {
List<Widget> _mediaList = [];
int currentPage = 0;
int lastPage;
#override
void initState() {
super.initState();
_fetchNewMedia();
}
_handleScrollEvent(ScrollNotification scroll) {
if (scroll.metrics.pixels / scroll.metrics.maxScrollExtent > 0.33) {
if (currentPage != lastPage) {
_fetchNewMedia();
}
}
}
_fetchNewMedia() async {
var result = await PhotoManager.requestPermissionExtend();
if (result != null) {
// success
//load the album list
List<AssetPathEntity> albums =
await PhotoManager.getAssetPathList(onlyAll: true);
print(albums);
List<AssetEntity> media =
await albums[0].getAssetListPaged(page: currentPage, size: 60);
print(media);
List<Widget> temp = [];
for (var asset in media) {
temp.add(
FutureBuilder(
future: asset.thumbnailDataWithSize(
ThumbnailSize(200, 200),
),
builder: (BuildContext context, snapshot) {
if (snapshot.connectionState == ConnectionState.done)
return GestureDetector(
onTap: () async {
File file = await asset.file;
print(file.toString());
},
child: Stack(
children: <Widget>[
Positioned.fill(
child: Image.memory(
snapshot.data,
fit: BoxFit.cover,
),
),
if (asset.type == AssetType.video)
Align(
alignment: Alignment.bottomRight,
child: Padding(
padding: EdgeInsets.only(right: 5, bottom: 5),
child: Icon(
Icons.videocam,
color: Colors.white,
),
),
),
],
),
);
return Container();
},
),
);
}
setState(() {
_mediaList.addAll(temp);
currentPage++;
});
} else {
// fail
PhotoManager.openSetting();
}
}
#override
Widget build(BuildContext context) {
// final controller = Get.put(EServicesController());
return Scaffold(
appBar: AppBar(
toolbarHeight: 50,
backgroundColor: Colors.white,
title: Column(
children: [
Text(
"Add Photos".tr,
style: GoogleFonts.poppins(
color: Color(0xff000000),
fontSize: 16,
fontWeight: FontWeight.w600),
),
],
),
centerTitle: false,
elevation: 0.5,
automaticallyImplyLeading: false,
leadingWidth: 15,
leading: new IconButton(
icon: new Icon(Icons.arrow_back_ios, color: Color(0xff3498DB)),
onPressed: () => {Get.back()},
),
),
body: Column(
children: [
Container(
color: Colors.white,
child: Padding(
padding: const EdgeInsets.only(
left: 45.0, right: 45, top: 22, bottom: 35),
child: Container(
height: 280,
width: 280,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
),
child: Stack(
fit: StackFit.expand,
children: [
Image.asset(
'assets/icon/image-test.png',
fit: BoxFit.cover,
),
ColorFiltered(
colorFilter: ColorFilter.mode(
Colors.white.withOpacity(0.3),
BlendMode.srcOut), // This one will create the magic
child: Stack(
fit: StackFit.expand,
children: [
Container(
decoration: BoxDecoration(
color: Colors.black,
backgroundBlendMode: BlendMode
.dstOut), // This one will handle background + difference out
),
Align(
alignment: Alignment.topCenter,
child: Container(
margin: const EdgeInsets.only(top: 80),
height: 200,
width: 200,
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(100),
),
),
),
],
),
),
],
),
),
),
),
Expanded(
child: NotificationListener<ScrollNotification>(
onNotification: (ScrollNotification scroll) {
_handleScrollEvent(scroll);
return;
},
child: Padding(
padding: const EdgeInsets.all(22.0),
child: GridView.builder(
itemCount: _mediaList.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3),
itemBuilder: (BuildContext context, int index) {
return _mediaList[index];
}),
),
),
),
],
),
//bottomNavigationBar: SendUpdateButton(),
);
}
}

flutter: navigator.pop() is not working properly in my code

I have code below in flutter and when i press on back arrow button it crashes the app and white screen appear however in appears by default in other pages and i implemented it in other pages manually ... can someone please tell me what is the problem here cuz i couldn't figure it out?
thanks in advance
// ignore_for_file: avoid_function_literals_in_foreach_calls, prefer_const_constructors, prefer_const_literals_to_create_immutables, use_key_in_widget_constructors, avoid_unnecessary_containers, curly_braces_in_flow_control_structures, sized_box_for_whitespace, deprecated_member_use, file_names
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
// ignore: unused_import
import 'package:google_fonts/google_fonts.dart';
import 'package:hexcolor/hexcolor.dart';
// ignore: unused_import
import 'package:localize_and_translate/localize_and_translate.dart';
import 'package:menu_app/About.dart';
void main() => runApp(HotDrinks());
class HotDrinks extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
var screenHeight = MediaQuery.of(context).size.height;
var screenWidth = MediaQuery.of(context).size.width;
Future<List<Widget>> createList() async {
List<Widget> items = <Widget>[];
String dataString = await rootBundle
.loadString(translator.translate("assets/hotDrinks.json"));
List<dynamic> dataJSON = jsonDecode(dataString);
dataJSON.forEach((object) {
String finalString = "";
List<dynamic> dataList = object["placeItems"];
dataList.forEach((item) {
finalString = finalString + item + " | ";
});
items.add(Padding(
padding: EdgeInsets.all(2.0),
child: Container(
decoration: BoxDecoration(
color: Color.fromRGBO(255, 255, 255, 0.7),
borderRadius: BorderRadius.all(Radius.circular(10.0)),
boxShadow: [
BoxShadow(
color: Colors.black12,
spreadRadius: 2.0,
blurRadius: 5.0),
]),
margin: EdgeInsets.all(5.0),
child: Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
ClipRRect(
child: Image.asset(
object["placeImage"],
fit: BoxFit.cover,
width: 280,
height: 180,
),
),
SizedBox(
width: 250,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
translator.translate(object["placeName"]),
style: GoogleFonts.elMessiri(
textStyle: TextStyle(
fontSize: 15.0, color: Colors.black54)),
),
Text(
translator.translate(" ${object["minOrder"]} IQD"),
style:
TextStyle(fontSize: 12.0, color: Colors.black54),
)
],
),
),
)
],
),
),
));
});
return items;
}
return Scaffold(
appBar: AppBar(
backgroundColor: HexColor("#242424"),
leading: IconButton(
icon: Icon(Icons.arrow_back_ios),
iconSize: 20.0,
onPressed: () {
Navigator.pop(context); //not working
},
),
title: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
"assets/images/logo.png",
fit: BoxFit.contain,
height: 40,
),
],
),
),
body: SafeArea(
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min, // set min
children: <Widget>[
Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/images/backg.png"),
fit: BoxFit.cover,
),
),
height: 3000,
width: screenWidth,
child: FutureBuilder<List<Widget>>(
initialData: [Text("")],
future: createList(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting)
return Text("Loading");
if (snapshot.hasError) {
return Text("Error ${snapshot.error}");
}
if (snapshot.hasData) {
return Padding(
padding: EdgeInsets.all(8.0),
child: GridView.count(
childAspectRatio: 1, // items' width/height
crossAxisCount: 2,
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
children: [
// ignore: sdk_version_ui_as_code
...?snapshot.data,
],
));
} else {
return CircularProgressIndicator();
}
}),
)
],
),
)),
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => About()),
);
},
backgroundColor: Colors.black,
child: Icon(
MdiIcons.information,
color: Colors.white,
)),
);
}
}
It's because there's nothing "underneath" MyHomePage.
Here's how routing works in Flutter - think of it as a stack of screens. The initial route (bottom of the stack) is the first screen you see when you open the app, in your case it's MyHomePage. If you push a route on top of this screen, the old screen (MyHomePage) is still there, but hidden underneath the new screen that you just pushed. So if you use pop() in this new screen, it will kill it and take you back to the route that's underneath - MyHomePage.
In your example, when you open the app, the home screen is MyHomePage and there's nothing underneath, hence why there's nothing to display.
To visualise this, take a look at this video at the 11:00 mark.

flutter: GridView not showing properly

i'm trying to create a restaurant menu app in flutter language, and i wanted to view my saved data inside json file as gridView but sadly i'm getting error while running the app.. However, i tried to change the gridView to listView and its showing good..
so is there a way to show them as gridView?
thanks in advance
[
{
"placeImage": "assets/images/wood.jpg",
"placeName": "The Hawkers",
"placeItems": ["Burgers","Chinese","Fast Food","Italian","Juice"],
"minOrder": 20
},
{
"placeImage": "assets/images/wood.jpg",
"placeName": "Flipping Noodles",
"placeItems": ["Burgers","Chinese","Fast Food","Italian","Juice"],
"minOrder": 50
},
{
"placeImage": "assets/images/wood.jpg",
"placeName": "Pizza Hut",
"placeItems": ["Pizza","Chinese","Fast Food","Italian","Juice"],
"minOrder": 20
},
{
"placeImage": "assets/images/wood.jpg",
"placeName": "Blue Hill",
"placeItems": ["Burgers","Chinese","Fast Food","Italian","Juice"],
"minOrder": 40
},
{
"placeImage": "imagess/bluehill.jpg",
"placeName": "Blue Hill",
"placeItems": ["Burgers","Chinese","Fast Food","Italian","Juice"],
"minOrder": 40
}
]
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
void main() => runApp(Breakfast());
class Breakfast extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
var bannerItems = ["Burger", "Cheese Chilly", "Noodles", "Pizza"];
var bannerImage = [
"images/burger.jpg",
"images/cheesechilly.jpg",
"images/noodles.jpg",
"images/pizza.jpg"
];
class MyHomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
var screenHeight = MediaQuery.of(context).size.height;
var screenWidth = MediaQuery.of(context).size.width;
Future<List<Widget>> createList() async {
List<Widget> items = new List<Widget>();
String dataString =
await DefaultAssetBundle.of(context).loadString("assets/data.json");
List<dynamic> dataJSON = jsonDecode(dataString);
dataJSON.forEach((object) {
String finalString = "";
List<dynamic> dataList = object["placeItems"];
dataList.forEach((item) {
finalString = finalString + item + " | ";
});
items.add(Padding(
padding: EdgeInsets.all(2.0),
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(10.0)),
boxShadow: [
BoxShadow(
color: Colors.black12,
spreadRadius: 2.0,
blurRadius: 5.0),
]),
margin: EdgeInsets.all(5.0),
child: Row(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10.0),
bottomLeft: Radius.circular(10.0)),
child: Image.asset(
object["placeImage"],
width: 80,
height: 80,
fit: BoxFit.cover,
),
),
SizedBox(
width: 250,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(object["placeName"]),
Padding(
padding: const EdgeInsets.only(top: 2.0, bottom: 2.0),
child: Text(
finalString,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 12.0,
color: Colors.black54,
),
maxLines: 1,
),
),
Text(
"Min. Order: ${object["minOrder"]}",
style:
TextStyle(fontSize: 12.0, color: Colors.black54),
)
],
),
),
)
],
),
),
));
});
return items;
}
return Scaffold(
body: Container(
height: screenHeight,
width: screenWidth,
child: SafeArea(
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.fromLTRB(10, 5, 10, 5),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
IconButton(icon: Icon(Icons.menu), onPressed: () {}),
Text(
"Foodies",
style: TextStyle(fontSize: 50, fontFamily: "Samantha"),
),
IconButton(icon: Icon(Icons.person), onPressed: () {})
],
),
),
BannerWidgetArea(),
Container(
child: FutureBuilder(
initialData: <Widget>[Text("")],
future: createList(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Padding(
padding: EdgeInsets.all(8.0),
child: GridView.count(
crossAxisCount: 3,
crossAxisSpacing: 4.0,
mainAxisSpacing: 2.0,
children: snapshot.data,
),
);
} else {
return CircularProgressIndicator();
}
}),
)
],
),
)),
),
floatingActionButton: FloatingActionButton(
onPressed: () {},
backgroundColor: Colors.black,
child: Icon(
MdiIcons.food,
color: Colors.white,
)),
);
}
}
class BannerWidgetArea extends StatelessWidget {
#override
Widget build(BuildContext context) {
var screenWidth = MediaQuery.of(context).size.width;
PageController controller =
PageController(viewportFraction: 0.8, initialPage: 1);
List<Widget> banners = new List<Widget>();
for (int x = 0; x < bannerItems.length; x++) {
var bannerView = Padding(
padding: EdgeInsets.all(10.0),
child: Container(
child: Stack(
fit: StackFit.expand,
children: <Widget>[
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(20.0)),
boxShadow: [
BoxShadow(
color: Colors.black38,
offset: Offset(2.0, 2.0),
blurRadius: 5.0,
spreadRadius: 1.0)
]),
),
ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(20.0)),
child: Image.asset(
bannerImage[x],
fit: BoxFit.cover,
),
),
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(20.0)),
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [Colors.transparent, Colors.black])),
),
Padding(
padding: EdgeInsets.all(10.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
bannerItems[x],
style: TextStyle(fontSize: 25.0, color: Colors.white),
),
Text(
"More than 40% Off",
style: TextStyle(fontSize: 12.0, color: Colors.white),
)
],
),
)
],
),
),
);
banners.add(bannerView);
}
return Container(
width: screenWidth,
height: screenWidth * 9 / 16,
child: PageView(
controller: controller,
scrollDirection: Axis.horizontal,
children: banners,
),
);
}
}
Firstly I would prefer having data from Future instead of <Widget> and will avoid forEach method to handle complex and bigger computation.
Lets processed with current condition of code-structure. According to your question, main issue is using ListView/GridView.
While SingleChildScrollView is handling the scroll, use GridView.count or ListView
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
About the top level-column
body: SafeArea(
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min, // set min
children: <Widget>[
To check error, define states of FutureBuilder
child: FutureBuilder<List<Widget>>(
initialData: [Text("")],
future: createList(context),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting)
return Text("Loading");
if (snapshot.hasError) {
return Text("Error ${snapshot.error}");
}
if (snapshot.hasData) {
return Padding(
padding: EdgeInsets.all(8.0),
child: GridView.count(
childAspectRatio: 1 // items' width/height
crossAxisCount: 3,
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
children: [
...snapshot.data!,
],
),
To load JSON, I've used like String dataString = await rootBundle.loadString("json/data.json");
To handle item size use childAspectRatio.
Assuming you don't have issue with loading images/BannerWidgetArea() widgets.
Does it solve the issue?

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

Flutter - flutter_html package - customTextStyle isn't defined

As per the example in the flutter_html package, I am trying to add customTextStyle(the current size of the fonts is too small).
Each time I add the code from the example I get a red squiggly line (using Android Studio) telling me that it is not defined. Yet it is in the example:
customTextStyle: (dom.Node node, TextStyle baseStyle) {
if (node is dom.Element) {
switch (node.localName) {
case "p":
return baseStyle.merge(TextStyle(height: 2, fontSize: 20));
}
}
return baseStyle;
},
There is a mention in the example code (a comment) stating that:
//Must have useRichText set to false for this to work.
This is fine, but how do I set it to false? I tried to add this to various places in that very same code but it won't work and it will tell me that it is not defined. Do I need some additional package? This is not clear.
Thank you for your kind help with this.
This is a single_news_screen.dart file where I use this package. Code for this file is here:
import 'package:flutter/material.dart';
import 'package:date_format/date_format.dart';
import 'package:flutter_html/flutter_html.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:thw_network/utilities/constants.dart';
import 'package:thw_network/screens/main_screen.dart';
class SingleNewsScreen extends StatefulWidget {
SingleNewsScreen({ this.dataNews });
final dataNews;
#override
_SingleNewsScreenState createState() => _SingleNewsScreenState();
}
class _SingleNewsScreenState extends State<SingleNewsScreen> {
dynamic news;
#override
void initState() {
super.initState();
news = widget.dataNews;
}
cardTitle(String title) {
if(title.length > 120) {
return title.substring(0,120) + '...';
}
return title;
}
cardDate(String date) {
int year = int.parse(date.substring(0,4));
int month = int.parse(date.substring(5,7));
int day = int.parse(date.substring(8,10));
return formatDate(DateTime(year, month, day), [d, ' ', M,', ', yyyy]);
}
#override
Widget build(BuildContext context) {
double contentHeight = MediaQuery.of(context).size.height - 338;
return Scaffold(
body: Container(
decoration: BoxDecoration(
color: Color(0xFFf5f5f5),
),
constraints: BoxConstraints.expand(),
child: SafeArea(
child: Column(
children: <Widget>[
Container(
height: 260.0,
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(
news['jetpack_featured_media_url'],
),
fit: BoxFit.cover,
colorFilter: ColorFilter.mode(
Colors.black.withOpacity(0.7),
BlendMode.darken
),
),
color: Color(0xFF1F1F98),
gradient: LinearGradient(
begin: Alignment.topCenter,
colors: [Colors.black, Colors.black],
stops: [0.0, 0.5]
),
),
child: Column(
children: <Widget>[
Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width * 0.85,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 20, right:20, bottom: 10, left: 20),
child: Text(
'THE HIGHWIRE',
style: kSingleOverlayAuthorTextStyle
)
), /* add child content here */
Padding(
padding: const EdgeInsets.only(top: 10, right:20, bottom: 10, left: 20),
child: Text(
cardTitle(news['title']['rendered']),
style: kSingleOverlayTitleTextStyle
)
), /* add child content here */
Padding(
padding: const EdgeInsets.only(top: 10, right:20, bottom: 20, left: 20),
child: Text(
cardDate(news['date']),
style: kSingleOverlayDateTextStyle
)
),
],
)
),
Container(
width: MediaQuery.of(context).size.width * 0.15,
child: Align(
alignment: Alignment.topRight,
child: Padding(
padding: EdgeInsets.all(10.0),
child: FloatingActionButton(
backgroundColor: Colors.white,
elevation: 0,
onPressed: () {
Navigator.pop(context, MaterialPageRoute(builder: (context) {
return MainScreen();
}),);
},
child: Icon(
Icons.close,
size: 25.0,
color: Colors.deepPurpleAccent
),
),
),
),
)
],
),
],
),
),
Container(
height: contentHeight,
child: SingleChildScrollView(
child: Html(
data: news['content']['rendered'],
padding: EdgeInsets.all(30.0),
onLinkTap: (url) async {
if (await canLaunch(url)) {
await launch(url);
} else {
throw 'Could not launch $url';
}
},
),
),
),
],
),
),
),
);
}
}
Try to import this on the top of the widget
import 'package:flutter_html/flutter_html.dart';
import 'package:html/dom.dart' as dom; // that is
import 'package:url_launcher/url_launcher.dart';
For more details flutter-html
According to the authors, its a bug (see the end of the README).
This package has a known issue where text does not wrap correctly.
I believe you need to set useRichText: true in the Html() widget. Probably right after the data:"" attribute