How to switch between widgets in a table? Flutter - flutter

I need your help. I have a table with data in explorer_screen, when you click on each line, it goes to the corresponding page with detailed information about the block block_info_screen. So I need to add the ability to switch between these blocks, which are in the table on the details page. So that you can not return to the table and select another block, but immediately switch from block_info_screen to the elements following the table. As far as I understand, I need to wrap each row in the table in a push widget and use buttons and Navigator.push to switch between these widgets from the block_info_screen page.
Could you elaborate more on how to implement this feature?
explorer_screen - here is the table
return DataTable(
columns: const [
DataColumn(label: Text('Height')),
DataColumn(label: Text('Hash')),
DataColumn(label: Text('Time')),
],
rows: List.generate(5, (index) {
return DataRow(cells: [
DataCell(TextButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => BlockInfoPage(
hashBlock: blocksData[index].hash,
heightBlock:
'${blocksData[index].height}',
)));
},
child: Text('${blocksData[index].height}'))),
DataCell(Text(blocksData[index].hash)),
DataCell(Text('${blocksData[index].time}')),
]);
}));
block_info_screen - here is detailed information and here you need to implement switching between data in the table
return Column(children: [
_blockInfo(blocksInfoData),
const SizedBox(height: 20),
_blockDetails(blocksInfoData),
]);
Buttons to be implemented on the details page
Here is my table and when I click on each element I get a page with detailed information. You have to switch between them.

What you can do is you can send your whole list to the next screen i.e block screen and also the current index of the data cell that is selected. So initially you can display the selected element and then you can manage/change your index on next and back buttons as you have the access to the whole list.
If it's tough to understand.. let me know I'll elaborate.. but i would suggest you to try this out first. 🥇

Related

How do i modify the data of an existing variable in flutter?

I want to make an editable TextWidget in flutter but I don't really know how to go around it, I did some research, but still can't find a good solution.
Here's my sample code below.
I have a variable called
int qty = 1;
and so I called the variable in TextWidget
Column(
children: [
Text(
"${qty}",
style: TextStyle(),
)
],
),
I want to have these features that make user tab on the value to change it if they want, upon tap, a pop-up dialog will show to give the user the ability to change the existing value to whatever the user wants.
Please if anyone knows how, please help.
You will need a statfull widget to call setState and make the UI update with the new value stored in your qty variable. (I'am assuming that you are not using any state managment).
I wrote a possible solution for what you need.
Let look into some considerations:
Text will show whatever is in the qty as long we call setState after (or do it inside) we change the value of qty.
You need some widget to detect your tap. If you want to the text be 'clicable' then it should be wraped inside that widget.
The onTap/onPress call back of that widget should show a new widget. For this you can use the already made showDialog() and pass it a Dialog Widget. in here you will put your ui for that.
In some point of that UI you need to introduce the new value. So you can use a simple TextField that will save the introduced value, where you can assign it to qty, without forgetting to call setState! Note that it deal with strings, so you neet to do an int.parse() ou double.parse accordingly to you qty var type.
And I think that's it.
The could be other ways of doing it. This is a good and simple approach for your need.
I wrote a piece of code to help or somelse how is trying to do it:
InkWell(
// can be gesture detector, button, etc
onTap: () => showDialog(
context: context,
builder: (context) => Dialog(
child: Container(
color:
Colors.white60, // change it accordingly to you
height: 80, // change it accordingly to you
width: 200, // change it accordingly to you
child: Column(
children: [
const Text('Change your value here'),
TextField(
decoration:
InputDecoration(hintText: qty.toString()),
onChanged: (insertValue) => setState(() {
qty = int.parse(insertValue);
}),
// you can use other callBack function (like onComplete,
// onSaved), wich is more eficient than calling setState eveytime,
// but you have to do the needed adtaptions. Like onSave
// needs a key to call the save function. is easy just google it.
),
],
)),
)),
child: Text(
"${qty}",
),
),
What you are probably looking is a DropdownButton.
You would have something like this:
int qty = 1;
List<int> listOfValues = [1,2,3,4];
and then in your column you would have
DropdownButton<int>(
// This are the list of items that will appear in your dropdown menu.
// items is all the options you want your users to be able to select from,
// and it take a list of `DropdownMenuItem`. So instead of creating a `DropdownMenuItem`
// for each of the items in `listOfValues`, we iterate through it and return
// a `DropdownMenuItem`
items: listOfValues
.map((item) => DropdownMenuItem<int>(
value: item,
child: Text('$item'),
))
.toList(),
value: qty,
onChanged: (value) {
if (value != null) {
setState(() {
qty = value;
});
}
},
),
For more information on DropDownButton, check the following links:
https://api.flutter.dev/flutter/material/DropdownButton-class.html
https://www.youtube.com/watch?v=K8Y7sWZ7Q3s
Note: In a scenario where you want to increase the quantity of an item, like in a shopping cart, maybe having a button increment qty by 1 would be better.

Expand flutter datatable row on click

I'm currently using a DataTable to display a summary of some data like this
DataTable(
showCheckboxColumn: false,
columns: columnNames,
rows: state.alerts.alerts
.map(
(alert) => DataRow(
cells: [
const DataCell(Icon(
Icons.circle,
color: Colors.amber,
)),
const DataCell(Text("Something"),),
const DataCell(Text("Something")),
const DataCell(Text("TO DO")),
DataCell(Text(DateTime.fromMillisecondsSinceEpoch(alert.time.toInt(), isUtc: true).toString())),
],
onSelectChanged: (bool? selected) {
if (selected == null || !selected) return;
// Show details
},
),
)
.toList())
Which looks something like this
I would like to have it so when a user selects a row, that row expands vertically and shows additioal information whilst still part of the table (i.e. all rows below the selected row should be pushed down). The functionality I'd like to achieve is exactly what https://api.flutter.dev/flutter/material/ExpansionPanelList-class.html is intended for however using that would mean I loose access to the advantages of using a table (automated column sizing etc).
Is there a way I can create a custom table row without copying the entire DataTable source out and modifying how rows are generated?
^EDIT: After looking into the source of DataTable this doesn't look like a viable option, DataTable ultimatly mashes everything into a Table which enforces column widths. The only work around I can think of would be creating a new table for each row so a non tabled widget can be inserted in between but this would likely break a lot of stuff and be horrible for performance.
Expandable row in table with flutter- is it possible? looks like a step in the right direction however much like the OP, I can't see a way to apply Expandable to a TableRow rather than a TableCell
Thanks

Using TextField and Button to create a message bubble in Flutter

Android Studio + Flutter
I have a Row at the bottom of the screen.
It includes TextField and Button (Add).
When there is some text in TextField and user clicks Add, I want it to appear as a Bubble inside a Container starting from the top left.
What would be the correct way to do it? I want the bubbles to accumulate like a notes app and eventually be scrollable too.
Thanks!
Try using the Snackbar Widget, which can be personalized heavily.
Here's the documentation.
EDIT. Since you want a permanent list of bubbles on the top, I'd suggest using a provider, so that when you click the button, the onTap event validates and adds the data to a list (below, myElements). Then, up to the top, just add a Consumer Widget that listens to changes to the list (it rebuilds its children every time something changes). In the following example code (I have not tested it!) I use an Expanded widget just for fun and I use a ListView.builder inside the Consumer to show the list of elements you've added, since the amount of added element could be high. Finally, I suggest using either ListTile or Card or a combination of the two, since you want something aesthetically beatiful like a bubble (you'll have to play with the settings, a little):
return ... (
child: Column(
children: [
Text("Some title..?"),
Expanded(
Consumer(
builder: (ctx, myElements, _) => ListView.builder(
itemCount: myElements.length,
itemBuilder: (ctx, i) => ListTile(
title: Text("You added ${myElements[i]}"),
// something else...?
),
),
),
),
Row( /* ... Text field + Button here... */),
],
),
// ...

SliverList setState to Affect Only Selected Item Flutter

I have a button on every item on my SliverList. When I click a specific list item button, I wish it change to a different widget by using setState. Only that specific item button should change to a different widget while the rest on the list retains its own item button.
Example below. The problem of course is that when I click any button on the list, all buttons on every item on the list changes. What is needed so that it affects only the specific item on the list whose button was pressed?
SliverList(
delegate: SliverChildBuilderDelegate((BuildContext context, int index) {
final item = gd[index];
return Container(
child: Column(
children: [
item.mypicwidget(context,item.pid),
_shownewwidget
? item.newwidget(context)
: RaisedButton(
onPressed: () {
setState(() {
_shownewwidget=true;
});
},
child: const Text('Press Me'),
),
]
),
);
Figured this out.
I believe the approach is to add to the existing list an object key to represent whether widget1 or widget2 to render, eg. tag: 'normal' or tag: 'clicked'. Depending on index.tag, either widget1 or widget2 will be displayed. So for a widget with a button wherein the tag is normal, the button will have a function when clicked changes the index.tag of the item from normal to clicked. When the Sliverlist sees this new value, it automatically renders the corresponding widget.

Is it possible to calculate how many maps in the document in firestore? If yes, Is it possible to user ListView.builder?

My document has 7 maps. I have to create 7 ListTiles using 7 maps. Is it need to create one by one listView? Or Is there any way to create 1 listTile and assign 7 maps values?
StreamBuilder(
stream: db.getRequirement(uid),
builder: (context,AsyncSnapshot<RequirementModel> snapshot) {
return Column(
children: <Widget>[
pendingWidget(snapshot.data.drivingLicense.status),
pendingWidget(snapshot.data.nic.status),
pendingWidget(snapshot.data.vehiclePhotos.status),
pendingWidget(snapshot.data.vehicleLicense.status),
],
);
),
custom Widget
Widget pendingWidget(String status) {
return ListTile(
dense: true,
title: CustomText(
text:Strings.drivingLicense
),
subtitle: CustomText(
text: status
)
);
}
Yes, it can be done in ListView.builder. In fact its better for large amount of list view items, as it only builds items that are visible on the screen. Meanwhile, ListView builds everything at once regardless whether they are visible or not.
You could refer to the following link by google to learn how to work on this;
https://flutter.dev/docs/cookbook/lists/long-lists