how to style the Horizontal scroll bar according to this UI flutter - flutter

This is my code for the horizontal scrollbar. how to style this according to given UI. where and how I should add styles on this code. the code is showing how I placed the scroll bar in my home. dart. need suggestions to add styles.
home.dart.
body: ListView(
children: [
buildSearchInput(),
Padding(
padding: const EdgeInsets.only(top: 40, left: 20, right: 20),
child: Column(
children: [
SizedBox(
height: kToolbarHeight,
child: ListView(
scrollDirection: Axis.horizontal,
children: List.generate(4, (index) => Text("item $index")),
),
),
],
),
)
,

You can use Container with StadiumBorder to decorate them and using ListView.separated to have space between items.
final List<String> data = ["item A", "Item Number 2", "new One"];
Widget itemW({
required String text,
required Color bgcolor,
required Color textColor,
}) {
return Container(
padding: const EdgeInsets.all(16),
alignment: Alignment.center,
decoration: ShapeDecoration(
shape: const StadiumBorder(),
color: bgcolor,
),
child: Text(
text,
style: TextStyle(color: textColor),
),
);
}
....
ListView.separated(
itemCount: data.length,
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) =>
itemW(color: Colors.cyanAccent,
bgcolor: Colors.cyanAccent,
text: data[index]),
separatorBuilder: (context, index) {
return const SizedBox(
width: 10,
);
},
),

Related

Flutter: Make all screen scrollable with GridView.builder inside

In my home screen my app shows carousel first then a vertical list of challenges cards retrieved from Cloud Firestore using GridView.builder as follows:
GridView.builder(
scrollDirection: Axis.vertical,
itemCount: _challenges.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 1,
childAspectRatio: MediaQuery.of(context).size.width /
(MediaQuery.of(context).size.height / 4),
),
itemBuilder: (context, index) {
return InkWell(
onTap: () {
if (_challenges[index]["isLocked"] == "true") {
showLockedDialog();
} else {
checkParticipation(index);
if (checkPart == true) {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) =>
ChallengeDetails(_challenges[index])));
}
checkPart = true;
}
},
child: Stack(
children: [
Center(
child: ClipRRect(
borderRadius: BorderRadius.circular(15),
child: Image(
image: NetworkImage(_challenges[index]["image-path"]),
fit: BoxFit.cover,
height: 150,
width: 350,
opacity: _challenges[index]["isLocked"] == "true"
? AlwaysStoppedAnimation(.4)
: null,
),
),
),
Center(
child: Text(
"${_challenges[index]["name"]}\n",
style: TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.bold),
),
),
Center(
child: Text(
"\n${_challenges[index]["date"]}",
style: TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.bold),
textDirection: TextDirection.ltr,
)),
Center(
child: SizedBox(
height: 130,
width: 130,
child: _challenges[index]["isLocked"] == "true"
? Image.asset("assets/lock-icon.jpg")
: null,
),
)
],
),
);
});
Everything retrieving fine and it is rendered in my home_screen as follows:
body: Column(
children: [
AdsBanner(),
SizedBox(
height: 30,
),
Padding(
padding: const EdgeInsets.only(right: 8, left: 8, bottom: 5),
child: Row(
children: [
Text(
AppLocalizations.of(context)!.challenges + " ",
style: TextStyle(fontSize: 20),
),
Text(
AppLocalizations.of(context)!.clickToParticipate,
style: TextStyle(fontSize: 15),
)
],
),
),
Expanded(child: ChallengeCard()),
],
),
The problem is that only the GridView area is scrolling and what am seeking for is to scroll the whole screen with the GridView area, I was trying to use the CustomScrollView() but its not working properly.
I'll be thankful for any help.
First in your GridView.builder add these:
GridView.builder(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
...
)
then in your home_screen wrap your column with SingleChildScrollView:
SingleChildScrollView(
child: Column(
children: [
AdsBanner(),
SizedBox(
height: 30,
),
Padding(
...
),
),
You can provide physics: NeverScrollableScrollPhysics() on GridView to disable scroll effect. If you want scrollable as secondary widget use primary: false, to have Full Page scrollable, you can use body:SingleChildScrollView(..) or better using body:CustomScrollView(..)

How to design horizontal scroll bar with separate colors

I have designed a horizontal scroll bar. here you can see my code. I want to design this bar according to the left side UI. The right side image shows my implementation so far. how do I design this with separate colours as the image shows?
final List<String> data = ["FRUIT AND BERRIES", "VEGETABLES", "BREAD","MILK"];
Padding(
padding: const EdgeInsets.only(top: 20, left: 20, right: 20),
child: Column(
children: [
SizedBox(
height: 50,
child: ListView.separated(
itemCount: data.length,
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) =>
itemW(color: Color(0xffEEEACF), text: data[index]), //try to change text colour from here but it change whole box color. :(
separatorBuilder: (context, index) {
return const SizedBox(
width: 5,
);
},
),
),
],
),
),
//horizontal scroll bar
Widget itemW({
required String text,
required Color color,
}) {
return Container(
padding: const EdgeInsets.all(16),
alignment: Alignment.center,
decoration: ShapeDecoration(
shape: const StadiumBorder(),
color: color,
),
child: Text(text),
);
}
You can use a map to map items with colors.
final Map<String,Color> itemColors = {
"FRUIT AND BERRIES" : Color(0xffEEEACF),
"VEGETABLES": Color(0xffFFFFFF),
"BREAD" : Color(0xff000000),
"MILK" : Color(0xffFF0000)
}
full Code:
final List<String> data = ["FRUIT AND BERRIES", "VEGETABLES", "BREAD","MILK"];
final Map<String,Color> itemColors = {
"FRUIT AND BERRIES" : Color(0xffEEEACF),
"VEGETABLES": Color(0xffFFFFFF),
"BREAD" : Color(0xff000000),
"MILK" : Color(0xffFF0000)
}
Padding(
padding: const EdgeInsets.only(top: 20, left: 20, right: 20),
child: Column(
children: [
SizedBox(
height: 50,
child: ListView.separated(
itemCount: data.length,
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) =>
itemW(color: itemColors[data[index]]!, text: data[index]), //try to change text colour from here but it change whole box color. :(
separatorBuilder: (context, index) {
return const SizedBox(
width: 5,
);
},
),
),
],
),
),
//horizontal scroll bar
Widget itemW({
required String text,
required Color color,
}) {
return Container(
padding: const EdgeInsets.all(16),
alignment: Alignment.center,
decoration: ShapeDecoration(
shape: const StadiumBorder(),
color: color,
),
child: Text(text),
);
}

it's possible to make listview in expand and fill parent without overflow?

it's possible to make listview in expand and fill the container without overflow the container, and shrink when listview is short of content without declare manual min or max height?
Code
Flexible(
fit: FlexFit.loose,
child: Container(
padding: EdgeInsets.symmetric(vertical: 20, horizontal: 10),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(kBoxRadius),
boxShadow: [kBoxShadow]),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
DText(
"Aug 2021",
size: 12,
weight: FontWeight.bold,
),
SizedBox(height: 10),
Row(
children: dates,
),
SizedBox(height: 15),
Container(
height: 1,
color: Color(0xFFE7E7E7),
),
Container(
constraints:
BoxConstraints(minHeight: 0, maxHeight: 600),
child: ListView.separated(
shrinkWrap: true,
itemBuilder: (context, index) {
return DText("Asd");
},
separatorBuilder: (_, __) {
return SizedBox(height: 10);
},
itemCount: 20,
),
)
],
),
),
)
Expectation
when the content is big
because i set manually max height.
Yes, it is possible using shrinkWrap: true. The code will be something like below,
class App extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(),
body: Center(
child: Container(
color: Colors.red,
child: ListView(
shrinkWrap: true,
children: <Widget>[
ListTile(title: Text('Apple')),
ListTile(title: Text('Orange')),
ListTile(title: Text('Banana')),
],
),
),
),
),
);
}
}

Can't display image when list is empty in Flutter

I am displaying an image in my code when the list is empty. I am using firebase to fetch data and store it in the list since there is no data stored yet so the list is empty initially. But it is not displaying the image on empty condition
Code:
// tab bar view her
Expanded(
child: TabBarView(
controller: _tabController,
children: [
Container(
padding: EdgeInsets.only(right: 32, left: 32),
child: Medicine(),
),
// second tab bar view widget
Container(
padding: EdgeInsets.only(right: 32, left: 32),
child: MedHistory(),
),
],
),
),
],
),
Widget Medicine() {
print("MedicineList ${med_list.length}");
if(med_list.isEmpty) {
noMedicine();
}else {
ListView.separated(
physics: NeverScrollableScrollPhysics(),
padding: EdgeInsets.symmetric(vertical: 11, horizontal: 20),
shrinkWrap: true,
primary: false,
itemBuilder: (context, index) {
return MedicinesList(
med_list[index].userSdate,
med_list[index].userReminder,
med_list[index].userEdate,
med_list[index].userFreq,
med_list[index].userDosage,
med_list[index].userMed,
med_list[index].key);
},
separatorBuilder: (_, __) => Container(),
itemCount: med_list.length);
}
}
Widget noMedicine() {
return Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Image.asset(("assets/images/Medicine-amico.png")),
SizedBox(
height: 20,
),
Text(
'Hurray! You don\'t have any pending medicines to take!',
style: TextStyle(
fontFamily: 'Montserrat',
fontWeight: FontWeight.w600,
fontSize: 14,
color: const Color(0x78000000),
height: 1.4285714285714286,
),
textAlign: TextAlign.center,
),
],
),
);
}
My screen should display this in case the list is empty:
Kindly help me out in solving the problem, Thank you
Can you try using med_list.isEmpty instead of med_list.length == 0 in your if check?
Edit: also make the list empty through List<MedicineList> med_list = []; or List<MedicineList> med_list = <MedicineList>[]; instead of List<MedicineList> med_list = List();.
Edit 2: The issue was that widgets were made using Widget name = {}. A widget has to be a class which extends either Stateless or Stateful. It also has to have an #override build(BuildContext context) {} fucntion. Please see comments for more details.
By using the condition of checking if list is empty or not inside TabView would make it and will display the image as well:
Expanded(
child: TabBarView(
controller: _tabController,
children: <Widget>[
med_list.length == 0
? noMedicine()
: ListView.separated(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
primary: false,
itemBuilder: (context, index) {
return MedicinesList(
med_list[index].userSdate,
med_list[index].userReminder,
med_list[index].userEdate,
med_list[index].userFreq,
med_list[index].userDosage,
med_list[index].userMed,
med_list[index].key);
},
separatorBuilder: (_, __) => Container(),
itemCount: med_list.length,
),
// second tab bar view widget
Container(
padding: EdgeInsets.only(right: 32, left: 32),
child: MedHistory(),
),
],
),
),

Flutter GridView is not scrolling

I am adding a header in the grid view. The header is scrolling but when touching grid view. It is not scrolling. I want to scroll header and gridview.
I have used SingleChildScrollView and Expanded. How to solve the please help me.
My code is shown below
Widget ItemGridview() {
return Container(
color: Colors.white,
padding: EdgeInsets.all(10),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new Expanded(
child: SingleChildScrollView(
child: Column(
children: <Widget>[
new Text(
'Items of products',
style: TextStyle(fontWeight: FontWeight.w700, fontSize: 18.0),
textAlign: TextAlign.left,
),
GridView.count(
shrinkWrap: true,
primary: true,
padding: EdgeInsets.only(top:15.0),
crossAxisCount: 3,
childAspectRatio: 0.60, //1.0
mainAxisSpacing: 0.2, //1.0
crossAxisSpacing: 4.0, //1.0
children: createCategoryList(),
),
],
),
)
)
]
),
);
}
In my code Items of products is the header.
List<Widget> createCategoryList() {
List<Widget> createCategoryList = List<Widget>();
for (int i = 0; i < documents.length; i++) {
createCategoryList
.add(makeGridCell(documents[i].data['title'], "name", 8,documents[i].data['id']));
}
return createCategoryList;
}
Container makeGridCell(String name, String image, int count, String id) {
return Container(
child: new GestureDetector(
onTap: () {
},
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisSize: MainAxisSize.min,
verticalDirection: VerticalDirection.down,
children: <Widget>[
new Container(
child: Image.asset('assets/' + image + ".jpg"),
),
new Container(
color: Colors.white,
padding: EdgeInsets.only(left: 5),
child: new Text(name,
style: TextStyle(
fontWeight: FontWeight.w500, fontSize: 18.0)),
),
],
),
));
}
The createCategoryList() is the list of items in grid written in widget.
I had similar widget tree like you
a gridview.count() wrapped in SingleChildScrollView adding
physics: ScrollPhysics(),
to GridView.count() Widget Solved my problem
source:https://github.com/flutter/flutter/issues/19205
Add physics: ScrollPhysics() property to Gridview. it iwll scroll.
just add some property in GridView
Widget _buildFields(BuildContext context) {
return Container(
color: Colors.white,
child: GridView.count(
crossAxisCount: 2,
crossAxisSpacing: 2.0,
mainAxisSpacing: 2.0,
shrinkWrap: true,
scrollDirection: Axis.vertical,
physics: NeverScrollableScrollPhysics(),
children: List.generate(choices.length, (index) {
return Center(
child: new Column(
children: [
new Expanded(
child: SelectCard(choice: choices[index]),//your card wight
),
],
),
);
}),
));
}
and use like this
class _Dashboard extends State<Dashboard> {
#override
Widget build(BuildContext context) {
return OrientationBuilder(builder: (context, orientation) {
return ListView(
children: <Widget>[
Container(
height: 200,
child: Image.network(
"https://www.gizbot.com/img/2013/11/23-weekend-deals-top-10-latest-smartphones.jpg"),
),
_buildFields(context),
],
);
});
}
}
You have some issues related to the Scroll of your widgets, you can reduce the amount of Widgets using Wrap, like this :
Container(
color: Colors.white,
padding: EdgeInsets.all(10),
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Text(
'Items of products',
style: TextStyle(fontWeight: FontWeight.w700, fontSize: 18.0),
textAlign: TextAlign.left,
),
Padding(
padding: const EdgeInsets.only(top: 15.0),
child: Wrap(
spacing: 20.0,
alignment: WrapAlignment.spaceEvenly,
children:createCategoryList(),
),
],
),
)
)
]
),
);
Add a constraint width or a fixed with to the widget of your item:
return Container(
constraints:
BoxConstraints(maxWidth: MediaQuery.of(context).size.width / 4),
child: new GestureDetector(
I think you need to use some custom scroll view
CustomScrollView(
primary: false,
slivers: <Widget>[
SliverPadding(
padding: const EdgeInsets.all(20.0),
sliver: SliverGrid.count(
crossAxisSpacing: 10.0,
crossAxisCount: 2,
children: <Widget>[
const Text('He\'d have you all unravel at the'),
const Text('Heed not the rabble'),
const Text('Sound of screams but the'),
const Text('Who scream'),
const Text('Revolution is coming...'),
const Text('Revolution, they...'),
],
),
),
],
)
Just ran into this myself, change your primary parameter for the GridView to false, give that a try.
In Gridview.builder scrolling is not working for smaller resolutions like tablet mode,mobile mode then just wrap the Gridview.builder under the listview.builder widget.
SizedBox(
width: screenSize.width,
height: screenSize.height * entry.contentHeightFactor,
child: ListView.builder(
itemCount: 1,
itemBuilder: (context, index) {
return Card(
child: Container(
width: screenSize.width * 0.8,
height: screenSize.height * 0.72,
padding: const EdgeInsets.all(10),
child: GridView.builder(
scrollDirection: Axis.vertical,
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
),
padding: const EdgeInsets.all(5),
itemCount: 30,
itemBuilder: (BuildContext context, int index) {
return Padding(
padding: const EdgeInsets.all(8.0),
child:Card(....),
);
},
),
),
);
},
),
),