I'm trying to clone the comments section of youtube.
But when I scroll the bottom sheet comments, which should be expand only when I grab the top part of the bottom sheet and pull it, it expands. I hope I was able to explain fully.
DraggableScrollableSheet(
initialChildSize: 0.55,
maxChildSize: 1,
snap: true,
snapSizes: const [
0.55,
1,
],
builder: (context, scrollController) => Container(
color: Color(0xff181818),
child: ListView(
controller: scrollController,
children: [
customAppBar(context),
Row(
children: [
const SizedBox(
width: 15,
),
filter("All", Colors.white, Colors.black),
const SizedBox(
width: 15,
),
filter("News", Colors.grey.withOpacity(0.2), Colors.white),
],
),
const SizedBox(
height: 20,
),
ListView(
shrinkWrap: true,
physics: ScrollPhysics(),
children: [
SizedBox(
height: 45,
width: double.infinity,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 15.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const CircleAvatar(
radius: 26,
backgroundColor: Colors.pink,
child: Text(
"R",
style: TextStyle(
color: Colors.white,
fontSize: 22,
fontWeight: FontWeight.bold),
),
),
const SizedBox(
width: 10,
),
Expanded(
child: TextFormField(
decoration: InputDecoration.collapsed(
hintText: "Add a comment...",
hintStyle: TextStyle(
color: Colors.white.withOpacity(0.6),
fontSize: 20)),
))
],
),
),
),
Divider(
color: Colors.white.withOpacity(0.5),
thickness: 1,
height: 30,
),
comment(),
comment(),
comment(),
comment(),
comment(),
comment(),
],
),
],
),
),
);
buildBottomSheet(context) => showModalBottomSheet(
isDismissible: false,
backgroundColor: Colors.transparent,
context: context,
isScrollControlled: true,
barrierColor: Colors.transparent,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
builder: (context) => Sheet(),
);
What can I do so that the comments scroll within themselves and the bottom sheet can only expand when pulled from top of the bottom sheet?
The problem fixed when I created the bottom sheet with scaffold, created the app bar and list view, gave the app bar a Draggable scroll sheet scrollcontroller and gave a separate scroll controller to the listview.
DraggableScrollableSheet(
initialChildSize: 0.55,
maxChildSize: 1,
snap: true,
expand: false,
snapSizes: const [
0.55,
1,
],
builder: (context, scrollController) => Scaffold(
backgroundColor: Colors.black,
appBar: PreferredSize(
child: customAppBar(context, scrollController),
preferredSize: Size.fromHeight(100)),
body: Container(
color: Color(0xff181818),
child: ListView(
shrinkWrap: true,
children: [
Row(
children: [
const SizedBox(
width: 15,
),
filter("All", Colors.white, Colors.black),
const SizedBox(
width: 15,
),
filter("News", Colors.grey.withOpacity(0.2), Colors.white),
],
),
const SizedBox(
height: 20,
),
SizedBox(
height: 45,
width: double.infinity,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 15.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const CircleAvatar(
radius: 26,
backgroundColor: Colors.pink,
child: Text(
"R",
style: TextStyle(
color: Colors.white,
fontSize: 22,
fontWeight: FontWeight.bold),
),
),
const SizedBox(
width: 10,
),
Expanded(
child: TextFormField(
decoration: InputDecoration.collapsed(
hintText: "Add a comment...",
hintStyle: TextStyle(
color: Colors.white.withOpacity(0.6),
fontSize: 20)),
))
],
),
),
),
Divider(
color: Colors.white.withOpacity(0.5),
thickness: 1,
height: 30,
),
ListView.builder(
shrinkWrap: true,
controller: myScrollController,
itemCount: 10,
itemBuilder: ((context, index) => comment())),
],
),
),
),
);
}
}
You need to change like maxChildSize:.55, and therefore inner snaps can't be bigger than this. setting 1 will provide the draggle to have full screen.
builder: (context) => DraggableScrollableSheet(
initialChildSize: 0.55,
maxChildSize: 1,
snap: true,
snapSizes: const [
0.55,
],
Related
I was using PagedListView (from This package )inside TabBarView and faced the above error. I tried wrapping the PagedListView within a container with height and width mentioned but it didn't help. Can anyone help me with this?
Relavant code:
DefaultTabController(
length: 2,
child: Column(
children: [
Container(
margin: EdgeInsets.only(
top: getProportionateScreenWidth(24),
left: getProportionateScreenWidth(24),
right: getProportionateScreenWidth(24),
),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(5)),
color: cardColor,
),
child: Padding(
padding: const EdgeInsets.all(2),
child: TabBar(
indicator: BoxDecoration(
borderRadius: BorderRadius.circular(5),
color: brandPurple),
labelColor: primaryTextColor,
unselectedLabelColor: secondaryTextColor,
tabs: [
Tab(text: AppLocalizations.of(context)!.pending),
Tab(text: AppLocalizations.of(context)!.solved),
],
),
),
height: getProportionateScreenWidth(48),
),
SizedBox(
height: getProportionateScreenWidth(20),
),
Container(
height: getProportionateScreenHeight(575),
child: TabBarView(children: <Widget>[
// pendingDoubtsBody(),
_paginatedPendingDoubtBody(),
solvedDoubtsBody(),
]),
),
],
),
),
_paginatedPendingDoubtsBody:
Widget _paginatedPendingDoubtBody() {
return PagedListView(
pagingController: _pendingPagingController,
builderDelegate: PagedChildBuilderDelegate<TeacherDoubtModel>(
itemBuilder: (context, doubt, index) =>
TeacherQuestionCard(question: doubt),
firstPageProgressIndicatorBuilder: (context) => Shimmer.fromColors(
baseColor: Colors.white.withOpacity(0.4),
highlightColor: Colors.grey.withOpacity(0.4),
child: ListView.builder(
itemCount: 3,
itemBuilder: (context, index) {
return Padding(
padding: EdgeInsets.only(
left: getProportionateScreenWidth(24),
right: getProportionateScreenWidth(24),
bottom: getProportionateScreenHeight(12),
),
child: Card(
elevation: 1.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
child: SizedBox(
height: getProportionateScreenHeight(133),
width: double.infinity,
),
),
);
},
),
),
newPageProgressIndicatorBuilder: (context) => Center(
child: CircularProgressIndicator(
color: Colors.white,
),
),
noItemsFoundIndicatorBuilder: (context) => Center(
child: Text(
'No doubts pending',
style: Theme.of(context)
.textTheme
.bodyText2
?.copyWith(color: Colors.white),
)),
firstPageErrorIndicatorBuilder: (context) => Center(
child: Text(
'Some error',
style: Theme.of(context)
.textTheme
.bodyText2
?.copyWith(color: Colors.white),
),
)),
);
}
I'm having a Row which contains a list of widgets , a Builder and a variable that adds new item to the list to be built with the Builder.
Anyway , I was trying to wrap the whole Rows with SingleChildScrollView , but now , every part of my Row is scrolling separately .
My Row contains two widgets Expanded() and inside the Expanded() , I got a itemBuilder.
I got a button in the bottom that calls two functions , and they will add new Widgets to the List.
class _ajouterUnDocumentState extends State<ajouterUnDocument> {
List<Widget> _cardList = [
(InputRefNomProduit()),
];
List<Widget> _cardList2 = [
(InputQuntitePrixProduit()),
];
void _addCardWidgetExp1() {
setState(() {
_cardList.add(SizedBox(height: 10));
_cardList.add(InputRefNomProduit());
});
}
void _addCardWidgetExp2() {
setState(() {
_cardList2.add(SizedBox(height: 10));
_cardList2.add(InputQuntitePrixProduit());
});
}
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xFF2A2D3E),
body: Padding(
padding:
EdgeInsets.only(top: 60.0, bottom: 60.0, left: 120.0, right: 120.0),
child: Form(
key: _formKey,
child: Card(
shadowColor: Color.fromARGB(255, 255, 255, 255),
color: Color(0xFF2A2D3E),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(40.0)),
elevation: 10.0,
child: Container(
width: 1800,
child: Column(
children: <Widget>[
Center(
child: Container(
padding: EdgeInsets.all(20),
child: Column(
children: <Widget>[
Text(
"AJOUTER UN FOURNISSEUR",
style: TextStyle(
fontSize: 30, fontWeight: FontWeight.bold),
),
Divider(
thickness: 3,
),
SingleChildScrollView(
child: Container(
child: Row(
mainAxisSize: MainAxisSize.max,
children: [
Expanded(
flex: 3,
child: Column(
children: [
SizedBox(
height: 10,
),
SizedBox(
height: 530,
width: 500,
child: ListView.builder(
itemCount: _cardList.length,
itemBuilder: (context, index) {
return _cardList[index];
}),
),
],
),
),
SizedBox(width: 25),
Expanded(
flex: 3,
child: Column(
children: [
SizedBox(
height: 10,
),
SizedBox(
height: 530,
width: 500,
child: ListView.builder(
itemCount: _cardList2.length,
itemBuilder: (context, index) {
return _cardList2[index];
}),
),
],
),
),
],
),
),
),
//Membership Widget from the widgets folder
Center(
child: Row(
children: <Widget>[
SizedBox(
width: 400.0,
),
MaterialButton(
color: Colors.grey[200],
onPressed: () {},
child: Text(
"Annuler",
style: TextStyle(color: Colors.black),
),
),
SizedBox(
width: 20.0,
),
MaterialButton(
color: Color.fromARGB(255, 75, 100, 211),
onPressed: () {
_addCardWidgetExp1();
_addCardWidgetExp2();
},
child: Text(
"Ajouter",
style: TextStyle(color: Colors.white),
),
),
],
),
),
],
),
),
),
],
),
),
),
),
),
);
}
}
This is InputQuntitePrixProduit():
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
return Row(
children: <Widget>[
Expanded(
flex: 1,
child: Container(
width: 25.0,
child: Text(
"$label",
textAlign: TextAlign.left,
style: TextStyle(
fontWeight: FontWeight.w900,
color: Color.fromARGB(255, 255, 255, 255),
),
),
),
),
Expanded(
flex: 3,
child: Container(
width: MediaQuery.of(context).size.width / 3.7,
color: Color.fromARGB(255, 255, 255, 255),
child: TextFormField(
controller: fieldController,
validator: fieldValidator,
style: TextStyle(
fontSize: 15.0,
color: Colors.black,
),
decoration: InputDecoration(
contentPadding: EdgeInsets.all(10.0),
hintText: "$content",
hintStyle: TextStyle(
color: Color.fromARGB(255, 190, 190, 190),
fontSize: 14),
fillColor: Color.fromARGB(255, 0, 0, 0),
),
),
),
),
SizedBox(
width: 5.0,
),
Expanded(
flex: 2,
child: Container(
width: 50.0,
child: Text(
"$label2",
textAlign: TextAlign.left,
style: TextStyle(
fontWeight: FontWeight.w900,
color: Color.fromARGB(255, 255, 255, 255),
),
),
),
),
SizedBox(
width: 5.0,
),
Expanded(
flex: 3,
child: Container(
width: MediaQuery.of(context).size.width / 3.7,
color: Color.fromARGB(255, 255, 255, 255),
child: TextFormField(
enabled: false,
controller: fieldController,
validator: fieldValidator,
style: TextStyle(
fontSize: 15.0,
color: Colors.black,
),
decoration: InputDecoration(
contentPadding: EdgeInsets.all(10.0),
hintText: "$content2",
hintStyle: TextStyle(
color: Color.fromARGB(255, 190, 190, 190),
fontSize: 14),
fillColor: Color.fromARGB(255, 0, 0, 0),
),
),
),
),
],
);
},
);
}
}
I have the following code for a DraggableScrollableSheet in Flutter.
DraggableScrollableSheet(
builder: (BuildContext context, ScrollController scrollController) {
return ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(35),
topRight: Radius.circular(35),
),
child: Container(
color: ColorData.secondaryColor,
child: Padding(
padding: const EdgeInsets.symmetric(
vertical: 10,
horizontal: 15,
),
child: Column(
children: [
Container(
height: 3,
width: 30,
decoration: BoxDecoration(
color: ColorData.primaryDividerColor,
borderRadius: BorderRadius.circular(16),
),
),
const SizedBox(
height: 18,
),
SizedBox(
width: _screenWidth,
child: const Text(
'Exchange Houses',
textAlign: TextAlign.start,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
),
),
),
const SizedBox(
height: 8,
),
SizedBox(
width: _screenWidth,
child: const Text(
'(Tap to select)',
textAlign: TextAlign.start,
),
),
const SizedBox(
height: 10,
),
Expanded(
child: ListView.separated(
itemCount: 5,
itemBuilder: (context, index) => const ExchangeHouseCard(
id: 1,
houseName: 'Test House',
houseContactNumber: '+94 77123456',
houseUrl:
'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQrLlwS2ymz1oFL10jTbD7QMcCffrrAzUAbMA&usqp=CAU',
houseImageUrl:
'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQrLlwS2ymz1oFL10jTbD7QMcCffrrAzUAbMA&usqp=CAU',
houseLatitude: 7.0012345,
houseLongitude: 20.301456,
userCurrencyName: 'USD',
convertingCurrencyName: 'LKR',
exchangeRate: 200.00,
change: 500.00,
changeInConvertingCurrency: 1200.00,
),
separatorBuilder: (context, index) => const SizedBox(
height: 5,
),
),
),
],
),
),
),
);
},
),
In the above code, I am trying to make my DraggableScrollableSheet be able be to dragged upwards or collapsed downwards when user drags the sheet. No matter how I try, I can not drag or collapse the sheet. It stays where it is.
Furthermore, something interesting happens if I set controller property of my ListView to the scrollController I get from the builder method in DraggableScrollableSheet. In this case, the DraggableScrollableSheet becomes draggable if we try to scroll the ListView.
But I want the DraggableScrollableSheet to be draggable if I drag from a general area of the sheet. How to implement this to the above DraggableScrollableSheet?
(I also tried wrapping the widget that is being returned inside the builder method with a ListView and setting controller property of the ListView to scrollController that I get from the builder method. But this also gives a render error. I could not find a way to fix this.)
Can someone please help?
You need to give isScrollControlled to true and set the height
showModalBottomSheet(
context: context,
isScrollControlled: true,
backgroundColor: Colors.transparent,
builder: (context) {
return DraggableScrollableSheet(
initialChildSize: 0.9,
maxChildSize: 0.9,
builder: (BuildContext context, ScrollController scrollController) {
return ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(35),
topRight: Radius.circular(35),
),
child: Container(
color: ColorData.secondaryColor,
child: Padding(
padding: const EdgeInsets.symmetric(
vertical: 10,
horizontal: 15,
),
child: Column(
children: [
Container(
height: 3,
width: 30,
decoration: BoxDecoration(
color: ColorData.primaryDividerColor,
borderRadius: BorderRadius.circular(16),
),
),
const SizedBox(
height: 18,
),
SizedBox(
width: _screenWidth,
child: const Text(
'Exchange Houses',
textAlign: TextAlign.start,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
),
),
),
const SizedBox(
height: 8,
),
SizedBox(
width: _screenWidth,
child: const Text(
'(Tap to select)',
textAlign: TextAlign.start,
),
),
const SizedBox(
height: 10,
),
Expanded(
child: ListView.separated(
itemCount: 5,
controller: scrollController,
itemBuilder: (context, index) =>
const ExchangeHouseCard(
id: 1,
houseName: 'Test House',
houseContactNumber: '+94 77123456',
houseUrl:
'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQrLlwS2ymz1oFL10jTbD7QMcCffrrAzUAbMA&usqp=CAU',
houseImageUrl:
'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQrLlwS2ymz1oFL10jTbD7QMcCffrrAzUAbMA&usqp=CAU',
houseLatitude: 7.0012345,
houseLongitude: 20.301456,
userCurrencyName: 'USD',
convertingCurrencyName: 'LKR',
exchangeRate: 200.00,
change: 500.00,
changeInConvertingCurrency: 1200.00,
),
separatorBuilder: (context, index) =>
const SizedBox(
height: 5,
),
),
),
],
),
),
),
);
},
);
});
I am trying to show the list of items using ListView.builder in ```expansion tile, but it is not showing anything, nor giving any error.
here is the code of expansion tile
customExpansionTile(context, "Additional discount", true,
Icon(Icons.add_task, color: HexColor("#5344ed")), <Widget>[
Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
width: MediaQuery.of(context).size.width * 0.9,
child: Row(
children: [
SizedBox(
width: MediaQuery.of(context).size.width * 0.022,
),
textformfieldCustomwithouticon(
context,
TextInputType.number,
MediaQuery.of(context).size.width * 0.4,
quantity,
"Enter the quantity",
"Quantity ",
55.0),
SizedBox(
width: MediaQuery.of(context).size.width * 0.03,
),
textformfieldCustomwithouticon(
context,
TextInputType.number,
MediaQuery.of(context).size.width * 0.42,
discountPercentage,
"Enter the discount",
"Discount",
55.0),
],
),
),
SizedBox20(),
customButton(context, "Add", () {},
MediaQuery.of(context).size.width * 0.85, 55.0),
SizedBox20(),
// here i'm using Listview.builder
Flexible(
fit: FlexFit.loose,
child: Container(
width:MediaQuery.of(context).size.width * 0.9,
height:MediaQuery.of(context).size.height*0.5,
child: ListView.builder(
itemCount: books.length,
itemBuilder: (context, index) {
final book = books[index];
return buildDiscount(book);
},
),
)),
],
),
SizedBox10()
]),
buildDiscount code:
Widget buildDiscount(Book book) => Card(
elevation: 0.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(10),
),
),
child: ListTile(
trailing: SizedBox(
height: 100,
child: Column(
children: [
InkWell(
onTap: () {
_getVariantRowInfo(book.id, book.id, book.id);
},
child: Icon(Icons.edit, color: HexColor("#7367f0")),
),
SizedBox(
height: 5,
),
InkWell(
onTap: () {},
child: Icon(Icons.delete, color: HexColor("#7367f0")),
),
],
),
),
title: Padding(
padding: const EdgeInsets.fromLTRB(0, 10, 15, 0),
child: Text(
" Quantity: 90",
style: GoogleFonts.montserrat(
fontSize: 15, fontWeight: FontWeight.bold,color: Colors.red),
),
),
horizontalTitleGap: 10,
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
" Discount %: " + "10%",
style: GoogleFonts.montserrat(fontSize: 15),
),
Text(
" Discounted Price: " + "90",
style: GoogleFonts.montserrat(fontSize: 15),
),
SizedBox(
height: 10,
)
],
),
));
output
please help, where i'm doing wrong.
customExpansionTile
Widget customExpansionTile(context, text,initiallyExpanded,leading,childern) {
return GestureDetector(
child: Container(
width:MediaQuery.of(context).size.width*0.9,
// height: 400,
decoration: BoxDecoration(
border: Border.all(color: HexColor("#6e6b7b")),
color: Colors.white,
borderRadius: BorderRadius.all(
Radius.circular(10),
),
),
child: ExpansionTile(
title: Text(
text,
style: GoogleFonts.montserrat(
fontSize: 18.0,
fontWeight: FontWeight.bold,
color: HexColor("#5344ed")),
),
initiallyExpanded:initiallyExpanded,
leading:leading,
children: childern,
),
),
);
}
if you use Container with width and height u needn't Flexible widget like Expanded and Flexible at parent, remove Flexible, also you can add shrinkWrap: true to ListView.builder
Flexible( /// <--- remove this parent or remove Container if you get flexible ListView.builder
fit: FlexFit.loose,
child: Container(
width:MediaQuery.of(context).size.width * 0.9,
height:MediaQuery.of(context).size.height*0.5,
child: ListView.builder(
itemCount: books.length,
itemBuilder: (context, index) {
final book = books[index];
return buildDiscount(book);
},
),
)),
or
Try to use Expanded something like
Expanded:
child customExpansionTile(context, "Additional discount", true,
Icon(Icons.add_task, color: HexColor("#5344ed")), [
Expanded: child:
Column(
mainAxisSize: MainAxisSize.min,
.....
I have a problem with fixed button inside scroll view , I made a column with SingleChildScrollView and two button, but the problem is that the screen do not scroll. I tried the bottom Navigation bar but it has the same problem. How I can fix this?
my code :
Column(
children: [
Expanded(
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Column(
children: [
ListView.builder(
shrinkWrap: true,
itemCount: 200,
itemBuilder: (context, index) {
return Text("200");
},
),
ListView.builder(
shrinkWrap: true,
itemCount: 20,
itemBuilder: (context, index) {
return Text("bargougui");
},
),
],
),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: ClipRRect(
borderRadius: BorderRadius.circular(20.0),
child: Container(
width: 150,
height: 50,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.grey[300],
),
onPressed: () {},
child: Text(
'Contacter',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w500,
color: Colors.black,
fontStyle: FontStyle.italic,
),
),
),
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: ClipRRect(
borderRadius: BorderRadius.circular(20.0),
child: Container(
width: 150,
height: 50,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.yellow,
),
onPressed: () {},
child: Text(
'Acheter',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w500,
color: Colors.black,
fontStyle: FontStyle.italic,
),
),
),
),
),
),
],
),
],
),
screen I want to make like this
any help will be appreciated ^^
Use Stack widget,
Stack(
children:[
SingleChildScrollView(),
Positioned(
bottom:0,
left:15,
right:15,
child:Row(children :[Button1(),Button2()],
,)
]
Try tweaking the numbers to fit your case.