So i want to call my ChatMessages() in my scaffold, however I do not know where to call it without getting an error, here is my ChatMessages() function;
Widget chatMessages() {
return StreamBuilder(
stream: messageStream,
builder: (context, snapshot) {
return snapshot.hasData
? ListView.builder(
itemCount: snapshot.data.docs.length,
itemBuilder: (context, index) {
DocumentSnapshot ds = snapshot.data.docs[index];
return Text(ds["message"]);
})
: Center(
child: CircularProgressIndicator(),
);
},
);
then here is my scaffold;
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.chatWithUsername),
),
body: Column(
children: [
Spacer(),
Container(
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 10),
decoration: BoxDecoration(
color: Theme.of(context).scaffoldBackgroundColor,
),
child: SafeArea(
child: Row(
children: [
Icon(Icons.attach_file),
SizedBox(
width: 20,
),
Expanded(
child: Container(
padding: EdgeInsets.symmetric(horizontal: 20 * 0.75),
decoration: BoxDecoration(
color: Colors.green.withOpacity(0.05),
borderRadius: BorderRadius.circular(40)),
child: Row(
children: [
SizedBox(
width: 20 / 4,
),
Expanded(
child: TextField(
controller: TextEditingController(),
decoration: InputDecoration(
hintText: "Send a message",
border: InputBorder.none),
)),
Icon(
Icons.send,
color: Theme.of(context)
.textTheme
.bodyText1
.color
.withOpacity(0.64),
),
],
Where can I implement the Chatmessages() within the scaffold to receive the data? For context I am adding messaging functionality to my app and this seems like a very easy fix however I cant figure it out :')
Ok, you'll need to have the following layout in your build function:
#override
Widget build(BuildContext context) {
return Container(
color: Theme.of(context).scaffoldBackgroundColor,
child: SafeArea(
top: false,
child: Scaffold(
appBar: AppBar(),
body: Column(
children: [
Expanded(
child: StreamBuilder<String>(),
),
MessageEntryWidget(),
],
),
),
),
);
}
should be something like this then:
#override
Widget build(BuildContext context) {
return Container(
color: Theme.of(context).scaffoldBackgroundColor,
child: SafeArea(
top: false,
child: Scaffold(
appBar: AppBar(
title: Text('chatWithUsername'),
),
body: Column(
children: [
Expanded(
child: StreamBuilder<String>(
stream: messageStream,
builder: (context, snapshot) {
return ListView.builder(
itemCount: itemCount,
itemBuilder: (context, index) {
//DocumentSnapshot ds = snapshot.data.docs[index];
return Text('message');
},
);
}),
),
Padding(
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 4),
child: Row(
children: [
Icon(Icons.attach_file),
SizedBox(
width: 20,
),
Expanded(
child: Container(
padding: EdgeInsets.symmetric(horizontal: 20 * 0.75),
decoration: BoxDecoration(
color: Colors.green.withOpacity(0.05),
borderRadius: BorderRadius.circular(40)),
child: Row(
children: [
SizedBox(
width: 20 / 4,
),
Expanded(
child: TextField(
controller: TextEditingController(),
decoration: InputDecoration(
hintText: 'Send a message',
border: InputBorder.none),
)),
Icon(
Icons.send,
color: Theme.of(context)
.textTheme
.bodyText1
?.color
?.withOpacity(0.64) ??
Colors.red,
)
],
),
),
)
],
),
),
],
),
),
),
);
}
Wrap the ListView.builder in the StreamBuilder you have ...
Related
I am creating simple listview builder where its content is a container that having a Text, here I want to set container's width based on length of text,
but I am getting maximum width instead of text width.
and y is it taking maximum width...
(simple example, whatsapp chattext)
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(body: SafeArea(
child: Column(children: [
Expanded(
child: ListView.builder(
itemCount: expenselist.length,
itemBuilder: (context,index){
return Padding(
padding: EdgeInsets.only(bottom: 5),
child: Container(
padding: EdgeInsets.all(20),
color: Colors.blue,
child: Text(expenselist[index]['Amount'].toString()),
),
);
}),
),
Container(
color: Colors.blue[100],
child: TextField(
decoration: InputDecoration(
hintText: 'Enter Amount'
),
),
),
],),
),),
);
}
you have to wrap your container with Align widget then wrap it again with another container. Your code should be like this:
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: SafeArea(
child: Column(
children: [
Expanded(
child: ListView.builder(
itemCount: 10,
itemBuilder: (context, index) {
return Container(
child: Align(
child: Padding(
padding: const EdgeInsets.only(bottom: 5),
child: Container(
padding: const EdgeInsets.all(20),
color: Colors.blue,
child: const Text('Test content'),
),
),
),
);
}),
),
Container(
color: Colors.blue[100],
child: const TextField(
decoration: InputDecoration(hintText: 'Enter Amount'),
),
),
],
),
),
),
);
}
I leave the entire code fragment, the main idea is to have a textfield that, by using the keyboard, shows me a series of elements, in the description variable, I have that element to select, this works well, the only issue is, how to keep my alertdialog with all the correct notes.
return await Get.generalDialog(
barrierLabel: "Barrier",
barrierDismissible: false,
transitionBuilder: (context, a1, a2, widget) {
return StatefulBuilder(builder: (context, setState) {
return Transform.scale(
scale: a1.value,
child: Opacity(
opacity: a1.value,
child: Dialog(
insetAnimationCurve: Curves.bounceOut,
insetPadding: EdgeInsets.only(right: 20, left: 20),
//backgroundColor: colorFour(),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12.0),
),
child: SingleChildScrollView(
child: Container(
height: 340,
child: Column(
children: <Widget>[
Container(
alignment: Alignment.topCenter,
height: 50,
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(12),
topRight: Radius.circular(12),
),
),
padding: EdgeInsets.all(5),
child: Center(
child: Text(
title,
style: TextStyle(
color: Colors.white,
fontSize: 18,
fontWeight: FontWeight.w600),
maxLines: 2,
textAlign: TextAlign.center,
),
),
),
SingleChildScrollView(
padding: EdgeInsets.only(left: 10, right: 10),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.stretch,
children: [
Container(
margin: EdgeInsets.only(top: 10),
child: TextFormField(
controller: controller,
decoration: InputDecoration(
border: OutlineInputBorder(
gapPadding: 5.0)),
keyboardType: TextInputType.text,
maxLines: 1,
onChanged: (String cadena) async {
listado = pivote
.where((x) => x.descripcion
.split("/")[value]
.toLowerCase()
.contains(
cadena.toLowerCase()))
.toList();
setState(() {});
},
),
),
Container(
height: 200,
margin: EdgeInsets.only(
top: 10, bottom: 10.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(
Radius.circular(5)),
border: Border.all(
color: Colors.grey, width: 1)),
child: ListView.builder(
padding: const EdgeInsets.all(0.0),
physics: BouncingScrollPhysics(),
itemCount: listado.length,
shrinkWrap: true,
scrollDirection: Axis.vertical,
itemBuilder: (context, index) {
return Container(
height: 34,
child: InkWell(
child: SizedBox.expand(
child: Align(
alignment:
Alignment.centerLeft,
child: Padding(
padding:
EdgeInsets.only(
right: 5,
left: 5),
child: Text(
listado[index]
.descripcion
.split(
"/")[value],
textAlign:
TextAlign.left),
),
),
),
onTap: () {
Get.back(result: {
"item": listado[index],
});
}),
);
}),
),
],
)),
],
),
),
),
),
));
});
},
pageBuilder: (context, animation1, animation2) {
return Container();
});
I need to overlay my alertdialog, that is to say that the size does not break my design, this happens after focusing on the textfield
Show us some code to help you out.
In any case, it might make sense to wrap the layout in a SingleChildScrollView.
Here is a very good explanation.
https://api.flutter.dev/flutter/widgets/SingleChildScrollView-class.html
yourAlertDialog(
context: context,
builder: (BuildContext context) {
return SingleChildScrollView(child: yourchild);
},
);
Your layout should be wrapped in Scrollview , I didn't replicate or run this code but it should be like this:
AlertDialog(
title: Text("title", style: TextStyle(color: ThemeColors.colorPrimary),),
content: Container(
width: double.maxFinite,
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: StatefulBuilder(builder: (BuildContext context1, StateSetter setState) {
this.setState = setState;
return Container(
height: 340,
child: Column(
children: <Widget>[
//your container
],
),
),
}),
)),
);
This is my code. i need an vertical listview at the top and an horizontal listview at the bottom. top listview shouldn't move with the bottom horizontal listview. My app freezes when i go to this page. i need to stop the main.dart and restart the app.i need a screen something like this. what should i do
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_ecommerce_app/common_widget/BottomNavBarWidget.dart';
import 'package:flutter_ecommerce_app/screens/ShoppingCartPage(p).dart';
class ExpanPrdCat extends StatefulWidget {
#override
_ExpanPrdCatState createState() => _ExpanPrdCatState();
}
class _ExpanPrdCatState extends State<ExpanPrdCat> {
bool isLoading = false;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
elevation: 0,
centerTitle: true,
title: Text('Vegetables'),
leading: IconButton(
onPressed: () {
Navigator.pop(context);
},
icon: Icon(Icons.arrow_back_ios_rounded),
),
actions: [
IconButton(
onPressed: () {},
icon: Icon(Icons.search),
color: Color(0xFF323232),
),
],
),
// bottomNavigationBar: BottomNavBarWidget(),
body: Container(
child: Column(children: [
Container(
height: 90,
child: Padding(
padding:
const EdgeInsets.only(top: 5, bottom: 5, left: 1, right: 1),
child: Container(
child: ListView.builder(
scrollDirection: Axis.horizontal,
shrinkWrap: true,
itemBuilder: (context, index) {
return categoryItemsTabs(index);
},
itemCount: 5,
)),
),
),
Container(
child: ListView.builder(
primary: false,
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemBuilder: (context, index) {
return cartItems(index);
},
itemCount: 3,
),
)
]),
),
);
}
//==================================================
categoryItemsTabs(int index) {
return Stack(
alignment: Alignment.center,
children: <Widget>[
Container(
margin: EdgeInsets.only(right: 3),
height: 40,
width: 120,
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(
"https://hips.hearstapps.com/hmg-prod.s3.amazonaws.com/images/broccoli-in-a-pile-royalty-free-image-593310638-1564523257.jpg"),
fit: BoxFit.cover,
colorFilter: ColorFilter.mode(
Colors.black.withOpacity(0.4), BlendMode.darken)),
borderRadius: BorderRadius.circular(15)),
),
Container(
alignment: Alignment.center,
child: Text(
"Organic",
style: TextStyle(
color: Colors.white, fontSize: 15, fontWeight: FontWeight.bold),
),
),
],
);
}
cartItems(int index) {
return Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
height: 120,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: Colors.grey[300],
),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
Container(
width: 80,
height: 80,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
image: DecorationImage(
image: NetworkImage(
"https://economictimes.indiatimes.com/thumb/height-450,width-600,imgsize-111140,msid-72862126/potato-getty.jpg?from=mdr"),
fit: BoxFit.cover)),
),
Padding(
padding: const EdgeInsets.only(left: 15, top: 15),
child: Row(
children: [
Container(
width: 160,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"potato",
style: TextStyle(
fontSize: 25,
),
overflow: TextOverflow.ellipsis,
),
SizedBox(
height: 5,
),
Text(
"malayalam name",
style: TextStyle(fontSize: 20),
overflow: TextOverflow.ellipsis,
),
SizedBox(
height: 5,
),
Column(
children: [
Text("price"),
],
)
],
),
),
],
),
),
Row(
children: [
Column(
children: [
Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(05)),
height: 20,
child: DropdownButton<String>(
icon: Icon(Icons.keyboard_arrow_down),
underline: SizedBox(),
hint: Text("choose"),
items: ['1 Kg', '2Kg'].map((String value) {
return new DropdownMenuItem<String>(
value: value,
child: new Text(value),
);
}).toList(),
onChanged: (_) {},
),
),
SizedBox(
height: 50,
),
Row(
children: [
Container(
height: 20,
width: 70,
child: RaisedButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10)),
color: Colors.blue,
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => CartScreen()),
);
},
child: Text(
" Add",
style: TextStyle(
color: Colors.white,
fontSize: 12,
fontWeight: FontWeight.w800),
),
),
)
],
)
],
),
],
)
],
),
),
),
)
],
);
}
}
Just add physics: ClampingScrollPhysics(), in your ListView.builder properties.
Example:
Container(
child: ListView.builder(
primary: false,
scrollDirection: Axis.vertical,
shrinkWrap: true,
physics: ClampingScrollPhysics(),
itemBuilder: (context, index) {
return cartItems(index);
},
itemCount: 3,
),
)
You can do it using SingleChildScrollView :
for horizontal scrolling
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: [],
),
),
for vertical scrolling
SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Column(
children: [],
),
),
return Scaffold(
appBar: AppBar(....),
body: Container(
child: Column(children: [
Container(
height: 90,
width: MediaQuery.of(context).size.width,
child: Padding(
padding:
const EdgeInsets.only(top: 5, bottom: 5, left: 1, right: 1),
child: Container(
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
return categoryItemsTabs(index);
},
itemCount: 5,
),
),
),
),
Expanded(
child: Container(
child: ListView.builder(
scrollDirection: Axis.vertical,
itemBuilder: (context, index) {
return cartItems(index);
},
itemCount: 3,
),
),
)
]),
),
);
I am getting error with listview builder and not sure how to resolve it.
If I remove the Listview builder code then it is not giving the error.
Here is the code.
Widget build(BuildContext context) {
return Theme(
isMaterialAppTheme: true,
data: ThemeData(
),
child:Scaffold(
backgroundColor: _dark ? null : Colors.grey.shade200,
key: _scaffoldKey,
appBar: myAppBar(),
endDrawer: myDrawer(),
body: Stack(
children: <Widget>[
SingleChildScrollView(
child: Stack(
children: <Widget>[
Container(
margin: EdgeInsets.fromLTRB(16.0, 10.0, 16.0, 16.0),
child: Column(
children: <Widget>[
Stack(
children: <Widget>[
Container(
decoration: BoxDecoration(
color:Colors.grey,
// color: Colors.orange,
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(4.0),
bottomRight: Radius.circular(4.0))),
padding: EdgeInsets.symmetric(horizontal:16.0, vertical: 15.0),
width: double.infinity,
child: Text("Booking Details",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 18.0,
// fontWeight: FontWeight.bold,
color: Colors.white,
letterSpacing: 3,
wordSpacing: 3
),),
),
],
),
SizedBox(height: 20.0),
Container(
child: new ListView.builder(
itemCount: lists.length,
itemBuilder: (BuildContext context, int i) {
return Card(
margin:
const EdgeInsets.fromLTRB(10.0, 15.0, 10.0, 0.0),
child: new ExpansionPanelList(
expansionCallback: (int index, bool status) {
setState(() {
_selectedIndex= index;
_selectedIndex = _selectedIndex == i ? null : i;
});
},
children: [
new ExpansionPanel(
isExpanded: _selectedIndex == i,
headerBuilder: (BuildContext context,
bool isExpanded) =>
new Container(
padding:
const EdgeInsets.only(left: 15.0),
alignment: Alignment.centerLeft,
child: new Text(
'list-$i',
)),
body: new Container(child: new Text('content-$i'),),),
],
),
);
}),
),
How can I fix the issue?
You can try setting a height for the container that is holding your listview
Container(
height: 200.0, //for example
child: ListView.builder(
//your code
)
)
I am designed very heavy nested design like below, the issue when my list expands the listview doesn't seems to be scrolling what is the reason for this, the bottomsheet gets expanded but there is no focus on listview inside it, if i scrolls by touching the 'Operational Hours' text it starts scrolling but when it goes upwards i can't slide it down.
_showDialog(BuildContext context) {
print("_showDialog");
showModalBottomSheet(
context: context,
isScrollControlled: true,
builder: (BuildContext context) {
return DraggableScrollableSheet(
expand: false,
builder: (context, scrollController) {
return Container(
child: Stack(
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Align(
alignment: Alignment.topCenter,
child: Container(
margin: EdgeInsets.symmetric(vertical: 8),
height: 8.0,
width: 70.0,
decoration: BoxDecoration(
color: Colors.grey[400],
borderRadius: BorderRadius.circular(10.0)))),
SizedBox(height: 16),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 24),
child: Text('Operational Hours',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: widget.isTab(context)
? TabTextStyles.mediumText
.copyWith()
.fontSize
: PhoneTextStyles.mediumText
.copyWith()
.fontSize)),
),
],
),
ListView(
controller: scrollController,
children: <Widget>[
SizedBox(height: 54.0),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 24),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
SizedBox(height: 20.0),
Text('Select days to add hours',
style: widget.isTab(context)
? TabTextStyles.mediumText.copyWith()
: PhoneTextStyles.mediumText.copyWith()),
]),
),
DaysList()
],
),
],
),
decoration: BoxDecoration(
shape: BoxShape.rectangle,
color: Theme.of(context).backgroundColor,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(24.0),
topRight: Radius.circular(24.0),
),
),
);
},
);
},
);
}
There are couple of mistakes you're making. First, put widgets in Column that are always going to be visible at top, second wrap your DaysList in Expanded and pass ScrollController to it.
This is your method:
void _showDialog(BuildContext context) {
showModalBottomSheet(
context: context,
isScrollControlled: true,
builder: (BuildContext context) {
return DraggableScrollableSheet(
expand: false,
builder: (context, scrollController) {
return Column(
children: <Widget>[
// Put all heading in column.
column,
// Wrap your DaysList in Expanded and provide scrollController to it
Expanded(child: DaysList(controller: scrollController)),
],
);
},
);
},
);
}
This is your Column:
Widget get column {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Align(
alignment: Alignment.topCenter,
child: Container(
margin: EdgeInsets.symmetric(vertical: 8),
height: 8.0,
width: 70.0,
decoration: BoxDecoration(color: Colors.grey[400], borderRadius: BorderRadius.circular(10.0)),
),
),
SizedBox(height: 16),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 24),
child: Text('Operational Hours', style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 24),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
SizedBox(height: 20.0),
Text('Select days to add hours'),
],
),
),
SizedBox(height: 16),
],
);
}
And this is how your DaysList should look like:
class DaysList extends StatelessWidget {
final ScrollController controller;
const DaysList({Key key, this.controller}) : super(key: key);
#override
Widget build(BuildContext context) {
return ListView.builder(
controller: controller, // assign controller here
itemCount: 20,
itemBuilder: (_, index) => ListTile(title: Text("Item $index")),
);
}
}
Output:
Screenshot:
Call this method:
void showMyBottomSheet(BuildContext context) {
showModalBottomSheet(
context: context,
isScrollControlled: true,
builder: (_) {
return DraggableScrollableSheet(
maxChildSize: 0.8,
expand: false,
builder: (_, controller) {
return Column(
children: [
Container(
width: 100,
height: 8,
margin: EdgeInsets.symmetric(vertical: 10),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: Colors.grey,
),
),
Expanded(
child: ListView.builder(
controller: controller,
itemCount: 100,
itemBuilder: (_, i) => ListTile(title: Text('Item $i')),
),
),
],
);
},
);
},
);
}