Flutter: checkBox onChanged - checkbox

I was trying to implement a checkbox that would disable and enable a button. But I was blocked by this following error:
I/flutter (19999): The following assertion was thrown building DisclaimerPage(dirty, state: DisclaimerPageState#24b3d):
I/flutter (19999): setState() or markNeedsBuild() called during build.
I/flutter (19999): This Overlay widget cannot be marked as needing to build because the framework is already in the
I/flutter (19999): process of building widgets. A widget can be marked as needing to be built during the build phase
I/flutter (19999): only if one of its ancestors is currently building. This exception is allowed because the framework
I/flutter (19999): builds parent widgets before children, which means a dirty descendant will always be built.
I/flutter (19999): Otherwise, the framework might not visit this widget during this build phase.
Here is my code for building the page:
class DisclaimerPageState extends State<DisclaimerPage> {
bool checkBoxValue = false;
#override
Widget build(BuildContext context) {
var _floatButtonOnPressed;
if (checkBoxValue) {
_floatButtonOnPressed = navToHome();
}
return new Scaffold(
appBar: AppBar(
title: Text("Disclaimer"),
leading: Container(),
),
body: Container(
child: Card(
child: Column(
children: <Widget>[
Text("ADHJASDKHKDAD"),
Row(
children: <Widget>[
Checkbox(
value: checkBoxValue,
onChanged: (bool newValue) {
setState(() {
checkBoxValue = newValue;
});
}),
Text("I understand"),
],
),
],
),
),
),
floatingActionButton: FloatingActionButton.extended(
onPressed: _floatButtonOnPressed,
label: Text("PROCEED"),
icon: Container(),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
);
}
navToHome() {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ImmunityHomePage(title: 'ImMUnity')),
);
}
}
Am I doing something wrong? My checkbox implementation is based on the documentation of checkbox.dart. So I am a little confused here. Help is appreciated. Thank you so much!

Instead of checking checkBoxValue & setting onPressed, you should check checkBoxValue inside your on press function then manage navigation.
SO first remove this
if (checkBoxValue) {
_floatButtonOnPressed = navToHome();
}
Then update onPressed of floating action button as
onPressed: (){navToHome();},
Then update you navToHome() function
navtoHome(){
if(checkValue){
//your navigation code here
}
}

Related

React-leaflet-draw doesn't keep updated onCreated to a hook state of drawn features

Context
I am trying to save my collection of my drawn features dynamically into a state hook, and keeping them updated from onCreated, onEdited and onDeleted.
This is how my UI looks like:
Problem
The issue happens when, I click on the trash icon and remove one of the created features with (let's say) id=2, and then create another new feature of id=3; it looks like the onCreated method doesn't have it's state of features updated, and when creating the feature of id 3, it returns to show the deleted figure of id 2 in the data (but not on the map).
This is how it looks like when the old figure is deleted, but when creating a new one, the onCreate makes it persistent in the data displayed at the right container.
This is the code that I run: (The featureCollection is the state hook passed from the App.js):
import { FeatureGroup } from "react-leaflet";
import { EditControl } from "react-leaflet-draw";
export default function EditFeature({ lkey, setlKey, featuresCollection, setFeaturesCollection }) {
const _onCreated = (e) => {
let layer = { id: e.layer._leaflet_id, ...e.layer.toGeoJSON() };
setlKey(e.layer._leaflet_id);
setFeaturesCollection({
...featuresCollection,
features: [layer, ...featuresCollection.features]
});
};
const _onDeleted = (e) => {
let unwanted = Object.keys(e.layers._layers);
unwanted = unwanted.map(item => Number(item));
// Filter out those layers whose id is in the unwanted array
let filtered = featuresCollection.features.filter(e => !unwanted.includes(e.id));
setFeaturesCollection({
...featuresCollection,
features: [...filtered]
});
};
return (
<FeatureGroup>
<EditControl
key={lkey}
id="EditControl"
onCreated={_onCreated}
onDeleted={_onDeleted}
position="topright"
draw={{
circle: false,
circlemarker: false,
polyline: false,
marker: false,
polygon: {
allowIntersection: false,
shapeOptions: {
color: "purple",
weight: 3
},
},
rectangle: {
shapeOptions: {
color: "purple",
weight: 3
}
}
}}
/>
</FeatureGroup>
);
};
My main goal is to achieve that my state keeps updated the figures shown in the map, in order to then export those to a geojson file, like the web GeoJSON.io does! (within React tho).
Reference:
https://github.com/alex3165/react-leaflet-draw/issues/154

Rendering an action menu in Ant Table on Row hover

I'm using Ant table to display some data. So far so good except the requirement that I need to display an action menu when a particular row hovered over. Here's the mock of what I'm trying to achieve:
Ant table's onRow callback will allow me to get the record that's being hovered over and onRowClassName allows me to pass a class name so I can dynamically apply css on the row hovered over. But I'm stuck on rendering an element at the end of the row like you see in the screenshot.
I'm a bit stumbled on how to go about doing this. Closest thing I came across is this context menu implementation: https://codesandbox.io/s/rm23kroqyo
Appreciate any input.
One way to do this is to add a column for the actions and add a className for it.
export const columns = [
{ title: `Name`, dataIndex: `name` },
{ title: `Age`, dataIndex: `age` },
{ title: `Address`, dataIndex: `address` },
{
title: "",
dataIndex: "actions",
render: (actions) =>
actions &&
actions.map((action) => (
<a className="action" href>
{action}
</a>
)),
className: "actions"
}
];
add the actions on the data
const dataWithActions = data.map((item) =>
item.key === "2" ? { ...item, actions: ["Like", "Share"] } : item
);
Then set it's position absolute so it does not take up space
.actions {
position: absolute;
}
.ant-table-row {
position: relative;
}
And finally position it when the row is hovered
.ant-table-row:hover .actions {
display: block;
height: 54px;
right: 0;
}
Here's the updated codesandbox:
https://codesandbox.io/s/custom-context-menu-table-antd-forked-b6y5c

Why Cloud Firestore updates so much? [duplicate]

This question already has an answer here:
Firestore - unexpected reads
(1 answer)
Closed 2 years ago.
I'm working on a project for a logistics warehouse.
The idea is that I use Cloud Firestore for store pallets in a rack and that I can find it back in the system.
I can see my pallets in the app and it works well.
Cloud Firestore has a read amount of 50.000 reads per day.
If I start up the app it calculates the number of documents in the list and I can see it in the usage tab.
That's okay but even if I do nothing in the app, the number increases.
Is there a solution to read the data only if the flutter page opens?
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
class overzicht extends StatefulWidget {
#override
_overzichtState createState() => _overzichtState();
}
class _overzichtState extends State<overzicht> {
Future _data;
Future getPosts() async{
var firestore = Firestore.instance;
QuerySnapshot qn = await firestore.collection("locaties").getDocuments();
return qn.documents;
}
#override
void initState() {
super.initState();
_data = getPosts();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Center(child: Text('Overzicht')),backgroundColor: Color.fromRGBO(17, 32, 42, 1),),
body: Container(
child: FutureBuilder(
future: _data,
builder: (_, snapshot) {
if(snapshot.connectionState == ConnectionState.waiting){
return Center(
child: Text('Loading...'),
);
} else{
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (_, index){
return ListTile(
title: Text(snapshot.data[index].data["location"]),
);
});
}
}),
),
);
}
}
This has been answered before here:
If you leave the console open on a collection/document with busy write activity, the console will automatically read the changes that update the console's display. This is very often the source of unexpected reads.

How can I display a Persona component in a CommandBar in React Fabric-UI?

I am trying to display a Persona component on the far right of my CommandBar component, which I use as a header for my application.
Here's a code snippet
const getFarItems = () => {
return [
{
key: 'profile',
text: <Persona text="Kat Larrson" />,
onClick: () => console.log('Sort')
}
]
}
const FabricHeader: React.SFC<props> = () => {
return (
<div>
<CommandBar
items={getItems()}
farItems={getFarItems()}
ariaLabel={'Use left and right arrow keys to navigate between commands'}
/>
</div>
);
}
This throws a type error because the text prop expects a string and not a component. Any help would be appreciated!
Under the ICommandBarItemProps there is a property called commandBarButtonAs that the docs state:
Method to override the render of the individual command bar button.
Note, is not used when rendered in overflow
And its default component is CommandBarButton which is basically a Button
Basically there are two ways to do this.
Keep using Button, and apply your own renderer. Basically the IButtonProps you can add onRenderChildren which would allow you to add any Component such as Persona to render. This example would show you how it is done https://codepen.io/micahgodbolt/pen/qMoYQo
const farItems = [{
// Set to null if you have submenus that want to hide the down arrow.
onRenderMenuIcon: () => null,
// Any renderer
onRenderChildren: () => ,
key: 'persona',
name: 'Persona',
iconOnly: true,
}]
Or add your own crazy component not dependent on CommandBarButton but that means you need to handle everything like focus, accessibility yourself. This example would show you how it is done https://codepen.io/mohamedhmansour/pen/GPNKwM
const farItems = [
{
key: 'persona',
name: 'Persona',
commandBarButtonAs: PersonaCommandBarComponent
}
];
function PersonaCommandBarComponent() {
return (
);
}

Slide-up view in Flutter

I'm trying to make something similar to google/apple maps screen in flutter. I just started experimenting in Flutter and I have a hard time understand that "Draggable widget". Could someone give me example code how they made their slide-up view, I can learn from? I can't find any.
There's also the sliding_up_panel Flutter library you could use to implement the same sort of design that Google/Apple Maps uses.
Draggable (and DragTarget) is not used for what you call slide-up view
slide-up view, from the android world, is for bottom aligned modals.
Draggable is to transfer data using Drag&Drop.
In flutter, bottom modals are fairly simple :
First, make sure you have somewhere above in your tree a Scaffold. As it's what will position everything together.
Then, call either showBottomSheet or showModalBottomSheet with whatever content you like. The content will now automatically appear at the bottom of your screen.
That's it, your job is done ! You can optionally now add a custom close event. For this, you'll just have to call Navigator.pop(context).
But both modal and non-modal bottom sheet can be closed out of the box using common gestures. Such as back button, navbar back, of click outside.
Full example :
class MyExample extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
home: new Scaffold(
appBar: new AppBar(title: new Text('Example')),
body: new Center(
child: new Builder(builder: (context) {
return new Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
new RaisedButton(
onPressed: () => modal(context),
child: new Text("modal"),
),
new RaisedButton(
onPressed: () => showSlideupView(context),
child: new Text("non modal"),
),
],
);
}),
),
),
);
}
void showSlideupView(BuildContext context) {
showBottomSheet(
context: context,
builder: (context) {
return new Container(
child: new GestureDetector(
onTap: () => Navigator.pop(context),
child: new Text("Click me to close this non-modal bottom sheet"),
),
);
});
}
modal(BuildContext context) {
showModalBottomSheet(
context: context,
builder: (context) {
return new Container(
child: new Text("This is a modal bottom sheet !"),
);
});
}
}
Now you can use Sliding Up Panel plugin to do that, its awesome.
As an alternative: From the docs https://api.flutter.dev/flutter/material/showModalBottomSheet.html
Widget build(BuildContext context) {
return Center(
child: ElevatedButton(
child: const Text('showModalBottomSheet'),
onPressed: () {
showModalBottomSheet<void>(
context: context,
builder: (BuildContext context) {
return Container(
height: 200,
color: Colors.amber,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
const Text('Modal BottomSheet'),
ElevatedButton(
child: const Text('Close BottomSheet'),
onPressed: () => Navigator.pop(context),
)
],
),
),
);
},
);
},
),
);
}

Resources