Link with a image and gestureDetector - android

I am making a app for fun and to learn. When I added interactivity by first time, I found a error by adding gesturedetector. Gesture detector has to open a new function which is a window with more things. The gesture detector is inside a column, inside a container inside a ListView (The order is LsitView->Container->GestureDetector)
class _HomePageUserState extends State<HomePageUser> {
#override
Widget build(BuildContext context) {
return ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
//itemCount: 100,
itemBuilder: (context, index) {
return Center(
child: Container (
height: 300,
width: 400,
alignment:Alignment.center,
decoration: BoxDecoration(
border: Border.all(color: Colors.black),
borderRadius: BorderRadius.circular(10.0),
),
child: Stack(
children: <Widget> [
Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(padding: EdgeInsets.all(10), child: Text('Nombre del comercio'),),
Padding(padding: EdgeInsets.only(left: 10), child: Icon(Icons.open_in_new),),
],
),
Expanded(
child: GestureDetector(
child: Image.network('https://upload.wikimedia.org/wikipedia/commons/thumb/2/20/Spaghetti_Bolognese_mit_Parmesan_oder_Grana_Padano.jpg/800px-Spaghetti_Bolognese_mit_Parmesan_oder_Grana_Padano.jpg',
fit: BoxFit.fitWidth,
height: 200,),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const VistaUsuario()),
);
},
onLongPress: () {},
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(padding: EdgeInsets.all(10), child: Text('Estrellas'),),
Padding(padding: EdgeInsets.all(10), child: Text('Precio (rango)'),),
],
),
],
),
],
),
),
);
},
);
}
}
The error is:
Se produjo una excepción. FlutterError (Vertical viewport was given unbounded height. Viewports expand in the scrolling direction to fill their container. In this case, a vertical viewport was given an unlimited amount of vertical space in which to expand. This situation typically happens when a scrollable widget is nested inside another scrollable widget. If this widget is always nested in a scrollable widget there is no need to use a viewport because there will always be enough vertical space for the children. In this case, consider using a Column instead. Otherwise, consider using the "shrinkWrap" property (or a ShrinkWrappingViewport) to size the height of the viewport to the sum of the heights of its children.)

Try to wrap your GestureDetector in SingleChildScrollView .this will scroll the page.
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Test page'),
),
body:SingleChildScrollView(
child:Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
GestureDetector(
child: Image.network('https://upload.wikimedia.org/wikipedia/commons/thumb/2/20/Spaghetti_Bolognese_mit_Parmesan_oder_Grana_Padano.jpg/800px-Spaghetti_Bolognese_mit_Parmesan_oder_Grana_Padano.jpg',
fit: BoxFit.fitWidth,
height: 200,),
onTap: () {
Navigator.push(context, MaterialPageRoute(builder: (context) => const VistaUsuario()),
);
},
),
],
),
),
),
);
}
Another Solution is to use Expanded widget.This will expand the image to take rest of the page
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Test page'),
),
body:Center(
child:Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 0,
),
Expanded(
child: GestureDetector(
child: Image.network('https://upload.wikimedia.org/wikipedia/commons/thumb/2/20/Spaghetti_Bolognese_mit_Parmesan_oder_Grana_Padano.jpg/800px-Spaghetti_Bolognese_mit_Parmesan_oder_Grana_Padano.jpg',
fit: BoxFit.fitWidth,
height: 200,),
onTap: () {
Navigator.push(context, MaterialPageRoute(builder: (context) => const VistaUsuario()),
);
},
),
),
],
),
),
),
);
}

Related

How to have a ListView without scrolling the parent column view in flutter?

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'));
}

How to fix overflow in flutter

here is my app
as you can see working well, I installed this on my phone, and it works fine too.
and I send this to my friend, and his phone showing like this
mine and his phone is same phone, literally same phone, but in his and any others phone is showing this overflow, mine and this emulator have no problem, how do i fix overflow problem
class Homescreen extends StatelessWidget {
const Homescreen({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: AppBar(
title: const Text("Pluto Guess Game"),
backgroundColor: Colors.white60,
),
body: Container(
color: Colors.white,
child: SafeArea(
child: ListView(
children: [
Card(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
PlayerWidget(
player: messi
),
PlayerWidget(
player: neymar
)
],
),
),
Card(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
PlayerWidget(
player: mbappe
)
PlayerWidget(
player: ramos
)
],
),
),
Card(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
PlayerWidget(
player: messi
),
PlayerWidget(
player: neymar
)
],
),
),
Card(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
PlayerWidget(
player: messi
),
PlayerWidget(
player: neymar
)
],
),
),
Card(
child: IconButton(
icon: const Icon(Icons.gesture),
iconSize: 50,
color: Colors.black,
splashColor: Colors.orange,
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (nav) {
return const Asking();
},
),
);
},
),
),
],
),
),
),
),
);
}
}
and also I'm new at flutter, I know I'm doing lot of mistake in this code please suggest that also
->Use This Code
Widget build(BuildContext context) {
double h = MediaQuery.of(context).size.height;
double w = MediaQuery.of(context).size.width;
return Scaffold(
appBar: getAppBar(context, "Back", "", []),
body: SafeArea(
top: true,
bottom: true,
child: Column(
children: [
Expanded(
child: ListView.builder(
shrinkWrap: true,
physics: BouncingScrollPhysics(),
itemCount: 15,
itemBuilder: (context,v){
return
Container(
padding: EdgeInsets.only(left: 15.0,right: 15.0),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
height: h*0.2,
width: w*0.4,
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.circular(25.0)
),
),
Container(
height: h*0.2,
width: w*0.4,
decoration: BoxDecoration(
color: Colors.black38,
borderRadius: BorderRadius.circular(25.0)
),
),
],
),
SizedBox(height: 15.0,),
Divider(
color: Colors.black,
),
SizedBox(height: 15.0,),
],
),
);
}),
)
],
),
),
);
}
Without your code I can't make corrections to the current code. but if you need responsive UI that work regardless of screen size, I suggest you use Rows, Columns with Expanded Widget, as necessary.
for example if you need to have 2 Items inside a Row where each occupies same space you can use,
Row (
children: [
Expanded (
flex:1
child: YourWidget()
),
Expanded (
flex:1
child: YourWidget()
)
]
)
Remember to remove hardcoded size properties along the main axis of your Colum or Row.
Same goes for Columns.
If you need each to have varied sizes, you can use flex property of the Expanded Widget. for example, one items has 1/3 of width and other has 2/3 you can put 1 and 2 as flex values.
more explanation from flutter team: Expanded

How to slide pages under appbar flutter

I've been trying so hard to build page view system for quotes app. I want the page to flow full screen from top to bottom and bottom to top scrollable/swipe able to navigate between different quotes each time
like this. The scroll will bring new page each time its not casual scroll. I haven't found any guide regarding this on internet so far.
I don't know about how to build it, nothing is popping in my mind for days now. I've tried pageview with gesture detector for swiping up and down, it doesn't works as desired and appbar is static too and the bottom containers as well I don't want this. What I want is the page/screen to flow under the appbar or even a button on top right corner and under 2 buttons on the bottom.
Create a column of Containers where each Container's height and width equals the height and width of the screen. You can do that by using:
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
Also, make sure to wrap your code with a SingleChildScrollView widget to scroll vertically.
Here's the code:
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: SingleChildScrollView(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Center(child: Text('Quote number one')),
Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
IconButton(icon: Icon(Icons.share), onPressed: () {}),
IconButton(
icon: Icon(Icons.favorite), onPressed: () {})
],
),
)
],
),
),
Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: Column(
children: [
Text('Quote number two'),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
IconButton(icon: Icon(Icons.share), onPressed: () {}),
IconButton(icon: Icon(Icons.favorite), onPressed: () {})
],
)
],
),
)
],
),
),
),
);
}
}
You can use PageView to get this type of view
Drive Video link
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
PageController pageController;
PageView pageView;
List<String> quotes = [
'#Quote 1\n\n“I\'m selfish, impatient and a little insecure. I make mistakes, I am out of control and at times hard to handle. But if you can\'t handle me at my worst, then you sure as hell don\'t deserve me at my best.” ',
'#Qoute 2\n\nSo many books, so little time.',
'#Quote 3\n\n A room without books is like a body without a soul'
];
#override
void initState() {
super.initState();
pageController = PageController();
final _quotes = List.generate(quotes.length, (index) => quoteWidget(index));
pageView = PageView(
children: _quotes,
controller: pageController,
scrollDirection: Axis.vertical,
);
}
Widget quoteWidget(int index) {
return Scaffold(
backgroundColor: Colors.black,
body: Column(
children: [
Expanded(
flex: 3,
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Center(
child: Text(
quotes[index],
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w300,
color: Colors.white,
),
),
),
),
),
Expanded(
flex: 1,
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
FloatingActionButton(
onPressed: () {},
child: Icon(Icons.share),
),
const SizedBox(width: 20),
FloatingActionButton(
onPressed: () {},
child: Icon(Icons.favorite_border),
),
],
),
),
Expanded(child: Container())
],
),
);
}
#override
void dispose() {
pageController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
appBar: AppBar(
brightness: Brightness.dark,
title: Text(widget.title),
),
body: SafeArea(
child: Stack(
alignment: Alignment.bottomCenter,
children: [
pageView,
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
child: Row(
children: [
RaisedButton.icon(
icon: Icon(Icons.menu_book),
label: Text('General'),
onPressed: () {},
),
const Spacer(),
Container(
width: 50,
height: 50,
margin: const EdgeInsets.symmetric(horizontal: 10),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(5),
),
child: Icon(Icons.color_lens),
),
Container(
width: 50,
height: 50,
margin: const EdgeInsets.symmetric(horizontal: 10),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(5),
),
child: Icon(Icons.person),
),
],
),
)
],
),
),
);
}
}

Container is wrap the text widget but why the button widget get affected by the textAlign?

Sir, In code I am wrapping the only Text widget. After that I used some custom style like text align. But after use I expected to center only the text part because only this widget get wrapped not to the other. But I saw my button also get centered. How it possible? I was wrapped one widget but my other widget get affected. What's logic into there, sir?
You need to set a crossAxisAlignment: CrossAxisAlignment.start, and wrap the headline text with center widget. hope the below code can show you a good example.
class Demo extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("title"),
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Center(
child: Text("Whats your favourite food?"),
),
RaisedButton(
onPressed: () {},
child: Container(
padding: EdgeInsets.zero,
decoration: BoxDecoration(),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text("Answer 1"),
),
),
),
RaisedButton(
onPressed: () {},
child: Container(
padding: EdgeInsets.zero,
decoration: BoxDecoration(),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text("Answer 1"),
),
),
),
RaisedButton(
onPressed: () {},
child: Container(
padding: EdgeInsets.zero,
decoration: BoxDecoration(),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text("Answer 1"),
),
),
),
],
),
);
}
}
Set column widget's mainaxisalignement to start, or wrap all widget that you don't want to center in a column

current way to use List in flutter for scrollable with expanded or flex

my screen is not scrollable , and has limit height ( only scrollable in the limit height )
I do want to make my page on there for scrollable,
here is my current page now :
if you see in the gif above, my page is not scrollable and only stuck in the one box and scrollable inside, I do love to scroll able them for all page normally, should I use ListView here ?? but how can I make the pic and text for responsive like above ? but I do make the hight of text too close also, can I know how u tiny up the text on the list also ??
here is my code for that Widget
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
data['title'],
softWrap: true,
),
),
body: Container(
padding: EdgeInsets.all(MediaQuery.of(context).size.width * 0.05),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Expanded(
flex: 1,
child: Align(
alignment: Alignment.center,
child: Image.network('https://i.ibb.co/nrWqyMx/belgium.png'),
)
),
Expanded(
flex: 2,
child: Align(
alignment: Alignment.topLeft,
child: ListView.builder(
itemBuilder: (ctx, index) {
return Container(
height: MediaQuery.of(context).size.width * 0.14,
child: ListTile(
leading: Icon(Icons.radio_button_checked, size: 17),
title: Text(data['ingredients'][index], style: TextStyle(height: 1.3),),
)
);
},
itemCount: data['ingredients'].length,
),
)
)
],
),
),
);
}
link : flutter codepen
Scaffold(
appBar: AppBar(
title: Text(
'MyAppBar',
style:
TextStyle(color: Colors.cyan[100], fontWeight: FontWeight.bold),
),
),
body: ListView(
children: <Widget>[
Container(
child: Image.network
('https://i.ibb.co/nrWqyMx/belgium.png'),
),
ListView.builder(
physics: ScrollPhysics(),
shrinkWrap: true,
itemBuilder: (ctx, index) {
return Container(
height: MediaQuery.of(context).size.width * 0.14,
child: ListTile(
leading: Icon(Icons.radio_button_checked, size: 17),
title: Text("data['ingredients'][index]", style: TextStyle(height: 1.3),),
)
);
},
itemCount:25,
)
],
),
);
You will need put a ScrollView as a main container of your widget. Something like this:
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
color: Colors.red,
child: SingleChildScrollView(
child: Column(
children: [
Text("Title"),
ListView.builder(
shrinkWrap: true,
itemCount: 3,
itemBuilder: (context, index) {
return Container(
height: 300,
width: double.infinity,
decoration: BoxDecoration(
color: Colors.blue,
border: Border.all(
color: Colors.black,
style: BorderStyle.solid
)
),
);
},
)
],
),
),
)
);
}
}

Categories

Resources