How to put a dropdown menu in a DataTable title? - node.js

I'm new here and with Flutter, at this moment i'm developing an app to list data from my node api. I have found the way to filter that data and then show it in a flutter Datatable. Now, i want to give format to my "Cantidad" column. I though creating like a dropdown button and put it in the title of my Cantidad column. Then I will select the format between "Bandejas" or "Plantas" , these will change the value of all the cells in this columns. Do you have any idea to achieve this?
My app screnshoot
I drawed it to make more sense to you, if you take a look in my cantidad title there is a red arrow, i want to design a dropdown there. It's only a simbolyc draw.

Since label in DataColumn can be any widget, you can just use a DropdownButton there, here's a code sample i just did.
return DataTable(
border: TableBorder.all(width: 1),
columns: [
const DataColumn(
label: Text('Fecha'),
),
const DataColumn(
label: Text('Especie'),
),
DataColumn(
label: DropdownButton(
hint: const Text(
'Cantidad',
style: TextStyle(color: Colors.black),
),
underline: Container(),
items: const [
DropdownMenuItem(
value: 'Bandejas',
child: Text('Bandejas'),
),
DropdownMenuItem(
value: 'Plantas',
child: Text('Plantas'),
),
],
onChanged: (value) {
//Here update your column values
},
),
),
],
rows: const [],
);
Here's how it looks:

Related

[FLUTTER]: Cut text depending of height of ListTile

I have the following widget. The problem is I need to cut my subtitle string depending on the height and width of the ListTile. Now, height of the ListTile depends on length of substring I have. Longer is my substring, longer is the height of the ListTile. It looks awkward. Putting ListTile inside Container widget is good, but the substring overlaps the next ListTile content. it looks terrible too. Another solution was using FittedBox, I thought. But, I need the fixed size of each ListTile, without changing the fontSize. That's why the FixedBox doesn't fit me:) It changes the fontSize. I need to cut my string when it reaches the end of the ListTile. How can I solve this?
InkWell(
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => ProductScreen(product),
),
);
},
child: Column(
children: [
Container(
padding: const EdgeInsets.symmetric(
vertical: 8.0,
horizontal: 4.0,
),
child: ListTile(
title: Text(
product.title.toUpperCase(),
style: Styles.listTitleStyle,
),
subtitle: Text(
product.description,
style: Styles.listBodyStyle,
),
),
),
const Divider(height: 1.0),
],
For your text widget add something like this,
subtitle: Text(
maxLines: 2, //customize your number of lines
overflow: TextOverflow.ellipsis, //add this to set (...) at the end of sentence
product.description,
style: Styles.listBodyStyle,
),

Unnecessary Stateless Widget Rebuilds (Flutter/Dart) - Possibly StreamBuilder Related?

I am having an issue with very high levels of widget rebuild. In particular when any navigation between pages happens.
App Background:
I am essentially building an app to create and display collections (in this case house plants). Authentication, database, and image storage are all via Firebase. This data is then delivered to widgets via streams. All my custom widgets are currently stateless.
Summary of Main Page Structure:
I have a main "library" page that displays this information. This page has a column with a list of "Group" widgets. The major widget structure for the column looks like this:
Group
Collection
PlantTile
PlantTile
Collection
PlantTile
PlantTile
PlantTile
Group
Collection
PlantTile
Collection
PlantTile
PlantTile
etc...
Obviously the number of groups, collections, and plantTiles will vary depending on what the user has submitted to the database.
Problem:
Every time I navigate between pages in the app, each plant Tile rebuilds not once, but 5 times. In the example image there are 49 of these tiles, resulting in 245 rebuilds. The plantTiles are stateless but wrapped in a StreamBuilder to display data. These widgets contain images and box shadows which seem to be very taxing on the system to rebuild.
Widget Rebuild Stats
GridView.builder wraps each plantTile with a StreamBuilder
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:plant_collector/formats/constants.dart';
import 'package:plant_collector/screens/plant.dart';
import 'package:plant_collector/widgets/dialogs/select/dialog_select.dart';
import 'package:provider/provider.dart';
import 'package:plant_collector/models/ui_builders/builders_general.dart';
import 'package:plant_collector/formats/colors.dart';
class TilePlant extends StatelessWidget {
final Map plantMap;
final String collectionID;
final List<dynamic> possibleParents;
TilePlant({
#required this.plantMap,
#required this.collectionID,
#required this.possibleParents,
});
#override
Widget build(BuildContext context) {
return GestureDetector(
onLongPress: () {
showDialog(
context: context,
builder: (BuildContext context) {
return DialogSelect(
title: 'Move to Another Collection',
text:
'Please select the collection where you would like to move this plant.',
plantID: plantMap[kPlantID],
listBuildColumn: Provider.of<UIBuilders>(context)
.createDialogCollectionButtons(
selectedItemID: plantMap[kPlantID],
currentParentID: collectionID,
possibleParents: possibleParents,
),
);
},
);
},
child: Container(
decoration: BoxDecoration(
image: plantMap[kPlantThumbnail] != null
? DecorationImage(
image: CachedNetworkImageProvider(plantMap[kPlantThumbnail]))
: DecorationImage(
image: AssetImage(
'assets/images/default.png',
),
),
boxShadow: kShadowBox,
shape: BoxShape.rectangle,
),
child: FlatButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => PlantScreen(
plantID: plantMap[kPlantID],
forwardingCollectionID: collectionID,
),
),
);
},
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
plantMap[kPlantName] != null
? Padding(
padding: EdgeInsets.all(1.0),
child: Container(
color: Color(0x44000000),
margin: EdgeInsets.all(2.0),
padding: EdgeInsets.all(3.0),
constraints: BoxConstraints(
maxHeight: 50.0,
),
child: Text(
plantMap[kPlantName],
textAlign: TextAlign.center,
overflow: TextOverflow.fade,
style: TextStyle(
fontSize: 10.0,
color: Colors.white,
),
),
),
)
: Container(),
],
),
),
),
);
}
}
What I Would Like:
These widgets have no reason to update. The point of wrapping in the stream was that after the initial creation, a plantTile should only be updated if a stream event is delivered (the user modifies plant data). So ideally the widget rebuild of plantTile on navigation would be zero (not 5 x 49 = 245), and if the data of a plant is changed, 1 rebuild.
I have read that there may be an issue with the StreamBuilders firing at every screen build. I tried to follow other guides to solve this but I must be missing something because I can't seem to stop it.
Any help would be much appreciated! I am new to this, so hopefully I'm not doing something fundamentally wrong.

How to make a custom table widget in flutter?

I'm making a custom widget for showing a weekly schedule. I want it to look somewhat like a normal table, with the days in the header and the time of day on the vertical axis. Then I want to add events in the calendar, but as an event can span several cells, I can not use the built in table (it has no col/row span).
So I started to make my own table using CustomPaint. It went OK until I came to the header part, which I am stuck on the layout with my idea. In the code I supplied you can see that the header will have the same width as the side bar (with time) and the WeekView (the CustomPaint table). This means I have no idea how to align the header (Monday, Tuesday etc..) with the grid in the WeekView as the space the side bar takes up is not known. And as I want the side bar to scroll with the table, it has to be inside the scrollview. Can I solve this any other way? Maybe with slivers (that I know very little of yet)?
#override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
WeekSelector(
week: controller.week,
onPrevPressed: onPrevPressed,
onNextPressed: onNextPressed,
),
WeekHeader(),
Expanded(
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Container(
child: Row(
children: <Widget>[
Text("09:00"), // here will be a bar for the time
Expanded(
child: WeekView(
startHour: 9,
endHour: 18,
),
),
],
),
),
),
),
],
);
}

Blur background behind dialog flutter? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I want to achieve blur background behind dialog on SimpleDialog class. What I'm looking for is something similar to this, but for flutter.
Github Android project
EDIT:
I already checked this question, but this is about the Dialog, I want to implement it on SimpleDialog.
Just wrap your Dialog inside BackdropFilter
return new BackdropFilter(
filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10),
child: Dialog(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15.0)),
backgroundColor: Color(ColorResources.BLACK_ALPHA_65),
child: _dialogContent(),
)
);
Widget _dialogContent() {}//Your dialog view
I implemented blured background with showGeneralDialog method to make a blur transition as smooth as possible. Here is an example:
showGeneralDialog(
barrierDismissible: true,
barrierLabel: '',
barrierColor: Colors.black38,
transitionDuration: Duration(milliseconds: 500),
pageBuilder: (ctx, anim1, anim2) => AlertDialog(
title: Text('blured background'),
content: Text('background should be blured and little bit darker '),
elevation: 2,
actions: [
FlatButton(
child: Text('OK'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
),
transitionBuilder: (ctx, anim1, anim2, child) => BackdropFilter(
filter: ImageFilter.blur(sigmaX: 4 * anim1.value, sigmaY: 4 * anim1.value),
child: FadeTransition(
child: child,
opacity: anim1,
),
),
context: context,
);
In flutter, The dimming effect behind the dialog and bottom sheets is done using a class named 'ModalBarrier'. So what you can do is just modify the code where it dims the background.
You can easily search the file in 'IntelliJ' by using the shortcut 'Double shift'
First, you need to
import 'dart:ui' show ImageFilter;
Then in the build method change (Line: 96)
child: color == null ? null : DecoratedBox(
decoration: BoxDecoration(
color: color,
),
),
into
child: color == null ? null : BackdropFilter(
filter: new ImageFilter.blur(sigmaX: 3, sigmaY: 3),
child: Container(color: Color(0x01000000)),
),
You can change the value of 'sigma' as per your usecase.
Screenshot : Blurred Dialog
try implementing this code
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
fit: StackFit.expand,
children: <Widget>[
Image.asset('asset url', fit: BoxFit.cover),
blur(),
],
),
),
],
),
);
}
Widget blur(){
if(
//dialog pops up or is active
){
return BackdropFilter(
filter: ImageFilter.blur(sigmaX:5.0,sigmaY:5.0),
);
}
else{
return Image.asset('asset url', fit: BoxFit.cover);////if dialog not active returns an unfiltered image
}
}

How to change the entire theme's text color in Flutter?

There is probably something obvious I'm missing. Is there one property that can change the color of all the text in a Flutter app?
The way I am doing it now is, in my MaterialApp:
theme: ThemeData(
textTheme: Theme.of(context).textTheme.copyWith(
body1:
Theme.of(context).textTheme.body1.apply(color: Colors.pink),
body2:
Theme.of(context).textTheme.body2.apply(color: Colors.pink),
display1:
Theme.of(context).textTheme.display1.apply(color: Colors.pink),
display2:
Theme.of(context).textTheme.display2.apply(color: Colors.pink),
... // and so on
),
),
),
I also tried
textTheme: Theme.of(context).textTheme.apply(bodyColor: Colors.pink),
but this applies to Dropdown text, not regular text. Likewise, displayColor applies to the appBar text and a InputDecoration text, but not regular text. I don't seem to have any decorationText in my code so I'm not sure what that one is for.
I note there is a textSelectionColor property but that only applies for TextField widgets.
I think TextTheme.apply is what you want. bodyColor will be applied to headline, title, subhead, button, body1, and body2. displayColor will be applied to display1 through display4, and caption. If you specify both bodyColor and displayColor and use the same color value, that will effectively change text colors on all text styles.
Example:
final newTextTheme = Theme.of(context).textTheme.apply(
bodyColor: Colors.pink,
displayColor: Colors.pink,
);
For the entire app, you can set textTheme property in the Material app widget.
MaterialApp(
theme: ThemeData(
textTheme: TextTheme(
bodyText1: TextStyle(),
bodyText2: TextStyle(),
).apply(
bodyColor: Colors.orange,
displayColor: Colors.blue,
),
),
)
To provide an alternative that seems to work without setting all the Text styles directly is to change the style of the DefaultTextStyle at the place in the Widget tree to take effect
return DefaultTextStyle(
style: TextStyle(color: Colors.pink),
child: _YOUR_WIDGETS_
)
Maybe a bit late... but you can use this:
ThemeData(
primaryTextTheme: Typography(platform: TargetPlatform.iOS).white,
textTheme: Typography(platform: TargetPlatform.iOS).white,
)
mine is working with this:
return MaterialApp(
theme: ThemeData(
textTheme: TextTheme(
bodyText2: TextStyle(
color: Colors.white,
),
),
),
);
I found using copyWith() on the TextTheme works well, as you can just change specific properties like fontsize - leaving everthing else unchanged.
textTheme: TextTheme().copyWith(
bodyText2: TextStyle(
fontSize: 30,
fontWeight: FontWeight.bold
)
),

Resources