когда я пытаюсь добавить построитель списка, весь мой экран становится черным вот код построителя представления списка
ListView.builder(
shrinkWrap = true,
scrollDirection: Axis.horizontal,
itemBuilder: (BuildContext context, int index) {
final data = courseCardList[index];
return Row(
children: [
CourseList(
color: data.color,
icon: data.icon,
caption: data.caption,
head: data.head,
timePeriod: data.timePeriod,
rating: data.rating,
),
],
);
},
),
что вызвало эту ошибку? если нужен какой-либо другой код, пожалуйста, прокомментируйте
вот полный код: https://github.com/Mishalhaneef/unais-academy-ui-repo
вот код этой страницы
import 'package:flutter/material.dart';
import 'package:unais_academy_ui/homescreen.dart';
import 'package:unais_academy_ui/screen/counstruction%20page/construction_page.dart';
import 'package:unais_academy_ui/screen/dashboard/widgets/course_bar.dart';
import 'package:unais_academy_ui/screen/homepage/widgets/course_list.dart';
import 'package:unais_academy_ui/constants.dart';
import 'package:flutter_svg/flutter_svg.dart';
import '../dashboard/model.dart';
import 'widgets/card_view.dart';
class MainScreen extends StatelessWidget {
const MainScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
String userName = 'mishal';
return Container(
decoration: const BoxDecoration(gradient: kHomeColor),
child: Scaffold(
drawer: NavigationDrawerWidget(),
//appBar code
appBar: PreferredSize(
preferredSize: const Size.fromHeight(60.0),
child: Column(
children: [
const SizedBox(height: 2),
AppBar(
elevation: 0,
backgroundColor: kMainTheme,
leading: Builder(builder: (BuildContext context) {
return IconButton(
icon: SvgPicture.asset(
'assets/icons/sidebar.svg',
color: Colors.black,
),
iconSize: 10,
onPressed: () {
Scaffold.of(context).openDrawer();
},
tooltip:
MaterialLocalizations.of(context).openAppDrawerTooltip,
);
}),
actions: [
IconButton(
onPressed: () {
HomeScreen.selectedIndexNotifier.value = 1;
},
icon: SvgPicture.asset('assets/icons/search.svg')),
const SizedBox(width: 10),
GestureDetector(
onTap: () {
HomeScreen.selectedIndexNotifier.value = 3;
},
child: CircleAvatar(
radius: 16.0,
child: ClipRRect(
child: Image.asset('assets/account.jpg'),
borderRadius: BorderRadius.circular(50.0),
),
),
),
const SizedBox(width: 20)
],
),
],
),
),
backgroundColor: Colors.transparent,
//body code
body: ListView(
children: [
Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
const SizedBox(height: 37),
Padding(
padding: EdgeInsets.only(left: 30, right: 0),
child: Row(
children: [
const Text('Helo ',style: headRichText),
Text(userName[0].toUpperCase(), style: headRichText),
Text(userName.substring(1).toLowerCase(), style: headRichText),
],
)
),
const Padding(
padding: EdgeInsets.only(left: 30, right: 0),
child: Text("Find a course you want to learn",
style: secondRichText),
),
// ignore: sized_box_for_whitespace
CardView(
backgroundColor: sLinearColorBlue,
buttonText: 'Join Now!',
headText: '50% off',
personImage: 'assets/person_home.png',
secondText: 'For Any Course!',
),
const SizedBox(height: 18),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Padding(
padding: EdgeInsets.only(left: 30),
child: Text('Explore Course', style: helperTextStyle),
),
Padding(
padding: const EdgeInsets.only(right: 15),
child: TextButton(
// ignore: prefer_const_constructors
style: ButtonStyle(
padding: MaterialStateProperty.all(EdgeInsets.zero),
),
onPressed: () {
Navigator.of(context)
.pushNamed(ConstructionPage.routeName);
},
child: const Text(
'See All',
style: TextStyle(color: Colors.blue),
),
),
)
],
),
const SizedBox(height: 1),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: const [
SizedBox(width: 30),
CourseList(
color: kLiteRed,
icon: 'assets/youtube.png',
caption: 'How To Market Your YouTube Channel',
head: 'Marketing',
timePeriod: 18,
rating: 4.6,
),
SizedBox(width: 20),
CourseList(
color: kLiteRose,
icon: 'assets/chart.png',
caption: 'Grow Your Channel With this very usefull tips',
head: 'Channel Growth',
timePeriod: 18,
rating: 4.3,
),
SizedBox(width: 20),
CourseList(
color: kLiteGreen,
icon: 'assets/diagram.png',
caption: 'How to Make Thumbnail Attractive',
head: 'Creative',
timePeriod: 18,
rating: 3.4,
),
SizedBox(width: 20),
CourseList(
color: kLiteRose,
icon: 'assets/calender.png',
caption: 'Light Your Video Like A Pro',
head: 'Creative',
timePeriod: 18,
rating: 5.0,
),
SizedBox(width: 20),
CourseList(
color: kLiteRed,
icon: 'assets/youtube.png',
caption: 'How To Market Your YouTube Channel',
head: 'Marketing',
timePeriod: 18,
rating: 3.9,
),
SizedBox(width: 20),
],
),
),
// Expanded(
// child: GridView.count(
// childAspectRatio: 3 / 4,
// crossAxisCount: 20,
// mainAxisSpacing: 34,
// crossAxisSpacing: 30,
// padding: const EdgeInsets.all(20),
// children: List.generate(
// courseCardList.length,
// (index) {
// final data = courseCardList[index];
// return CourseList(
// color: data.color,
// icon: data.icon,
// caption: data.caption,
// head: data.head,
// timePeriod: data.timePeriod,
// rating: data.rating,
// );
// },
// ),
// ),
// ),
// ListView.separated(
// shrinkWrap: true,
// scrollDirection: Axis.horizontal,
// itemBuilder: (BuildContext context, int index) {
// final data = courseCardList[index];
// return CourseList(
// color: data.color,
// icon: data.icon,
// caption: data.caption,
// head: data.head,
// timePeriod: data.timePeriod,
// rating: data.rating,
// );
// },
// itemCount: courseCardList.length,
// separatorBuilder: (BuildContext context, int index) {
// return SizedBox();
// },
// ),
const SizedBox(height: 14),
const Padding(
padding: EdgeInsets.only(left: 50, right: 50),
child: Divider(height: 1),
),
const SizedBox(height: 10),
const Padding(
padding: EdgeInsets.only(left: 30),
child: Text('Your Course', style: helperTextStyle),
),
const SizedBox(height: 22),
SingleChildScrollView(
scrollDirection: Axis.vertical,
child: ListView.separated(
physics: const BouncingScrollPhysics(),
shrinkWrap: true,
itemBuilder: (BuildContext context, int index) {
final data = myCourseBar[index];
return CourseBar(
icon: data.icon,
caption: data.caption,
time: data.time,
colorTheme: data.colorTheme,
duration: data.duration,
status: data.status,
);
},
itemCount: myCourseBar.length,
separatorBuilder: (BuildContext context, int index) {
return const SizedBox(height: 20);
},
),
),
])
],
),
),
);
}
}
class NavigationDrawerWidget extends StatelessWidget {
const NavigationDrawerWidget({Key? key}) : super(key: key);
final padding = const EdgeInsets.symmetric(horizontal: 20);
@override
Widget build(BuildContext context) {
const name = 'Mishal Haneef';
const email = '[email protected]';
const urlImage = 'assets/account.jpg';
// ignore: prefer_const_constructors
return Drawer(
// ignore: prefer_const_constructors
child: Material(
color: kDeepBlueTheme,
child: ListView(
padding: padding,
children: <Widget>[
Container(
decoration: BoxDecoration(
color: kDeepBlueTheme.withGreen(130),
borderRadius: const BorderRadius.only(
bottomLeft: Radius.circular(30),
bottomRight: Radius.circular(30))),
child: buildHeader(
urlImage: urlImage,
name: name,
email: email,
onClicked: () => null,
),
),
const SizedBox(height: 48),
buildMenuItem(
text: 'Account',
icon: Icons.people,
),
const SizedBox(height: 16),
buildMenuItem(
text: 'Dash Board',
icon: Icons.dashboard,
),
const SizedBox(height: 16),
buildMenuItem(
text: 'Explore',
icon: Icons.explore,
),
const SizedBox(height: 16),
buildMenuItem(
text: 'Wishlist',
icon: Icons.info,
),
const SizedBox(height: 16),
const SizedBox(height: 24),
const Divider(color: Colors.white70),
const SizedBox(height: 24),
buildMenuItem(
text: 'Terms &',
icon: Icons.info,
),
const SizedBox(height: 16),
buildMenuItem(
text: 'Logout',
icon: Icons.logout,
),
],
),
),
);
}
Widget buildMenuItem({
required String text,
required IconData icon,
VoidCallback? onClicked,
}) {
return ListTile(
leading: Icon(
icon,
color: Colors.white,
),
title: Text(
text,
style: const TextStyle(color: Colors.white),
),
onTap: () {},
);
}
Widget buildHeader({
required String urlImage,
required String name,
required String email,
required VoidCallback onClicked,
}) {
return Padding(
padding: const EdgeInsets.only(top: 40, right: 10, left: 10),
child: InkWell(
borderRadius: BorderRadius.circular(30),
onTap: onClicked,
child: Container(
padding: const EdgeInsets.only(top: 10, bottom: 10),
child: Row(
children: [
CircleAvatar(
radius: 20,
backgroundImage: AssetImage(urlImage),
),
const SizedBox(width: 20),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
name,
style: const TextStyle(fontSize: 20, color: Colors.white),
),
const SizedBox(height: 4),
Text(
email,
style: const TextStyle(fontSize: 14, color: Colors.white),
)
],
),
const Spacer(),
],
),
),
),
);
}
}
это код главной страницы, если вам нужен полный курс, который я уже дал перед этим кодом
Добавьте itemCount: courseCardList.length
это не работает
@SaifulIslam добавил код, пожалуйста, проверьте его
Я думаю, ты забыл itemCount
Expanded(
child:ListView.builder(
shrinkWrap = true,
itemCount = 5,// add this line or put courseCardList.length
scrollDirection: Axis.horizontal,
itemBuilder: (BuildContext context, int index) {
final data = courseCardList[index];
return Row(
children: [
CourseList(
color: data.color,
icon: data.icon,
caption: data.caption,
head: data.head,
timePeriod: data.timePeriod,
rating: data.rating,
),
],
);
},
),
),
предоставьте itemCount вашему ListviewBuilder, а также оберните его расширенным или некоторым виджетом фиксированного размера, например контейнером, например:
Expanded(
child: ListView.builder(
itemCount: your counts(int)
.....
.....
)
)
нет, я добавил количество элементов сейчас, но я могу прокручивать только вниз, когда я устанавливаю ось в горизонтальное положение, это просто пусто, только часть снова
Под ListView Widget
shrinkWrap: true
itemCount: courseCardList.length
Если это все еще не решает проблему,
Удалите виджет Row()
, поскольку я вижу, что вы возвращаете только один виджет под ним, поэтому сразу верните этот виджет CourseList()
Код должен выглядеть примерно так.
ListView.builder(
shrinkWrap : true,
itemCount: courseCardList.length,
scrollDirection: Axis.horizontal,
itemBuilder: (BuildContext context, int index) {
final data = courseCardList[index];
return CourseList(
color: data.color,
icon: data.icon,
caption: data.caption,
head: data.head,
timePeriod: data.timePeriod,
rating: data.rating,
);
},
),
он не работает, когда scrollDirection: Axis.horizontal,
меняется на вертикальный, он работает нормально, но вертикальная прокрутка мне нужна, как в горизонтальной
что не работает, можете поделиться проблемой?
все готово, братан, все, что мне нужно сделать, это задать фиксированную высоту и ширину, теперь все готово
фиксированная высота и ширина не являются динамическим или хорошим решением, так как проблемы будут возникать на разных устройствах с разными размерами экрана.
Горизонтальный Listview.builder нуждается в фиксированной высоте. Горизонтальный элемент списка не должен иметь бесконечную высоту. поэтому мне пришло в голову решение, просто оберните Listview.builder контейнером и установите высоту этого контейнера, как показано ниже.
Фреймворк Flutter может знать высоту виджета только после его создания.
Если вы создаете дочерние элементы ListView динамически, он не может вычислить требуемую высоту ListView до тех пор, пока не будут построены все его дочерние элементы, что может никогда не произойти (бесконечный ListView).
Вы можете либо задать ListView фиксированную высоту и динамически построить его дочерние элементы, либо высота ListView зависит от его дочерних элементов.
Container(
height: 200,
child: ListView.builder(
shrinkWrap = true,
scrollDirection: Axis.horizontal,
itemBuilder: (BuildContext context, int index) {
final data = courseCardList[index];
return Row(
children: [
CourseList(
color: data.color,
icon: data.icon,
caption: data.caption,
head: data.head,
timePeriod: data.timePeriod,
rating: data.rating,
),
],
);
},
),
);
Можете ли вы поделиться своим полным фрагментом кода, чтобы лучше понять, кстати, я думаю, что здесь чего-то не хватает, чтобы «courseCardList[index] изменить на courseCardList[index].length»