I want to achieve UI like Windows File Explorer
windows file explorer
Build one list as start and inside it a list of items and the item contains a title and a list of items
The image you attached looks like it could be replicated with a ListView.builder returning an ExpansionTile containing a GridView.
SizedBox(
height: 40,
width: 300,
child: ListView.builder(
itemBuilder: (context, index) {
return ExpansionTile(
title: const Text('title'),
children: [
SizedBox(
height: 100,
width: 200,
child: GridView.count(
crossAxisCount: 3,
children: List.generate(
3,
(index) {
return SizedBox(
height: MediaQuery.of(context).size.height / 1.8,
child: const Icon(Icons.folder),
);
},
),
),
),
],
);
},
),
);
This builds several expansion tiles each containing 3 folder icons. You may consider adding a little bit more to your question as it is a little vague, but I hope this helps!
Related
I would like to create a list of cards each with a button that displays a menu (edit, delete ...) but I don't know where to start or which widget to use. There is also the problem that each button must respond individually.
I use Hive for my card data
Do you know how to do it ?
Align(
alignment: Alignment.centerRight,
child: SizedBox(
width: 4.29,
height: 16,
child: SvgPicture.asset('assets/Icones/IconesNewDesign/edit.svg', width: 4.29, height: 16,fit: BoxFit.scaleDown,
),
),
Edit:
I need something like this
first you need to take listviewbuilder and then take card inside it and you can also take icons of delte and edit in card
ListView.builder(
itemcount;2,
itembuilder(context,index)
{
retun Card(
child:Column(
childern[
Image.Asset(""),
Row(
childern[
Icon(Icons.delte),
Spacer(),
Icon(Icons.edit),
]
)
]
)
)
)
You could use ListTiles with PopupMenuButtons
final List<String> _cards = ["One", "Two", "Three", "Four", "Five"];
ListView.builder(
itemCount: _cards.length,
itemBuilder: (context, index) => Card(
elevation: 5,
child: ListTile(
title: Text(_cards[index]),
trailing: PopupMenuButton(
itemBuilder: (ctx) => [
PopupMenuItem(child: Text("Delete")),
PopupMenuItem(child: Text("Edit")),
],
),
),
),
)
I have a horizontal ListView and depending on the app state, there might be 1-2 items in the list or many.
Now, I want to have the items centered as long as there are only a few available and scrolling is not needed. So far my items always stick to the left side as you can see in the ListView with the lime background color. That one I wanted centered, even if 2 or 3 items are visible, but with more, it shall scroll and then start at the left side with listing the items.
return Container(
color: Colors.lime,
child: ListView(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
children: listItems));
the items itself are this:
Widget getPersonCircleWidget(BuildContext context, Person p) {
return Container(
color: Colors.transparent, //yellow,
child: Padding(
padding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
child: CircularProfileAvatar('',
child: Image(
fit: BoxFit.cover,
image:
UserPhotoManager.singleton.getUserProfilePhoto(p.userId)),
borderColor: colorCirclePhotoBorder,
borderWidth: 2,
elevation: 10,
radius: 40,
onTap: () {
....
}),
),
);
}
Any idea how to solve this?
Just wrap your ListView with Center widget.
Center(
child: ListView(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
children: listItems.map<Widget>((a) => CircleAvatar(
child: Text(a))).toList(),
),
),
When ListView exceed available room on the screen it will automatically left aligned.
Try it on dartpad.
I'm building out an app in flutter and I want to display a few cards in a list-view. The problems I'm facing are the following:
I get a text-overflow when I have Text widgets in a column.I semi-fixed this by wrapping the Text widget in an Expanded widget, but it looks a bit cutoff (ex. "Question: How do you do problem 2?" (refer to picture below)).
I want to build a larger card with a greater height and more room/white space. I've tried wrapping my column widget in a container and set the height manually, but that doesn't seem to do anything.
Here is what the card looks like right now:
Relevant code shown below:
itemBuilder: (context, index) => snapshot
.data.metadata.isFromCache
? _buildListItem(context,
snapshot.data.documents[index])
Widget _buildListItem(BuildContext context, DocumentSnapshot document) {
return document.data['didProblems']
? Card(
child: Center(
child: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('${document.data['fullName'].toString()}'),
SizedBox(
height: 5.0,
),
Text('HW Assignment: ${document.data['title'].toString()}'),
SizedBox(
height: 5.0,
),
Text('Problems attempted: ${document.data['problems']}'),
Expanded(child: Text('Question: ${document.data['question'].toString()}'), flex: 1,),
],
),
),
),
)
Any help is appreciated. Thanks in advance!
if u r using listview then set itemExtent property to ur convenience e.g.
ListView.builder(
itemCount: 10,
itemBuilder: (_, int index) => YourWidget(),
itemExtent: 150,
),
Even after wrapping your text in an Expanded you have to set overflow to TextOverflow.clip
Try this
Expanded(child: Text('Question: ${document.data['question'].toString()}', overflow: TextOverflow.clip), flex:1,),
I have a page with container + listView. Now the listView is scrollable, but I would like the whole page to be scrollable. (so if the user scrolls, the container goes 'away')
Column(
children: <Widget>[
Container(
color: Colors.white.withOpacity(0.95),
width: 400,
height: 400,
child: Text("")),
ListView(
children: posts,
),
],
),
Is this possible, and how can it be achieved?
Thanks!
You can wrap the whole page with a SingleChildScrollView
here is an example:
SingleChildScrollView( // <- added
child: Column(
children: <Widget>[
Container(
color: Colors.white.withOpacity(0.95),
width: 400,
height: 400,
child: Text("")),
ListView(
shrinkWrap: true, // <- added
primary: false, // <- added
children: posts,
),
],
),
);
for more info about see this question
What if you don't use Column and use ListView.builder and
according to indexes you show the widget.
For example on 0 index you show the Container.
This way you don't have to use any different widget for scrolling
and as per your requirement the container will scroll with the list.
This way there is no chance that you will get any overflow error
like you were getting while using Column.
Plus point of ListView.builder is that your posts will be created lazily and that is efficient way of creating ListView in Flutter. No matter how many posts you have your UI will not lag.
This at first may look like a hack but according to your requirement that the container must also be able to get scrolled, this solution makes sense to me because Container can be considered as a first element of the list.
Let me know if it works for you or not.
Following is the working code for your reference:
#override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: posts.length + 1, // +1 because you are showing one extra widget.
itemBuilder: (BuildContext context, int index) {
if (index == 0) {
return Container(
color: Colors.white.withOpacity(0.95),
width: 400,
height: 400,
child: Text(""));
}
int numberOfExtraWidget = 1; // here we have 1 ExtraWidget i.e Container.
index = index - numberOfExtraWidget; // index of actual post.
return posts[index];
},
);
}
I hope this works for you, in case of any doubt please comment.
There are multiple ways you can achieve what you want. The only problem is that if you have large number of posts, listview with children posts, as shrinkWrap is set to true, will take time to calculate its required height, for that it will have to populate all of its children.
First
ListView(
children: <Widget>[
Container(
color: Colors.white.withOpacity(0.95),
width: 400,
height: 400,
child: Text("")),
ListView(
physics: NeverScrollableScrollPhysics(),
primary: false,
shrinkWrap: true,
children: posts,
),
),
],
),
Second
SingleChildScrollView(
child: Column(
children: <Widget>[
Container(
color: Colors.white.withOpacity(0.95),
width: 400,
height: 400,
child: Text("")),
ListView(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
primary: false,
children: posts,
),
],
),
),
use SingleChildScrollView then Container with hard coded container height, then list view builder, that should fix your issue.
I tried the following:
SingleChildScrollView(
child: Container(
height: 1000,
width: 400,
child: ListView(
children: <Widget>[
Container(
color: Colors.white.withOpacity(0.95),
width: 400,
height: 400,
child: Text("")),
ListView(
children: posts,
),
],
),
),
),
This works, but I would like that the container has a dynamic height and width? Is that possible? Thanks!
I would like to have a drop shadow on each item and each item should overlap the top of the next sibling.
It's probably too late for the original poster, but maybe it will help someone else looking for this:
The best solution I found to this (without resorting to a manually managed stack) is to use an Align widget with a height factor of less than 1. This will cause the next item to overlap with the previous one.
Here are the key elements to make this work:
final elements = ['A', 'B', 'C'];
final padExtend = 16.0;
final media = MediaQuery.of(context);
return ListView.builder(
itemCount: elements.length,
itemBuilder: (BuildContext context, int index) {
final String content = elements[index];
return Align(
child: Container(
width: media.size.width - padExtend / 2.0,
padding: EdgeInsets.all(padExtend),
decoration: BoxDecoration(
boxShadow: [
BoxShadow(color: Colors.grey, spreadRadius: 3, blurRadius: 3, offset: Offset(2, 1)),
],
color: Colors.white,
),
child: Text(content),
),
alignment: Alignment.topCenter,
heightFactor: 0.9,
);
},
);
Since the align would center the elements, a media query is used to set a fixed width.
Wraping your elements with OverflowBox and giving the maxHeight value will achieve this effect.
return SizedBox(
height: 35, //--> list children will be 35 in height
child: OverflowBox(
maxHeight: 50, // --> allowing the child to overflow will cause overlap between elements
child: Container(
height: 50,
child: Text((index + 1).toString()),
),
),
);
use SizedOverflowBox (preferred) or OverflowBox, it is very easy to implement such effects... Flutter YYDS
You could try my package (signed_spacing_flex). It's exactly the same as a normal Column (or Row and Flex). But it lets you set negative spacing which causes its children to overlap.
You can also set which children should be on top when they overlap.
It works with expanded children if you need.
You can use a elevation and padding top to achieve the effect you want :
ListView.builder(
itemCount: 5,
itemBuilder: (BuildContext content, int index) {
return Padding(
padding: const EdgeInsets.only(top: 8.0),
child: Material(
elevation: 5.0,
child: new Container(
height: 100.0,
),
),
);
})
If you want to overlap your items just use a heightFactor below 1.0
return Align(
alignment: Alignment.topLeft,
heightFactor: 0.9,
child: your item...