How to create Expandable/Contractable Horizontal ListView? - flutter

I am quite new to flutter, but I want to create an app in which my main vertical list could be dragged from bottom part of the screen to above part and when I do that my horizontal listview(as shown in image) will fade away, for this I thought of using SliverAppBar, but I don't know how to add Horizontal ListView to it.
I want to achieve UI something like this.

For starter, try this if you want a SliverAppBar approach but I recommend using a two List instead. One horizontal and one vertical
return Scaffold(
body: CustomScrollView(
slivers: <Widget>[
SliverAppBar(
expandedHeight: 300,
centerTitle: true,
pinned: true,
elevation: 4,
floating: true,
title: Text(
'Subscribe Now',
style: TextStyle(color: Colors.white),
),
flexibleSpace: FlexibleSpaceBar(
titlePadding: const EdgeInsets.all(0),
collapseMode: CollapseMode.pin,
background: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: 4,
itemBuilder: (BuildContext context, int index) {
return Container(
color: Colors.indigoAccent,
margin: EdgeInsets.only(left: 20, bottom: 16, top: 180),
child: SizedBox(
height: 100,
width: 100,
child: Center(
child: Text('Item No. $index'),
),
),
);
}),
),
),
SliverList(
delegate:
SliverChildBuilderDelegate((BuildContext context, int index) {
return Container(
margin: const EdgeInsets.fromLTRB(16, 8, 16, 12),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.black,
),
padding: const EdgeInsets.all(22),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'Get 7 days free',
style: Theme.of(context)
.textTheme
.headline
.copyWith(color: Colors.white),
),
const SizedBox(
height: 2,
),
Text(
'Save 50% off',
style: Theme.of(context)
.textTheme
.button
.copyWith(color: Colors.greenAccent),
),
const SizedBox(
height: 6,
),
Text(
'\$60',
style: Theme.of(context).textTheme.headline.copyWith(
fontWeight: FontWeight.w700,
color: Colors.white,
fontSize: 28),
)
],
),
);
}, childCount: 10),
)
],
),
);

Related

extendBody: true, property moves

I am trying to recreate the main page of Spotify. At first I wasn't able to make my navigation bar transparent then I learned that I should use extendBody: true property. It worked and I got a transparent navigation bar but now it seems like it changed the space between the items on the screen and I am clueless at this point. This is the part where I added extendBody property:
#override
Widget build(BuildContext context) {
return Scaffold(
extendBody: true,
appBar: AppBar(
backgroundColor: Color(0xFF212121),
title: Text("Spotify", style: TextStyle(fontFamily: 'Work Sans', fontWeight: FontWeight.bold)),
elevation: 0,
actions: [
IconButton(onPressed: (){}, icon: Icon(Icons.notifications_outlined)),
IconButton(onPressed: (){}, icon: Icon(Icons.history)),
IconButton(onPressed: (){}, icon: Icon(Icons.settings)),
],
),
And this is the part that forms gridlist and the problematic part:
FutureBuilder<List<GridListe>>(
future: gridListeyiGetir(),
builder: (context, snapshot){
if(snapshot.hasData){
var gridListe = snapshot.data;
return Padding(
padding: const EdgeInsets.only(top: 15),
child: GridView.builder(
shrinkWrap: true,
itemCount: gridListe!.length,
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, childAspectRatio: 3/1),
itemBuilder: (context, index){
var list = gridListe[index];
return Card(
semanticContainer: true,
color: Color(0xFF535353),
child: Row(
children: [
Image.asset("resimler/${list.listeResmi}", fit: BoxFit.fitHeight),
Padding(
padding: const EdgeInsets.only(left: 5),
child: Text(list.listeAdi, style:TextStyle(color: Colors.white,fontFamily: 'Work Sans' ,fontWeight: FontWeight.bold) , ),
),
],
),
);
}
),
);
}else{
return const Center();
}
},
),
Padding(
padding: const EdgeInsets.only(right: 280),
child: const Text("Made For You", style: TextStyle(color: Colors.white, fontFamily: 'Work Sans',fontWeight: FontWeight.bold, fontSize: 15)),
),
Padding(
padding: const EdgeInsets.only(top: 10),
child: SizedBox(
height: 180,
child: ListView(
scrollDirection: Axis.horizontal,
children: [
SizedBox(
width: 160,
child: Card(
elevation: 0,
color: Color(0xFF212121),
child:
Column(mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Image.asset("resimler/dailymix1.jpg"),
Text("Daily Mix 1", style: TextStyle(color: Colors.white, fontFamily: "Work Sans", fontWeight: FontWeight.bold), ),
],
),
),
),
As can be seen in the images the grid list and "Made For You" text should be somewhat close to eachother however its not the case.
when extendBody:false
when extendBody:true

DraggableScrollableSheet Scrolling Problem

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,
],

Scrollbar is not visible when wrapping listView Builder with SingleChildScrollView or ListView

**> Here is my code. it contains a ListView builder which is wrapped with
RawScrollBar widget and they both wrapped with SingleChildScrollView
Widget. I want a show ScrollBar in ListView.Builder**
Scaffold(
backgroundColor: kPrimaryColor,
body: SafeArea(
child: SizedBox(
height: kGetSize(context).height,
child: Column(
children: [
const SizedBox(
height: 16,
),
const Center(
child: UserLevelDetailsContainer(),
),
Expanded(
child: Padding(
padding:
const EdgeInsets.symmetric(horizontal: 24, vertical: 24),
**child: SingleChildScrollView(
physics: const ScrollPhysics(),
controller: _scrollController,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
'General Subjects',
style: GoogleFonts.openSans(
fontWeight: FontWeight.w700,
fontSize: 20,
color: const Color(0xfff3c304)),
),
const SizedBox(
height: 8,
),
RawScrollbar(
thumbVisibility: true,
interactive: true,
thumbColor: Colors.black,
controller: _scrollController,
radius: const Radius.circular(60),
thickness: 6,
child: ListView.builder(
controller: _scrollController,
physics: const NeverScrollableScrollPhysics(),
itemCount: SubjectDetail.listOfSubjects.length,
shrinkWrap: true,
itemBuilder: (context, index) {
return SizedBox(
width: 344,
height: 96,
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12.0),
),
child: ListTile(
contentPadding: const EdgeInsets.symmetric(
horizontal: 24, vertical: 8),
title: Padding(
padding: const EdgeInsets.only(bottom: 4),
child: Text(
SubjectDetail
.listOfSubjects[index].name,
style: GoogleFonts.openSans(
fontWeight: FontWeight.w700,
fontSize: 15),
),
),
subtitle: Text(
SubjectDetail
.listOfSubjects[index].description,
style: GoogleFonts.openSans(
fontWeight: FontWeight.w400,
fontSize: 10),
),
trailing: Image.asset(SubjectDetail
.listOfSubjects[index].imageUrl),
),
),
);
},
),
),**
const SizedBox(
height: 8,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'General Subjects',
style: GoogleFonts.openSans(
fontWeight: FontWeight.w700,
fontSize: 20,
color: const Color(0xfff3c304)),
),
Text(
'*select one subject',
style: GoogleFonts.openSans(
fontWeight: FontWeight.w300,
fontSize: 14,
color: const Color(0xfff3c304)),
)
],
),
],
),
),
),
)
],
),
),
),
);
I have given same ScrollController object to ListView builder,
RawScrollBar and SingleChildScollView widget.Altough I had given
different ScrollController objects to them

ListTile at the bottom of the screen

I want a List Tile from my Menu at the bottom of the screen. I done it with a Sized box, it worked for my Nokia 7.1, but when I debug with another phone with a another resulution the solution doesn´t work, because I customized the box for the Nokia and not for another phones. Now I don´t konw how I can do it. I tried by using an Container istead of a Drawer, but it doesn´t slove the problem. Here is my Code:
return Drawer(
child: ListView(
physics: NeverScrollableScrollPhysics(),
padding: EdgeInsets.zero,
children: <Widget>[
DrawerHeader(
decoration: BoxDecoration(
color: Colors.green,
),
child: Text(
'Menü',
style: GoogleFonts.oswald(
textStyle: TextStyle(
color: Colors.black,
fontSize: 45,
)
),
),
),
[ListTiles]
This is the List Tile I want at the bottom:
// this is my first attempt:
/*SizedBox(
height: 410,
),*/
ListTile(
leading: Icon(Icons.arrow_back_outlined,
color: Colors.black,
size: 30,
),
title: Text('Back',
style: GoogleFonts.raleway(
textStyle: TextStyle(
color: Colors.black,
fontSize: 30,
)
)
),
onTap: () => Navigator.pop(context),
),
],
),
);
Judging by the ListView combined with physics: NeverScrollableScrollPhysics(), I think a refactor to the following solution might also work for you (condensed for brevity):
Drawer(child:
CustomScrollView(
physics: NeverScrollableScrollPhysics(),
slivers: <Widget>[
SliverToBoxAdapter(child:
Column(children: [
DrawerHeader(decoration: BoxDecoration(color: Colors.green), child: Text('Menü')),
// all of your list tiles
],
crossAxisAlignment: CrossAxisAlignment.stretch,
),
),
SliverFillRemaining(child:
Align(child:
ListTile(
leading: Icon(Icons.arrow_back_outlined, color: Colors.black, size: 30),
title: Text('Back'),
onTap: () => Navigator.pop(context),
),
alignment: Alignment.bottomCenter,
),
hasScrollBody: false,
)
],
)
)

How to make fixed button flutter?

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.