I have a MultiBlocProvider assigned for an app that has a Bottom Navigation Bar to navigate through main routes like Home, Search, Wishlist ...
I use setState(){} to change the currentPage for each route.
Recently I've added Blocs to each of them by using flutter_bloc package and I'm using BlocProvider to provide the bloc to each BlocBuilder,
#override
Widget build(BuildContext context) {
return SafeArea(
top: false,
child: Scaffold(
key: _scaffoldKey,
body: PageStorage(
child: Stack(
children: <Widget>[
AnimatedSwitcher(
duration: Duration(milliseconds: 200),
child: BlocProvider<WishlistBloc>(
create: (BuildContext context) => WishlistBloc(WishlistRepository()),
child: currentPage),
),
bottomBar(currentPageScroll)
],
),
bucket: bucket,
),
),
);
}
Is it ok to use MultiBlocProvider to provide all the BlocsProviders I need?
they could be more than 10 providers, would it affect the performance of the app?
It's definitely OK, MultiBlocProvider created for this purposes. But you need to understand, that if you with your creation also send(for e.x.) initialize event which started loading in all 10 blocs some data you will have some issues. So, if you will have some performance issues, please create separate SO question and community will help to find root-cause of this.
Related
I need to implement such a widget in Flutter. Full version of the page, where this widget is going to be used is here Maybe you know build-in widgets, which could help me. But if there are none, what is the best way to implement this widget?
You can use a ListTile
ListTile(
leading: const Text("Lbikgabsb"),
trailing: Column(
children: [
const Text("900 P"),
const Text("2"), // add your decoration to the background
),
],
),
),
Alternatively you can use:
SizedBox(
height: your_height,
width:double.infinity,
child: Row(
children:[
Text("Lbikgabsb"),
Column(
children: [
const Text("900 P"),
const Text("2"), // add your decoration to the background
],
),
),
You can choose whichever approach works best for your app
I am trying to insert pagination in my flutter app, which will look exactly like the ine in facebook. I have read about infinite_scroll_pagination package, but I was not able to achieve it. Can anyone help me on this please?
For this you should use refreshindicator as shown in official flutter docs.
RefreshIndicator(
onRefresh: _onRefresh,
child: ListView(
padding: EdgeInsets.all(8.0),
physics: const BouncingScrollPhysics(parent: AlwaysScrollableScrollPhysics()),
children: _listData.map((i) {
return ListTile(
title: Text("Item $i"),
);
}).toList(),
)
);
I created a new Flutter app from scratch, in Android Studio. In one of my previous apps, I intentionally used a weird font style. Now, for some reason, the new app has the same fonts. Is it possible that I had stored some "global" font style somewhere in the Android Studio, and now it's getting re-used? How can I get rid of it and revert the "normal" fonts?
Here's the code of one widget and its screenshot in the emulator:
import 'package:flutter/material.dart';
class LoginScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return SafeArea(
child: Container(
child: Column(
children: <Widget>[
RaisedButton(
child: Text('Login'),
onPressed: () {
Navigator.pushNamed(context, '/');
},
),
Text('Login'),
],
),
),
);
}
}
No, there shouldn't be.
In my case it also appeared in the debug app, but disappeared again when I recompiled the project. I haven't seen it in a finished app yet.
Check out this video for problem demo
https://youtu.be/GsdWcTEbUbg
As there is a large number of code, I will try to summarize the structure of the code here.
In a nutshell:
Scaffold(
appBar: AppBar(),
body: StreamBuilder<dynamic>(
stream: globals.chatRoomBloc.threadScreen,
builder: (BuildContext context, AsyncSnapshot snapshot) {
return Column(
crossAxisAlignment:
CrossAxisAlignment.stretch, // sticks to the keyboard
children: <Widget>[
Expanded(
child: Scrollbar(
child: ListView.builder(
shrinkWrap: true,
itemCount: list.length,
itemBuilder: (BuildContext context, int index) {
return TileWidget();
},
),
),
),
],
);
},
),
)
TileWidget is stateful, appends the TextField and resize the widget when the reply button is pressed. Then when the user clicks on the Textfield, the keyboard pops up.
Now my problem is that the screen is reloaded when the keyboard pops up.
I tried the following solutions:
Using TextField inside a Streambuilder : I am setting up the stream only once, that is when the page is loaded the first time. Any changes to the stream is made when a new chat or entry is added. In my case, this does not happen.
Flutter Switching to Tab Reloads Widgets and runs FutureBuilder I am not sure if this is the same problem, but the solution does not change anything for me.
Issue #11895 - I went through this as well, but is not helping.
I think the screen is trying to resize and redraw to accommodate the keyboard drawer. But it is for some reason failing to do that and loading everything over again. Am I missing something ? Is there a way around this ?
As one of the links you provides points out your buildmethod fires whenever the state of the app changes i.e the keyboard pops up, so move the streambuilder outside of it. There are a few more changes you could do. Try the following,
create a variable outside of the build method.
var myStreamBuilder;
//....
//inside initialstate method
myStreamBuilder = StreamBuilder<dynamic>(
stream: globals.chatRoomBloc.threadScreen,
builder: (BuildContext context, AsyncSnapshot snapshot) {
return Column(
crossAxisAlignment:
CrossAxisAlignment.stretch, // sticks to the keyboard
children: <Widget>[
Expanded(
child: Scrollbar(
child: ListView.builder(
shrinkWrap: true,
itemCount: list.length,
itemBuilder: (BuildContext context, int index) {
return TileWidget();
},
),
),
),
],
);
},
),
Then in your build method call the variable.
Scaffold(
appBar: AppBar(),
resizeToAvoidBottomInset: false, //don't forget this!
body: myStreamBuilder
)
EDIT: Make sure you check your snapshot that it hasData or not. If there is no data then something should be returned until it does have data, this way the user is informed what the app is doing.
Also this property might also be helpful to you. resizeToAvoidBottomInset - https://api.flutter.dev/flutter/material/Scaffold/resizeToAvoidBottomInset.html
I think if you use of MediaQuery So that's why Probleam create and one more Solution is Create constructor and getList again.
class Demo(){
getlist(); // get list again
}
I faced similar issue when keyboard open or closed the page reloads
basically I just delete the following line from MainActivity.XML
and all works fine
android:windowSoftInputMode="adjustResize">
I am trying to use Navigator.pop(context); in an appbar but the problem is that it shows a black screen and then you have to press the back button on android then it pops current black screen, so where is this black screen coming from that I don't know and in iPhone there is no back button so that why it is stuck in that screen. Please do help me
This is the code where I am using this Navigator code.
#override
Widget build(BuildContext context) {
return new Scaffold(
backgroundColor: Color.fromRGBO(30, 30, 30, 1.0),
appBar: new AppBar(
elevation: 0.0,
backgroundColor: Color.fromRGBO(30, 30, 30, 1.0),
actions: <Widget>[
new IconButton(
icon: Icon(Icons.settings_power),
onPressed: () {
Navigator.pop(context);
}),
],
title: new Text(
"PROLOG",
style: new TextStyle(color: Colors.white),
),
centerTitle: true,
),
);
}
and the most strange thing is that I am using this piece of code in another class its working fine. So where is the problem...
The reason why you're getting a black/blank screen after calling Navigator.pop(context) is because there's no widget/screen beyond the current Navigator stack.
In Flutter, SystemChannels.platform.invokeMethod('SystemNavigator.pop') is used to remove the topmost Flutter instance. As mentioned in the docs, the method should remove the current Activity from the stack in Android. The behavior is a bit different on iOS though.
If you're trying to implement this function to close the app, this is highly discouraged. This is pointed out on Apple's archived doc. I'm trying to search for an updated reference, but navigating through Apple's Developer docs is challenging.
Anyway, I've made some changes to your code snippet if you'd like to try this out.
Add this in your imports
import 'dart:io' show Platform, exit;
As for the code, exit(int) is used for iOS. It's recommended to use an exit code from the range 0...127 as mentioned in the docs. While SystemChannels.platform.invokeMethod('SystemNavigator.pop') is used for other platforms (mainly Android in this case).
Widget build(BuildContext context) {
return new Scaffold(
backgroundColor: Color.fromRGBO(30, 30, 30, 1.0),
appBar: new AppBar(
elevation: 0.0,
backgroundColor: Color.fromRGBO(30, 30, 30, 1.0),
actions: <Widget>[
new IconButton(
icon: Icon(Icons.settings_power),
// if Platform is iOS call exit(0)
// else call the preferred method
// https://api.flutter.dev/flutter/services/SystemNavigator/pop.html
onPressed: () => Platform.isIOS
? exit(0)
: SystemChannels.platform.invokeMethod('SystemNavigator.pop'),
),
],
title: new Text(
"PROLOG",
style: new TextStyle(color: Colors.white),
),
centerTitle: true,
),
);
}
Demo