How to programmatically call multiple widget under a stack in flutter - flutter

I've a screen with several buttons and I would like to show a sliding panel for each button (passing some information to show in the panel).
I've used this widget:
https://pub.dev/packages/sliding_up_panel
I would like to understand how I can show a widget that is under a Stack passing programmatically some information once I click on a specific button.
It is possible?
Following a brief snipped of code in which we can see the Stack that contains the SlidingPanel. I would like to be able to show the Sliding panel clicking on a specific button and passing an information to it programmatically.
The only solution that I've found up to now is adding all the possible sliding panel to the Stack and then based on the click on the button showing only the one I need, but I hope there is a better way to do this.
Thank you
return Stack(
children: [
Scaffold(
.....
),
SlidingUpPanel(
panelController: panelController,
nameTEController: nameTEPanel,
platform: 'Instagram',
)
]

Just populate your list of Widgets inside a List. If you are using a StatefullWidget, then just call setState(() => )
You could do something like this:
List<Widget> _myWidgetList = [];
[...]
return Stack(
children: _myWidgetList);
List<Widget> _buildMyWidgetList() {
final List<Widget> tmpList = [];
tmpList..add(Widget1)
..add(Widget2);
setState(() => _myWidgetList = tmp);
}
Then just call your buildWidgets functions on the Buttons.
Another way would be to use Bloc: https://pub.dev/packages/flutter_bloc

Related

passing data to a new scree nusing builder (flutter)

I'm tryng to pass data from grid view builder to a materialpageroute component to a new screen, I already pass movies index, but can't seem to give it to the new screen
In the first screenshot, you are trying to assign title as a parameter in onTap function. You cannot do that in onTap.
I think you want to pass the title to DetailPage, you can get the title in movies[index], so you don't have to declare a title.
In the second screenshot, if you want to show the title of your movie in the AppBar, you must do it using title parameter.
AppBar(
title: Text(movies[index].original_title),
),
And you cannot give just one widget to Column's children parameter. It must be a list.
Column(
children: [
_yourWidget(),
],
), // put your widget inside list
If you have one widget, you don't need to use Column.
Lastly, you get just one movie, so that you don't have to use ListView. You can use a single widget like Container. And if you want your view can be scrollable, you can wrap the Column with SingleChildScrollView, like this:
SingleChildScrollView(
child: Column(
children: [
_yourWidget(),
],
),
),
Edit: You didn't declare movies at the top:
class DetailPage extends StatelessWidget {
final Movie? movies; // declare this first
const DetailPage {...} // your constructor
}

Custom Event listeners in flutter

I have a widget with a list and a button with a tree dot icon in every row that shows and hides a panel in its own row. I only want one panel open in the list. When I click on a row button, I'd like to close the panels of the other rows list.  All the buttons in the list are siblings. I'd like to send an event to the other rows' code to close the panels. Which is the correct manner of flutter?  
I have tried NotificationListener but it does not work because the components to be notified are not their parents.
The question is if the correct thing to do is to use the event_listener library or to use streams. I'm new to flutter/dart and streams seem too complex to me. It's a very simple use case and in this entry
Flutter: Stream<Null> is allowed?
they say
*
Some peoples use streams as a flux of events instead of a value
changing over time, but the class isn't designed with this in mind.
They typically try to represent the following method as a stream:
So with simple events with 0 or 1 argument. event_listener or Streams?
This is the screen I'm working on. I want that when one yellow button panel opens the other one closes.
Your question is broad and it seems to be a design question, i.e. it doesn't have a right answer.
However, I don't think you should use Streams or EventListeners at all in this case, because you should not make components in the same layer communicate with each other. Components should only communicate with their parents and children, otherwise your code will increase in complexity really fast. That's even documented in flutter_bloc.
Other than that, if you don't lift state up, i.e. move the responsibility of triggering the removal of the other rows to a parent Widget, than you're fighting against Flutter instead of letting it help you.
It's easy to create a parent Widget, just wrap one Widget around it. What you want to do is hard, so why would try to communicate with sibling widgets instead of using what's Flutter designed to do?
This is a suggestion:
class _NewsSectionState extends State<NewsSection> {
Widget build(BuildContext context) {
return ListView.builder(
itemCount: newsInSection.length;
itemBuilder: (_, int index) => NewsTile(
title: Text('${newsInSection[index].title}')
onDismiss: () => onDismiss(index),
// I don't know how you set this up,
// but () => onDismiss(Index)
// should animate the dismiss of the Row with said index
),
);
}
}
class NewsRow extends StatefulWidget {
final void Function() onDismiss;
#override
State<NewsRow> _createState => _NewsRowState();
}
class _NewsRowState extends State<NewsRow> {
Widget build(BuildContext context) {
return Row(
children: [
// title
// home button
// fav button
// remove button
IconButton(
Icons.close,
onPressed: widget.onDismiss,
),
],
);
}
}

Modifying FAB from inside a nested route while using BottomNavigation Flutter

I've been having a problem while trying to personalize the FloatingActionButton, contained in a main page, from withing a nested route for a BottomNavigation. Right now what I have is this widget tree:
As you can see the app contains a Scaffold with a BottomNavigationBar and for each index from this BottomNavigation I have a new Navigator, from which I can navigate between nested routes. The problem is that the FAB configuration for each nested routed inside these Navigators is different, and therefore I needed to know which strategy should I use to change it's options, more specifically the icon and onPress method
Solution:
In the end I thought about a simple enough solution, don't know if it is the more adequate one, but it does work quite well.
Basically what I did was to create a provider in which I would have a list containing the FAB function for each route, being called accordingly with the one being displayed at the moment.
You can make your AppScreen a stateful widget, create an int _currentIndex = 0 in the state and after clicking on any of the BottomNavigationBarItems you can call setState changing the _currentIndex.
Then, in your build method you can do something like this:
Widget fabChild;
VoidCallback fabOnPressed;
if (_currentIndex == 0) {
fabChild = ...
fabOnPressed = ...
} else if (_currentIndex == 2) {
// (...)
}
return Scaffold(
floatingActionButton: FloatingActionButton(
child: fabChild,
onPressed: fabOnPressed,
),
);

I need to make this layout but I am confused as to what should I use how to place them like in the image I have posted below

Since i want this to be my layout i was trying to implement it with a showModalBottomSheet but the problem is that this widget only works on the button click as it is showing me error when i am trying to call the method as it is in the initState method. So then I started to work with bottomSheet value present in the scaffold but then the background is being displayed only upto the starting of the bottom sheet creating the distance between the model sheet and the background whereas I want it to overlap like in the image..How should I prepare this layout.
There is no such parameter as "bottomSheet" in Scaffold, there is one called bottomAppBar, which is used for making Bottom Bars like the one on the Youtube Android App. So this should help you make the basic structure.
Use a Stack widget to put widgets on top of each other, in first layer, add the image using the NetworkImage widget, then in the second layer, make a Column, like this:
#override
Widget build() => Scaffold(
body: _body(),
);
_body() => Stack(
children: <Widget>[
NetworkImage(your_url_here),
Column(
children: <Widget>[
_basicDetails(),
_guidePanel(),
]
),
]);
Then create 2 new methods after the _body method like this:
_body() => Stack(...);
_basicDetailsPage() => Container();
_guidePanel() => Container();
Create your layout in these 2 methods. Comment if you need more help :)
For additional help, please join the Facebook Group "Let's Flutter With Dart"

How to dynamically add Children to Scaffold Widget

Let's say, I have a chat screen that looks like this.
Now, when the user clicks the "Press when ready" button, the method fetchNewQuestion() is called.
My intention is that this will make a HTTP request, and display the result using
_buildUsersReply(httpResponse);
But, the problem is that this return must be made inside the current scaffold's widget as a child under the existing children, so that it is built at the bottom with the previous ones still there. The result would be like this:
You can find my complete code here.
Is this possible to be done pro-grammatically? Or do I have to change the concept of how I do this?
[Update, I now understand that my approach above is wrong and I have to use a listview builder. CurrentStatus below shows my progress towards achieving that goal.]
Current status:
I have built a list of Widgets:
List<Widget> chatScreenWidgets = [];
And on setState, I am updating that with a new Widget using this:
setState(() { chatScreenWidgets.add(_buildUsersReply("I think there were 35 humans and one horse.")); });
Now at this point, I am not sure how to pass the widget inside the scaffold. I have written some code that does not work. For instance, I tried this:
Code in the image below and in the gist here:
Just for future reference, here is what I really needed to do:
1. Create a list of widgets
List<Widget> chatScreenWidgets = [];
2. Inside my method, I needed to use a setState in order to add elements to that list. Every widget I add to this will be displayed on ths Scaffold.
`setState(() {
chatScreenWidgets.add(_buildUsersReply("Some Text"));
});`
3. And then, load that inside my Scaffold, I used an itemBuilder in order to return a list of widgets to my ListView. I already had that ListView (where I was manually adding children). Now this just returns them through the setState method inside my business logic method (in this case, fetchNewQuestion()).
body: Stack(
children: <Widget>[
Padding(
padding: EdgeInsets.only(bottom: 0),
child: new ListView.builder(
physics: BouncingScrollPhysics(),
padding: EdgeInsets.symmetric(horizontal: 25),
itemCount: chatScreenWidgets.length,
itemBuilder: (BuildContext context, int itemCount) {
return chatScreenWidgets[itemCount];
}
),
),
],
),
);`
I hope this helps future flutter engineers!
forget about the scaffold the idea is about what you really want to change, lets say it is
a list and your getting the data from an array if you update the array, then the list will update,if it is another type widgets then you can handle it in a different way i will edit this answer if you clarify what each part does in your widget as i cant read your full code.
first you have to create an object with two attributes one is the type of the row(if it is a user replay or other messages) and the second attribute is the string or the text.
now create a global list in the listview class from the above object, so you get the data from the user or even as a news and you create a new object from the above class and add your data to it and add it to the list.
item builder returns a widget so according to the the widget that you return the row will be set , so according to the data in the object call one of your functions that return the views like _buildUsersReply(string text).
if you have any other question you can ask :) if this what you need please mark it as the answer.