i have 4 List and i want to change them by tapping on gesturedetector on tap event, but i receive an error. I tried call setState , but as i understood only stateful widget can do it. This lists already receive i just want to rebuild widget, i tried use it from state, but it also won't work.
error
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:vltest/Models/_request.dart';
import 'package:vltest/settings.dart';
import 'package:http/http.dart' as http;
import 'Models/_workers.dart';
import 'database.dart';
List<Requests> ActiveRequests = List.empty();
List<Requests> ClosedRequests = List.empty();
List<Requests> ActiveRequestsTO = List.empty();
List<Requests> ClosedRequestsTO = List.empty();
class RequestsPage extends StatefulWidget {
const RequestsPage();
#override
_RequestsPageState createState() => _RequestsPageState();
}
class _RequestsPageState extends State<RequestsPage> {
ScrollController controller = ScrollController();
bool closeTopContainer = false;
double topContainer = 0;
List<Widget> itemsData = [];
void getPostsData(List<Requests> list) {
List<Requests> responseList = list;
List<Widget> listItems = [];
responseList.forEach((post) {
listItems.add(Container(
height: 150,
margin: const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(20.0)),
color: Colors.white,
boxShadow: [
BoxShadow(color: Colors.black.withAlpha(100), blurRadius: 10.0),
]),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20.0, vertical: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
post.shopAddress,
style: const TextStyle(
fontSize: 15, fontWeight: FontWeight.bold),
),
SizedBox(
height: 10,
),
Text(
post.problemPart,
style: const TextStyle(
fontSize: 12,
color: Colors.red,
fontWeight: FontWeight.bold),
),
SizedBox(
height: 10,
),
Text(
post.serialNumber,
style: const TextStyle(
fontSize: 15,
color: Colors.black,
fontWeight: FontWeight.bold),
)
],
),
//requestPhoto(post)
],
),
)));
});
setState(() {
itemsData = listItems;
});
}
void updatePostsData(List<Requests> list) {
List<Requests> responseList = list;
List<Widget> listItems = [];
responseList.forEach((post) {
GenerateRequestCards(listItems, post);
});
}
void GenerateRequestCards(List<Widget> listItems, Requests post) {
listItems.add(Container(
height: 150,
margin: const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(20.0)),
color: Colors.white,
boxShadow: [
BoxShadow(color: Colors.black.withAlpha(100), blurRadius: 10.0),
]),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20.0, vertical: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
post.shopAddress,
style: const TextStyle(
fontSize: 15, fontWeight: FontWeight.bold),
),
SizedBox(
height: 10,
),
Text(
post.problemPart,
style: const TextStyle(
fontSize: 12,
color: Colors.red,
fontWeight: FontWeight.bold),
),
SizedBox(
height: 10,
),
Text(
post.serialNumber,
style: const TextStyle(
fontSize: 15,
color: Colors.black,
fontWeight: FontWeight.bold),
)
],
),
//requestPhoto(post)
],
),
)));
setState(() {
itemsData = listItems;
});
}
Image requestPhoto(Requests post) {
if (post.imageUrl == "") {
return Image.network(
post.imageUrl,
height: double.infinity,
);
} else {
return Image.network(
"https://i.ibb.co/TctYZfx/Logo-Main-3-1.jpg",
height: double.infinity,
);
}
}
#override
void initState() {
super.initState();
WidgetsBinding.instance
.addPostFrameCallback((_) => loadUserInfo().then((value) {
setState(() {});
}));
controller.addListener(() {
double value = controller.offset / 119;
setState(() {
topContainer = value;
closeTopContainer = controller.offset > 50;
});
});
}
#override
Widget build(BuildContext context) {
final Size size = MediaQuery.of(context).size;
final double categoryHeight = size.height * 0.30;
return SafeArea(
child: Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
elevation: 0,
backgroundColor: Colors.white,
leading: Icon(
Icons.arrow_back,
color: Colors.black,
),
actions: <Widget>[
IconButton(
icon: Icon(Icons.search, color: Colors.black),
onPressed: () {},
),
IconButton(
icon: Icon(Icons.person, color: Colors.black),
onPressed: () {},
)
],
),
body: Container(
height: size.height,
child: Column(
children: <Widget>[
const SizedBox(
height: 10,
),
AnimatedOpacity(
duration: const Duration(milliseconds: 200),
opacity: closeTopContainer ? 0 : 1,
child: AnimatedContainer(
duration: const Duration(milliseconds: 200),
width: size.width,
alignment: Alignment.topCenter,
height: closeTopContainer ? 0 : categoryHeight,
child: CategoriesScroller(
ActiveRequests: ActiveRequests,
ClosedRequests: ClosedRequests,
ActiveRequestsTO: ActiveRequestsTO,
ClosedRequestsTO: ClosedRequestsTO),
),
),
Expanded(
child: ListView.builder(
controller: controller,
itemCount: itemsData.length,
physics: BouncingScrollPhysics(),
itemBuilder: (context, index) {
double scale = 1.0;
if (topContainer > 0.5) {
scale = index + 0.5 - topContainer;
if (scale < 0) {
scale = 0;
} else if (scale > 1) {
scale = 1;
}
}
return Opacity(
opacity: scale,
child: Transform(
transform: Matrix4.identity()..scale(scale, scale),
alignment: Alignment.bottomCenter,
child: Align(
heightFactor: 0.7,
alignment: Alignment.topCenter,
child: itemsData[index]),
),
);
})),
],
),
),
),
);
}
Future<void> loadUserInfo() async {
Workers workers = await DBProvider.db.getWorkerInfo();
ActiveRequests = await getRequestsInfo(workers, "repair", "active");
ClosedRequests = await getRequestsInfo(workers, "repair", "closed");
ActiveRequestsTO = await getRequestsInfo(workers, "maintenance", "active");
ClosedRequestsTO = await getRequestsInfo(workers, "maintenance", "closed");
getPostsData(ActiveRequests);
setState(() {});
}
Future<void> updateLoadersData() async {
Workers workers = await DBProvider.db.getWorkerInfo();
ActiveRequests = await getRequestsInfo(workers, "repair", "active");
ClosedRequests = await getRequestsInfo(workers, "repair", "closed");
ActiveRequestsTO = await getRequestsInfo(workers, "maintenance", "active");
ClosedRequestsTO = await getRequestsInfo(workers, "maintenance", "closed");
setState(() {});
}
Future<List<Requests>> getRequestsInfo(
Workers workers, String type, String status) async {
Map data = {
'login': workers.login,
'type': type,
'status': status,
};
//encode Map to JSON
var body = json.encode(data);
final response = await http.post(
Uri.parse(GlobalSettings.serverHTTP + 'api/requests/list'),
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer ${workers.token}"
},
body: body);
if (response.statusCode == 200) {
Iterable l = json.decode(response.body);
List<Requests> loaders =
List<Requests>.from(l.map((model) => Requests.fromJson(model)));
return loaders;
} else {
throw Exception('Failed to load album');
}
}
List<T> map<T>(List list, Function handler) {
List<T> result = [];
for (var i = 0; i < list.length; i++) {
result.add(handler(i, list[i]));
}
return result;
}
}
class CategoriesScroller extends StatelessWidget {
const CategoriesScroller({
Key? key,
required this.ActiveRequests,
required this.ClosedRequests,
required this.ActiveRequestsTO,
required this.ClosedRequestsTO,
}) : super(key: key);
final List<Requests> ActiveRequests;
final List<Requests> ClosedRequests;
final List<Requests> ActiveRequestsTO;
final List<Requests> ClosedRequestsTO;
#override
Widget build(BuildContext context) {
final double categoryHeight =
MediaQuery.of(context).size.height * 0.30 - 50;
return SingleChildScrollView(
physics: BouncingScrollPhysics(),
scrollDirection: Axis.horizontal,
child: Container(
margin: const EdgeInsets.symmetric(vertical: 20, horizontal: 20),
child: FittedBox(
fit: BoxFit.fill,
alignment: Alignment.topCenter,
child: Row(
children: <Widget>[
Container(
width: 150,
margin: EdgeInsets.only(right: 20),
height: categoryHeight,
decoration: BoxDecoration(
color: Colors.orange.shade400,
borderRadius: BorderRadius.all(Radius.circular(20.0))),
child: Padding(
padding: const EdgeInsets.all(12.0),
child: GestureDetector(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"Active",
style: TextStyle(
fontSize: 18,
color: Colors.white,
fontWeight: FontWeight.bold),
),
SizedBox(
height: 10,
),
Text(
"Repair",
style: TextStyle(
fontSize: 15,
color: Colors.white,
fontWeight: FontWeight.bold),
),
SizedBox(
height: 10,
),
Text(
ActiveRequests.length.toString(),
style: TextStyle(fontSize: 16, color: Colors.white),
),
],
),
onTap: () {
List<Widget> list = [];
ActiveRequests.forEach((element) {
_RequestsPageState()
.GenerateRequestCards(list, element);
});
},
),
),
),
Container(
width: 150,
margin: EdgeInsets.only(right: 20),
height: categoryHeight,
decoration: BoxDecoration(
color: Colors.orange.shade400,
borderRadius: BorderRadius.all(Radius.circular(20.0))),
child: Padding(
padding: const EdgeInsets.all(12.0),
child: GestureDetector(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"Closed",
style: TextStyle(
fontSize: 18,
color: Colors.white,
fontWeight: FontWeight.bold),
),
SizedBox(
height: 10,
),
Text(
"Repair",
style: TextStyle(
fontSize: 15,
color: Colors.white,
fontWeight: FontWeight.bold),
),
SizedBox(
height: 10,
),
Text(
ClosedRequests.length.toString(),
style: TextStyle(fontSize: 16, color: Colors.white),
),
],
),
onTap: () {
List<Widget> list = [];
ClosedRequests.forEach((element) {
_RequestsPageState()
.GenerateRequestCards(list, element);
});
},
),
),
),
Container(
width: 150,
margin: EdgeInsets.only(right: 20),
height: categoryHeight,
decoration: BoxDecoration(
color: Colors.orange.shade400,
borderRadius: BorderRadius.all(Radius.circular(20.0))),
child: Padding(
padding: const EdgeInsets.all(12.0),
child: GestureDetector(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"Active",
style: TextStyle(
fontSize: 18,
color: Colors.white,
fontWeight: FontWeight.bold),
),
SizedBox(
height: 10,
),
Text(
"Maintenance",
style: TextStyle(
fontSize: 15,
color: Colors.white,
fontWeight: FontWeight.bold),
),
SizedBox(
height: 10,
),
Text(
ActiveRequestsTO.length.toString(),
style: TextStyle(fontSize: 16, color: Colors.white),
),
],
),
onTap: () {
List<Widget> list = [];
ActiveRequestsTO.forEach((element) {
_RequestsPageState()
.GenerateRequestCards(list, element);
});
},
),
),
),
Container(
width: 150,
margin: EdgeInsets.only(right: 20),
height: categoryHeight,
decoration: BoxDecoration(
color: Colors.orange.shade400,
borderRadius: BorderRadius.all(Radius.circular(20.0))),
child: Padding(
padding: const EdgeInsets.all(12.0),
child: GestureDetector(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"Closed",
style: TextStyle(
fontSize: 18,
color: Colors.white,
fontWeight: FontWeight.bold),
),
SizedBox(
height: 10,
),
Text(
"Maintenance",
style: TextStyle(
fontSize: 15,
color: Colors.white,
fontWeight: FontWeight.bold),
),
SizedBox(
height: 10,
),
Text(
ClosedRequestsTO.length.toString(),
style: TextStyle(fontSize: 16, color: Colors.white),
),
],
),
onTap: () {
List<Widget> list = [];
ClosedRequestsTO.forEach((element) {
_RequestsPageState()
.GenerateRequestCards(list, element);
});
},
),
),
),
],
),
),
),
);
}
}
Give me an advice please...
Call setState after checking if it is mouted or not, like
if (mounted) {
setState(() {});
}
Sorry for long delay, honestly, i forgot about conversation, i solve problem by rewrite code , in statefull widget
Related
i have implement a List from api and it gives me actual response which is working fine. but when i implemented a list search on it. Then the list doesn't show up when i open that screen. but when i start searching it gives me the correct search results.
here is my code:
import 'dart:convert';
import 'package:fb_installer_phase1/api/controller/user_auth_controller.dart';
import 'package:fb_installer_phase1/api/model/technician.dart';
import 'package:fb_installer_phase1/views/user_management/add_user_screen.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:http/http.dart' as http;
import 'package:shared_preferences/shared_preferences.dart';
import '../../api/network_calls/api_configration.dart';
import '../../utils/app_constants.dart';
import '../../utils/color_resourse.dart';
class UserListScreen extends StatefulWidget {
const UserListScreen({Key? key}) : super(key: key);
#override
State<UserListScreen> createState() => _UserListScreenState();
}
class _UserListScreenState extends State<UserListScreen> {
final TextEditingController searchController = TextEditingController();
String keyword = '';
bool isDataLoading = false;
List<TechData> _technicians = <TechData>[];
List<TechData> _techniciansList = <TechData>[];
Future getData() async {
SharedPreferences preferences = await SharedPreferences.getInstance();
bearerToken = preferences.getString(AppConstants.appToken)!;
String url = AppConstants.baseUrl + AppConstants.allTechnicianListApi;
try {
final response = await http.get(Uri.parse(url), headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Bearer $bearerToken',
});
debugPrint("Token: $bearerToken");
debugPrint("Response::: ${response.body}");
TechnicianModel model = TechnicianModel.fromJson(
jsonDecode(response.body));
_technicians = model.data!;
setState(() {
isDataLoading = false;
isDataLoading = !isDataLoading;
});
print("hello...: ${_technicians.length}");
} catch (exception) {
print(exception);
}
}
#override
void initState() {
getAllTechniciansData();
getData();
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(
backgroundColor: ColorResources.primaryColor,
child: Center(
child: Icon(
Icons.add,
size: 25.h,
),
),
onPressed: () {
Get.to(() => const AddUserScreen());
},
),
appBar: AppBar(
flexibleSpace: Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
stops: [
0.2,
0.7,
1,
],
colors: [
Color(0XFF3DDA76),
Color(0XFF6DD2D1),
Color(0XFF41B1A1),
],
)),
),
centerTitle: true,
backgroundColor: ColorResources.primaryColor,
title: const Text("User List"),
systemOverlayStyle: SystemUiOverlayStyle.light,
),
body: Column(
children: [
SizedBox(
height: 20.h,
),
_createSearchbar(),
SizedBox(
height: 15.h,
),
Container(
width: double.infinity,
margin: EdgeInsets.symmetric(horizontal: 15.w),
height: 35.h,
color: const Color(0xffF2F2F2),
child: Row(
children: [
Container(
width: 80.w,
height: double.infinity,
color: Colors.transparent,
alignment: Alignment.centerLeft,
padding: EdgeInsets.only(left: 10.w),
child: Text(
"Name",
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.w600,
fontSize: 12.sp),
),
),
Container(
width: 170.w,
height: double.infinity,
color: Colors.transparent,
alignment: Alignment.centerLeft,
padding: EdgeInsets.only(left: 10.w),
child: Text(
"Email",
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.w600,
fontSize: 12.sp),
),
),
Container(
height: double.infinity,
color: Colors.transparent,
alignment: Alignment.centerLeft,
padding: EdgeInsets.only(left: 10.w),
child: Text(
"App Status",
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.w600,
fontSize: 12.sp),
),
)
],
),
),
_userListView(),
],
),
);
}
#override
void dispose() {
super.dispose();
FocusScope.of(context).unfocus();
}
Container _createSearchbar() {
return Container(
height: 50.h,
margin: EdgeInsets.symmetric(horizontal: 15.w),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.white,
border: Border.all(color: ColorResources.grey300)),
child: Row(
children: [
SizedBox(
height: 50.h,
width: 40.h,
child: const Center(
child: Icon(
Icons.search,
color: ColorResources.primaryColor,
),
),
),
Expanded(
child: TextField(
decoration: InputDecoration(
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
errorBorder: InputBorder.none,
disabledBorder: InputBorder.none,
contentPadding:
EdgeInsets.only(left: 15.w, bottom: 11.h, top: 11, right: 15),
hintText: "Search here",
),
onChanged: searchTechnicians,
)),
],
),
);
}
TextEditingController controller = TextEditingController();
Widget _userListView() {
return isDataLoading || _techniciansList.isNotEmpty || controller.text.isNotEmpty
? Expanded(child: ListView.builder(
itemCount: _techniciansList.length ,
itemBuilder: (context, index) {
if (_techniciansList.isNotEmpty) {
return Container(
margin: EdgeInsets.symmetric(horizontal: 15.w),
height: 32.h,
//color: const Color(0xffF2F2F2),
child: Row(
children: [
Container(
width: 80.w,
height: double.infinity,
color: Colors.transparent,
alignment: Alignment.centerLeft,
padding: EdgeInsets.only(left: 10.w),
child: Text(
_techniciansList[index].name!,
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.w400,
overflow: TextOverflow.ellipsis,
fontSize: 11.sp),
),
),
Container(
width: 170.w,
height: double.infinity,
color: Colors.transparent,
alignment: Alignment.centerLeft,
padding: EdgeInsets.only(left: 10.w),
child: Text(
_techniciansList[index].email!,
overflow: TextOverflow.ellipsis,
maxLines: 2,
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.w400,
fontSize: 11.sp),
),
),
Expanded(
child: Container(
height: double.infinity,
color: Colors.transparent,
alignment: Alignment.centerLeft,
padding: EdgeInsets.only(left: 5.w),
child: Text(
_techniciansList[index].phone! ?? '',
style: TextStyle(
color: Colors.black,
overflow: TextOverflow.ellipsis,
fontWeight: FontWeight.w400,
fontSize: 11.sp),
),
),
)
],
),
);
} else {
return const SizedBox();
}
}
))
: const Expanded(
child: Center(child: CircularProgressIndicator(
color: ColorResources.primaryColor,)),
);
}
searchTechnicians(String text) {
_techniciansList.clear();
if (text.isEmpty) {
setState(() {
});
return;
}
_technicians.forEach((element) {
if (element.name!.contains(text)
|| element.email!.contains(text)
|| element.phone!.contains(text)) {
_techniciansList.add(element);
}
});
print("searchresults: ${_techniciansList.length}");
setState(() {
});
}
}
Because initially your _techniciansList.length will be zero and your list view is depend on _techniciansList.length.
If you want to show the list you have to manage conditions like
if controller.text.isEmpty than show ListView with all product list
You need check if search field is empty pass _technicians, like this:
Widget _userListView() {
return isDataLoading ||
_techniciansList.isNotEmpty ||
controller.text.isNotEmpty ||
_technicians.isNotEmpty
? Expanded(
child: ListView.builder(
itemCount: controller.text.isEmpty
? _technicians.length
: _techniciansList.length,
itemBuilder: (context, index) {
if (_techniciansList.isNotEmpty || _technicians.isNotEmpty) {
return Container(
margin: EdgeInsets.symmetric(horizontal: 15.w),
height: 32.h,
//color: const Color(0xffF2F2F2),
child: Row(
children: [
Container(
width: 80.w,
height: double.infinity,
color: Colors.transparent,
alignment: Alignment.centerLeft,
padding: EdgeInsets.only(left: 10.w),
child: Text(
controller.text.isEmpty
? _technicians[index].name!
: _techniciansList[index].name!,
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.w400,
overflow: TextOverflow.ellipsis,
fontSize: 11.sp),
),
),
Container(
width: 170.w,
height: double.infinity,
color: Colors.transparent,
alignment: Alignment.centerLeft,
padding: EdgeInsets.only(left: 10.w),
child: Text(
controller.text.isEmpty
? _technicians[index].email!
: _techniciansList[index].email!,
overflow: TextOverflow.ellipsis,
maxLines: 2,
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.w400,
fontSize: 11.sp),
),
),
Expanded(
child: Container(
height: double.infinity,
color: Colors.transparent,
alignment: Alignment.centerLeft,
padding: EdgeInsets.only(left: 5.w),
child: Text(
controller.text.isEmpty
? _technicians[index].phone! ?? ''
: _techniciansList[index].phone! ?? '',
style: TextStyle(
color: Colors.black,
overflow: TextOverflow.ellipsis,
fontWeight: FontWeight.w400,
fontSize: 11.sp),
),
),
)
],
),
);
} else {
return const SizedBox();
}
}))
: const Expanded(
child: Center(
child: CircularProgressIndicator(
color: ColorResources.primaryColor,
)),
);
}
I am trying to scrape a countdown website using Flutter webscraper package. I successfully scraped the images and titles, but couldn't scrape the timer running, as it changes according to the timer, so after doing some research I saw that if I disable the JavaScript I can scrape the counter but I'm unable to do so..
class _SchedulesState extends State<Schedules> {
late List<Map<String, dynamic>> scheduleWall = [];
late List<Map<String, dynamic>> scheduleEpisode = [];
late List<Map<String, dynamic>> scheduleName = [];
late List<Map<String, dynamic>> scheduleDay = [];
late List<Map<String, dynamic>> scheduleHour = [];
late List<Map<String, dynamic>> scheduleMins = [];
bool scheduleLoaded = false;
int page = 1;
void scheduleFetch() async {
final scheduleScraper = WebScraper("https://animecountdown.com");
isJavaScriptSimpleObject(false);
if (await scheduleScraper.loadWebPage("")) {
scheduleWall = scheduleScraper.getElement(
'countdown-content-main-columns-column-items-item-left-poster > img',
['src'],
);
scheduleName = scheduleScraper.getElement(
'countdown-content-main-columns-column-items-item-right > countdown-content-main-columns-column-items-item-right-title',
['title'],
);
scheduleEpisode = scheduleScraper.getElement(
'countdown-content-main-columns-column-items-item-right > countdown-content-main-columns-column-items-item-right-episode',
['title'],
);
scheduleDay = scheduleScraper.getElement(
'div.countdown-item.day > div.countdown-item-number',
['title'],
);
scheduleHour = scheduleScraper.getElement(
'div.countdown-item.hour > div.countdown-item-number',
['title'],
);
scheduleMins = scheduleScraper.getElement(
'div.countdown-item.min > div.countdown-item-number',
['title'],
);
// ignore: avoid_print
print(scheduleName);
setState(() {
scheduleLoaded = true;
});
}
}
#override
void initState() {
super.initState();
scheduleFetch();
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: const Color(0xff121212),
body: scheduleLoaded
? SafeArea(
child: SingleChildScrollView(
child: Wrap(
children: [
for (int i = 0; i < scheduleWall.length; i++)
Padding(
padding: const EdgeInsets.only(
left: 25.0, top: 20.0, right: 25.0, bottom: 20.0),
child: ClipRRect(
borderRadius: BorderRadius.circular(20.0),
child: Stack(
children: [
CachedNetworkImage(
imageUrl: "https:" +
scheduleWall[i]['attributes']['src'],
color: Colors.grey,
colorBlendMode: BlendMode.multiply,
fit: BoxFit.cover,
width: 400,
height: 450.0,
placeholder: (context, url) {
return const Padding(
padding: EdgeInsets.all(8.0),
child: Center(
child: SpinKitPulse(
size: 40.0,
color: Colors.cyan,
),
),
);
},
),
Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Center(
child: Text(scheduleName[i]['title'],
maxLines: 2,
style: const TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white,
fontSize: 30.0)),
),
),
const SizedBox(
height: 115.0,
),
Center(
child: Text(scheduleEpisode[i]['title'],
style: const TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white,
fontSize: 30.0)),
),
const SizedBox(height: 140),
Row(
children: [
Padding(
padding:
const EdgeInsets.only(left: 85.0),
child: Text(scheduleEpisode[i]['title'],
style: const TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white,
fontSize: 2.0)),
),
Padding(
padding:
const EdgeInsets.only(left: 50.0),
child: Text(scheduleEpisode[i]['title'],
style: const TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white,
fontSize: 2.0)),
),
Padding(
padding:
const EdgeInsets.only(left: 50.0),
child: Text(scheduleEpisode[i]['title'],
style: const TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white,
fontSize: 2.0)),
),
const SizedBox(),
],
),
Row(
children: const [
Padding(
padding: EdgeInsets.only(left: 85.0),
child: Text("days",
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white,
fontSize: 20.0)),
),
Padding(
padding: EdgeInsets.only(left: 40.0),
child: Text("hours",
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white,
fontSize: 20.0)),
),
Padding(
padding: EdgeInsets.only(left: 30.0),
child: Text("mins",
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white,
fontSize: 20.0)),
),
],
)
],
)
],
),
),
)
],
),
),
)
: const Center(
child: SpinKitWanderingCubes(color: Colors.cyanAccent),
),
);
}
}
here i got width issue for data table and I also want every rowDivider will be remove,
and here I use animation, if you have any idea to improve animation then tell me.
here i got width issue for data table and I also want every rowDivider will be remove,
and here I use animation, if you have any idea to improve animation then tell me.
this is my full code
import 'package:bonanza_flutter/Constants/constants.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
double _height = 60.0;
bool _isExpanded = false;
Future<bool> _showList() async {
await Future.delayed(Duration(milliseconds: 300));
return true;
}
Future<bool> _showList1() async {
await Future.delayed(Duration(milliseconds: 10));
return true;
}
bool isOnPMS = true;
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.transparent,
appBar: AppBar(
),
body: SingleChildScrollView(
child: Column(
children: [
// imageSlider(),
pmsData(),
// advantages(),
// products(),
Container(
height: 20,
)
],
),
),
);
}
}
extension WidgetExtension on _HomePageState {
pmsData() {
return Container(
color: lightBlue,
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(20.0),
child: Column( crossAxisAlignment: CrossAxisAlignment.start,children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"PMS",
style:
TextStyle(fontSize: tSize16, fontWeight: FontWeight.w500),
),
Row(
children: [
Container(
width: 22,
height: 22,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(3),
color: skyBlue,
),
child: Icon(
Icons.arrow_back_ios_outlined,
color: Colors.white,
size: 17,
),
),
SizedBox(
width: 20,
),
Container(
width: 22,
height: 22,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(3),
color: skyBlue,
),
child: Icon(
Icons.arrow_forward_ios_rounded,
color: Colors.white,
size: 17,
),
),
],
)
],
),
SizedBox(
height: 8,
),
Text(
"ICICI Prudential PMS",
style: TextStyle(
fontSize: tSize14, fontWeight: FontWeight.w500, color: skyBlue),
),
SizedBox(
height: 12,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"\u{20B9} 50,00,000",
style: TextStyle(
fontSize: tSize11,
fontWeight: FontWeight.w500,
color: blackColor),
),
SizedBox(
height: 5,
),
Text(
"ICICI Prudential PMS",
style: TextStyle(
fontSize: tSize11,
fontWeight: FontWeight.w500,
color: greyColor),
),
SizedBox(
height: 14,
),
Text(
"\u{20B9} 2,02,993 (+4.06%)",
style: TextStyle(
fontSize: tSize11,
fontWeight: FontWeight.w500,
color: green2Color),
),
SizedBox(
height: 5,
),
Text(
"Gains & Loss",
style: TextStyle(
fontSize: tSize11,
fontWeight: FontWeight.w500,
color: greyColor),
),
],
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"\u{20B9} 52,02,993",
style: TextStyle(
fontSize: tSize11,
fontWeight: FontWeight.w500,
color: blackColor),
),
SizedBox(
height: 5,
),
Text(
"Current Market Value",
style: TextStyle(
fontSize: tSize11,
fontWeight: FontWeight.w500,
color: greyColor),
),
SizedBox(
height: 14,
),
Text(
"\u{20B9} 5",
style: TextStyle(
fontSize: tSize11,
fontWeight: FontWeight.w500,
color: blackColor),
),
SizedBox(
height: 5,
),
Text(
"Total Holdings",
style: TextStyle(
fontSize: tSize11,
fontWeight: FontWeight.w500,
color: greyColor),
),
],
),
SizedBox(
width: 0,
)
],
),
],),
),
AnimatedContainer(
duration: Duration(milliseconds: 300),
height: _height,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
),
// padding: EdgeInsets.only(left: 15, right: 15),
child: Column(
children: [
_isExpanded
? SizedBox.shrink()
: FutureBuilder(
future: _showList1(),
/// will wait untill box animation completed
builder: (context, snapshot) {
if (!snapshot.hasData) {
return SizedBox();
}
return Center(
child: Padding(
padding: const EdgeInsets.only(
top: 20.0, bottom: 00, left: 70, right: 70),
child: SizedBox(
height: 25,
width: 100,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
primary: skyBlue,
shadowColor: Colors.transparent),
onPressed: () {
setState(() {
isOnPMS = !isOnPMS;
if (!_isExpanded) {
setState(() {
_height = 350;
_isExpanded = true;
});
} else {
setState(() {
_height = 50;
_isExpanded = false;
});
}
});
print(_isExpanded);
},
child: Text("View More"),
),
),
),
);
}),
_isExpanded
? FutureBuilder(
future: _showList(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return SizedBox();
}
return Padding(
padding: const EdgeInsets.only(
top: 20.0, bottom: 00, left: 0, right: 0),
child: Column(
children: [
DataTable(
columns: const <DataColumn>[
DataColumn(
label: Text(
'#',style: TextStyle(color: Colors.white),
),
),
DataColumn(
label: Text(
'STOCK',style: TextStyle(color: Colors.white),
),
),
DataColumn(
label: Text(
'SECTOR',style: TextStyle(color: Colors.white),
),
),
DataColumn(
label: Text(
'WEIGHT',style: TextStyle(color: Colors.white),
),
),
],
rows: const <DataRow>[
DataRow(
cells: <DataCell>[
DataCell(Text('1')),
DataCell(Text('TCS')),
DataCell(Text('Global')),
DataCell(Text('11%')),
],
),
DataRow(
cells: <DataCell>[
DataCell(Text('2')),
DataCell(Text('DMART')),
DataCell(Text('Consumers')),
DataCell(Text('10%')),
],
),
DataRow(
cells: <DataCell>[
DataCell(Text('3')),
DataCell(Text('ICICIBANK')),
DataCell(Text('Financials')),
DataCell(Text('12%')),
],
),
DataRow(
cells: <DataCell>[
DataCell(Text('4')),
DataCell(Text('RELIANCE')),
DataCell(Text('Industrial')),
DataCell(Text('13%')),
],
),
],
dividerThickness: 0,
headingRowColor:
MaterialStateColor.resolveWith(
(states) => greyColor),
headingRowHeight: 30,
),
Center(
child: Padding(
padding: const EdgeInsets.only(
top: 20.0,
bottom: 00,
left: 70,
right: 70),
child: SizedBox(
height: 25,
width: 100,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
primary: skyBlue,
shadowColor: Colors.transparent),
onPressed: () {
setState(() {
isOnPMS = !isOnPMS;
if (!_isExpanded) {
setState(() {
_height = 350;
_isExpanded = true;
});
} else {
setState(() {
_height = 50;
_isExpanded = false;
});
}
});
print(_isExpanded);
},
child: const Text('View Less'),
),
),
),
)
],
),
);
})
: SizedBox.shrink(),
],
),
)
],
),
);
}
}
I want like this dataDable.
this is my ui which I created.
Wrap DataTable with SingleChildScrollView and set scrollDirection to horizontal.
Use TableBorder to remove divider.
when i play audio that time my song is loading that time showing error in IOS and when back from that page then i got this error "_dependents.isempty' is not true".
For android its working fine.
this is my card's page from here I going to details page where I am playing my song
import 'package:audioplayers/audioplayers.dart';
import 'package:cwc/constants/constants.dart';
import 'package:cwc/ui/video/video_player.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import '../podcast_details_page.dart';
class PodcastCompoentPurple extends StatefulWidget {
final cwcAudioListData;
const PodcastCompoentPurple({Key? key, this.cwcAudioListData,}) : super(key: key);
#override
State<PodcastCompoentPurple> createState() => _PodcastCompoentPurpleState();
}
class _PodcastCompoentPurpleState extends State<PodcastCompoentPurple> {
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.fromLTRB(18, 0, 18, 0),
child: GestureDetector(
onTap: () async{
isBtnHide=false;
await Navigator.push(context, MaterialPageRoute(builder: (context){
return PodcastDetailsPage(cwcAudioListData:widget.cwcAudioListData);
}));
print("s3 $playing");
if (playing==true) {
//pause song
var res = await audioPlayer.pause();
if (res == 1) {
setState(() {
playing = false;
print("s2 $playing");
});
}
}
print("s1 $playing");
},
child: Container(
height: 234,
// width: 260,
width: double.infinity,
decoration: BoxDecoration(
color: widget.cwcAudioListData['packages'][0]["name"]
.toString()
.toLowerCase() ==
"starter"
? Color(0xff69C583).withOpacity(.25)
:widget.cwcAudioListData['packages'][0]["name"]
.toString()
.toLowerCase() ==
"explorer"
? Color(0xFFC691D3).withOpacity(0.25)
: Color(0xFFF6931E).withOpacity(0.25),
// color: Colors.red,
borderRadius: const BorderRadius.all(
Radius.circular(10),
),
),
child: Padding(
padding: const EdgeInsets.fromLTRB(10, 10, 10, 10),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
height: 145,
// width: 300,
width: double.infinity,
decoration: BoxDecoration(
color: widget.cwcAudioListData['packages'][0]["name"]
.toString()
.toLowerCase() ==
"starter"
? Color(0xff69C583).withOpacity(.25)
: widget.cwcAudioListData['packages'][0]["name"]
.toString()
.toLowerCase() ==
"explorer"
? Color(0xFFC691D3).withOpacity(0.25)
: Color(0xFFF6931E).withOpacity(0.25),
// color: Colors.red,
borderRadius: const BorderRadius.all(
Radius.circular(10),
),
image: DecorationImage(
image: NetworkImage('${widget.cwcAudioListData['coverImage']}'),
fit: BoxFit.cover,
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Center(
child: CircleAvatar(
backgroundColor: Color(0xffF1F2F6).withOpacity(0.5),
radius: 23,
child: Icon(
Icons.headphones,
size: 24,
color: Color(0xffF1F2F6).withOpacity(1),
),
),
),
],
),
),
SizedBox(
height: 10,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'${widget.cwcAudioListData['title']}',
style: GoogleFonts.poppins(
fontWeight: FontWeight.w600,
fontSize: 14,
color: Color(0xFF444444)),textAlign: TextAlign.center,
),
Text(
'${widget.cwcAudioListData['description']}',
maxLines: 2,
style: GoogleFonts.poppins(
fontSize: 12, color: Color(0xFF444444)),
),
],)
],
),
),
),
),
);
}
}
This is my details page.
import 'package:audioplayers/audioplayers.dart';
import 'package:cwc/constants/constants.dart';
import 'package:cwc/constants/top_card.dart';
import 'package:cwc/ui/video/video_screen.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:intl/intl.dart';
import 'package:flutter/material.dart';
class PodcastDetailsPage extends StatefulWidget {
final cwcAudioListData;
const PodcastDetailsPage({Key? key, this.cwcAudioListData}) : super(key: key);
#override
_PodcastDetailsPageState createState() => _PodcastDetailsPageState();
}
class _PodcastDetailsPageState extends State<PodcastDetailsPage> {
Duration duration = new Duration();
Duration position = Duration();
var url = '';
#override
void initState() {
url=widget.cwcAudioListData['upload'].toString();
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xffffffff).withOpacity(1),
body: SafeArea(
child: Stack(
children: [
Container(
width: double.infinity,
height: 350,
decoration: BoxDecoration(
color: Color(0xffF6931E),
image: DecorationImage(
image: NetworkImage('${widget.cwcAudioListData["coverImage"]}'),
fit: BoxFit.cover,
),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.fromLTRB(18, 12, 0, 0),
child: GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: const CircleAvatar(
radius: 23,
backgroundColor: Colors.white,
child: Icon(Icons.arrow_back_ios_new,
color: Colors.black),
),
),
),
const SizedBox(
height: 138,
),
Padding(
padding: EdgeInsets.fromLTRB(18, 0, 18, 15),
child: Container(
height: 80,
),
),
],
),
),
Padding(
padding: const EdgeInsets.only(top: 270.0),
child: Container(
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topRight: Radius.circular(24.0),
topLeft: Radius.circular(24.0),
),
),
// height: 50,
width: double.infinity,
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.fromLTRB(19, 33, 0, 0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'${widget.cwcAudioListData["title"]}',
style: GoogleFonts.poppins(
fontSize: 18,
color: Color(0xff444444),
fontWeight: FontWeight.w600,
),
),
Text(
"${formateDat(DateTime.parse(widget.cwcAudioListData['uploadDate']))} at ${DateFormat("hh:mm a").format(DateFormat("yyyy-MM-ddTHH:mm:ssZ").parseUTC("${widget.cwcAudioListData['uploadDate']}").toLocal())}",
// 'Sept, 10th 2021',
style: GoogleFonts.poppins(
fontSize: 12,
color: Color(0xff8F9698),
fontWeight: FontWeight.w600,
),
),
Text(
'FREE to watch',
style: GoogleFonts.poppins(
fontSize: 14,
color: Color(0xff69C583),
fontWeight: FontWeight.w500,
),
),
],
),
)
],
),
Padding(
padding: const EdgeInsets.fromLTRB(20, 20, 0, 0),
child: Text(
'Video Description',
style: GoogleFonts.poppins(
fontSize: 18,
color: Color(0xFF69C583),
fontWeight: FontWeight.w500),
),
),
Padding(
padding: const EdgeInsets.fromLTRB(20, 8, 17, 22),
child: Text(
'${widget.cwcAudioListData["description"]}',
style: GoogleFonts.poppins(
fontSize: 13,
fontWeight: FontWeight.normal,
color: Color(0xff444444),
),
),
),
],
),
),
),
)
],
),
),
bottomNavigationBar: isBtnHide == false
? Container(
color: Colors.white,
child: Padding(
padding: const EdgeInsets.fromLTRB(0, 10, 0, 10),
child: Row(
children: [
SizedBox(
width: 30,
),
Expanded(
child: ElevatedButton(
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all(Color(0xFF158998)),
shape: MaterialStateProperty.all<
RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(18.0),
side: BorderSide(
color: Colors.teal, width: 0.0)))),
onPressed: () async {
setState(() {
isBtnHide = true;
});
getAudio();
},
child: Padding(
padding: const EdgeInsets.all(15.0),
child: Text(
'Listen Now',
style: GoogleFonts.poppins(fontSize: 14),
),
),
),
),
const SizedBox(
width: 30,
),
],
),
),
)
: Container(
color: Colors.white,
height: 80,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.only(bottom: 29.0),
child:
duration.toString().split(".")[0].toString() == "0:00:00" ? Padding(
padding: const EdgeInsets.all(8.0),
child: CircularProgressIndicator(color: selectBlueColor,),
): InkWell(
onTap: () {
getAudio();
},
child: Icon(
playing == false ||
position.inSeconds.toDouble() ==
duration.inSeconds.toDouble()
? Icons.play_circle_outline
: Icons.pause_circle_outline,
size: 40,
color: selectBlueColor,
),
),
),
Column(
children: [
slider(),
Row(
children: [
Text(
"${position.toString().split(".")[0]}",
style: TextStyle(fontWeight: FontWeight.w700),
),
SizedBox(
width: MediaQuery.of(context).size.width / 2.55,
),
Text(
"${duration.toString().split(".")[0]}",
style: TextStyle(fontWeight: FontWeight.w300),
),
],
)
],
)
],
),
),
);
}
Widget slider() {
return Container(
width: MediaQuery.of(context).size.width / 1.3,
child: Slider.adaptive(
activeColor: selectBlueColor,
inactiveColor: Colors.grey[350],
value: position.inSeconds.toDouble(),
min: 0.0,
max: duration.inSeconds.toDouble(),
onChanged: (double value) {
print(duration.inSeconds.toDouble());
setState(() {
audioPlayer.seek(Duration(seconds: value.toInt()));
});
}));
}
Future<void> getAudio() async {
// playing is false by default
print(playing);
if (playing) {
//pause song
var res = await audioPlayer.pause();
if (res == 1) {
setState(() {
playing = false;
});
}
} else {
//play song
var res = await audioPlayer.play(url, isLocal: true);
if (res == 1) {
setState(() {
print(res);
playing = true;
});
}
}
audioPlayer.onDurationChanged.listen((Duration d) {
// print('Max duration: $d');
if (mounted) {
setState(() => duration = d);
}
});
audioPlayer.onAudioPositionChanged.listen((Duration dd) {
if (mounted) {
setState(() {
position = dd;
});
}
});
}
}
formateDat(DateTime date) {
final DateFormat formatter = DateFormat.MMM();
String formatted = formatter.format(date);
formatted = "${formatted} " + "${date.day}";
var week = DateFormat('EEEE').format(date);
var we = week[0] + week[1] + week[2];
return "$we, " + formatted;
}
This is my error
this is my video recording.
I am having problem when I used the scrollcontroller to controll the gridview. I am having the error ( type 'String' is not a subtype of type 'int' of 'index'). But it was perfectly working before using the scrollcontroller. I don't where i need to change in order to remove this error. I also check the other issues regarding this in stackoverflow but couldn't get it. Can anyone check and tell me what can be change here in order to remove the error and show the data and also if my condition is right for loading 10 data in every scroll end.
import 'dart:convert';
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
import 'package:gridview_screoll/grid_content.dart';
import 'package:http/http.dart' as http;
import 'package:flutter/material.dart';
import 'constant.dart';
class ScrollableGrid extends StatefulWidget {
#override
_ScrollableGridState createState() => _ScrollableGridState();
}
class _ScrollableGridState extends State<ScrollableGrid> {
List data = [];
bool isLoading = false;
ScrollController _scrollController;
int pageCount = 1;
#override
void initState() {
// TODO: implement initState
super.initState();
this.fetchTopProducts();
addItemIntoLisT(pageCount);
_scrollController = new ScrollController(initialScrollOffset: 5.0)
..addListener(_scrollListener);
}
_scrollListener() {
if (_scrollController.offset >=
_scrollController.position.maxScrollExtent &&
!_scrollController.position.outOfRange) {
setState(() {
isLoading = true;
if (isLoading) {
pageCount = pageCount + 1;
addItemIntoLisT(pageCount);
}
});
}
}
void addItemIntoLisT(var pageCount) {
for (int i = (pageCount * 10) - 10; i < pageCount * 10; i++) {
fetchTopProducts();
isLoading = false;
}
}
#override
void dispose() {
_scrollController.dispose();
super.dispose();
}
fetchTopProducts() async {
setState(() {
isLoading = true;
});
var url = base_api + "api_frontend/top_products";
var response = await http.get(url);
print(response.body);
if (response.statusCode == 200) {
setState(() {
data.add(json.decode(response.body)['top_products']);
isLoading = false;
});
} else {
setState(() {
data = [];
isLoading = false;
});
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
elevation: 0.1,
backgroundColor: Colors.indigo,
title: Text('GridControll'),
//backgroundColor: Color.fromRGBO(244, 246, 249, 1),
),
body: SingleChildScrollView(
child: Column(
children: [
Container(
height: MediaQuery.of(context).size.height * 88/100,
color: Color.fromRGBO(244, 246, 249, 1),
margin: const EdgeInsets.only(
left: 0.0, bottom: 2.0, right: 0.0, top: 0),
child: getBody2(),
),
],
),
),
);
}
Widget getBody2() {
if (isLoading || data.length == 0) {
return Center(
child: CircularProgressIndicator(
valueColor: new AlwaysStoppedAnimation<Color>(primary)));
}
return StaggeredGridView.countBuilder(
padding: const EdgeInsets.all(10.0),
controller: _scrollController,
shrinkWrap: true,
// physics: NeverScrollableScrollPhysics(),
crossAxisCount: 2,
itemCount: data.length - 1,
itemBuilder: (context, index) {
return GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
//builder: (context) => ProductDetails(item: data2[index]),
builder: (context) => productDetail(data[index]),
),
);
},
child: cardItem2(data[index]));
},
staggeredTileBuilder: (int index) => StaggeredTile.fit(1),
mainAxisSpacing: 10.0,
crossAxisSpacing: 10.0,
);
}
}
Here is grid_content.dart:
import 'package:html_unescape/html_unescape.dart';
import 'package:flutter/material.dart';
Widget cardItem2(item) {
// var img = item['thumbnail'];
// var thumbnail = base_api+"uploads/product_thumbnails/"+img;
var productId = item['product_id'];
var thumbnail = item['thumbnail'];
var unescape = new HtmlUnescape();
var name = unescape.convert(item['name']);
var unit = item['unit'];
var discount = item['discount'];
var price = item['price'];
var discountPrice = item['discount_price'];
return discount != '0%' ? Card(
elevation: 6,
shadowColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(9.0)),
child: Stack(
fit: StackFit.loose,
alignment: Alignment.center,
children: [
Column(
children: <Widget>[
Stack(
children: [
ClipRRect(
borderRadius: BorderRadius.only(topRight: Radius.circular(9), topLeft: Radius.circular(9)),
child: FadeInImage.assetNetwork(
placeholder: 'assets/loading_animated.gif',
image: thumbnail,
height: 110,
width: double.infinity,
fit: BoxFit.cover,
),
),
],
),
Padding(
padding: const EdgeInsets.only(left:6.0, right: 6.0),
child: Row(
children: [
Expanded(
child: Padding(
padding: const EdgeInsets.all(4.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
name,
style: TextStyle(
fontSize: 16.0,
color: Colors.black87,
fontWeight: FontWeight.w100,
),
),
Text(
unit,
style: TextStyle(
fontSize: 12.0,
color: Colors.black45,
fontWeight: FontWeight.w100,
),
),
Row(
children: [
Expanded(
flex: 2,
child: Text(
discountPrice,
style: TextStyle(
fontSize: 16.0,
color: Colors.green,
fontWeight: FontWeight.w500,
),
),
),
Expanded(
flex: 2,
child: Text(
price,
style: TextStyle(
fontSize: 12.0,
color: Colors.black38,
fontWeight: FontWeight.w500,
decoration: TextDecoration.lineThrough,
),
),
),
ButtonTheme(
padding: EdgeInsets.symmetric(vertical: 4.0, horizontal: 6.0), //adds padding inside the button
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, //limits the touch area to the button area
minWidth: 0, //wraps child's width
height: 25,
child: FlatButton(
minWidth: 5,
height: 40,
color: Color.fromRGBO(100, 186, 2, 1),
onPressed: () {
},
child: Icon(Icons.shopping_cart, color: Colors.white,),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
side: BorderSide(color: Color.fromRGBO(100, 186, 2, 1),)),
),
),
],
),
],
),
),
),
],
),
),
],
),
],
),
) : Card(
elevation: 6,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(9.0)),
child: Stack(
fit: StackFit.loose,
alignment: Alignment.center,
children: [
Column(
children: <Widget>[
Stack(
children: [
ClipRRect(
borderRadius: BorderRadius.only(topRight: Radius.circular(9), topLeft: Radius.circular(9)),
child: FadeInImage.assetNetwork(
placeholder: 'assets/loading_animated.gif',
image: thumbnail,
height: 110,
width: double.infinity,
fit: BoxFit.cover,
),
),
],
),
Padding(
padding: const EdgeInsets.only(left:6.0, right: 6.0),
child: Row(
children: [
Expanded(
child: Padding(
padding: const EdgeInsets.all(4.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
name,
style: TextStyle(
fontSize: 16.0,
color: Colors.black87,
fontWeight: FontWeight.w100,
),
),
Text(
unit,
style: TextStyle(
fontSize: 12.0,
color: Colors.black45,
fontWeight: FontWeight.w100,
),
),
Row(
children: [
Expanded(
flex: 1,
child: Text(
price,
style: TextStyle(
fontSize: 15.0,
color: Colors.green,
fontWeight: FontWeight.w500,
),
),
),
ButtonTheme(
padding: EdgeInsets.symmetric(vertical: 4.0, horizontal: 6.0),
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
minWidth: 0, //wraps child's width
height: 25,
child: FlatButton(
minWidth: 10,
//height: 40,
color: Color.fromRGBO(100, 186, 2, 1),
onPressed: () {
},
child: Icon(Icons.shopping_cart, color: Colors.white,),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
side: BorderSide(color: Color.fromRGBO(100, 186, 2, 1),)),
),
),
],
),
],
),
),
),
],
),
),
],
),
],
),
);
}
productDetail(item) {
// var img = item['thumbnail'];
// var thumbnail = base_api+"uploads/product_thumbnails/"+img;
var productId = item['product_id'];
var thumbnail = item['thumbnail'];
var unescape = new HtmlUnescape();
var name = unescape.convert(item['name']);
var discount = item['discount'];
var price = item['price'];
var disPrice= item['discount_price'];
var unit = item['unit'];
return Scaffold(
appBar: AppBar(
elevation: 0.1,
iconTheme: IconThemeData(color: Colors.white),
backgroundColor: Colors.red,
title: Center(
child: Padding(
padding: const EdgeInsets.only(right: 50),
child: Text(
'Product Details',
style: TextStyle(color: Colors.white),
),
),
),
actions: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 15, right: 25.0),
child: GestureDetector(
child: Stack(
alignment: Alignment.topCenter,
children: <Widget>[
Icon(
Icons.favorite,
),
],
),
onTap: () {},
),
)
],
),
body: SingleChildScrollView(
child: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
child: FadeInImage.assetNetwork(
placeholder: 'assets/black_circle.gif',
image: thumbnail,
height: 210,
width: 360,
fit: BoxFit.cover,
),
),
),
Center(
child: Card(
color: Colors.white38,
child: Padding(
padding: const EdgeInsets.only(left: 12.0, right: 12, top: 4, bottom: 4),
child: Text(
unit,
style: TextStyle(
fontSize: 11,
color: Colors.black87,
),
),
),
),
),
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: Center(
child: discount != '0%' ? Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
disPrice,
style: TextStyle(
fontSize: 22,
color: Colors.black87,
fontWeight: FontWeight.bold),
),
Padding(
padding: const EdgeInsets.only(left: 8.0),
child: Text(
price,
style: TextStyle(
fontSize: 18,
color: Colors.black54,
decoration: TextDecoration.lineThrough,
),
),
),
],
): Text(
price,
style: TextStyle(
fontSize: 22,
color: Colors.black87,
fontWeight: FontWeight.bold),
),
),
),
Padding(
padding: const EdgeInsets.only(top: 4.0),
child: Center(
child: Text(
name,
style: TextStyle(
fontSize: 18,
color: Colors.black54,
),
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Divider(),
),
Container(
child: Center(
child: Text(
'Quantity',
style: TextStyle(color: Colors.black45, fontSize: 15),
),
),
),
Container(
child: Center(
child: Text(
'1',
style: TextStyle(
color: Colors.black,
fontSize: 22,
fontWeight: FontWeight.bold),
),
),
//child: Text(store.activeProduct.qty.toString()),
),
Padding(
padding: const EdgeInsets.only(
left: 100.0, right: 100.0, bottom: 10.0),
child: FlatButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(4)),
side: BorderSide(color: Color.fromRGBO(41, 193, 126, 1)),
),
color: Color.fromRGBO(41, 193, 126, 1),
padding: EdgeInsets.only(top: 8, bottom: 8),
child: Center(
child: Text(
'BUY NOW',
style: TextStyle(color: Colors.white, fontSize: 16),
),
),
onPressed: () {
}),
),
Padding(
padding: const EdgeInsets.only(
left: 100.0, right: 100.0, bottom: 10.0),
child: FlatButton(
padding: EdgeInsets.only(top: 8, bottom: 8),
child: Center(
child: Text(
'ADD TO CART',
style: TextStyle(color: Color.fromRGBO(41, 193, 126, 1), fontSize: 16),
),
),
onPressed: () {
}),
),
],
),
),
),
);
}
Here is the json file:
{
"top_products": [
{
"product_id": "63",
"category_id": "59",
"name": "Ice Cream",
"price": "$9",
"discount_price": "$8.91",
"discount": "1%",
"unit": "3 kg",
"thumbnail": "http://192.168.0.105/uploads/product_thumbnails/72908baa78a2db38f678283a2e483903.jpg"
},
{
"product_id": "65",
"category_id": "47",
"name": "Malta",
"price": "$5",
"discount_price": "$4.5",
"discount": "10%",
"unit": "1 kg",
"thumbnail": "http://192.168.0.105/uploads/product_thumbnails/a63dcb5e4f883eb946585d287d25c397.jpg"
},
{},
{},
{},
...
],
"message": "Top hundred products",
"status": 200,
"validity": true
}
======== Exception caught by widgets library =======================================================
The following _TypeError was thrown building:
type 'String' is not a subtype of type 'int' of 'index'
When the exception was thrown, this was the stack:
#0 cardItem2 (package:gridview_screoll/grid_content.dart:7:23)
#1 _ScrollableGridState.getBody2.<anonymous closure> (package:gridview_screoll/scroll_grid.dart:130:20)
#2 SliverChildBuilderDelegate.build (package:flutter/src/widgets/sliver.dart:449:22)
#3 SliverVariableSizeBoxAdaptorElement._build.<anonymous closure> (package:flutter_staggered_grid_view/src/widgets/sliver.dart:144:38)
#4 _HashMap.putIfAbsent (dart:collection-patch/collection_patch.dart:140:29)
...
====================================================================================================
itemCount: data.length - 1,
Change this to this:
itemCount: data.length;