So I'm tring to make an app to show a detail card view page when I click on the gif of the character, so i'm trying to implement the ListView.build() inside an expand that is inside a column. but it gives me this error FlutterError (BoxConstraints has NaN values in minHeight and maxHeight.
The offending constraints were:
BoxConstraints(w=Infinity, NaN<=h<=NaN; NOT NORMALIZED))
here it's my code:
import 'package:flutter/material.dart';
import 'package:vertical_card_pager/vertical_card_pager.dart';
import 'models/hero_model.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 MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Valorant Agents',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
alert(String msg) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(msg),
action: SnackBarAction(
label: "FECHAR",
onPressed: () => ScaffoldMessenger.of(context).hideCurrentSnackBar(),
),
));
}
//ImagesController _imagesController = Get.find();
//List for agents and respective gif for each one.
final List<HeroModel> heros = [
HeroModel("JETT", "images/jett_valo.gif"),
HeroModel("KILLJOY", "images/killjoy_valo.gif"),
HeroModel("SAGE", "images/sage_valo.gif"),
HeroModel("SOVA", "images/sova_valo.gif"),
HeroModel("VIPER", "images/viper_valo.gif"),
HeroModel("RAZE", "images/raze_valo.gif"),
HeroModel("YORU", "images/yoru_valo.gif"),
HeroModel("BREACH", "images/breach_valo.gif"),
HeroModel("ASTRA", "images/astra_valo.gif"),
HeroModel("CYPHER", "images/cypher_valo.gif"),
HeroModel("OMEN", "images/omen_valo.gif"),
HeroModel("PHOENIX", "images/phoenix_valo.gif"),
HeroModel("SKYE", "images/skye_valo.gif"),
];
#override
//Head Logo
Widget build(BuildContext context) {
// ImagesController _imagesController = Get.find();
return Scaffold(
backgroundColor: Colors.black38,
body: SafeArea(
child: Column(
children: [
SizedBox(
width: double.infinity,
height: 70,
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 5),
child: Center(
child: Image.asset(
"images/logo.png",
fit: BoxFit.cover,
),
),
),
),
// CardView
Expanded(
child: ListView.builder(
itemCount: heros.length,
itemBuilder: (context, index) {
return VerticalCardPager(
titles: [for (var hero in heros) hero.title],
images: [
for (var hero in heros)
Hero(
tag: hero.title,
child: ClipRRect(
borderRadius: BorderRadius.circular(20.0),
child: Image.asset(
hero.image,
fit: BoxFit.cover,
),
),
),
],
textStyle: const TextStyle(
color: Colors.white, fontWeight: FontWeight.bold),
initialPage: 2,
align: ALIGN.CENTER,
);
}),
)
],
)));
}
}
You don't needed to use VerticalCardPager inside listView, try this:
Expanded(
child: Container(
child: VerticalCardPager(
titles: [for (var hero in heros) hero.title],
images: [
for (var hero in heros)
Hero(
tag: hero.title,
child: ClipRRect(
borderRadius: BorderRadius.circular(20.0),
child: Image.asset(
hero.image,
fit: BoxFit.cover,
),
),
),
],
textStyle: const TextStyle(
color: Colors.white, fontWeight: FontWeight.bold),
initialPage: 2,
align: ALIGN.CENTER,
),
),
)
The issue is with the Expanded widget. You are using the Expanded widget inside the Column whose height is not fixed. You can resolve it by either wrapping column inside SizedBox and setting some height or using shrinkWrap inside ListView.builder and removing the Expanded widget.
Solution 1
SizedBox(
height: MediaQuery.of(context).size.height,
child: Column(
children: [
SizedBox(
width: double.infinity,
height: 70,
...
),
// CardView
Expanded(
child: ListView.builder(
itemCount: heros.length,
itemBuilder: (context, index) {
...
}),
)
],
)
Solution 2:
SingleChildScrollView(
child: Column(
children: [
SizedBox(
width: double.infinity,
height: 70,
...
),
// CardView
ListView.builder(
itemCount: heros.length,
shrinkWrap: true, // add this
physics: NeverScrollableScrollPhysics(),
itemBuilder: (context, index) {
...
})
],
),
)
P.S:- If you want to use 2nd solution you need to restrict ListView scrolling by setting physics to NeverScrollableScrollPhysics and wrapping Column with SingleChildScrollView
Related
Please look at this image Home Page
Now when I scroll the ListView it becomes like this -
Home Page
Now I know the reason why this is happening, it is because I used ListView as a parent to this entire view and added ListView.builder() and other widgets as its child.
What I want is to scroll the ListView.builder() without scrolling the entire page.
For this I first tried to use Column as parent but that ended up giving the overflow pixels error.
And then I set the physics: const NeverScrollableScrollPhysics() inside the parent ListView but after that it made my ListView.builder() to show all of its list items.
Here is my Code for Home Screen
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
Expanded(
child: ListView(
padding: const EdgeInsets.only(top: 45, bottom: 24),
children: [
header(),
const SizedBox(height: 36),
const BalanceCard(),
const SizedBox(height: 36),
Recent()
],
),
),
Align(
alignment: Alignment.bottomCenter,
child: bottomNavigationBar(),
),
],
),
); }
Recent List Code
class RecentItems extends StatefulWidget {
final List<Transaction> transactions;
RecentItems({required this.transactions});
#override
State<RecentItems> createState() => _RecentItemsState();
}
class _RecentItemsState extends State<RecentItems> {
#override
Widget build(BuildContext context) {
return SizedBox(
height: 450,
child: Expanded(child: ListView.builder(
itemBuilder: (context, index) {
final item = widget.transactions[index].toString();
return Dismissible(
direction: DismissDirection.endToStart,
key: UniqueKey(),
onDismissed: (direction) {
setState(() {
widget.transactions.removeAt(index);
});
// Then show a snackbar.
ScaffoldMessenger.of(context)
.showSnackBar(const SnackBar(content: Text('Transaction Deleted')));
},
background: Container(
color: Colors.red,
alignment: AlignmentDirectional.centerEnd,
child: const Padding(
padding: EdgeInsets.fromLTRB(0.0, 0.0, 15.0, 0.0),
child: Icon(
EvaIcons.trash2,
color: Colors.white,
),
),
),
child: Card(
elevation: 5,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0),
),
child: ListTile(
leading: CircleAvatar(
radius: 30,
foregroundImage: widget.transactions[index].Image,
backgroundColor: primaryColor,
),
title: Text(
widget.transactions[index].title,
style: const TextStyle(color: secondaryColor),
),
subtitle: Text(
DateFormat.yMMMd().format(widget.transactions[index].date),
),
trailing: Text(
'\$${widget.transactions[index].amount}',
style: const TextStyle(color: secondaryColor),
),
),
),
);
},
itemCount: widget.transactions.length,
),)
);
}
}
Recent Widget -
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 24),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Recent Transactions',
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.bold,
color: secondaryColor),
),
const SizedBox(height: 5),
RecentItems(transactions: _userTransactions),
],
),
)
The entire screen scrolls because Recent() is included in the same ListView as header() and balanceCard().
Try something like this:
Scaffold(
body: Column(
children: [
Expanded(
child: ListView(
padding: const EdgeInsets.only(top: 45, bottom: 24),
children: [
header(),
const SizedBox(height: 36),
const BalanceCard(),
const SizedBox(height: 36),
],
),
),
// Recent items removed from ListView
Recent(),
Align(
alignment: Alignment.bottomCenter,
child: bottomNavigationBar(),
),
],
),
)
I hope this helps.
By simplifying your code, this is an example of a layout where you have a single Column in the Scaffold. The Column contains some sized, unsized and aligned children.
One child, Recent is a ListView, without explicit height, but wrapped into an Expanded widget. This way it will occupy all the remaining area left by the other children, and it will be scrollable.
(You will run into trouble with this if the children without Recent occupy all the available area.)
Please have a look at this code, you can copy-paste it into a DartPad fiddle:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: MyWidget(),
),
),
);
}
}
class MyWidget extends StatelessWidget {
#override
Widget build(BuildContext context) => Scaffold(
body: Column(
children: [
const Text('header()'),
const SizedBox(height: 36),
const Text('BalanceCard()'),
const SizedBox(height: 36),
Expanded(child: Recent()),
const Align(
alignment: Alignment.bottomCenter,
child: Text('bottomNavigationBar()'),
),
],
),
);
}
class Recent extends StatelessWidget {
#override
Widget build(BuildContext context) => ListView.builder(
itemCount: 100, itemBuilder: (context, index) => Text('Item $index'));
}
I have a page with name playerPage which contains the bottomNavigationBar which has got mini player and navigation items respectively. I also have a MyHomePage which contains the songs to be played. I created a constructor with Function name miniPlayer in MyHomePage to call _miniPlayer method in the playerPage but I am getting an error that says Method not found: 'miniPlayer'.
MyHomePage
class MyHomePage extends StatefulWidget {
final Function miniPlayer;
const MyHomePage(this.miniPlayer);
// const MyHomePage({Key? key}) : super(key: key);
#override
State<MyHomePage> createState() => _MyHomePageState(miniPlayer);
}
class _MyHomePageState extends State<MyHomePage> {
final Function miniPlayer;
_MyHomePageState(this.miniPlayer);
Widget _recommended(context) {
return Column(
children: [
StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance.collection("Worship").snapshots(),
builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
if(snapshot.hasData) {
final snap = snapshot.data!.docs;
return ListView.builder(
shrinkWrap: true,
primary: false,
itemCount: snap.length,
itemBuilder: (context, index) {
return Stack(
children: [
GestureDetector(
child:Container(
height:50,
width: MediaQuery.of(context).size.width,
child: Card(
child: Center(
child: Row (
children : [
Text(
snap[index]['name'],
textAlign: TextAlign.start,
style: const TextStyle(
color: Colors.black54,
fontWeight: FontWeight.bold,
),
),
SizedBox(width:50),
Text(
snap[index]['title'],
textAlign: TextAlign.start,
style: const TextStyle(
color: Colors.black54,
fontWeight: FontWeight.bold,
),
),
]
)),
)),
onTap: () {
var ur= snap[index]['url'];
var ti =snap[index]['title'];
var music =snap[index]['music'];
**miniPlayer(url:ur,le:ti,music:music);** Getting error here
},
)
],
// ),
);
},
);
} else {
return const SizedBox();
}
},
)
],
);
}
PlayerPage
this is the miniPlayer method in the playerPage
Widget miniPlayer(le,url,music) {
this.le =le;
this.url =url;
this.music =music;
setState(() {
});
if(widget.le.isEmpty) {
return SizedBox();
}
return AnimatedContainer(
duration: const Duration(milliseconds: 500),
color: Colors.indigo,
height: MediaQuery.of(context).size.height * 0.07,
width: MediaQuery.of(context).size.width,
child: Row(
children: [
Container(
padding: EdgeInsets.only(left: 6),
child: CircleAvatar(
backgroundColor: Colors.indigo,
radius: 20,
child: IconButton(
icon: Icon(
isPlaying ? Icons.pause : Icons.play_arrow_rounded,
color: Colors.white,
),
onPressed: () async {
if (isPlaying) {
await audioPlayer.pause();
} else {
await audioPlayer.resume();
}
},
),
),
),
const SizedBox(
width: 10,
),
Container(
padding: EdgeInsets.only(left: 5),
width: MediaQuery.of(context).size.width * 0.85,
child: Column(
children: [
Expanded(
child: Marquee(
textDirection: TextDirection.ltr,
velocity: 30,
blankSpace: 90,
//pauseAfterRound: const Duration(seconds: 2),
text: widget.le,
style: const TextStyle(
color: Colors.white,
fontSize: 15,
fontWeight: FontWeight.bold),
))
],
))
],
),
);
}
First of all, here it's not properly understood. It's a little bit messy. But one thing is make sure you pass it down the widget tree. And another thing is try not to pass properties through private constructors.
You can easily access that property (aka. miniPlayer function) just by typing widget.miniPlayer. In that way you can be more sure that this function is available in the main widget class.
Also you're returning an widget inside a function. Make sure you use it. Other wise that widget getting returned won't do anything inside a function.
I have an application like this:
My aim is that when I press the eye icon next to the text "Hello", I want a box to open just below the text and write the German version of "Hello". So it will say "Hallo".
My purpose is to show the meaning of the word.
When I press the eye, I want to show the German of the word. How can I make a white box under the word Hello, that is, the box in which the German language will be written?
Codes:
import 'package:flutter/material.dart';
import 'package:carousel_slider/carousel_slider.dart';
class selamlasmaLearn extends StatelessWidget {
List <wordAndMeaning> wordsList = [wordAndMeaning("Hello", "Hallo"), wordAndMeaning("Go", "Gehen")];
#override
Widget build(BuildContext context) {
return Scaffold(
body: Builder(
builder: (context) {
final double height = MediaQuery.of(context).size.height;
return CarouselSlider(
options: CarouselOptions(
height: height,
viewportFraction: 1.0,
enlargeCenterPage: false,
),
items: wordsList.map((wordAndMeaning word) {
return Builder(
builder: (BuildContext context) {
return Container(
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(color: Colors.amber),
child: Center(
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
word.word,
style: TextStyle(fontSize: 45, color: Colors.white),
),
SizedBox(width: 10,),
Icon(Icons.remove_red_eye_sharp, color: Colors.white, size: 25,), // <<<<<<<<<
],
),
),
);
},
);
}).toList(),
);
}
),
);
}
}
class wordAndMeaning {
String word;
String meaning;
wordAndMeaning(this.word, this.meaning);
}
I keep the word and its German in a list called wordsList.
Thanks for the help in advance.
You can convert the widget to StatefulWidget or use a ValueNotifier to control the preserve/notify the state visibility.
You can use Visibility widget or just if to show and hide German text.
class selamlasmaLearn extends StatefulWidget {
#override
State<selamlasmaLearn> createState() => _selamlasmaLearnState();
}
class _selamlasmaLearnState extends State<selamlasmaLearn> {
bool _showGerman = false;
List<wordAndMeaning> wordsList = [
wordAndMeaning("Hello", "Hallo"),
wordAndMeaning("Go", "Gehen")
];
#override
Widget build(BuildContext context) {
return Scaffold(
body: Builder(builder: (context) {
final double height = MediaQuery.of(context).size.height;
return CarouselSlider(
options: CarouselOptions(
height: height,
viewportFraction: 1.0,
enlargeCenterPage: false,
),
items: wordsList.map((wordAndMeaning word) {
return Builder(
builder: (BuildContext context) {
return Container(
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(color: Colors.amber),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(word.word,
style:
TextStyle(fontSize: 45, color: Colors.white)),
if (_showGerman) Text(word.meaning), //modify the way you want
],
),
const SizedBox(
width: 10,
),
IconButton(
icon: Icon(Icons.remove_red_eye_sharp),
color: Colors.white,
iconSize: 25,
onPressed: () {
setState(() {
_showGerman = !_showGerman;
});
},
),
],
),
);
},
);
}).toList(),
);
}),
);
}
}
Use the Tooltip widget
I'm emphasizing on the popup part in your question title. When using a Tooltip you ensure that your widgets do not shift position or jump when the Tooltip widget appear, as the example below illustrates.
Example code:
import 'package:flutter/material.dart';
class TooltipExample extends StatelessWidget {
const TooltipExample({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Tooltip(
// Set the tooltip to trigger on a single tap, tapping outside the
// widget will make the tooltip disappear.
triggerMode: TooltipTriggerMode.tap,
// The message shown when the tooltip appears.
message: "Tooltip showing!",
// Consider adjusting this to your needs.
showDuration: const Duration(days: 1),
// The widget that must be clicked to show the tooltip.
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisSize: MainAxisSize.min,
children: const [
Text("Hello"),
SizedBox(
width: 8,
),
Icon(Icons.visibility),
],
),
),
),
const Padding(
padding: EdgeInsets.all(8.0),
child: Text("Cover me!"),
)
],
),
);
}
}
// Some code to run the above example, note the theme part that turns the
// tooltip white.
class App extends StatelessWidget {
const App({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
// Style the overall design of tooltips in the app in one place,
// or provide in each tooltip individually.
theme: ThemeData(
tooltipTheme: const TooltipThemeData(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(
Radius.circular(4),
),
),
textStyle: TextStyle(
backgroundColor: Colors.white,
color: Colors.black,
),
),
),
home: const Scaffold(
backgroundColor: Colors.amber,
body: TooltipExample(),
),
);
}
}
void main() => runApp(const App());
Here is how it looks:
Note that the Tooltip widget overlays whatever is below it. (instead of pushing it further down - like toggling the visibility of a normal widget in a row or column would have done)
I am getting a range error while running my code.
I just want to show the items on my home screen but it is showing an error. Please help me. Thank you very much in advance. I don't know where I am getting this error. Here is my error output.
Exception caught by widgets library ═══════════════════════════════════════════════════════
The following RangeError was thrown building HomeScreen(dirty, dependencies: [MediaQuery, _InheritedTheme, _LocalizationsScope-[GlobalKey#4b453]]):
RangeError (index): Invalid value: Not in range 0..3, inclusive: 4
The relevant error-causing widget was:
HomeScreen file:///C:/Project/ur_info/lib/WelcomeScreen/WelcomeScreen.dart:56:45
When the exception was thrown, this was the stack:
#0 List.[] (dart:core-patch/growable_array.dart:146:60)
#1 HomeScreen.build (package:urinfo/Home/home.dart:72:45)
#2 StatelessElement.build (package:flutter/src/widgets/framework.dart:4576:28)
#3 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4502:15)
#4 Element.rebuild (package:flutter/src/widgets/framework.dart:4218:5)
...
Here is My Code
Home.Dart
import 'package:flutter/widgets.dart';
import 'package:flutter/material.dart';
import 'package:urinfo/Home/items.dart';
import 'Events.dart';
import 'categories.dart';
class HomeScreen extends StatelessWidget {
final url;
final Events events;
const HomeScreen({Key key, this.url, this.events}) : super(key: key);
#override
Widget build(BuildContext context) {
var size = MediaQuery.of(context).size;
return SafeArea(
child: Scaffold(
backgroundColor: Colors.pink[50],
body: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Container(
width: double.infinity,
decoration: BoxDecoration(
color: Colors.pink[50]
),
child: Padding(
padding: EdgeInsets.only(left: 10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
SizedBox(height: size.height*0.05 ),
Center(
child: RichText(
text: TextSpan(
style: Theme.of(context).textTheme.headline5,
children: [
TextSpan(text: "Hello Welcome Back Pratul", style: TextStyle(fontWeight: FontWeight.bold))
]
),
),
),
SizedBox(height: 10),
Center(child: Text("Categories", style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20, color: Colors.indigo),)),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Padding(
padding: EdgeInsets.only(top: 10),
child: Row(
children: <Widget>[
Categories (
name: "Btech", imageurl: "assets/icons/Btech.svg",),
Categories (
name: "BA Hons.", imageurl: "assets/icons/Bahons.svg",),
Categories (
name: "Pharmacy", imageurl: "assets/icons/nursing.svg",),
Categories (
name: "Business", imageurl: "assets/icons/Business.svg",),
],
),
),
),
SizedBox(height: size.height*.12,),
Center(child: Text("Upcomming Events", style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20, color: Colors.indigo),)),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Padding(
padding: const EdgeInsets.only(top: 15, right: 10),
child: Row(
children: <Widget>[
Events(item: items[items.length]),
SizedBox(width: 15)],
),
),
)
],
),
),
),
),
),
);
}
}
Events.Dart
import 'package:flutter/material.dart';
import 'package:urinfo/webview.dart';
import 'items.dart';
class Events extends StatelessWidget {
final Item item;
const Events({Key key, this.item}) : super(key: key);
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: (){
Navigator.push(context, MaterialPageRoute(builder: (context)=> Webview()));
},
child: Container(
width: 120,
height: 170,
child: Stack(
children: <Widget>[
Container(
height: 150,
decoration: BoxDecoration(
color: item.color,
borderRadius: BorderRadius.circular(20)
),
),
Column(
children: <Widget>[
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20)
),
child: Padding(
padding: const EdgeInsets.only(top: 5, left: 5, right: 5),
child: Image.asset(item.imageurl, fit: BoxFit.cover, width: 100,),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Center(child: Text(item.name, style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18, color: Colors.white),)),
)
],
),
],
),
),
);
}
}
Items.dart
import 'package:flutter/material.dart';
class Item {
final String imageurl, name, weburl;
final int id;
final Color color;
Item({this.color, this.imageurl, this.name, this.weburl, this.id});
}
List<Item> items=[
Item(
id: 0,
imageurl: "assets/images/Dexterix.jpg",
name: "Dexterix",
weburl: "https://dexterix.tech/",
color: Colors.black,
),
Item(
id: 1,
imageurl: "assets/images/space apps.jpg",
name: "Space Apps",
weburl: "https://dexterix.tech/",
color: Colors.black,
),
Item(
id: 2,
imageurl:"assets/images/books.jpg",
name: "Books Show",
weburl: "https://dexterix.tech/",
color: Colors.yellow[200],
),
Item(
id: 3,
imageurl: "assets/images/SIH.png",
name: "SIH",
weburl: "https://dexterix.tech/",
color: Colors.white10,
),
];
WelcomeScreen.dart
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:introduction_screen/introduction_screen.dart';
import '../Home/home.dart';
class WelcomeScreen extends StatefulWidget {
#override
_WelcomeScreenState createState() => _WelcomeScreenState();
}
class _WelcomeScreenState extends State<WelcomeScreen> {
List<PageViewModel> getPages() {
return [
PageViewModel(
image: Image.asset("assets/images/Welcom.png"),
title: ('Welcome To Ur Info'),
body: "Your Own Info App",
footer: Text("Lets Get Started"),
decoration: PageDecoration(pageColor: Colors.lightBlue[50])
),
PageViewModel(
image: Image.asset("assets/images/Exams.png"),
title: ('Get Your Exams Details'),
body: "Download your admit cards & other details",
footer: Text(""),
decoration: PageDecoration(pageColor: Colors.green[100])
), PageViewModel(
image: Image.asset("assets/images/Events.png"),
title: ('Track all the upcomming Events'),
body: "No need to worry about events",
footer: Text(""),
decoration: PageDecoration(pageColor: Colors.yellow[50])
), PageViewModel(
image: Image.asset("assets/images/study.png"),
title: ('Daily Feeds on Exams & Syllabus'),
body: "Provides daily news related to education",
footer: Text(""),
),
];
}
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: IntroductionScreen(
globalBackgroundColor: Colors.pink[50],
pages: getPages(),
onSkip: (){
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => HomeScreen()
));
},
onDone: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => HomeScreen()
));
},
showSkipButton: true,
showNextButton: true,
dotsDecorator: DotsDecorator(
color: Colors.pink,
activeColor: Colors.blueAccent[700],
),
dotsFlex: 1,
skip: Text('Skip'),
next: Text('Next'),
done: Text('Get Started'),
)
),
);
}
}
items.length == 4 while lists always start at an index of 0. Therefore it will try to find an item of index 1 to index of 4. I recommend using items.length - 1.
I found a trick that works for me, when facing the RangeError (index) error: Invalid value: Not in range 0..3, inclusive: 4 in Flutter.
Apparently it happens that the scrolling attached to the listview goes too fast to the point of exceeding the length of the array by one unit.
First I add itemCount: items.length, then in itemBuilder and before the return I insert this: if (index> = items.length) {return const Offstage (); }
A complete example:
DisplayItemsList () Widget {
final widget = ListView.builder (
physics: ScrollPhysics (),
reverse: reverse,
shrinkWrap: true,
controller: scrollControllerClientsList,
itemCount:items.length,
itemBuilder: (_, index) {
log ('displayItemsList: itemBuilder: index: $ index');
if (index> = items.length) {
return const Offstage ();
}
return displayOneOiLine (index);
},
);
I'm working on a Flutter project and I was trying to achieve an AlertDialog similar to the option's dialog specified on MaterialDesign Guidelines, but with a TextInput at the bottom.
I have managed to get something similar to what I want but I there's a problem I can't solve: when the user taps on TextInput and the keyboard appears, I'd like the TextInput to be on top of the keyboard with the listview getting smaller on the y-axis (that's why I'm just setting maxHeight on ConstrainedBox), so that the user can see what he texts, but I'm getting just the opposite, the listview keeps the same size and the InputText is not visible.
I have tried changing the listview with a column nested on a SingleChildScrollView, or wrapping the entire original Column on a SingleChildScrollView, but none of them seems to work.
This is my current code:
#override
Widget build(BuildContext context) {
return AlertDialog(
title: Text(widget.title),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(20))
),
actions: <Widget>[
FlatButton(
child: const Text('CANCEL'),
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
textColor: Theme.of(context).accentColor,
onPressed: () {
widget.onCancel();
},
),
FlatButton(
child: const Text('OK'),
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
textColor: Theme.of(context).accentColor,
onPressed: () {
widget.onOk();
},
),
],
content: Container(
width: double.maxFinite,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Divider(),
ConstrainedBox(
constraints: BoxConstraints(
maxHeight: MediaQuery.of(context).size.height*0.4,
),
child: ListView.builder(
shrinkWrap: true,
itemCount: widget.exercises.length,
itemBuilder: (BuildContext context, int index){
return RadioListTile(
title: Text(widget.exercises[index].name),
value: index,
groupValue: _selected,
onChanged: (value){
setState(() {
_selected = index;
});
}
);
}
),
),
Divider(),
TextField(
autofocus: false,
maxLines: 1,
style: TextStyle(fontSize: 18),
decoration: new InputDecoration(
border: InputBorder.none,
hintText: widget.hintText,
),
),
],
),
),
);
}
Could somebody provide me some help?
Thanks a lot!!
You can copy paste run full code below
You can in content use SingleChildScrollView
code snippet
content: SingleChildScrollView(
child: Container(
width: double.maxFinite,
working demo
full code
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class Exercise {
String name;
Exercise({this.name});
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
List<Exercise> exercises = [
Exercise(name: 'A'),
Exercise(name: 'B'),
Exercise(name: 'C'),
Exercise(name: 'D'),
Exercise(name: 'E'),
Exercise(name: 'F'),
Exercise(name: 'G')
];
int _selected;
void _incrementCounter() {
setState(() {
_counter++;
});
}
#override
Widget build(BuildContext context) {
return AlertDialog(
title: Text(widget.title),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(20))),
actions: <Widget>[
FlatButton(
child: const Text('CANCEL'),
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
textColor: Theme.of(context).accentColor,
onPressed: () {
//widget.onCancel();
},
),
FlatButton(
child: const Text('OK'),
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
textColor: Theme.of(context).accentColor,
onPressed: () {
//widget.onOk();
},
),
],
content: SingleChildScrollView(
child: Container(
width: double.maxFinite,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Divider(),
ConstrainedBox(
constraints: BoxConstraints(
maxHeight: MediaQuery.of(context).size.height * 0.4,
),
child: ListView.builder(
shrinkWrap: true,
itemCount: exercises.length,
itemBuilder: (BuildContext context, int index) {
return RadioListTile(
title: Text(exercises[index].name),
value: index,
groupValue: _selected,
onChanged: (value) {
setState(() {
_selected = index;
});
});
}),
),
Divider(),
TextField(
autofocus: false,
maxLines: 1,
style: TextStyle(fontSize: 18),
decoration: new InputDecoration(
border: InputBorder.none,
hintText: "hint",
),
),
],
),
),
),
);
}
}