flutter local notifications send ID with payload option - flutter

I have an application that stores data with sqflite. I access the records that I list with listview from the detail page with the constructor method. Short and simple codes are as follows.
notes.dart --> main page
child: ListView.builder(
itemCount: notes.length,
itemBuilder: (context, index) {
return NoteClass(
notes: notes[index],
);
},
),
note_class.dart -->
return Column(
children: <Widget>[
Dismissible(
key: UniqueKey(),
movementDuration: Duration(milliseconds: 400),
background: Container(
child: Padding(
padding: EdgeInsets.only(left: 38),
child: Align(
alignment: Alignment.centerLeft,
child: Icon(
LineIcons.trash,
color: Colors.red.shade900,
size: 27,
),
),
),
),
onDismissed: (direction) {
_deleteNote(widget.notes.noteID);
},
child: Card(
margin: EdgeInsets.only(top: 2, bottom: 2),
elevation: 2,
shape: RoundedRectangleBorder(),
child: Container(
height: 80,
child: ListTile(
onTap: (){
_detailPage(context, widget.notes);
},
contentPadding: EdgeInsets.only(left: 10, right: 5),
title: Stack(
children: <Widget>[
Container(
padding: EdgeInsets.only(top: 17),
child: Icon(Icons.note)
),
Container(
padding: EdgeInsets.only(left: 45),
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: <Widget>[
Column(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
crossAxisAlignment:
CrossAxisAlignment.start,
children: <Widget>[
Container(
padding: EdgeInsets.only(top: 0),
child: Text(
widget.notes.noteHeader,
style: TextStyle(
fontSize: 19,
color: Colors.grey[900]),
)),
Container(
padding: EdgeInsets.only(top: 0),
child: Text(
widget.notes.noteBody,
style: TextStyle(
fontSize: 17,
color: Colors.grey[900]),
),
),
],
),
],
),
),
],
),
),
),
)),
],
);
_detailPage(BuildContext context, NoteModel noteModel) {
Navigator.push(
context,
PageTransition(
type: PageTransitionType.rightToLeft,
child: NoteDetail(
content: noteModel,
)));
}
note_detail.dart
Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Card(
elevation: 3,
shape: RoundedRectangleBorder(),
child: Container(
alignment: Alignment.centerLeft,
height: 50,
width: MediaQuery.of(context).size.width,
padding: EdgeInsets.only(left: 8, top: 0),
child: SelectableText(
widget.content.noteHeader,
style: TextStyle(fontSize: 18, color: Colors.grey[800],),
),
),
),
Card(
elevation: 3,
shape: RoundedRectangleBorder(),
child: Container(
alignment: Alignment.centerLeft,
height: 50,
width: MediaQuery.of(context).size.width,
padding: EdgeInsets.only(left: 8, top: 0),
child: SelectableText(
widget.content.noteBody,
style: TextStyle(fontSize: 18, color: Colors.grey[800],),
),
),
),],
),
On the note detail page I set notifications with flutterLocalNotificationsPlugin.schedule and I can view note details with notifications. But when I click on the notification I want to go to the detail page of the related note. I sent the ID of the record with the payload parameter.
Then, I added the onSelectNotification method in notes.dart.
Future onSelectNotification(String payload) async {
if (payload != null) {
######## what should I write here? ########
}
}
There is an ID value in payload. How can I access the note detail about ID information. Or click on the notification in which way I can go to the note detail page.

You're almost there. All you have to do is something similar to this:
class NoteDetail extends StatefulWidget {
final String payload;
NoteDetail (this.payload);
#override
State<StatefulWidget> createState() => NoteDetailState(payload);
}
class NoteDetailState extends State {
String payload;
NoteDetailState (this.payload);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar()
body:Column( your column code here))
}
// call this after something
void save() {
//dosomething
// go back to the old page
// notice the true, if all goes good with save send true otherwise false
Navigator.pop(context, true);
}
}
// use this code to go to detail
void navigateToDetail(String payload) async {
bool result = await Navigator.push(context,
MaterialPageRoute(builder: (context) => NoteDetail(payload)),
);
if (result == true) {
getData(); // refresh data from db
}
}

Related

Flutter ListView not scrolling (I feel like I've tried every solution on the internet)

If I drag and hold my finger down I can see a few items that are below the cutoff of the screen but as soon as I let go, it just bounces back to the top. I tried using SingleChildScrollView places, tried setting primary = true, and a bunch of other stuff that didn't help. I'm fairly new to flutter so any help would be appreciated!! Let me know if any more info is needed.
Here is my code:
import 'package:flutter/material.dart';
import 'package:drink_specials/models/restaurant.dart';
import 'package:drink_specials/screens/home/restaurant_list.dart';
class RestaurantNameTextStyle {
static TextStyle display5(BuildContext context) {
return Theme.of(context).textTheme.headline2.copyWith(color: Colors.white);
}
}
class RestaurantTypeTextStyle {
static TextStyle display5(BuildContext context) {
return Theme.of(context).textTheme.headline6.copyWith(color: Colors.white);
}
}
class RestaurantDetail extends StatelessWidget {
final Restaurant restaurant;
RestaurantDetail({Key key, #required this.restaurant}) : super(key: key);
#override
Widget build(BuildContext context) {
final topContentText = Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SizedBox(height: 100.0),
Text(
restaurant.name,
style: RestaurantNameTextStyle.display5(context),
),
SizedBox(height: 10.0),
Expanded(
flex: 6,
child: Padding(
padding: EdgeInsets.only(left: 10.0),
child: Text(
restaurant.restaurant_type,
style: RestaurantTypeTextStyle.display5(context),
))),
],
);
final topContent = Stack(
children: <Widget>[
Container(
padding: EdgeInsets.only(left: 10.0),
height: MediaQuery.of(context).size.height * 0.5,
decoration: new BoxDecoration(
image: new DecorationImage(
image: NetworkImage(restaurant.photo),
fit: BoxFit.cover,
),
)),
Container(
height: MediaQuery.of(context).size.height * 0.5,
padding: EdgeInsets.all(40.0),
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(color: Color.fromRGBO(58, 66, 86, .9)),
child: Center(
child: topContentText,
),
),
Positioned(
left: 8.0,
top: 60.0,
child: InkWell(
onTap: () {
Navigator.pop(context);
},
child: Icon(Icons.arrow_back, color: Colors.white),
),
)
],
);
final bottomContent = Container(
width: MediaQuery.of(context).size.width,
padding: EdgeInsets.all(8.0),
child: Center(
child: ListView.builder(
scrollDirection: Axis.vertical,
physics: const BouncingScrollPhysics(parent: AlwaysScrollableScrollPhysics()),
itemCount: restaurant.specials.length,
itemBuilder: (context, index) {
final item = restaurant.specials[index];
return Card(
elevation: 8.0,
margin: new EdgeInsets.symmetric(horizontal: 10.0, vertical: 6.0),
child: Container(
decoration: BoxDecoration(color: Color.fromRGBO(58, 66, 86, 1.0)),
child: ListTile(
contentPadding: EdgeInsets.symmetric(horizontal:20, vertical:10),
title: Text(item, style: TextStyle(color: Colors.white)),
)
),
);
}
),
),
);
return Scaffold(
body: Column(
children: <Widget>[
topContent,
Expanded(
child: bottomContent,
),
],
),
);
}
}
There is a ListView inside a SingleChildScrollView and both of them are scrollable. Scrolling on one of them should be disabled.
As they already explained. If you have a ListView.builder, you don't need SingleChildScrollView.
Try removing SingleChildScrollView. The code should look like this:
Scaffold(
body: Column(
children: <Widget>[
topContent,
Expanded(
child: bottomContent,
),
],
),
);
ListView already have scroll behavior so you won't need some SingleChildScrollView

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 execute the API when the textfield is filled BLOC FLUTTER?

how to execute the API when the textfield is filled. so when the textfield is filled it starts executing the API.
I've tried making a check function that works if the textfield is not null then I can only start the API execution. in the following ways:
in the block I make a check function to check whether the textfield (_prefix) is filled or not but this function is an error when called in inStState in the UI section.
BLOC :
class DenomPulsaBloc {
final _repository = EresidenceRepository();
final _prefix = BehaviorSubject<String>();
SharedPreferences sPrefs;
final BehaviorSubject<List<Payload>> _subject = BehaviorSubject<List<Payload>>();
Function(String) get prefix => _prefix.sink.add;
cek() async{
if(_prefix.value.length >= 3) {
denomPulsa();
}else{
print("GAGAL");
}
}
denomPulsa() async{
try{
sPrefs = await SharedPreferences.getInstance();
ListPulsaResponses responses = await _repository.listDenomPulsa(sPrefs.getString("userid"), sPrefs.getString("password"), sPrefs.getString("imei"),
sPrefs.getString("coordinate"), sPrefs.getString("bit61"), sPrefs.getString("bit62"), _prefix.value);
List<Payload> list = responses.data.payload;
_subject.sink.add(list);
print(list);
}catch(e){
print(e.toString());
_subject.sink.add(e);
}
}
dispose(){
_subject.close();
_prefix.close();
}
BehaviorSubject<List<Payload>> get subject => _subject;
}
UI :
class _PulsaPageState extends State<PulsaPage> {
DenomPulsaBloc denomPulsaBloc;
int selectedCard = -1;
#override
void initState() {
super.initState();
denomPulsaBloc = DenomPulsaBloc();
denomPulsaBloc.cek();
}
#override
void dispose() {
denomPulsaBloc.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: DefaultTabController(
length: 2,
child: Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
backgroundColor: Colors.white,
brightness: Brightness.light,
elevation: 0.0,
leading: InkWell(
onTap: () {
Navigator.of(context).pop();
},
child: Icon(
Icons.arrow_back_ios,
color: Colors.black,
size: SizeConfig.texIconSize,
),
),
),
body: SafeArea(
child: Container(
height: SizeConfig.screenHeight,
width: SizeConfig.screenWidth,
padding: EdgeInsets.symmetric(horizontal: SizeConfig.widthMultiplier * 4),
child: Column(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Container(
alignment: Alignment.centerLeft,
child: Text(
'Pulsa',
style: AppTheme.styleSubTitleBoldLarge,
)
),
Container(
margin: EdgeInsets.only(top: SizeConfig.heightMultiplier * 4),
decoration: BoxDecoration(
boxShadow: <BoxShadow>[
BoxShadow(blurRadius: 5.0, color: Colors.black12)
]
),
child: ClipRRect(
borderRadius: BorderRadius.circular(8.0),
child: Container(
padding: EdgeInsets.all(SizeConfig.heightMultiplier * 2),
color: Colors.white,
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Expanded(
flex: 1,
child:
Container(
child: Icon(Icons.phone_android, color: Colors.green, size: SizeConfig.texIconSize,),
),
),
Expanded(
flex: 9,
child: Container(
margin: EdgeInsets.only(left: SizeConfig.widthMultiplier * 3),
child:Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
child: Text(
'Number',
style: AppTheme.styleSubTitle,
),
),
Container(
child: Stack(children: <Widget>[
Container(
height: SizeConfig.heightMultiplier * 5.5,
child: TextFormField(
inputFormatters: [
new LengthLimitingTextInputFormatter(13)
],
style: AppTheme.styleSubTitleBlackSmall,
decoration: const InputDecoration(
hintText: '090900909'
),
onChanged: denomPulsaBloc.prefix,
),
),
Align(
alignment: Alignment.centerRight,
child: Container(
alignment: Alignment.centerRight,
height: SizeConfig.texIconSize,
width: SizeConfig.texIconSize,
margin: EdgeInsets.only(right: SizeConfig.widthMultiplier * 9, top: SizeConfig.heightMultiplier * 1.5),
child: Image.asset(
"res/images/xl.png",
fit: BoxFit.fill,
)
),
),
Align(
alignment: Alignment.centerRight,
child: Container(
margin: EdgeInsets.only(top: SizeConfig.heightMultiplier * 1.5),
child: InkWell(
onTap: (){},
child: Icon(
Icons.close,
size: SizeConfig.texIconSize,
),
)
)
)
]),
),
]
),
)
),
],
),
),
),
),
Expanded(
child: Container(
width: SizeConfig.screenWidth,
height: SizeConfig.screenHeight,
child: StreamBuilder(
stream: denomPulsaBloc.subject,
builder: (context, AsyncSnapshot<List<Payload>> snapshot) {
if (snapshot.hasData) {
// print(snapshot.data);
return listDenomPulsa(snapshot);
}else{
Error();
}
return Container();
},
),
),
),
],
),
),
),
),
),
);
}

Flutter - material design 2 semi transparent appbar

I want to get effect like this - when scrolled up, appbar is transparent with listview visible below it:
And scrolled down, only white color - first item below appbar:
My window layout:
return Container(
color: AppTheme.nearlyWhite,
child: SafeArea(
top: false,
bottom: false,
child: Scaffold(
backgroundColor: AppTheme.nearlyWhite,
body: Stack(
children: <Widget>[
DrawerUserController(
screenIndex: _drawerIndex,
drawerWidth: MediaQuery.of(context).size.width * 0.75,
animationController: (AnimationController animationController) => _sliderAnimationController = animationController,
onDrawerCall: (DrawerIndex drawerIndexdata) => _onDrawerCall(drawerIndexdata, _forceRefresh),
onDrawerTap:(DrawerIndex drawerIndexdata) => _onDrawerTap(drawerIndexdata),
screenView: Column(
children: <Widget>[
Padding(
padding: EdgeInsets.fromLTRB(8, MediaQuery.of(context).padding.top + 8, 8, 8),
child: _createAppBar(),
),
Expanded(
child:
Container(
color: Colors.white,
child: _screenView,
)
),
],
),
),
new FabDialer(_fabMiniMenuItemList, Colors.blue, new Icon(Icons.add))
],
),
),
),
);
}
_screenView is simple Listview().builder() and it shows InkWell widget for each item. My appbar is custom, defined like this:
_createAppBar() {
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: Column(
children: <Widget>[
Text(
_menuSelected,
style: TextStyle(
fontSize: 22,
color: AppTheme.darkText,
fontWeight: FontWeight.w400,
),
),
Text(
globals.cityName,
style: TextStyle(
fontSize: 15,
color: AppTheme.darkerText,
fontWeight: FontWeight.w400,
),
),
],
),
),
),
),
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(Icons.refresh, color: AppTheme.dark_grey,),
onTap: () => setState(() => _forceRefresh = true),
),
),
),
),
],
),
);
}
That's how it looks now with first list item visible:
So, almost there, but when scrolled down, appbar won't be transparent:
I tried to mess around with setting my appbar backround to color with transparency, without success. Also I need to get my widgets actually overlapped (ListView needs to overlap my appbar) and it generates error messages from Flutter.
Any ideas how to do that properly?
set extendBodyBehindAppBar: true in Scaffold widget. Then use Opacity widget like this,
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(home: Home()));
}
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
#override
Widget build(BuildContext context) {
return Scaffold(
extendBodyBehindAppBar: true,
appBar: PreferredSize(
preferredSize: const Size.fromHeight(kToolbarHeight),
child: Opacity( //Wrap your `AppBar`
opacity: 0.8,
child: AppBar(
title: Text("Demo"),
),
),
),
body: ListView.builder(
itemCount: 30,
itemBuilder: (context, index) {
return ListTile(
title: Text("Tile: $index"),
);
},
),
);
}
}
#override
Widget build(BuildContext context) {
return Container(
child: Stack(
children:[
Container(
color:Colors.white,
padding:EdgeInsets.all(10),
child:ListView.builder(
itemCount:25+1,
//length + 1 is beacause to show 1st item at the beginning
shrinkWrap:true,
itemBuilder:(con,ind){
return ind==0 ?
Container(height:70)
:ListTile(
title:Text('Item $ind',
style:TextStyle(color:Colors.black,))
);
}
)
),
Container(
height:70,
color:Colors.transparent,
child:Card(
color:Colors.white.withAlpha(80),
child: Row(
children:[
Expanded(
flex:1,
child: IconButton(
icon:Icon(Icons.list,color:Colors.black,size:25),
onPressed:(){
//todo
}
),
),
Expanded(
flex:3,
child: Text('Title',
style:TextStyle(color:Colors.black,)),
),
Expanded(
flex:1,
child: IconButton(
icon:Icon(Icons.search,color:Colors.black,size:25),
onPressed:(){
//todo
}
),
),
Expanded(
flex:1,
child: IconButton(
icon:Icon(Icons.more_vert,color:Colors.black,size:25),
onPressed:(){
//todo
}
),
)
]
),
)
)
]
)
);
}

Getting error -- type 'SocketException' is not a subtype of type 'widget' in flutter

My App is working properly on laptops means in the simulator but not on android phone. This error started when I have added a JSON connection. please help me in solving it.
Android Screenshot (it's not working in android)
IOS working Screenshot (it's working in ios)
Someone told me to add below code
static const Map<String, String> header = {
'Content-type': 'application/json',
'Accept': 'application/json',
};
tried this but still no luck.
import 'package:flutter/material.dart';
import 'package:xxxxxxxx/product_page.dart';
import 'homepage_banner.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'categoryJson.dart';
import 'mCategory.dart';
import 'featuredItemJSON.dart';
class HomeScreenBanner extends StatelessWidget {
static const Map<String, String> header = {
'Content-type': 'application/json',
'Accept': 'application/json',
};
Future<List<CategoryAPI>> fetchPosts() async {
http.Response response = await http
.get('http://api-url-here');
var responseJson = json.decode(response.body);
return (responseJson as List).map((p) => CategoryAPI.fromJson(p)).toList();
}
Future<List<MiddleCategoryAPI>> mfetchPosts() async {
http.Response response = await http
.get('http://api-url-here');
var mresponseJson = json.decode(response.body);
return (mresponseJson as List).map((p) => MiddleCategoryAPI.fromJson(p)).toList();
}
Future<List<FeaturedItemAPI>> ffetchPosts() async {
http.Response response = await http
.get('http://api-url-here');
var fresponseJson = json.decode(response.body);
return (fresponseJson as List).map((p) => FeaturedItemAPI.fromJson(p)).toList();
}
#override
void initState() async {
fetchPosts();
mfetchPosts();
ffetchPosts();
}
Build Method as requested:
final scrollingofferbanner = HomePageBanner();
#override
Widget build(BuildContext context) {
return Container(
child: new ListView(
children: <Widget>[
Container(
height: 139.0,
margin: EdgeInsets.only(left: 0, right: 0, top: 5, bottom: 0),
padding: EdgeInsets.only(top: 0),
alignment: Alignment.center,
color: Color(0xfffefeff),
child: new ListView(
scrollDirection: Axis.horizontal,
children: <Widget>[
Container(
child: new FutureBuilder<List<CategoryAPI>>(
future: fetchPosts(),
builder: (context, snapshot) {
if (snapshot.hasData){
List<CategoryAPI> posts = snapshot.data;
return new Row(
children: posts.map((post) => new Column(
children: <Widget>[
//category circle starts
Padding(
padding: const EdgeInsets.all(9.0),
child: new GestureDetector(
onTap: () {
// Change the color of the container beneath
Navigator.of(context).push(
new MaterialPageRoute(
builder: (context) => new ProductPage(
//producttitle: post.title,
)
)
);
},
child: Column(
children: <Widget>[
Container(
width: 60.0,
height: 60.0,
child: Column(
children: <Widget>[
CircleAvatar(
radius: 30.0,
backgroundImage:
NetworkImage(post.productimg),
backgroundColor: Colors.transparent,
),
],
),
),
Container(
width: 100.0,
margin: EdgeInsets.only(
left: 0, right: 0, top: 13, bottom: 1),
child: Column(
children: <Widget>[
Container(
child: Text(post.title,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 13.0,
fontFamily: 'avenirblack',
color: Color(0xff535353),
)),
)
],
),
),
],
),
),
),
//category circle ends
],
)).toList()
);
}
else if(snapshot.hasError)
{
return snapshot.error;
}
return new Center(
child: new Column(
children: <Widget>[
new Padding(padding: new EdgeInsets.all(50.0)),
new CircularProgressIndicator(),
],
),
);
},
),
),
],
),
),
//top category menu starts
//top category menu ends
scrollingofferbanner,
//middle category menu starts
new Container(
height: 188.00,
margin: EdgeInsets.only(left: 0, right: 0, top: 5, bottom: 0),
padding: EdgeInsets.only(top: 0),
alignment: Alignment.center,
color: Color(0xfffefeff),
child: new ListView(
scrollDirection: Axis.horizontal,
children: <Widget>[
Container(
child: new FutureBuilder<List<MiddleCategoryAPI>>(
future: mfetchPosts(),
builder: (context, snapshot) {
if (snapshot.hasData){
List<MiddleCategoryAPI> posts = snapshot.data;
return new Row(
children: posts.map((post) => new Column(
children: <Widget>[
//category circle starts
Padding(
padding: const EdgeInsets.all(9.0),
child: Container(
width: 128.0,
child: Center(
child: Column(
children: <Widget>[
Container(
child: FadeInImage.assetNetwork(
placeholder: 'assets/loading.gif',
image: post.imagen,
),
),
//new Image.network(post.imagen),
Container(
margin: EdgeInsets.only(
left: 0, right: 0, top: 5, bottom: 1),
child: Text(post.title,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 15.0,
fontFamily: 'avenirblack',
color: Color(0xff535353))))
],
),
),
),
),
//category circle ends
],
)).toList()
);
}
else if(snapshot.hasError)
{
return snapshot.error;
}
return new Center(
child: new Column(
children: <Widget>[
new Padding(padding: new EdgeInsets.all(50.0)),
new CircularProgressIndicator(),
],
),
);
},
),
),
],
),
)
//middle category menu ends
,
//featured product list starts
new Container(
height: 300.0,
color: Color(0xffF1ECE7),
child: new Column(
children: <Widget>[
Container(
padding: EdgeInsets.fromLTRB(20, 15, 0, 5),
child: new Row(
children: <Widget>[
Container(
child: Text('FEATURED ITEMS',
style: TextStyle(
color: Color(0xffE18C21), fontSize: 20.0)),
),
],
),
),
Container(
height: 250.00,
margin:
EdgeInsets.only(left: 10, right: 0, top: 0, bottom: 0),
padding: EdgeInsets.only(top: 0),
alignment: Alignment.center,
child: new ListView(
scrollDirection: Axis.horizontal,
children: <Widget>[
//category circle starts
Container(
child: new FutureBuilder<List<FeaturedItemAPI>>(
future: ffetchPosts(),
builder: (context, snapshot) {
if (snapshot.hasData){
List<FeaturedItemAPI> posts = snapshot.data;
return new Row(
children: posts.map((post) => new Column(
children: <Widget>[
//category circle starts
Padding(
padding: const EdgeInsets.all(9.0),
child: Container(
width: 180.0,
child: Center(
child: new GestureDetector(
onTap: () {
// Change the color of the container beneath
Navigator.of(context).push(
new MaterialPageRoute(
builder: (context) => new ProductPage(
ProductTitle: post.name,
ProductPrice: post.productprice,
ProductCode: post.productcode,
ProductDescription: post.productdescription,
ProductImage: post.productimg,
ProductAltTag: post.alttags,
Productid: post.id,
)
)
);
},
child: new Column(
children: <Widget>[
Container(
child: FadeInImage.assetNetwork(
placeholder: 'assets/loading.gif',
image: post.productimg,
),
),
Container(
margin: EdgeInsets.only(top: 10),
child: new Text(post.name),
)
// Image.network(
// post.productimg, // On click should redirect to an URL
// )
],
),
),
),
),
),
//category circle ends
],
)).toList()
);
}
else if(snapshot.hasError)
{
return snapshot.error;
}
return new Center(
child: new Column(
children: <Widget>[
new Padding(padding: new EdgeInsets.all(50.0)),
new CircularProgressIndicator(),
],
),
);
},
),
)
//category circle ends
],
),
)
],
),
),
//featured product list ends
],
),
);
}
}
Actually, I don't why this problem arises but somewhere I had read and found this solution :
you need to add
In the AndroidManifest.xml file located at android/app/src/main you need to add this permission in tag.
<uses-permission android:name="android.permission.INTERNET"/>
Somewhere there's an exception in one of the fetch methods (perhaps 1+). So, as a result, the output of HomeScreenBanner is an exception rather than a widget.
There's no widget build method in the code. However, since you say it was working on the simulator, I assume you haven't posted the build method here.
Try to add a try catch block and check which fetch method(s) have exception. A set of print statements might help as well.