How to Scroll multiple Textfields together in Flutter - android

I have a situation where 2 Textfields are placed inside a Stack Widget overlapping one another. Is there anyway i can scroll both the textfields together vertically if the data exceeds the size of the screen?
Stack(
children: [
Container(
width: MediaQuery.of(context).size.width,
padding: EdgeInsets.fromLTRB(15, 8, 0, 0),
child: SyntaxView(
code: codeController.text,
syntax: Syntax.C,
syntaxTheme: SyntaxTheme.gravityDark(),
withZoom: true,
withLinesCount: true),
),
Container(
width: 362,
padding: EdgeInsets.fromLTRB(55, 12, 0, 0),
child: TextFormField(
scrollPhysics: NeverScrollableScrollPhysics(),
focusNode: codeFocus,
controller: codeController,
autofocus: true,
keyboardType: TextInputType.multiline,
maxLines: null,
style: TextStyle(
color: Color(0x00ffffff),
// color: Colors.yellow,
height: 1.35,
fontFamily: "CodeFont",
fontSize: 12,
),
decoration: InputDecoration(
border: InputBorder.none,
),
onChanged: (value) {
setState(() {
CODE = value;
// print("X : ${codeController.text}");
});
},
),
),
],
),

A simple way way to handle that situation is to wrap your content in a ListView, which handles scrolling of its children. Here's a snippet from the ListView docs as an example:
ListView(
padding: const EdgeInsets.all(8),
children: <Widget>[
Container(
height: 50,
color: Colors.amber[600],
child: const Center(child: Text('Entry A')),
),
Container(
height: 50,
color: Colors.amber[500],
child: const Center(child: Text('Entry B')),
),
Container(
height: 50,
color: Colors.amber[100],
child: const Center(child: Text('Entry C')),
),
],
)
https://api.flutter.dev/flutter/widgets/ListView-class.html

Related

How do i make the last widget always be at the bottom of the screen?

So i'm currently creating a detail page. Im trying to get a particular look and ive tried quite a few different approach such as using expanded Slivefill but im unable to get the desired look.
From the above image, From the left the first case is acceptable as there is a larger amount of text, the second image is where i have a problem. im trying to get it the very least fill to bottom of the screen.
the last image is the ideal condition i would like to achieve if there is a smaller amount of data.
if anybody could assist or point me to the right direction it would be highly appreciated
Scaffold(
body: CustomScrollView(
slivers: [
SliverAppBar(
bottom: PreferredSize(
preferredSize: const Size(0, 1),
child: Container(),
),
pinned: false,
expandedHeight: MediaQuery.of(context).size.height * 0.4,
centerTitle: true,
flexibleSpace: Stack(
children: [
Positioned(
child: FlexibleSpaceBar(
background: Image.network(
loadedEvent.imageUrl,
fit: BoxFit.cover,
),
),
),
Positioned(
bottom: -1,
left: 0,
right: 0,
child: Container(
height: 20,
decoration: const BoxDecoration(
color: Color(0xfffffcf2),
borderRadius: BorderRadius.vertical(
top: Radius.circular(20),
),
),
),
),
],
),
),
SliverToBoxAdapter(
child: SingleChildScrollView(
child: Container(
color: Color(0xfffffcf2),
child: ListView(
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
padding: const EdgeInsets.all(20.0),
children: [
Text(
loadedEvent.title,
textAlign: TextAlign.center,
style: const TextStyle(
fontSize: 40,
fontWeight: FontWeight.bold,
letterSpacing: 1.0,
),
),
Spacer(),
Flexible(
fit: FlexFit.tight,
flex: 8,
child: RichText(
text: TextSpan(
style: const TextStyle(
color: Colors.black,
fontSize: 18.0,
),
text: loadedEvent.description,
),
),
),
Spacer(),
Flexible(
fit: FlexFit.loose,
child: Container(
color: Colors.black,
child: Text(loadedEvent.date),
),
),
],
),
),
),
),
],
),
);
Is this what you want to achieve?
#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: [
CustomScrollView(
slivers: [
SliverAppBar(
bottom: PreferredSize(
preferredSize: const Size(0, 1),
child: Container(),
),
pinned: false,
expandedHeight: MediaQuery.of(context).size.height * 0.4,
centerTitle: true,
flexibleSpace: Stack(
children: [
Positioned(
child: FlexibleSpaceBar(
background: Image.network(
loadedEvent.imageUrl,
fit: BoxFit.cover,
),
),
),
Positioned(
bottom: -1,
left: 0,
right: 0,
child: Container(
height: 20,
decoration: const BoxDecoration(
color: Color(0xfffffcf2),
borderRadius: BorderRadius.vertical(
top: Radius.circular(20),
),
),
),
),
],
),
),
SliverToBoxAdapter(
child: Container(
color: const Color(0xfffffcf2),
height: MediaQuery.of(context).size.height,
padding: const EdgeInsets.all(20.0),
child: Column(
children: [
Text(
loadedEvent.title,
textAlign: TextAlign.center,
style: const TextStyle(
fontSize: 40,
fontWeight: FontWeight.bold,
letterSpacing: 1.0,
),
),
const Spacer(),
Flexible(
fit: FlexFit.tight,
flex: 8,
child: RichText(
text: TextSpan(
style: const TextStyle(
color: Colors.black,
fontSize: 18.0,
),
text: loadedEvent.description,
),
),
),
const Spacer(),
],
),
),
),
],
),
Positioned(
bottom: 0.0,
child: Container(
color: Colors.black,
padding: const EdgeInsets.all(8.0),
width: MediaQuery.of(context).size.width,
child: Text(
loadedEvent.date,
style: const TextStyle(
color: Colors.white,
),
textAlign: TextAlign.center,
),
),
),
],
),
);
}
You can use flexible widget to the previous widget to set last widget to end of the screen. But you can't use scrollview otherwise ypu will get an error.

Flutter: Stack Overlap widget with second widget

Image link
How can I push the child widget outside the stack's bound.
I want to overlap the search bar at AppBar widget.
Stack's overflow property not working what we use instead of it.
I am using the positioned widget to move on child widget to outside the stack's boundary, but it remains same I am getting issue I need solution for this.
This is my code
PreferredSize _buildAppBar() {
return PreferredSize(
preferredSize: const Size.fromHeight(100),
child: AppBar(
centerTitle: true,
elevation: 0,
backgroundColor: Colors.transparent,
flexibleSpace: Stack(
clipBehavior: Clip.none,
fit: StackFit.loose,
// alignment: AlignmentDirectional.bottomEnd,
children: [
Expanded(
child: Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage('images/gym.jpg'), fit: BoxFit.cover),
),
),
),
Positioned(
bottom: 0,
left: 0,
right: 0,
// top: 90,
child: Container(
margin: const EdgeInsets.symmetric(horizontal: 10),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30),
// ignore: prefer_const_constructors
boxShadow: const [
BoxShadow(color: Colors.black12, blurRadius: 5)
]),
child: TextFormField(
// controller: controller,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(30),
borderSide: BorderSide.none,
),
hintText: 'Search Your Product',
hintStyle: TextStyle(color: Colors.grey[400]),
contentPadding:
const EdgeInsets.only(left: 22, right: 12),
fillColor: Colors.white,
filled: true,
suffixIcon: IconButton(
onPressed: () {},
icon: const Icon(
Icons.search,
size: 30,
))),
// obscureText: obscureText,
),
),
),
],
),
title: const Text(
'Home',
style: TextStyle(
color: Colors.white,
),
),
),
);
}
One of possilbe ways is to use CustomScrollView with SliverAppBar and Stack
Here is the link to one of the solutions

use textField and listview.builder in bottom sheet

Hey everyone I'm new to flutter and I have a problem.
I want to create an application that users after tapping on the Btn the bottom sheet will be open and after that ( here problem ) show the text field(for search) and the listView.
problem: when I do this nothing show me( even the bottom sheet don't appear)
this is my code :
enter code here
GestureDetector(
onTap: () {
showModalBottomSheet(
// ---------------------//
context: context,
builder: (context) {
return Container(
color: Color(0xff737373),
// to make the radius visible
child: Container(
decoration: BoxDecoration(
color: Theme.of(context).canvasColor,
borderRadius: BorderRadius.only(topLeft: Radius.circular(10), topRight: Radius.circular(10))),
child: countriesInfo == null
? Center(
child: CircularProgressIndicator(),
)
: Column(
children: <Widget>[
Container(
padding: EdgeInsets.all(10),
child: TextField(
keyboardType: TextInputType.text,
decoration: InputDecoration(
labelText: 'country',
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(10)),
),
),
),
),
ListView.builder(
itemBuilder: (context, index) {
return GestureDetector(
onTap: () {
_selectItem(countriesInfo[index]);
},
child: Container(
padding: EdgeInsets.only(left: 10, right: 10),
height: 50,
decoration: BoxDecoration(
color: Colors.white,
boxShadow: [BoxShadow(color: Colors.grey, blurRadius: 10, offset: Offset(0, 10))],
),
child: Row(
children: [
Image.network(
countriesInfo[index]._flag,
width: 50,
height: 50,
),
Text(
countriesInfo[index]._name,
style: TextStyle(fontSize: 15, fontWeight: FontWeight.bold),
),
],
), // name of the country
),
);
},
itemCount: countriesInfo == null ? 0 : countriesInfo.length,
),
],
)),
);
}); // end bottom nav
},
child: Container(
width: double.infinity,
margin: EdgeInsets.all(35),
padding: EdgeInsets.all(10),
decoration: BoxDecoration(color: Color(0xFFA3A3A3), borderRadius: BorderRadius.all(Radius.circular(15))),
child: Center(
child: Text(
"${selectedCountry == null ? countriesInfo[0].name : selectedCountry!.name.toString()}",
style: TextStyle(fontSize: 18),
),
),
),
),
if know any documentation or idea tell me please thank you.

How can I vertically center all the widgets inside a ListView?

I have this main screen with a ListView:
Screenshot
I decided to use a ListView as it resulted in screen overflow error each time the keyboard opened up.
This is my code:
ListView(children: [
Align(
alignment: Alignment.topCenter,
child: Padding(
padding: const EdgeInsets.only(top: 46.0, bottom: 8),
child: ClipRect(
child: Image.asset(
'images/icon.png',
scale: 2,
),
),
),
),
Align(
alignment: Alignment.center,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 24.0, vertical: 12.0),
child: TextField(
controller: _word,
textAlign: TextAlign.center,
decoration: InputDecoration(
suffixIcon: IconButton(
icon: Icon(Icons.close),
onPressed: () {
_word.text = '';
},
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.0),
),
filled: true,
fillColor: Colors.lightGreen[200],
hintStyle: TextStyle(color: Colors.green),
hintText: 'Enter a word',
),
),
),
),
Align(
alignment: Alignment.bottomCenter,
child: Padding(
padding: const EdgeInsets.only(top: 16, bottom: 12),
child: ConstrainedBox(
constraints: BoxConstraints.tightFor(width: 65, height: 65),
child: ElevatedButton(
style: ButtonStyle(
shape: MaterialStateProperty.all<CircleBorder>(CircleBorder())),
child: Icon(Icons.search),
onPressed: () async {
detectNetStatus(context);
String word = _word.text;
_word.text = '';
Navigator.push(context, MaterialPageRoute(builder: (context) {
return word == '' ? RandomResults() : Results(word);
}));
}),
),
),
),
]),
I've also used the Align widget on all the three screen widgets. But it seems that the use of Align practically has no effect on the placement of the three widgets.
I want to place the three widgets in such a way that the space above and below the three widgets is equal (or in other words, I want to group and place them in a vertically centered alignment).
This code will help you to get the concepet. if you need layoutSize wrap Stack with LayoutoutBuilder to get the constrains.
#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: [
Align(
alignment: Alignment.topCenter,
child: Padding(
padding: const EdgeInsets.only(top: 46.0, bottom: 8),
child: ClipRect(
child: Image.asset(
// 'images/icon.png',
"assets/me.jpg",
scale: 2,
),
),
),
),
Align(
/// change this value according to your desire
alignment: Alignment(0, .2),
child: ListView(
shrinkWrap: true,
children: [
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 24.0, vertical: 12.0),
child: TextField(
// controller: _word,F
textAlign: TextAlign.center,
decoration: InputDecoration(
suffixIcon: IconButton(
icon: Icon(Icons.close),
onPressed: () {
// _word.text = '';
},
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.0),
),
filled: true,
fillColor: Colors.lightGreen[200],
hintStyle: TextStyle(color: Colors.green),
hintText: 'Enter a word',
),
),
),
Padding(
padding: const EdgeInsets.only(top: 16, bottom: 12),
child: ConstrainedBox(
constraints: BoxConstraints.tightFor(width: 65, height: 65),
child: ElevatedButton(
style: ButtonStyle(
shape: MaterialStateProperty.all<CircleBorder>(
CircleBorder())),
child: Icon(Icons.search),
onPressed: () async {
// detectNetStatus(context);
// String word = _word.text;
// _word.text = '';
// Navigator.push(context,
// MaterialPageRoute(builder: (context) {
// return word == '' ? RandomResults() : Results(word);
// }));
}),
),
),
],
),
),
],
),
);
}
Here is the solution for your code to align the widget with centered with using of the Flex widget.
Widget build(BuildContext context) {
return Scaffold(
body: LayoutBuilder(
builder: (context, viewportConstraints) {
return SingleChildScrollView(
child: ConstrainedBox(
constraints: viewportConstraints.copyWith(
minHeight: viewportConstraints.maxHeight,
maxHeight: double.infinity,
),
child: Flex(
direction: Axis.vertical,
mainAxisAlignment: MainAxisAlignment.center,
children: [
ClipRect(
child: Image.asset(
"images/icon.png",
scale: 2,
),
),
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 10.0, vertical: 30.0),
child: TextField(
controller: _word,
textAlign: TextAlign.center,
decoration: InputDecoration(
suffixIcon: IconButton(
color: Colors.green,
icon: Icon(Icons.close),
onPressed: () {
_word.text = '';
},
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.0),
),
filled: true,
fillColor: Colors.yellow[50],
hintStyle: TextStyle(color: Colors.green),
hintText: 'Enter a word',
),
),
),
Padding(
padding: const EdgeInsets.only(bottom: 10.0),
child: ConstrainedBox(
constraints: BoxConstraints.tightFor(width: 65, height: 65),
child: ElevatedButton(
style: ButtonStyle(
shape: MaterialStateProperty.all<CircleBorder>(
CircleBorder())),
child: Icon(Icons.search),
onPressed: () async {
detectNetStatus(context);
String word = _word.text;
_word.text = '';
Navigator.push(context,
MaterialPageRoute(builder: (context) {
return word == '' ? RandomResults() : Results(word);
}));
}),
),
),
],
),
),
);
},
),
);
}

A RenderFlex overflowed by 128 pixels on the bottom

enter image description here
The relevant error-causing widget was:
Column file:///F:/App/Market/1.7/flutter_application/lib/src/pages/cart.dart:71:21
The overflowing RenderFlex has an orientation of Axis.vertical.
The edge of the RenderFlex that is overflowing has been marked in the rendering with a yellow and black striped pattern. This is usually caused by the contents being too big for the RenderFlex.
Consider applying a flex factor (e.g. using an Expanded widget) to force the children of the RenderFlex to fit within the available space instead of being sized to their natural size.
This is considered an error condition because it indicates that there is content that cannot be seen. If the content is legitimately bigger than the available space, consider clipping it with a ClipRect widget before putting it in the flex, or using a scrollable container rather than a Flex, like a ListView.
The specific RenderFlex in question is: RenderFlex#22d62 relayoutBoundary=up3 OVERFLOWING
... needs compositing
... parentData: not positioned; offset=Offset(0.0, 0.0) (can use size)
... constraints: BoxConstraints(0.0<=w<=411.4, 0.0<=h<=403.4)
... size: Size(411.4, 403.4)
... direction: vertical
... mainAxisAlignment: start
... mainAxisSize: max
... crossAxisAlignment: center
... verticalDirection: down
◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤
════════════════════════════════════════════════════════════════════════════════════════════════════
body: RefreshIndicator(
onRefresh: _con.refreshCarts,
child: _con.carts.isEmpty
? EmptyCartWidget()
: Stack(
alignment: AlignmentDirectional.bottomCenter,
children: [
Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(left: 20, right: 10),
child: ListTile(
contentPadding: EdgeInsets.symmetric(vertical: 0),
leading: Icon(
Icons.shopping_cart,
color: Theme.of(context).hintColor,
),
title: Text(
S.of(context).shopping_cart,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: Theme.of(context).textTheme.headline4,
),
subtitle: Text(
S
.of(context)
.verify_your_quantity_and_click_checkout,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: Theme.of(context).textTheme.caption,
),
),
),
ListView.separated(
padding: EdgeInsets.symmetric(vertical: 15),
scrollDirection: Axis.vertical,
shrinkWrap: true,
primary: true,
itemCount: _con.carts.length,
separatorBuilder: (context, index) {
return SizedBox(height: 15);
},
itemBuilder: (context, index) {
return CartItemWidget(
cart: _con.carts.elementAt(index),
heroTag: 'cart',
increment: () {
_con.incrementQuantity(
_con.carts.elementAt(index));
},
decrement: () {
_con.decrementQuantity(
_con.carts.elementAt(index));
},
onDismissed: () {
_con.removeFromCart(
_con.carts.elementAt(index));
},
);
},
),
],
),
Container(
padding: const EdgeInsets.all(18),
margin: EdgeInsets.only(bottom: 15),
decoration: BoxDecoration(
color: Theme.of(context).primaryColor,
borderRadius: BorderRadius.all(Radius.circular(20)),
boxShadow: [
BoxShadow(
color: Theme.of(context)
.focusColor
.withOpacity(0.15),
offset: Offset(0, 2),
blurRadius: 5.0)
]),
child: TextField(
keyboardType: TextInputType.text,
onSubmitted: (String value) {
_con.doApplyCoupon(value);
},
cursorColor: Theme.of(context).accentColor,
controller: TextEditingController()
..text = coupon?.code ?? '',
decoration: InputDecoration(
contentPadding: EdgeInsets.symmetric(
horizontal: 20, vertical: 15),
floatingLabelBehavior: FloatingLabelBehavior.always,
hintStyle: Theme.of(context).textTheme.bodyText1,
suffixText: coupon?.valid == null
? ''
: (coupon.valid
? S.of(context).validCouponCode
: S.of(context).invalidCouponCode),
suffixStyle: Theme.of(context)
.textTheme
.caption
.merge(
TextStyle(color: _con.getCouponIconColor())),
suffixIcon: Padding(
padding: const EdgeInsets.symmetric(horizontal: 15),
child: Icon(
Icons.confirmation_number,
color: _con.getCouponIconColor(),
size: 28,
),
),
hintText: S.of(context).haveCouponCode,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(30),
borderSide: BorderSide(
color: Theme.of(context)
.focusColor
.withOpacity(0.2))),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(30),
borderSide: BorderSide(
color: Theme.of(context)
.focusColor
.withOpacity(0.5))),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(30),
borderSide: BorderSide(
color: Theme.of(context)
.focusColor
.withOpacity(0.2))),
),
),
),
],
),
),
Wrap your column childrens with Expanded widget like this .
Column(
children: <Widget>[
Expanded(
child :
Padding(
padding: const EdgeInsets.only(left: 20, right: 10),
child: ListTile(
contentPadding: EdgeInsets.symmetric(vertical: 0),
leading: Icon(
Icons.shopping_cart,
color: Theme.of(context).hintColor,
),
title: Text(
S.of(context).shopping_cart,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: Theme.of(context).textTheme.headline4,
),
subtitle: Text(
S
.of(context)
.verify_your_quantity_and_click_checkout,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: Theme.of(context).textTheme.caption,
),
),
)),
Expanded(
child :
ListView.separated(
padding: EdgeInsets.symmetric(vertical: 15),
scrollDirection: Axis.vertical,
shrinkWrap: true,
primary: true,
itemCount: _con.carts.length,
separatorBuilder: (context, index) {
return SizedBox(height: 15);
},
itemBuilder: (context, index) {
return CartItemWidget(
cart: _con.carts.elementAt(index),
heroTag: 'cart',
increment: () {
_con.incrementQuantity(
_con.carts.elementAt(index));
},
decrement: () {
_con.decrementQuantity(
_con.carts.elementAt(index));
},
onDismissed: () {
_con.removeFromCart(
_con.carts.elementAt(index));
},
);
},
)),
],
)
enter image description here
The issue has been resolved, but another problem has appeared
There is an empty space that I can no longer press

Categories

Resources