Я создаю пользовательский интерфейс приложения для покупок через FLUTTER, во время разработки выдает ошибку при использовании (product.tittle, product.image, product.price). ошибка говорит, что getter 'title' был вызван по null, то же самое для цены и изображения. вот мой код -
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:shopping/constants.dart';
import 'package:shopping/models/Product.dart';
class Body extends StatelessWidget {
final Product product;
const Body({Key key, this.product}) : super(key: key);
@override
Widget build(BuildContext context) {
// it provides us total height and width
Size size = MediaQuery.of(context).size;
return SingleChildScrollView(
child: Column(
children: [
SizedBox(
height: size.height,
child: Stack(
children: [
Container(
margin: EdgeInsets.only(top: size.height * 0.3),
height: 500,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(24),
topRight: Radius.circular(24),
),
),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: kDefaultPaddin),
child: Column(crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Aristocratic Hand Bag",
style: TextStyle(color: Colors.white),
),
Text(
product.title,
style: Theme.of(context).textTheme.headline4.copyWith(
color: Colors.white, fontWeight: FontWeight.bold
),),
Row(
children: [
RichText(text: TextSpan(
children: [
TextSpan(text: "Price\n"),
TextSpan(
text: "${product.price}",
style: Theme.of(context)
.textTheme
.headline4
.copyWith(
color: Colors.white,
fontWeight: FontWeight.bold
)
),
]
),),
SizedBox(width: kDefaultPaddin),
Expanded(child: Image.asset(product.image))
],
)
],
),
),
],
),
)
],
),
);
}
}'''
файл product.dart
import 'package:flutter/material.dart';
class Product {
final String image, title, description;
final int price, size, id;
final Color color;
Product({
this.id,
this.image,
this.title,
this.price,
this.description,
this.size,
this.color,
});
}
List<Product> products = [
Product(
id: 1,
title: "Office Code",
price: 234,
size: 12,
description: dummyText,
image: "assets/images/bag_1.png",
color: Color(0xFF3D82AE)),
Product(
id: 2,
title: "Belt Bag",
price: 234,
size: 8,
description: dummyText,
image: "assets/images/bag_2.png",
color: Color(0xFFD3A984)),
Product(
id: 3,
title: "Hang Top",
price: 234,
size: 10,
description: dummyText,
image: "assets/images/bag_3.png",
color: Color(0xFF989493)),
Product(
id: 4,
title: "Old Fashion",
price: 234,
size: 11,
description: dummyText,
image: "assets/images/bag_4.png",
color: Color(0xFFE6B398)),
Product(
id: 5,
title: "Office Code",
price: 234,
size: 12,
description: dummyText,
image: "assets/images/bag_5.png",
color: Color(0xFFFB7883)),
Product(
id: 6,
title: "Office Code",
price: 234,
size: 12,
description: dummyText,
image: "assets/images/bag_6.png",
color: Color(0xFFAEAEAE),
),
];
String dummyText =
"Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since. When an unknown printer took a galley.";
ошибка -
Performing hot restart...
Syncing files to device Android SDK built for x86 64...
Restarted application in 1,256ms.
════════ Exception caught by widgets library ═══════════════════════════════════════════════════════
The following NoSuchMethodError was thrown building Body(dirty, dependencies: [MediaQuery]):
The getter 'title' was called on null.
Receiver: null
Tried calling: title
The relevant error-causing widget was:
Body file:///home/nitin/AndroidStudioProjects/shopping/lib/Screens/home/details/details_screen.dart:33:13
When the exception was thrown, this was the stack:
#0 Object.noSuchMethod (dart:core-patch/object_patch.dart:51:5)
#1 Body.build (package:shopping/Screens/home/details/body.dart:41:32)
#2 StatelessElement.build (package:flutter/src/widgets/framework.dart:4638:28)
#3 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4564:15)
#4 Element.rebuild (package:flutter/src/widgets/framework.dart:4280:5)
...
════════════ = ═════════════════════════════════════════════════ ════════════════════════════════════
1.body.dart файл
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:shopping/Screens/home/components/categories.dart';
import 'package:shopping/Screens/home/components/item_card.dart';
import 'package:shopping/Screens/home/details/details_screen.dart';
import 'package:shopping/constants.dart';
import 'package:shopping/models/Product.dart';
class Body extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: kDefaultPaddin),
child: Text(
"Women",
style: Theme.of(context)
.textTheme
.headline5
.copyWith(fontWeight: FontWeight.bold),
),
),
Categories(),
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: kDefaultPaddin),
child: GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
mainAxisSpacing: kDefaultPaddin,
crossAxisSpacing: kDefaultPaddin,
childAspectRatio: 0.75,
),
itemCount: products.length,
itemBuilder: (context, [index]) => ItemCard(
product: products[index],
press: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailsScreen(
product: products[index],
)
)),
),
),
),
)
],
);
}
}
2.categories.dart
import 'package:flutter/material.dart';
import 'package:shopping/constants.dart';
class Categories extends StatefulWidget {
@override
_CategoriesState createState() => _CategoriesState();
}
class _CategoriesState extends State<Categories> {
List<String> categories = ["Hand Bags","Jewellery","Footwear","Dresses"];
int selectedIndex = 0 ;
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: kDefaultPaddin),
child: SizedBox(
height: 25.0,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: categories.length,
itemBuilder: (context , index) => GestureDetector( onTap: () {
setState(() {
selectedIndex = index ;
});
},
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: kDefaultPaddin),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
categories[index],
style: TextStyle(
fontWeight: FontWeight.bold,
color: selectedIndex == index ? kTextColor : kTextLightColor ,
),
),
Container(
margin: EdgeInsets.only(top: kDefaultPaddin/4),
height: 2,
width: 30,
color: selectedIndex == index ? Colors.black : Colors.transparent,
),
],
),
),
),
),
),
);
}
}
3 item_card.dart
import 'package:flutter/material.dart';
import 'package:shopping/constants.dart';
import 'package:shopping/models/Product.dart';
class ItemCard extends StatelessWidget {
final Product product;
final Function press;
const ItemCard ({
Key key,
this.product,
this.press,
}) : super(key : key);
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: press,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Container(
padding: EdgeInsets.all(kDefaultPaddin),
decoration: BoxDecoration(
color: product.color,
borderRadius: BorderRadius.circular(16.0)
),
child: Image.asset(product.image),
),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: kDefaultPaddin/4),
child: Text(
product.title,
style: TextStyle(color: kTextLightColor),
),
),
Text("₹${product.price}",
style: TextStyle(fontWeight: FontWeight.bold),)
],
),
);
}
}
4. подробный экран
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:shopping/Screens/home/details/body.dart';
import 'package:shopping/constants.dart';
import 'package:shopping/models/Product.dart';
class DetailsScreen extends StatelessWidget {
final Product product;
const DetailsScreen({Key key, this.product}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: product.color,
appBar: AppBar(
backgroundColor: product.color,
elevation: 0,
leading: IconButton(icon: SvgPicture.asset("assets/icons/back.svg",
color: Colors.white,),
onPressed:() => Navigator.pop(context) ),
actions: [IconButton(
icon: SvgPicture.asset("assets/icons/search.svg"),
onPressed: () {},
),
IconButton(
icon: SvgPicture.asset("assets/icons/cart.svg"),
onPressed: () {},
),
SizedBox(width: kDefaultPaddin/2),
],
),
body: Body(),
);
}
}
5 home_screen.dart
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:shopping/Screens/home/components/body.dart';
import 'package:shopping/constants.dart';
class HomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
elevation: 0,
leading: IconButton(
icon: SvgPicture.asset("assets/icons/back.svg"),
onPressed: () {},
),
actions: [
IconButton(
icon: SvgPicture.asset("assets/icons/search.svg",color: kTextColor,),
onPressed: null
),
SizedBox(width: kDefaultPaddin/ 2 )
],
),
body: Body(),
);
}
}
6 constant.dart
import 'package:flutter/material.dart';
const kTextColor = Color(0xFF535353);
const kTextLightColor = Color(0xFFACACAC);
const kDefaultPaddin = 20.0;
7 main.dart
import 'package:flutter/material.dart';
import 'package:shopping/Screens/home/home_screen.dart';
import 'package:shopping/constants.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
textTheme: Theme.of(context).textTheme.apply(bodyColor: kTextColor),
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: HomeScreen(),
);
}
}