The problem is the following, I built my layout with a Layout Builder, inside it I check the screen size in width and define if it is a mobile device or a desktop/web, then I display the following layout >>>>
So far so good, but under the text 'a quiet afternoon' I want to put a list view with recommendations for songs to listen to in the afternoon, when I put the listview in the layout this happens here >>>>>
I don't know what's going on, so I'll put the whole code here, if anyone can help me I'd appreciate it!!
Main.dart
import 'package:desktop_window/desktop_window.dart';
import 'package:player/sreens/Home.dart';
import 'package:player/sreens/MainScreen.dart';
import 'package:player/sreens/playlist.dart';
import 'package:player/sreens/search.dart';
import 'package:universal_platform/universal_platform.dart';
Future setDesktopWindow() async {
await DesktopWindow.setMinWindowSize(const Size(400, 400));
await DesktopWindow.setWindowSize(const Size(1200, 700));
}
void main() {
WidgetsFlutterBinding.ensureInitialized();
if (UniversalPlatform.isDesktop) {
setDesktopWindow();
}
runApp(MaterialApp(
initialRoute: '/',
routes: {
'/': (context) => Home(),
'/main': (context) => MainScreen(),
'/playlist': (context) => Playlist(),
'/search': (context) => Search()
},
debugShowCheckedModeBanner: false,
title: "Music Player",
));
}
Home.dart (Inicial Route and Layout Builder is here!)
import 'package:flutter/material.dart';
import 'package:player/sreens/MainScreen.dart';
class Home extends StatefulWidget {
const Home({Key? key}) : super(key: key);
@override
State<Home> createState() => _HomeState();
}
class _HomeState extends State<Home> {
///Item atual em exibição na tela e selecionado na barra de navegação
///Valor padrão 0.
int _selectIndex = 0;
///Destination Rail, barra de navegação Lateral, Itens da barra de navegação
final destinationRail = const <NavigationRailDestination>[
NavigationRailDestination(icon: Icon(Icons.home), label: Text("Home")),
NavigationRailDestination(
icon: Icon(Icons.playlist_play), label: Text("Playlist")),
NavigationRailDestination(icon: Icon(Icons.search), label: Text("Search")),
];
///Destination Bottom, barra de navegação inferior, Itens da barra de navegação
final destinationBottom = const <BottomNavigationBarItem>[
BottomNavigationBarItem(icon: Icon(Icons.home), label: "Home"),
BottomNavigationBarItem(
icon: Icon(Icons.playlist_play),
label: "Playlist",
),
BottomNavigationBarItem(icon: Icon(Icons.search), label: "Search"),
];
///Método para trocar o item atual das barras de navegação
changeDestination(int index) {
setState(() {
_selectIndex = index;
});
}
@override
Widget build(BuildContext context) {
///Lista de telas a exibir em cada botão das barras de navegação.
List<Widget> screens = [
MainScreen(),
Text("playlist"),
Text("search"),
];
///Construção do layout principal, com as barras de navegação
///Utilizando o layout builder para definir qual barra demonstrar
return LayoutBuilder(
builder: (context, constrain) {
if (constrain.maxWidth > 400) {
///Tamanho Desktop e Web
return Scaffold(
body: Row(
children: [
NavigationRail(
selectedIndex: _selectIndex,
destinations: destinationRail,
onDestinationSelected: changeDestination,
labelType: NavigationRailLabelType.all,
),
const Padding(
padding: EdgeInsets.only(bottom: 8),
child: VerticalDivider(
width: 1,
thickness: 1,
),
),
Expanded(
child: Column(
children: [
screens[_selectIndex]
],
),
),
],
),
);
} else {
///Tamanho Mobile
return Scaffold(
bottomNavigationBar: BottomNavigationBar(
items: destinationBottom,
currentIndex: _selectIndex,
onTap: (indicie) {
setState(() {
_selectIndex = indicie;
});
},
),
body: screens[_selectIndex],
);
}
},
);
}
}
MainScreen.dart (the listview is here)
import '../utils/timeValidator.dart';
class MainScreen extends StatefulWidget {
const MainScreen({Key? key}) : super(key: key);
@override
State<MainScreen> createState() => _MainScreenState();
}
class _MainScreenState extends State<MainScreen> {
final ScrollController controller = ScrollController();
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
timeValidator(),
style: const TextStyle(
fontSize: 30,
fontFamily: 'nunito',
fontWeight: FontWeight.bold),
),
IconButton(
onPressed: () {},
icon: const Icon(
Icons.nightlight_outlined,
color: Colors.black,
),
),
],
),
Padding(
padding: const EdgeInsets.only(top: 16, bottom: 16),
child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Image.asset(
imageValidator(),
fit: BoxFit.cover,
width: MediaQuery.of(context).size.width,
height: 300,
),
),
),
Text(
sugestionValidator(),
style: const TextStyle(
fontFamily: 'nunito',
fontWeight: FontWeight.w600,
fontSize: 20),
),
************This is the error*************
ListView.separated(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
return ListTile(
title: Text("Teste"),
);
},
separatorBuilder: (context, index) => Divider(),
itemCount: 4)
],
),
);
}
}
CodePudding user response:
The main issue here ListTile
is trying to get infinite width while the ListView
is on horizontal
axis, this also providing infinite width. You can provide width on ListTile
to fix this issue.
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (_, constraints) => Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
Expanded( //or SizedBo with Height instead shrinkWrap for better perfomance
child: ListView.separated(
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
return SizedBox(
width: constraints.maxWidth,
child: ListTile(
title: Text("Teste"),
),
);
},
separatorBuilder: (context, index) => Divider(),
itemCount: 4),
)
],
),
),
);
}
}
CodePudding user response:
Okay, I managed to fix the problem and here's the thing, I had to use a CustomScrollView to be able to create the layout perfectly and without errors, using Slivers and Containers as parent components so I was able to create what I wanted, thanks