I'm trying to implement the API found here into my home_page.dart found below using this flutter learners project for JSON parsing. You can find the full code at this GitHub Repo
Looking at the current picture below, I would like the end project 'Trending News' section to return the article picture from the API, as well as the title instead of 'Item 1', 'Item 2' etc...
I'm having issues with this version, as when I try to run for debug I get the issue; The getter length was called on null
home_page.dart;
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:one/cryptoData/crypto_data.dart';
import 'package:one/modules/crypto_presenter.dart';
import 'main.dart';
import 'dart:convert';
import 'background.dart';
import 'dart:async';
import 'package:http/http.dart' as http;
Future<List<Photo>> fetchPhotos(http.Client client) async {
final response =
await client.get('https://newsapi.org/v2/top-headlines?sources=crypto-coins-news&apiKey=d40a757cfb2e4dd99fc511a0cbf59098');
// Use the compute function to run parsePhotos in a separate isolate
return compute(parsePhotos, response.body);
}
// A function that will convert a response body into a List<Photo>
List<Photo> parsePhotos(String responseBody) {
final parsed = json.decode(responseBody).cast<Map<String, dynamic>>();
return parsed.map<Photo>((json) => Photo.fromJson(json)).toList();
}
class Photo {
final int albumId;
final int id;
final String title;
final String url;
final String thumbnailUrl;
Photo({this.albumId, this.id, this.title, this.url, this.thumbnailUrl});
factory Photo.fromJson(Map<String, dynamic> json) {
return Photo(
albumId: json['albumId'] as int,
id: json['id'] as int,
title: json['title'] as String,
url: json['url'] as String,
thumbnailUrl: json['thumbnailUrl'] as String,
);
}
}
class HomePage extends StatefulWidget {
#override
_HomePageState createState() => new _HomePageState();
}
class _HomePageState extends State<HomePage> implements CryptoListViewContract {
CryptoListPresenter _presenter;
List<Crypto> _currencies;
bool _isLoading;
final List<MaterialColor> _colors = [Colors.blue, Colors.indigo, Colors.red];
final List<Photo> photos;
_HomePageState() {
_presenter = new CryptoListPresenter(this);
}
List<String> items = [
"Item 1",
"Item 2",
"Item 3",
"Item 4",
"Item 5",
"Item 6",
"Item 7",
"Item 8"
];
#override
void initState() {
super.initState();
_isLoading = true;
_presenter.loadCurrencies();
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Crypto App",
style: new TextStyle(
color: Colors.white,
fontFamily: 'Poppins',
fontSize: 22.5,
),
),
backgroundColor: const Color(0xFF273A48),
elevation: 0.0,
centerTitle: true,
),
body: _isLoading
? new Center(
child: new CircularProgressIndicator(),
)
: _allWidget()
);
}
Widget _allWidget() {
final _width = MediaQuery.of(context).size.width;
final _height = MediaQuery.of(context).size.height;
//CRYPTO FEED CRYPTO FEED CRYPTO FEED CRYPTO FEED CRYPTO FEED CRYPTO FEED CRYPTO FEED CRYPTO FEED CRYPTO FEED CRYPTO FEED CRYPTO FEED CRYPTO FEED CRYPTO FEED CRYPTO FEED
final headerList = new ListView.builder(
itemBuilder: (context, index) {
EdgeInsets padding = index == 0?const EdgeInsets.only(
left: 20.0, right: 10.0, top: 4.0, bottom: 30.0):const EdgeInsets.only(
left: 10.0, right: 10.0, top: 4.0, bottom: 30.0);
return new Padding(
padding: padding,
child: new InkWell(
onTap: () {
print('Card selected');
},
child: new Container(
decoration: new BoxDecoration(
borderRadius: new BorderRadius.circular(10.0),
color: Colors.lightGreen,
boxShadow: [
new BoxShadow(
color: Colors.black.withAlpha(70),
offset: const Offset(3.0, 10.0),
blurRadius: 15.0)
],
image: new DecorationImage(
image: new ExactAssetImage(
'assets/img_${index%items.length}.jpg'),
fit: BoxFit.fitHeight,
),
),
// height: 200.0,
width: 200.0,
child: new Stack(
children: <Widget>[
new Align(
alignment: Alignment.bottomCenter,
child: new Container(
decoration: new BoxDecoration(
color: const Color(0xFF273A48),
borderRadius: new BorderRadius.only(
bottomLeft: new Radius.circular(10.0),
bottomRight: new Radius.circular(10.0))),
height: 30.0,
child: new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Text(
'${items[index%items.length]}',
style: new TextStyle(color: Colors.white),
)
],
)),
)
],
),
),
),
);
},
scrollDirection: Axis.horizontal,
itemCount: photos.length,
);
final body = new Scaffold(
backgroundColor: Colors.transparent,
body: new Container(
child: new Stack(
children: <Widget>[
new Padding(
padding: new EdgeInsets.only(top: 10.0),
child: new Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
new Align(
alignment: Alignment.centerLeft,
child: new Padding(
padding: new EdgeInsets.only(left: 10.0,),
child: new Text(
"Trending News",
style: new TextStyle(
letterSpacing: 0.8,
fontFamily: 'Kanit',
fontSize: 17.5,
color: Colors.white,
),
)
),
),
new Container(
height: 300.0, width: _width, child: headerList),
new Expanded(child:
ListView.builder(
itemBuilder: (BuildContext context, int index) {
final int i = index;
final Crypto currency = _currencies[i];
final MaterialColor color = _colors[i % _colors.length];
return new ListTile(
title: new Column(
children: <Widget>[
new Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new Container(
height: 72.0,
width: 72.0,
decoration: new BoxDecoration(
color: Colors.white,
boxShadow: [
new BoxShadow(
color:
Colors.black.withAlpha(80),
offset: const Offset(2.0, 2.0),
blurRadius: 15.0)
],
borderRadius: new BorderRadius.all(
new Radius.circular(35.0)),
image: new DecorationImage(
image: new ExactAssetImage(
"cryptoiconsBlack/"+currency.symbol.toLowerCase()+"#2x.png",
),
fit: BoxFit.cover,
)),
),
new SizedBox(
width: 8.0,
),
new Expanded(
child: new Column(
mainAxisAlignment:
MainAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.start,
children: <Widget>[
new Text(
currency.name,
style: new TextStyle(
fontSize: 14.0,
fontFamily: 'Poppins',
color: Colors.black87,
fontWeight: FontWeight.bold),
),
_getSubtitleText(currency.price_usd, currency.percent_change_1h),
],
)),
],
),
new Divider(),
],
),
);
}))
],
),
),
],
),
),
);
return new Container(
decoration: new BoxDecoration(
color: const Color(0xFF273A48),
),
child: new Stack(
children: <Widget>[
new CustomPaint(
size: new Size(_width, _height),
painter: new Background(),
),
body,
],
),
);
}
// CRYPTO FEED CRYPTO FEED CRYPTO FEED CRYPTO FEED CRYPTO FEED CRYPTO FEED CRYPTO FEED CRYPTO FEED CRYPTO FEED CRYPTO FEED CRYPTO FEED CRYPTO FEED CRYPTO FEED CRYPTO FEED
Widget _getSubtitleText(String priceUSD, String percentageChange) {
TextSpan priceTextWidget = new TextSpan(
text: "\$$priceUSD\n", style: new TextStyle(color: Colors.black));
String percentageChangeText = "1 hour: $percentageChange%";
TextSpan percentageChangeTextWidget;
if (double.parse(percentageChange) > 0) {
percentageChangeTextWidget = new TextSpan(
text: percentageChangeText,
style: new TextStyle(color: Colors.green));
} else {
percentageChangeTextWidget = new TextSpan(
text: percentageChangeText, style: new TextStyle(color: Colors.red));
}
return new RichText(
text: new TextSpan(
children: [priceTextWidget, percentageChangeTextWidget]));
}
//DONT TOUCH, Works with cryptoListViewContract implimentation in _MyHomePageState
#override
void onLoadCryptoComplete(List<Crypto> items) {
// TODO: implement onLoadCryptoComplete
setState(() {
_currencies = items;
_isLoading = false;
});
}
#override
void onLoadCryptoError() {
// TODO: implement onLoadCryptoError
}
}
Last working version of the app;
Thanks, Jake
The list photos is null in your case. It is not initialized anywhere. I think you forgot to call fetchPhotos() method which returns List<Photo>. That's why null pointer exception occured.
Try changing everywhere where you have
.length
to
(... ?.length ?? 0)
Like
itemCount: photos?.length ?? 0,
final MaterialColor color = _colors[i % (_colors?.length ?? 0)];
'assets/img_${index % (items?.length ?? 0)}.jpg'),
...
replace
class Photo {
final int albumId;
final int id;
final String title;
final String url;
final String thumbnailUrl;
Photo({this.albumId, this.id, this.title, this.url, this.thumbnailUrl});
factory Photo.fromJson(Map<String, dynamic> json) {
return Photo(
albumId: json['albumId'] as int,
id: json['id'] as int,
title: json['title'] as String,
url: json['url'] as String,
thumbnailUrl: json['thumbnailUrl'] as String,
);
}
}
with:
class Photo {
final String albumId;
final String id;
final String title;
final String url;
final String thumbnailUrl;
Photo({this.albumId, this.id, this.title, this.url, this.thumbnailUrl});
factory Photo.fromJson(Map<String, dynamic> json) {
return Photo(
albumId: json['albumId'] as String,
id: json['id'] as String,
title: json['title'] as String,
url: json['url'] as String,
thumbnailUrl: json['thumbnailUrl'] as String,
);
}
}
Related
I am following a course video from YouTube to design a shopping cart in Flutter. But according to the course video, I am supposed to see the output showing the pictures of the items, their prices, units, and other details [shown in picture 1]. But in my output I am seeing nothing but only the AppBar title [shown in picture 2].
The output in the YouTube course video:
My Output:
I have attached the entire code below, please help fix my mistake.
main.dart
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:shopping_cart/cart_provider.dart';
import 'package:shopping_cart/cart_screen.dart';
import 'package:shopping_cart/product_list.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (_) => CartProvider(),
child: Builder(builder: (BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(),
debugShowCheckedModeBanner: false,
home: const CartScreen(),
);
}),
);
}
}
product_list.dart
import 'package:badges/badges.dart';
import 'package:flutter/material.dart' hide Badge;
import 'package:provider/provider.dart';
import 'package:shopping_cart/cart_model.dart';
import 'package:shopping_cart/db_helper.dart';
import 'cart_provider.dart';
import 'cart_screen.dart';
class ProductListScreen extends StatefulWidget {
const ProductListScreen({super.key});
#override
State<ProductListScreen> createState() => _ProductListScreenState();
}
class _ProductListScreenState extends State<ProductListScreen> {
DBHelper? dbHelper = DBHelper();
List<String> productName = [
'Mango',
'Orange',
'Grapes',
'Banana',
'Chery',
'Peach',
'Mixed Fruit Basket'
];
List<String> productUnit = [
'KG',
'Dozen',
'KG',
'Dozen',
'KG',
'KG',
'KG',
];
List<int> productPrice = [10, 20, 30, 40, 50, 60, 70];
List<String> productImage = [
'https://image.shutterstock.com/image-photo/mango-isolated-on-white-background-600w-610892249.jpg',
'https://image.shutterstock.com/image-photo/orange-fruit-slices-leaves-isolated-600w-1386912362.jpg',
'https://image.shutterstock.com/image-photo/green-grape-leaves-isolated-on-600w-533487490.jpg',
'https://media.istockphoto.com/photos/banana-picture-id1184345169?s=612x612',
'https://media.istockphoto.com/photos/cherry-trio-with-stem-and-leaf-picture-id157428769?s=612x612',
'https://media.istockphoto.com/photos/single-whole-peach-fruit-with-leaf-and-slice-isolated-on-white-picture-id1151868959?s=612x612',
'https://media.istockphoto.com/photos/fruit-background-picture-id529664572?s=612x612',
];
#override
Widget build(BuildContext context) {
final cart = Provider.of<CartProvider>(context); // reference
return Scaffold(
appBar: AppBar(
title: const Text("Product List"),
centerTitle: true,
backgroundColor: Colors.deepPurple,
actions: [
InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => CartScreen(),
),
);
},
child: Center(
child: Badge(
badgeContent: Consumer<CartProvider>(
builder: (context, value, child) {
return Text(
value.getCounter().toString(),
style: const TextStyle(
color: Colors.white,
fontSize: 15,
fontWeight: FontWeight.bold,
),
);
},
),
badgeAnimation: const BadgeAnimation.fade(
animationDuration: Duration(milliseconds: 300),
),
child: const Icon(
Icons.shopping_cart_outlined,
size: 30,
),
),
),
),
const SizedBox(width: 20),
],
),
body: Column(
children: [
Expanded(
child: ListView.builder(
itemCount: productName.length,
itemBuilder: ((context, index) {
return Card(
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: [
Image(
height: 100,
width: 100,
image:
NetworkImage(productImage[index].toString()),
),
const SizedBox(
width: 15,
),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
productName[index],
style: const TextStyle(fontSize: 23),
),
const SizedBox(
height: 5,
),
Text(
productUnit[index] +
" " r"$" +
productPrice[index].toString(),
style: const TextStyle(fontSize: 23),
),
const SizedBox(
height: 10,
),
Align(
alignment: Alignment.centerRight,
child: InkWell(
onTap: () {
dbHelper!
.insert(Cart(
id: index,
productId: index.toString(),
productName: productName[index]
.toString(),
initialPrice:
productPrice[index],
productPrice:
productPrice[index],
quantity: 1,
unitTag: productUnit[index]
.toString(),
image: productImage[index]
.toString()))
.then((value) {
print("Product is Added to Cart");
cart.addTotalPrice(double.parse(
productPrice[index].toString()));
cart.addCounter();
}).onError((error, stackTrace) {
print(error.toString());
});
},
child: Container(
height: 35,
width: 130,
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(50),
color: Colors.green,
),
child: const Center(
child: Text(
"Add to Cart",
style: TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.w500),
),
),
),
),
)
],
),
)
],
)
],
),
),
);
}),
),
),
Consumer<CartProvider>(builder: (context, value, child) {
return Column(
children: [
ReusableWidget(
'subtotal',
r'$' + value.getTotalPrice().toStringAsFixed(2),
),
],
);
})
],
),
);
}
}
class ReusableWidget extends StatelessWidget {
final String title, value;
const ReusableWidget(this.title, this.value, {super.key});
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 4),
child: Row(
children: [
Text(
title,
style: Theme.of(context).textTheme.titleSmall,
),
Text(
value,
style: Theme.of(context).textTheme.titleSmall,
)
],
),
);
}
}
db_helper.dart
import 'package:sqflite/sqflite.dart';
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart';
import 'dart:io' as io;
import 'cart_model.dart';
class DBHelper {
static Database? _db;
Future<Database?> get db async {
_db = await initDatabase();
if (_db != null) {
return _db!;
}
}
initDatabase() async {
io.Directory documentDirectory = await getApplicationDocumentsDirectory();
String path = join(documentDirectory.path, 'cart.db');
var db = await openDatabase(path, version: 1, onCreate: _onCreate);
return db;
}
// Method
_onCreate(Database db, int version) async {
await db.execute(
'CREATE TABLE cart (id INTEGER PRIMARY KEY, productId VARCHAR UNIQUE, productName TEXT, initialPrice INTEGER, productPrice INTEGER, quantity INTEGER, unitTag TEXT, image TEXT)',
);
}
Future<Cart> insert(Cart cart) async {
print(cart.toMap());
var dbClient = await db;
await dbClient!.insert('cart', cart.toMap());
return cart;
}
Future<List<Cart>> getCartList() async {
var dbClient = await db;
final List<Map<String, Object?>> queryResult =
await dbClient!.query("cart");
return queryResult.map((e) => Cart.fromMap(e)).toList();
}
}
cart_screen.dart
import 'package:badges/badges.dart';
import 'package:flutter/material.dart' hide Badge;
import 'package:provider/provider.dart';
import 'cart_model.dart';
import 'cart_provider.dart';
class CartScreen extends StatefulWidget {
const CartScreen({super.key});
#override
State<CartScreen> createState() => _CartScreenState();
}
class _CartScreenState extends State<CartScreen> {
#override
Widget build(BuildContext context) {
final cart = Provider.of<CartProvider>(context);
return Scaffold(
appBar: AppBar(
title: const Text("My Products"),
centerTitle: true,
backgroundColor: Colors.deepPurple,
actions: [
Center(
child: Badge(
badgeContent: Consumer<CartProvider>(
builder: (context, value, child) {
return Text(
value.getCounter().toString(),
style: const TextStyle(
color: Colors.white,
fontSize: 15,
fontWeight: FontWeight.bold,
),
);
},
),
badgeAnimation: const BadgeAnimation.fade(
animationDuration: Duration(milliseconds: 300),
),
child: const Icon(
Icons.shopping_cart_outlined,
size: 30,
),
),
),
const SizedBox(width: 20),
],
),
body: Column(
children: [
FutureBuilder(
future: cart.getData(),
builder: (context, AsyncSnapshot<List<Cart>> snapshot) {
if (snapshot.hasData) {
return Expanded(
child: ListView.builder(
itemCount: snapshot.data!.length,
itemBuilder: ((context, index) {
return Card(
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: [
Image(
height: 100,
width: 100,
image: NetworkImage(
snapshot.data![index].image.toString(),
),
),
const SizedBox(
width: 15,
),
Expanded(
child: Column(
mainAxisAlignment:
MainAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
snapshot.data![index].productName
.toString(),
),
const SizedBox(
height: 5,
),
Text(
snapshot.data![index].unitTag
.toString() +
" " r"$" +
snapshot.data![index].productPrice
.toString(),
style: const TextStyle(fontSize: 23),
),
const SizedBox(
height: 10,
),
Align(
alignment: Alignment.centerRight,
child: InkWell(
onTap: () {},
child: Container(
height: 35,
width: 130,
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(50),
color: Colors.green,
),
child: const Center(
child: Text(
"Add to Cart",
style: TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight:
FontWeight.w500),
),
),
),
),
)
],
),
)
],
)
],
),
),
);
}),
),
);
} else {
return const Text("Shahzain");
}
},
)
],
),
);
}
}
cart_provider.dart
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:shopping_cart/cart_model.dart';
import 'package:shopping_cart/db_helper.dart';
class CartProvider with ChangeNotifier {
DBHelper db = DBHelper(); // DBHelper() is a class
int _counter = 0;
int get counter => _counter;
double _totalPrice = 0.0;
double get totalPrice => _totalPrice;
late Future<List<Cart>> _cart;
Future<List<Cart>> get cart => _cart; // => means to indicate
Future<List<Cart>> getData() async {
_cart = db.getCartList();
return _cart;
}
void _setPrefItems() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setInt('cart_item', _counter);
prefs.setDouble('total_price', _totalPrice);
notifyListeners();
}
void _getPrefItems() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
// giving initial value by ?? 0 for null safety
_counter = prefs.getInt('cart_item') ?? 0;
// giving initial value by ?? 0.0 for null safety
_totalPrice = prefs.getDouble('total_price') ?? 0.0;
notifyListeners();
}
void addTotalPrice(double productPrice) {
_totalPrice = _totalPrice + productPrice;
_setPrefItems();
notifyListeners();
}
void removeTotalPrice(double productPrice) {
_totalPrice = _totalPrice - productPrice;
_setPrefItems();
notifyListeners();
}
double getTotalPrice() {
_getPrefItems();
return _totalPrice;
}
void addCounter() {
// initial value of counter was 0, will be incremented to 1, and will be stored to sharedPreferences
_counter++;
_setPrefItems();
notifyListeners();
}
void removeCounter() {
_counter--;
_setPrefItems();
notifyListeners();
}
int getCounter() {
_getPrefItems();
return _counter;
}
}
cart_model.dart
class Cart {
late final int? id;
final String? productId;
final String? productName;
final int? initialPrice;
final int? productPrice;
final int? quantity;
final String? unitTag;
final String? image;
// Creating the constructor
Cart({
required this.id, // primary key
required this.productId,
required this.productName,
required this.initialPrice,
required this.productPrice,
required this.quantity,
required this.unitTag,
required this.image,
});
Cart.fromMap(Map<dynamic, dynamic> res) // res = resources
: id = res['id'],
productId = res['productId'],
productName = res['productName'],
initialPrice = res['initialPrice'],
productPrice = res['productPrice'],
quantity = res['quantity'],
unitTag = res['unitTag'],
image = res['image'];
Map<String, Object?> toMap(){
return {
'id' : id,
'productId' : productId,
'productName' : productName,
'initialPrice' : initialPrice,
'productPrice' : productPrice,
'quantity' : quantity,
'unitTag' : unitTag,
'image' : image
};
}
}
in your main.dart file
you set,
home: const CartScreen(),
and the video tutorial you have followed, he sets home: ProductListsScreen()
Fix this and I hope your problem will be solved,
also, be sure where to use const
i am working on a project and my problem is related to Nested Object in api. I want to get message from my data object and it is not accessible and my model class don't give no thing about message. Actually I want from this line
"data":"{"message":"Saim12345 Has a Confirmed Appointment with you Dated 15-06-2022 at 06:20 PM at Online Video Consultation"}", .
Only the message value such as "Saim12345 Has a Confirmed Appointment with you Dated 15-06-2022 at 06:20 PM at Online Video Consultation"
I have tried JsonEcode to get its Index but not working well and i am also Created Seperate class of Data and created String message but that accesseed but gives null error if anybody can help me please response me as soon as possible
For Further This is
my Model Class
List<NotificationModel> notificationModelFromJson(String str) => List<NotificationModel>.from(json.decode(str).map((x) => NotificationModel.fromJson(x)));
String notificationModelToJson(List<NotificationModel> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class NotificationModel {
NotificationModel({
this.id,
this.type,
this.notifiableType,
this.notifiableId,
this.data,
this.readAt,
this.createdAt,
this.updatedAt,
});
double id;
String type;
String notifiableType;
int notifiableId;
String data;
DateTime readAt;
DateTime createdAt;
DateTime updatedAt;
factory NotificationModel.fromJson(Map<String, dynamic> json) => NotificationModel(
id: json["id"].toDouble(),
type: json["type"],
notifiableType: json["notifiable_type"],
notifiableId: json["notifiable_id"],
data: json["data"],
readAt: DateTime.parse(json["read_at"]),
createdAt: DateTime.parse(json["created_at"]),
updatedAt: DateTime.parse(json["updated_at"]),
);
Map<String, dynamic> toJson() => {
"id": id,
"type": type,
"notifiable_type": notifiableType,
"notifiable_id": notifiableId,
"data": data,
"read_at": readAt.toIso8601String(),
"created_at": createdAt.toString(),
"updated_at": updatedAt.toString(),
};
}
This my Class
class PatientNotification extends StatefulWidget {
final int notificationModelId;
const PatientNotification({Key key, this.notificationModelId}) : super(key: key);
#override
State<PatientNotification> createState() => _PatientNotificationState();
}
class _PatientNotificationState extends State<PatientNotification> {
NotificationModel notification;
List<NotificationModel> notificationModelList = [];
bool loading = true;
Map mapResponse;
void getNotifications() async {
notificationModelList = [];
Network network = new Network();
var response = await network.getData("/notifications");
log(response.body);
if (response.statusCode == 200) {
var json = cnv.jsonDecode(response.body);
// try{
if (json != null) {
json.forEach((element) {
notificationModelList.add(new NotificationModel.fromJson(element));
});
print(notificationModelList.length);
}
// }catch(e){
// // log(e);
// }
}
setState(() {
notificationModelList = notificationModelList;
// datalist=datalist;
loading = false;
});
}
#override
void initState() {
getNotifications();
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: Icon(
Icons.arrow_back_rounded,
color: AppColor.primary,
//size: .0,
// semanticLabel: 'Text to announce in accessibility modes',
),
),
TextButton(
onPressed: getNotifications,
child: Text(
"Notifications",
textAlign: TextAlign.left,
style: TextStyle(
fontSize: 24,
letterSpacing: 0.7,
color: Colors.black),
),
),
],
),
SizedBox(
height: 10,
),
Expanded(child: SingleChildScrollView(
child: Container(
height: MediaQuery
.of(context)
.size
.height * 0.8,
child: loading ? AppWidgetsCard.getProgressIndicator()
: notificationModelList.isEmpty
? AppWidgetsCard.getEmptyCard('Notification') :
ListView.builder(
itemCount: notificationModelList.length,
itemBuilder: (context, index) {
NotificationModel data = notificationModelList[index];
String dateFormate = DateFormat()
.add_yMMMEd()
.format(DateTime.parse(
data.createdAt.toString()));
String time = DateFormat()
.add_jm()
.format(DateTime.parse(
data.createdAt.toString()));
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
),
height: 110,
width: MediaQuery
.of(context)
.size
.width,
padding: EdgeInsets.symmetric(
horizontal: 1, vertical: 5),
child: Card(
elevation: 5,
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(15.0),
),
child: Row(
children: [
Container(
height: 100,
width: 100,
decoration: BoxDecoration(
borderRadius:
BorderRadius.only(
bottomLeft:
Radius.circular(15),
topLeft:
Radius.circular(15),
// topRight:
// Radius.circular(15),
// bottomRight:
// Radius.circular(15),
),
image: DecorationImage(
image: NetworkImage(
'https://emedz.net/images/doctors/male-avi.jpg'),
fit: BoxFit.fill
)
),
),
Expanded(
child: Padding(
padding:
const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment:
MainAxisAlignment
.spaceBetween,
children: [
Expanded(
child: Column(
mainAxisAlignment:
MainAxisAlignment
.spaceBetween,
crossAxisAlignment:
CrossAxisAlignment
.start,
children: [
Text(
data.data,
style: TextStyle(
fontSize: 12,
color: Colors
.black,
fontWeight:
FontWeight
.bold),
),
Expanded(
child:
SizedBox()),
Text('',
style: TextStyle(
fontSize: 10,
color: Colors
.blue),
),
Text(
'$dateFormate at $time ',
maxLines: 2,
style: TextStyle(
fontSize: 14,
),
),
],
),
),
],
),
),
),
],
),
),
);
}))
),
)
],
),
));
}
}
Unfortunately your data is String you have to convert it to json and parse it
so do this
dataJson = data.substring(1, data.length-1); //it will remove double quotes from string
then send this json to Data Model using......
final dataModel = dataModelFromJson(dataJson);// this line where you pass dataJson
Below is your Data Model Class.......
DataModel dataModelFromJson(String str) =>
DataModel.fromJson(json.decode(str));
String dataModelToJson(DataModel data) => json.encode(data.toJson());
class DataModel {
DataModel({
#required this.message,
});
String message;
factory DataModel.fromJson(Map<String, dynamic> json) => DataModel(
message: json["message"],
);
Map<String, dynamic> toJson() => {
"message": message,
};
}
I have resolved it in way such as
and printed my message
This is the result that i want Saim12345 Has a Confirmed Appointment with you Dated 15-06-2022 at 06:20 PM at Online Video Consultation
if (json != null) {
json.forEach((element) {
Map obj= element;
message=obj['data'];
message = message.replaceRange(0, 12, '');
message = message.replaceRange((message.length-2), message.length, '');
print(message);
// var klk= cnv.jsonDecode(plm);
print(message.toString());
notificationModelList.add(new NotificationModel.fromJson(element));
});
print(notificationModelList.length);
}
I have this code for expansion panel list which is working fine but I am not able to extend the size of the expansion panel. Also, I want the expansion panel to have a border radius but I am not sure if border radius can be given
return Column(children: [
Stack(
clipBehavior: Clip.none,
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 50),
child: ExpansionPanelList(
animationDuration: Duration(milliseconds: 1000),
children: [
ExpansionPanel(
headerBuilder: (context, isExpanded) {
return Column(
children: [
Text("Salmon Poké"),
Text("Rs. 2000"),
],
);
},
body: Text(
'This salmon sashimi is a delicious light appetizer served with fresh wasabi, ginger, soy sauce or a delicious side of soy yuzo citrus ponzu.',
style: TextStyle(
fontSize: 18,
color: Colors.black,
),
),
isExpanded: _expanded,
canTapOnHeader: true,
backgroundColor: Colors.white),
],
dividerColor: Colors.grey,
expansionCallback: (panelIndex, isExpanded) {
_expanded = !_expanded;
setState(() {});
},
),
),
Positioned(
top: -55,
right: 240,
child: CircleAvatar(
radius: 105,
child: ClipOval(
child: Image(
image: AssetImage('assets/images/salmon.png'),
),
),
backgroundColor: Colors.transparent,
),
),
],
),
]);
}
}
**Here is the UI for the given code **
This is the output I have.
Here is the output which I want. (This UI is made using container widgets but I want this layout using expansion panel list)
This is the output that I want
I really appreciate your help.
For border radius we need to make custom expansion list
import 'package:flutter/material.dart';
const double _kPanelHeaderCollapsedHeight = 48.0;
const double _kPanelHeaderExpandedHeight = 64.0;
class CustomExpansionPanelList extends StatelessWidget {
const CustomExpansionPanelList(
{Key key,
this.children: const <ExpansionPanel>[],
this.expansionCallback,
this.animationDuration: kThemeAnimationDuration})
: assert(children != null),
assert(animationDuration != null),
super(key: key);
final List<ExpansionPanel> children;
final ExpansionPanelCallback expansionCallback;
final Duration animationDuration;
bool _isChildExpanded(int index) {
return children[index].isExpanded;
}
#override
Widget build(BuildContext context) {
final List<Widget> items = <Widget>[];
const EdgeInsets kExpandedEdgeInsets = const EdgeInsets.symmetric(
vertical: _kPanelHeaderExpandedHeight - _kPanelHeaderCollapsedHeight);
for (int index = 0; index < children.length; index += 1) {
if (_isChildExpanded(index) && index != 0 && !_isChildExpanded(index - 1))
items.add(new Divider(
key: new _SaltedKey<BuildContext, int>(context, index * 2 - 1),
height: 15.0,
color: Colors.transparent,
));
final Row header = new Row(
children: <Widget>[
new Expanded(
child: new AnimatedContainer(
duration: animationDuration,
curve: Curves.fastOutSlowIn,
margin: _isChildExpanded(index)
? kExpandedEdgeInsets
: EdgeInsets.zero,
child: new SizedBox(
height: _kPanelHeaderCollapsedHeight,
child: children[index].headerBuilder(
context,
children[index].isExpanded,
),
),
),
),
new Container(
margin: const EdgeInsetsDirectional.only(end: 8.0),
child: new ExpandIcon(
isExpanded: _isChildExpanded(index),
padding: const EdgeInsets.all(16.0),
onPressed: (bool isExpanded) {
if (expansionCallback != null)
expansionCallback(index, isExpanded);
},
),
),
],
);
double _radiusValue = _isChildExpanded(index)? 8.0 : 0.0;
items.add(
new Container(
key: new _SaltedKey<BuildContext, int>(context, index * 2),
child: new Material(
elevation: 2.0,
borderRadius: new BorderRadius.all(new Radius.circular(_radiusValue)),
child: new Column(
children: <Widget>[
header,
new AnimatedCrossFade(
firstChild: new Container(height: 0.0),
secondChild: children[index].body,
firstCurve:
const Interval(0.0, 0.6, curve: Curves.fastOutSlowIn),
secondCurve:
const Interval(0.4, 1.0, curve: Curves.fastOutSlowIn),
sizeCurve: Curves.fastOutSlowIn,
crossFadeState: _isChildExpanded(index)
? CrossFadeState.showSecond
: CrossFadeState.showFirst,
duration: animationDuration,
),
],
),
),
),
);
if (_isChildExpanded(index) && index != children.length - 1)
items.add(new Divider(
key: new _SaltedKey<BuildContext, int>(context, index * 2 + 1),
height: 15.0,
));
}
return new Column(
children: items,
);
}
}
class _SaltedKey<S, V> extends LocalKey {
const _SaltedKey(this.salt, this.value);
final S salt;
final V value;
#override
bool operator ==(dynamic other) {
if (other.runtimeType != runtimeType) return false;
final _SaltedKey<S, V> typedOther = other;
return salt == typedOther.salt && value == typedOther.value;
}
#override
int get hashCode => hashValues(runtimeType, salt, value);
#override
String toString() {
final String saltString = S == String ? '<\'$salt\'>' : '<$salt>';
final String valueString = V == String ? '<\'$value\'>' : '<$value>';
return '[$saltString $valueString]';
}
}
Now use this widget in your application
import 'package:color_essence/customViews/CustomExpansionList.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
class ExpansionPanelDemo extends StatefulWidget {
#override
_ExpansionPanelDemoState createState() => _ExpansionPanelDemoState();
}
class _ExpansionPanelDemoState extends State<ExpansionPanelDemo> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Expansion Panel Demo'),
),
body: Container(
padding: EdgeInsets.all(10),
child: ListView.builder(
itemCount: itemData.length,
itemBuilder: (BuildContext context, int index) {
return CustomExpansionPanelList(
animationDuration: Duration(milliseconds: 1000),
children: [
ExpansionPanel(
body: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(20)),
),
padding: EdgeInsets.all(10),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
ClipOval(
child: CircleAvatar(
child: Image.asset(
itemData[index].img,
fit: BoxFit.cover,
),
),
),
SizedBox(
height: 30,
),
Text(
itemData[index].discription,
style: TextStyle(
color: Colors.grey[700],
fontSize: 15,
letterSpacing: 0.3,
height: 1.3),
),
],
),
),
headerBuilder: (BuildContext context, bool isExpanded) {
return Container(
padding: EdgeInsets.all(10),
child: Text(
itemData[index].headerItem,
style: TextStyle(
color: itemData[index].colorsItem,
fontSize: 18,
),
),
);
},
isExpanded: itemData[index].expanded,
)
],
expansionCallback: (int item, bool status) {
setState(() {
itemData[index].expanded = !itemData[index].expanded;
});
},
);
},
),
),
);
}
List<ItemModel> itemData = <ItemModel>[
ItemModel(
headerItem: 'Android',
discription:
"Android is a mobile operating system based on a modified version of the Linux kernel and other open source software, designed primarily for touchscreen mobile devices such as smartphones and tablets. ... Some well known derivatives include Android TV for televisions and Wear OS for wearables, both developed by Google.",
colorsItem: Colors.green,
img: 'assets/images/android_img.png'
),
];
}
class ItemModel {
bool expanded;
String headerItem;
String discription;
Color colorsItem;
String img;
ItemModel({this.expanded: false, this.headerItem, this.discription,this.colorsItem,this.img});
}
Wrap the ExpansionPanelList in a ClipRRect.
ClipRRect(
borderRadius: BorderRadius.circular(8),
child: ExpansionPanelList(
children: [ExpansionPanel(body: Text('Hello World'))])
)
I'm here with more questions flutter questions. Today, I'm having issues with Animator. I'm trying to have a little heart symbol animate for my post liking code, but I keep getting the following errors.
Compiler message:
../../../developer/flutter/.pub-cache/hosted/pub.dartlang.org/animator-0.1.4/lib/animator.dart:457:7: Error: No named parameter with the name 'blocs'.
blocs: [_animatorBloc],
^^^^^
../../../developer/flutter/.pub-cache/hosted/pub.dartlang.org/states_rebuilder-1.15.0/lib/src/state_with_mixin_builder.dart:142:3: Context: Found this candidate, but the arguments don't match.
StateWithMixinBuilder({
^^^^^^^^^^^^^^^^^^^^^
../../../developer/flutter/.pub-cache/hosted/pub.dartlang.org/animator-0.1.4/lib/animator.dart:494:27: Error: Method not found: 'StatesRebuilder.addToListeners'.
StatesRebuilder.addToListeners(
^^^^^^^^^^^^^^
../../../developer/flutter/.pub-cache/hosted/pub.dartlang.org/animator-0.1.4/lib/animator.dart:559:27: Error: Method not found: 'StatesRebuilder.removeFromListeners'.
StatesRebuilder.removeFromListeners(b, widget.name, "$hashCode");
^^^^^^^^^^^^^^^^^^^
I have attempted to run flutter clean with no avail and I could not find the best answers online. I attempted to update my pubspec.yaml, but that messed up a whole lot of my code in the project. I want to see what everyone else has to think.
Post.dart - looking at buildPostImage
class Post extends StatefulWidget {
final String postId;
final String ownerId;
final String userName;
final String location;
final String description;
final String mediaUrl;
final dynamic likes;
Post({
this.postId,
this.ownerId,
this.userName,
this.location,
this.description,
this.mediaUrl,
this.likes,
});
factory Post.fromDocument(DocumentSnapshot doc){
return Post(
postId: doc['postId'],
ownerId: doc['ownerId'],
userName: doc['username'],
location: doc['location'],
description: doc['description'],
mediaUrl: doc['mediaUrl'],
likes: doc['likes'],
);
}
int getLikeCount(likes) {
// if no likes, return 0
if(likes == null){
return 0;
}
int count = 0;
//if like explicitly set to true, add a like
likes.values.forEach((val){
if(val == true){
count += 1;
}
});
return count;
}
#override
_PostState createState() => _PostState(
postId: this.postId,
ownerId: this.ownerId,
userName: this.userName,
location: this.location,
description: this.description,
mediaUrl: this.mediaUrl,
likeCount: getLikeCount(this.likes),
likes: this.likes
);
}
class _PostState extends State<Post> {
final String currentUserId = currentUser?.id;
final String postId;
final String ownerId;
final String userName;
final String location;
final String description;
final String mediaUrl;
int likeCount;
Map likes;
bool isLiked;
bool showHeart = false;
_PostState({
this.postId,
this.ownerId,
this.userName,
this.location,
this.description,
this.mediaUrl,
this.likes,
this.likeCount,
});
buildPostHeader(){
return FutureBuilder(
future: usersRef.document(ownerId).get(),
builder: (context, snapshot){
if(!snapshot.hasData){
return circularProgress(context);
}
User user = User.fromDocument(snapshot.data);
return ListTile(
leading: CircleAvatar(
backgroundImage: CachedNetworkImageProvider(user.photoUrl),
backgroundColor: Colors.grey,
),
title: GestureDetector(
child: Text(
user.username,
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold
),
),
),
subtitle: Text(location),
trailing: IconButton(
onPressed: () => print("deleting post"),
icon: Icon(Icons.more_vert),
),
);
},
);
}
handleLikePosts() {
bool _isLiked = likes[currentUserId] == true;
if (_isLiked) {
postsRef.document(ownerId)
.collection('userPosts')
.document(postId)
.updateData({'likes.$currentUserId': false});
setState(() {
likeCount -= 1;
isLiked = false;
likes[currentUserId] = false;
});
} else if (!_isLiked) {
postsRef.document(ownerId)
.collection('userPosts')
.document(postId)
.updateData({'likes.$currentUserId': true});
setState(() {
likeCount += 1;
isLiked = true;
likes[currentUserId] = true;
showHeart = true;
});
Timer(Duration(milliseconds: 500),(){
setState(() {
showHeart = false;
});
});
}
}
buildPostImage() {
return GestureDetector(
onDoubleTap: handleLikePosts,
child: Stack(
alignment: Alignment.center,
children: <Widget>[
cachedNetworkImage(mediaUrl),
showHeart
? Animator(
duration: Duration(milliseconds: 300),
tween: Tween(begin: 0.8, end: 1.4),
curve: Curves.elasticOut,
cycles: 0,
builder: (anim) => Transform.scale(
scale: anim.value,
child: Icon(
Icons.favorite,
size: 80.0,
color: Colors.red,
),
),
)
: Text(""),
],
),
);
}
buildPostFooter() {
return Column(
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Padding(padding: EdgeInsets.only(top: 40.0, left: 20.0)),
GestureDetector(
onTap: handleLikePosts,
child: Icon(
isLiked ? Icons.favorite : Icons.favorite_border,
size: 28.0,
color: Colors.pink,
),
),
Padding(padding: EdgeInsets.only(right: 20.0)),
GestureDetector(
onTap: () => print('Showing comments'),
child: Icon(
Icons.chat,
size: 28.0,
color: Colors.blue[900],
),
),
],
),
Row(
children: <Widget>[
Container(
margin: EdgeInsets.only(left: 20.0),
child: Text(
"$likeCount likes ",
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
),
),
),
],
),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
margin: EdgeInsets.only(left: 20.0),
child: Text(
"$userName ",
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
),
),
),
Expanded(
child: Text(description),
)
],
)
],
);
}
#override
Widget build(BuildContext context) {
isLiked = (likes[currentUserId] == true);
return Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
buildPostHeader(),
buildPostImage(),
buildPostFooter(),
],
);
}
}
Thank you all for the help.
It looks like you are using 0.1.4 Version of Animator Package. Update it to the latest version which is 2.0.1 ( visit here for Animator Package Updates ).
Animator(
duration: Duration(milliseconds: 300),
tween: Tween(begin: 0.8, end: 1.5),
curve: Curves.elasticOut,
cycles: 0,
builder: (context, anim, child) => Transform.scale(
scale: anim.value,
child: Icon(Icons.favorite, color: Colors.pink, size: 100.0,),
),
)
Check if it works!
I am writing a flutter app that is listing the whole players of a card game. And if no players are inside the database, then there should be a text that is saying, that is no data found. But my problem is inside the getStatistik(). That function is returning no data.
This is my code where I want to display the player in sort of a ranking:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:watten/model/statistik.dart';
import 'package:watten/database/database.dart';
import 'package:watten/statistik/deleteStatistikDialog.dart';
Future<List<Statistik>> fetchStatistik() async{
var dbHelper = DBHelper();
List<Statistik> statistik = await dbHelper.getStatistik();
print("Length: "+statistik.length.toString()");
return statistik;
}
class Spielerstatistik extends StatefulWidget{
#override
State<StatefulWidget> createState() => _Spielerstatistik();
}
class _Spielerstatistik extends State<Spielerstatistik>{
List statistik;
var dbHelper = DBHelper();
bool datenVorhanden = true;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: new AppBar(
backgroundColor: Color(0xFF9C27B0),
title: new Text("Ranking")
),
body: new FutureBuilder<List<Statistik>>(
future: fetchStatistik(),
builder: (context, snapshot){
if(snapshot.hasData){
return new Column(
children: <Widget>[
new Expanded(
child: new ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
return new Card(
color: Colors.red,
child: new Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
ListTile(
leading: platzNr
? platzierung
: new Text(" ${index+1}"),
title: new Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
new Container(
child: new Text(
snapshot.data[index].name,
style: TextStyle(color: Colors.black),
overflow: TextOverflow.ellipsis,
),
width: 80.0,
),
new Padding(padding: EdgeInsets.only(left: 45.0)),
new Container(
child: new Text(
snapshot.data[index].spielanzahl.toString(),
style: TextStyle(color: Colors.black),
overflow: TextOverflow.ellipsis,
),
width: 55.0,
),
new Container(
decoration: new BoxDecoration(
border: new Border(
left: BorderSide(color: Colors.black26)
)
),
height: 40.0,
margin: EdgeInsets.only(right: 22.0),
),
new Container(
child: new Text(
snapshot.data[index].gewonneneSpiele.toString(),
style: TextStyle(color: textfarbe),
overflow: TextOverflow.ellipsis,
),
width: 12.0,
margin: EdgeInsets.only(right: 20.0),
),
new Container(
decoration: new BoxDecoration(
border: new Border(
left: BorderSide(color: Colors.black26)
)
),
height: 40.0,
margin: EdgeInsets.only(right: 8.0),
),
new Container(
child: new Text(
snapshot.data[index].erfolgsquote.roundToDouble().toString() + " %",//Erfolgsquote
style: TextStyle(color: Colors.black),
overflow: TextOverflow.ellipsis,
),
width: 65.0,
),
],
)
)
],
),
);
}
)
)
],
);
} else if(snapshot.data.length == 0){
return new Text("No Data found!");
}
return new Container(alignment: AlignmentDirectional.center,child: new CircularProgressIndicator(),);
}
),
);
}
}
And this is my code where I get the data for the database from:
Future<List<Statistik>> getStatistik() async{
var dbClient = await db;
List<Map> list = await dbClient.rawQuery('SELECT * FROM statistik');
List<Statistik> statistik = new List();
for(int i = 0; i<list.length; i++){
statistik.add(new Statistik(name: list[i]["$statistikName"] , spielanzahl: list[i]["$statistikSpielanzahl"], gewonneneSpiele: list[i]["$statistikWins"], erfolgsquote: list[i]["erfolgsquote"]));
}
return statistik;
}
My thoughts are that the FutureBuilder is not even making a real call, because print("Length: "+statistik.length.toString()"); that I built in, wasn't printing anything.
when snapshot.hasData is false, snapshot.data equals null. Therefore you can't do
if (snapshot.hasData) {} else if (snapshot.data.length > 0) {}
Instead just do a if (snapshot.hasData == false)
I think that there is no need to use $. Try the below code snippet. It is explained here in detail.
Future<List<Statistik>> getStatistik() async{
var dbClient = await db;
List<Map> list = await dbClient.rawQuery('SELECT * FROM statistik');
List<Statistik> statistik = new List();
for(int i = 0; i<list.length; i++){
statistik.add(new Statistik(name: list[i]["statistikName"] , spielanzahl: list[i]["statistikSpielanzahl"], gewonneneSpiele: list[i]["statistikWins"], erfolgsquote: list[i]["erfolgsquote"]));
}
return statistik;
}