How to show bottom sheet on map in flutter mobile application? - google-maps

I see a lot of tutorials for implementing bottom sheet in my flutter application, but i am facing problem in implementing that, all of them showing bottom sheet after onPressed/onTap and i do not want that. I had implemented google map in my application but now i want to show persistent bottom sheet after i got response from API on map screen and color of that bottom sheet must be transparent so that map can be visible through bottom sheet.
Can you share some code that how can i show bottomsheet without onpressed on google map screen in flutter mobile application?

you can use a stack widget and visibility widgets to show that.
here is some minimalist code
bool _isVisible=false;
//after you get a response fro your api you set state of `_isVisible` to `true/!_isVisible.`
Stack....
Positioned(bottom:10,left:0
child: Visibility(visible:!_isVisible,
child Container(color:Colors.Transparent,
child:Center(child:Text("your data here")))),
...

after getting your data :
return showModalBottomSheet(
isDismissible: false,
isScrollControlled: true,
context: context,
builder: (BuildContext context) => SingleChildScrollView(
child: Container(
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom),
child: ?,
),
),
);

Related

flutter_map WMS with custom CRS fails to load map image: Failed to decode Image data

I'm trying to create a simple flutter map widget that gets layers from a WMS server.
The server is this.
And you can see the its capabilities here.
Specifically, I want to use the layer "AMS_1956-1957".
As this layer is served in the CRS EPSG:4258, I'm creating a custom CRS for this FlutterMap to use (as it's stated in the documentation that only WGS84 (EPSG:4326) and Google Mercator (EPSG:3857) projections are supported).
I'm creating this custom CRS following the instructions here.
I'm getting the Proj4 definition string for this CRS (EPSG:4258) from here, as stated in the documentation: "+proj=longlat +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +no_defs"
So the code for creating the custom CRS is this:
var resolutions = <double>[32768, 16384, 8192, 4096, 2048, 1024, 512, 256, 128];
var maxZoom = (resolutions.length - 1).toDouble();
var epsg4258CRS = Proj4Crs.fromFactory(
code: 'EPSG:4258',
proj4Projection: proj4.Projection.add("EPSG:4258",
'+proj=longlat +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +no_defs'),
resolutions: resolutions,
);
Then I'm using this CRS in my FlutterMap widget as follows (again, based in the documentation).
#override
Widget build(BuildContext context) {
return FlutterMap(
options: MapOptions(
center: LatLng(41.61, -2.52),
zoom: 3.0,
),
layers: [
TileLayerOptions(
wmsOptions: WMSTileLayerOptions(
baseUrl: 'https://www.ign.es/wms/pnoa-historico?',
layers: ['AMS_1956-1957'],
crs: epsg4258CRS,
),
),
MarkerLayerOptions(
markers: [
Marker(
width: 5.0,
height: 5.0,
point: LatLng(41.61, -2.52),
builder: (ctx) => Container(
child: const FlutterLogo(),
),
),
],
),
],
);
}
}
The pointer is shown, so I guess it's doing something, but no map image is shown, and it returns the following error:
ImageCodecException: Failed to decode image data. Image source:
https://www.ign.es/wms/pnoa-historico?&service=WMS&request=GetMap&layers=AMS_1956-1957&styles=&format=image%2Fpng&srs=EPSG%3A4258&version=1.1.1&transparent=true&width=256&height=256&bbox=180,-90,180,-90
Ok, the WMS is working, as I can access it via QGIS, for example.
If I open the "image source" url created by flutter via browser it doesn't seem to work.
Plus, the bbox values in the url doesn't seem to make much sense, as they lie outside of the CRS boundaries. And the centering and zoom values I'm giving it doesn't seem to make any effect either...
If I try to open the url with different bbox values closer to the boundaries of the layer it shows something at least:
https://www.ign.es/wms/pnoa-historico?&service=WMS&request=GetMap&layers=AMS_1956-1957&styles=&format=image%2Fpng&srs=EPSG%3A4258&version=1.1.1&transparent=true&width=256&height=256&bbox=-9.5,2.5,12,44
Although I don't really fully understand what these numbers refer to (max x, min x, max y, min y?? // top-left corner, bottom-right corner // etc. ??)
Any help on what might be happening here will be much appreciated, thank you!

How to save values from popup window into an instance to other class?

I have designed a flutter screen, in which I have button upon pressing that Button A I get a popup window, which has Button 1 to add new textfield, and we can add any number of textfield, for this I have used flutter_form_bloc dependency example. Then in the popup window there is another button, ie Button 2, which upon pressed process the data entered into the textfields and exits the popup window.
Now when again I press the Button A to open the popup window all the textfields are gone and so the data. I don't want that to happen. I want that those should there until the main flutter screen is there or not exited.
Moreover, upon pressing the Button 2 in the popup window the data should be passed to the class of the main flutter screen in which Button Ais there and should stored in a instance so that the data passed could be processed further.
Here are the screenshots to get the idea
[Image 1]1 [Image 2]2
CODE
FormBlocListener<ListFieldFormBloc2, String, String>(
onSubmitting: (context, state) {
},
onSuccess: (context, state) {
String name1;
var parsedData = json.decode(state.successResponse);
List members = parsedData['members'];
members.forEach((member){
name1 = member['step'];
List<String> _step = [];
_step.add(member["step"]);
_AddStepsState().getsteps(members);
});
_AddStepsState(steps: members);
Navigator.pop(context);
},
onFailure: (context, state) {
Scaffold.of(context).showSnackBar(
SnackBar(content: Text(state.failureResponse)));
},
child: SingleChildScrollView(
physics: ClampingScrollPhysics(),
child: Column(
children: <Widget>[
BlocBuilder<ListFieldBloc<MemberFieldBloc2>,
ListFieldBlocState<MemberFieldBloc2>>(
bloc: formBloc.members,
builder: (context, state) {
if (state.fieldBlocs.isNotEmpty) {
return ListView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: state.fieldBlocs.length,
itemBuilder: (context, i) {
return MemberCard2(
memberIndex: i,
memberField: state.fieldBlocs[i],
onRemoveMember: () =>
formBloc.removeMember(i),
);
},
);
}
return Container();
},
),
RaisedButton(
color: Colors.blue[100],
onPressed: formBloc.addMember,
child: Text('ADD STEP'),
),
],
),
),
),
I tried to pass the LIST generated to another class in these ways _AddStepsState(steps: members); and _AddStepsState().getsteps(members); but both time it failed.
I want to the the list of the values in the text field generated to be passed to another class
And Also I want that while the user is in Screen1 as in Image 1 if the fields are edited as in image 2 and if the user opens the popup screen again the fields should remain there and not removed.
How should I achieve it?
if any more information is required , please let me know
the link to the dependency used is here flutter form bloc
I have just recently created an app that deals with a lot of forms and the solution I've gone with is as follows:
Have a file called data_center.dart where you can define classes to represent data created by a form / to be displayed in a "review" page.
class MyFormData{
String firstField;
String secondField;
int quantity;
// more attributes
// optional constructor
MyFormData({this.firstField, this.secondField, this.quantity});
}
Create a variable to hold instances of the class in data_center.dart
MyFormData currentMyFormDataInstance; // assign an instance every time a new form starts
Create instance in dialog (for example)
import 'data_center.dart' as DataCenter;
// code removed for brevity
return showDialog(
context: context,
builder: (BuildContext context) {
// create an instance to hold the current form data
currentMyFormDataInstance = DataCenter.MyFormData();
return AlertDialog(...);
]);
});
Store controller (assume we have a TextFormField) value in instance
TextFormField(
controller: _myController,
onChanged: (String _incomingValue){
DataCenter.currentMyFormDataInstance.firstField = _incomingValue;
}
)
I don't know if there are any critical flaws or inefficiencies that might come along but so far, it has worked very well for me as it allows me to easily manage all the different kinds of data groups I am collecting from the UI.
Moreover, storing these data as objects rather than data types such as Maps has allowed me to easily transform them by adding named constructors or extra methods that easily allows me to do common and frequent operations on my data.
For example, if you are using Cloud Firestore. I can add the following named constructor to easily map DocumentSnapshots to the class attributes.
MyFormData.fromDocumentSnapshot(){...}

How to prevent flutter web htmlelementview from catching touches from objects above it?

I am using an HTML element view from dart:html to display a webpage inside my flutter web app. It catches all the touches in its area, including the ones on the FAB above it, and also the ones on the drawer of the scaffold in context. I don't even need touch input on the webview, I just want to display it. Also, note that absorbpointer and ignorepointer do not solve the problem. Here is the code displaying the webpage, inside the body of the scaffold.
final IFrameElement _iframeElement = IFrameElement();
_iframeElement.src = "webpageurl";
_iframeElement.style.border = 'none';
// ignore: undefined_prefixed_name
ui.platformViewRegistry.registerViewFactory(
'iframeElement',
(int viewId) => _iframeElement,
);
Widget _iframeWidget;
_iframeWidget = HtmlElementView(
key: UniqueKey(),
viewType: 'iframeElement',
);
return Center(child: IgnorePointer(child: _iframeWidget));
Edit:
final IFrameElement _iframeElement = IFrameElement();
_iframeElement.src = "https://index.hu/";
_iframeElement.style.border = 'none';
// ignore: undefined_prefixed_name
ui.platformViewRegistry.registerViewFactory(
'iframeElement',
(int viewId) => _iframeElement,
);
Widget _iframeWidget;
_iframeWidget = HtmlElementView(
key: UniqueKey(),
viewType: 'iframeElement',
);
return Stack(
children: <Widget>[
IgnorePointer(
ignoring: true,
child: Center(
child: _iframeWidget,
),
),
Container(
color: Colors.transparent,
),
],
);
PointerInterceptor is a widget that prevents mouse events (in web) from being captured by an underlying HtmlElementView.
If you are still struggling with PointerInterceptor, you can look at DropzoneView from the package flutter_dropzone. When stacked above the iFrame it prevented the clicks from being captured by the underlying iFrame.
I created a conditional stack element that placed this DropzoneView when I needed this behavior. I just could not get PointerInterceptor to work.
This is worth a try. Maybe this will help - comment with your experience here.

Flutter view open below current one in map_view

I am using this Flutter map plugin. I have some markers on the map, and when I tap them another page should appear on top of the map, but instead I can only see it when I close the map.
I put the following code inside another method, in order to call it more conveniently from a Navigation Drawer:
mapView.show(new MapOptions(...))
when a marker is tapped i call this method:
showPage(
info = dbCall();
Navigator.push(
context,
new MaterialPageRoute(builder: (context) => new PageDemo(info, id)));
)
The things that puzzles me is that the context in MaterialPageRoute is the one of the NavigationDrawer, but I really don't know how to find another way to do it.

how to set layout for streambuilder and a button

HI i want to ask about how to set layout for streambuilder and a container.
I have a streambuilder named streamdb,
and bellow the streambuilder i want to add, a button name buttonscan.
Container container = new Container(margin: const EdgeInsets.all(10.0),
child: new Row(margin: const EdgeInsets.all(10.0),
children: [streamdb,buttonscan]));
have tried :
children : <Widget>[streamdb],buttonname]
children : <Widget>[streamdb,buttonname]
children : [new Expanded(streamdb),buttonname]
When I compiled above code produce an error, how to build a streambuilder and a button ?
last but not least why is it so hard to create a post asking a problem in stackoverflow ?
just solve my own problem.
Hopefully it can help other people with same problems.
its better to add New Expanded() to the list builder , so it tell the apps to expand as much as necessary
sometimes the class could not resolve "this" method , so since dart-flutter can ignore space,its better for me to just do this :
Widget build(BuildContext context) {
return new MaterialApp(
home: new Scaffold(
appBar: new AppBar(
title: new Text('MY App TITLE'),
),
body: new Center(
child: new Column(
children: <Widget>[
new Expanded(child:
new StreamBuilder()),mybutton,]))
PS : Kindly post more comment for better codes. Thanks!!