Arranging icons from cloud firestore in flutter - flutter

I have an AlertDialog with icons in that are from cloud firestore. I am struggling to change the layout of the icons so that it looks normal. (1) is what is currently being shown and (2) is what I am wanting to achieve.
(1)
(2)
This is my code:
Widget _buildPopupDialog(BuildContext context) {
return Scaffold(
body: StreamBuilder(
stream: FirebaseFirestore.instance.collection('icons').snapshots(),
builder: (context, snapshot) {
return new AlertDialog(
content: SingleChildScrollView(
child: new Container(
height: 500,
width: 300,
child: new ListView(
children: snapshot.data.documents
.map<Widget>((DocumentSnapshot document) {
return new MoodButton(
iconData: (IconData(document.data()['ref'],
fontFamily: 'MaterialIcons')),
onTap: () => print("Mood"),
);
}).toList(),
)),
),
);
}));
Any help would be greatly appreciated!

You should use GridView instead of ListView. Set the crossAxisCount property to 3 and you should get the result you want. If you have any doubts, you can find GridView's doc here

Related

What widget should I use?

This is what I am doing now.
Main Page:
I would like to make it same like this picture.Example:
I have tried couple ways and widget to build it but couldn't figure it out. Also, I want to retrieve the data from the Firebase and show them as the content.
Code 1: https://pastebin.com/A0nK1riQ
Code 2: https://pastebin.com/i1T7gBNy
Widget build(BuildContext context) {
return Container(
child: StreamBuilder(
stream: _products.snapshots(),
builder: (context, AsyncSnapshot<QuerySnapshot> streamSnapshot) {
if (streamSnapshot.hasData) {
return ListView.builder(
itemCount: streamSnapshot.data!.docs.length,
itemBuilder: (context, index) {
final DocumentSnapshot documentSnapshot =
streamSnapshot.data!.docs[index];
return Container(
margin: const EdgeInsets.all(10),
child: ListTile(
title: Text(documentSnapshot['name']),
subtitle: Text(documentSnapshot['price'].toString()),
trailing: SizedBox(
width: 100,
),
),
);
});
}
return SizedBox.shrink();
}),
);
}
You may use GridView.builder
https://api.flutter.dev/flutter/widgets/GridView-class.html
and in gridview build use column
According to me, first you have to check which NavigationRail icon clicked then put the condition on it's GestureDetector like
// global variable
String itemClickedValue = "";
then set the value in it according to user click
itemClickedValue = "first";
then check the condition while fetching data like
if(itemClickedValue.compareTo("first") == 0){
// pass that documentId or api and then show in list
}

Two direction scrolling in data table flutter

I made a DataTable in flutter and it has about 10 columns and that's more than what the screen can handle so I wrapped the DataTable inside a SingleChildScrollView widget and this solution worked fine until the rows inside the DataTable grew up and exceeded the screen height and I couldn't scroll down because of the scroll direction is set to horizontal in the SingleChildScrollView widget!
And as a temporary solution, I wrapped the DataTable inside a fittedBox inside the SingleChildScrollView but this doesn't solve the whole problem and still, there is some responsibility issues.
What I need is a way to make the DataTable scrollable in both directions horizontally and vertically.
This is my code
#override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.all(16),
child: Card(
child: Container(
padding: const EdgeInsets.all(16),
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: FutureBuilder(
future: getCategories(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(
child: CircularProgressIndicator(),
);
} else {
return FittedBox(
child: DataTable(
headingRowColor: MaterialStateProperty.resolveWith(
(states) => Colors.grey.shade900),
columns: _columns,
rows: _rows,
),
);
}
},
),
),
),
),
);
}
The easiest solution I know, is to wrap the SingleChildScrollView in a second SingleChildScrollView.
https://stackoverflow.com/a/57539405/1151983
But there are also other approaches:
https://stackoverflow.com/a/63546017/1151983

How can i include navigation for a listview in flutter ,

enter image description here
I want each list item to have its own route .I have attached a screenshot. My list view is customized, each item has its own name
Your question doesn't explain much, but rather than listview use listview.builder and then you can return any widget and pass your route based on itemindex.
ListView.builder(
itemCount: 10, *//Number of items in your static or dynamic*
itemBuilder: (context, index) {
return YourNewCommonWidgetForEveryItem(index);
},
),
For example I've to navigate the first item to somewhere else
Widget YourNewCommonWidgetForEveryItem(int Index){
return GestureDetector(
onTap:()=> index==0 ? locationtofirstItem : defaullt,
child: yourDesign(),
),
}
OfCourse the Above method won't work if you don't know where to navigate which item.
body: new ListView(
padding: const EdgeInsets.all(20.0),
children: List.generate(choices.length, (index) {
return Center(
child: ChoiceCard(
choice: choices[index],
item: choices[index],
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Detail(choice: choices[index])),
);},),);}))

How can I put a SearchView on top of a ListView?

I'm new to flutter and am trying to stack a searchView on top of a ListView. I would Look something like this:
I don't know how to achieve this layout on flutter, i tried using a column(which crashes the app), used the a stack (which overlaps the widgets) and i finally tried to add a search widget a the first item of the ListView but that didn't result am looking for.
Widget build(BuildContext context) {
return new Scaffold(
drawer: _makeDrawer(),
appBar: new AppBar(
title: new Center(
child: new Text("translate"),
),
actions: <Widget>[
new IconButton(icon: new Icon(Icons.people_outline), onPressed: () {})
],
),
body: _phraseListFutureBuilder(), // this part of the code renders the listview
);
}
FutureBuilder _phraseListFutureBuilder() {
return new FutureBuilder(
builder: (BuildContext context, AsyncSnapshot snapshot) {
return mPhrases.isEmpty
? new CircularProgressIndicator()
: _buildPhrases();
},
future: _fetchData());
}
A Column was the right choice, but you will also need an Expanded widget to specify which widget should fill the remaining space:
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
TextField(
decoration: InputDecoration(
labelText: 'Search'
),
),
Expanded(
child: _phraseListFutureBuilder(),
)
],
);

Remove Padding on CupertinoSliverNavigationBar

I am trying to use CupertinoSliverNavigationBar, actually it's great, but for some reason I can't place the trailing right on the end of navigation bar. I looked up and I (guess, I) found that there's Padding inside it
this is my code
new CupertinoPageScaffold(
child: new CustomScrollView(
slivers: <Widget>[
new CupertinoSliverNavigationBar(
largeTitle: new Text('Tasks'),
trailing: new CupertinoButton(
child: new Icon(AdditionalCupertinoIcons.compose, size: 32.0),
onPressed: () {
showDialog(
context: context,
builder: (BuildContext context) {
return new CupertinoAlertDialog();
});
},
padding: EdgeInsets.all(0.0),
),
)
],
),
),
Sadly, no can-do.
Looking at this line of source code, you can see that they are using a Padding at the end, which is _kNavBarEdgePadding, i.e. 16.0. Same for the start.
This means that with the CupertinoSliverNavigationBar you will not be able to remove that Padding because there is no access point to change it. You will have to create your own widget for that.
The _CupertinoPersistentNavigationBar widget contains the Padding and is used by CupertinoSliverNavigationBar, as can be seen here and for completion here.
There is an easy way to move a widget on the screen:
Widget _adjustNavigationBarButtonPosition(Widget button, double x) {
if (button == null) return null;
return Container(
transform: Matrix4.translationValues(x, 0, 0),
child: button,
);
}
Wrap your CupertinoButton with this method and specify an offset. To remove the padding completely, the offset should be 16.0.
You can use Matrix4.translationValues to move a child within the container. In your case x Matrix4.translationValues(12, 0, 0), should be positive to move the trailing to the right.
new CupertinoPageScaffold(
child: new CustomScrollView(
slivers: <Widget>[
new CupertinoSliverNavigationBar(
largeTitle: new Text('Tasks'),
trailing: Container(
transform: Matrix4.translationValues(12, 0, 0),
child : CupertinoButton(
child: new Icon(AdditionalCupertinoIcons.compose, size: 32.0),
onPressed: () {
showDialog(
context: context,
builder: (BuildContext context) {
return new CupertinoAlertDialog();
});
},
)
),
)
],
),
),