Why expanded view is not being shown - dart

I am trying out flutter, here I am having a simple card view, where there is an add AddButton , when the button is pressed new card is being added.
Now, i wanted to have it scrollable so added ListView and an expanded Widget in the Column. Here is the code...
import 'package:flutter/material.dart';
import './products.dart';
import './product_control.dart';
class ProductManger extends StatefulWidget {
final String startingProduct;
ProductManger({this.startingProduct = "Sweet Tester"});
#override
State<StatefulWidget> createState() {
return _ProductManagerState();
}
}
class _ProductManagerState extends State<ProductManger> {
List<String> _products = ['Food Tester'];
#override
void initState() {
_products.add(widget.startingProduct);
super.initState();
}
void _addProducts(String product) {
setState(() {
_products.add(product);
});
}
#override
Widget build(BuildContext context) {
return Column(children: [
Container(margin: EdgeInsets.all(10.0), child: ProductControl(_addProducts)),
Expanded(child: Products(_products))
]);
}
}
If I change that Expanded to Container with height, it works as expected, but now, nothing is being displayed except a button.
I am currently following a tutorial, exact same code is written, however, version of flutter is 0.3.2 and i am using 1.5
Or there could be some issue with the emulator?
Hope this helps.
Here is the listView code
import 'package:flutter/material.dart';
class Products extends StatelessWidget {
final List<String> products;
Products([this.products = const []]);
#override
Widget build(BuildContext context) {
return ListView(
children: products
.map((element) => Card(
child: Column(
children: <Widget>[
Image.asset('assets/food.jpg'),
Text(element)
],
),
))
.toList());
}
}
This is what is visible when i use Container with height 300.0 insted to expand
And when i use expand, this is what being shown

Please try to change
#override
Widget build(BuildContext context) {
return Column(children: [
Container(margin: EdgeInsets.all(10.0), child: ProductControl(_addProducts)),
Expanded(child: Products(_products))
]);
}
To
#override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Column: children: [
Container(
margin: EdgeInsets.all(10.0),
child: ProductControl(_addProducts)),
Expanded(child: Products(_products))
]);
}
If it does not work , Please give a look to SingleChildeScrollView

Ok, so after hours of time I found out finally, the error was in my main.dart file.
Initially, the code was
import 'package:flutter/material.dart';
import './product_manager.dart';
import 'package:flutter/rendering.dart';
void main(){
debugPaintSizeEnabled=true;
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.deepOrange,
accentColor: Colors.deepPurple
),
home: Scaffold(
appBar: AppBar(
title: Text("Alpit anand"),
),
body: Column(
children: [ProductManger()],
)),
);
}
}
But when i changed to
import 'package:flutter/material.dart';
import './product_manager.dart';
import 'package:flutter/rendering.dart';
void main(){
debugPaintSizeEnabled=true;
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.deepOrange,
accentColor: Colors.deepPurple
),
home: Scaffold(
appBar: AppBar(
title: Text("Alpit anand"),
),
body:
ProductManger(),
),
);
}
}
Thanks to pskink, you really helped me out. Thanks for your time. Although I still have to find out, why it wasn't working that way.

Related

BlocBuilder's build function does not reload

Currently, I am trying to learn how bloc pattern works but i have some problems. I am trying to use BLOC pattern on flutter counter application which is default application for flutter project. Here is my main (layout) code:
import 'package:flutter/material.dart';
import 'package:suaybtest/my-home-page-state.dart';
import 'my-home-page-bloc.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
final MyHomePageBloc _bloc = MyHomePageBloc();
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: BlocBuilder<MyHomePageEvent, MyHomePageState>(
bloc: _bloc,
builder: (context, MyHomePageState state) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'${state.counter}',
style: Theme.of(context).textTheme.display1,
),
],
),
);
}),
floatingActionButton: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
FloatingActionButton(
onPressed: () {
_bloc.dispatch(MyHomePageEvent.increment);
},
tooltip: 'Increment',
child: Icon(Icons.add),
),
FloatingActionButton(
onPressed: () {
_bloc.dispatch(MyHomePageEvent.decrement);
},
tooltip: 'Decrement',
child: Icon(Icons.remove),
),
],
));
}
#override
void dispose() {
super.dispose();
}
}
Bloc page is this:
import 'package:bloc/bloc.dart';
import 'package:suaybtest/my-home-page-state.dart';
enum MyHomePageEvent {
increment,
decrement,
}
class MyHomePageBloc extends Bloc<MyHomePageEvent, MyHomePageState> {
#override
MyHomePageState get initialState => MyHomePageState.initial();
#override
Stream<MyHomePageState> mapEventToState(MyHomePageEvent event) async* {
MyHomePageState state = currentState;
switch (event) {
case MyHomePageEvent.increment:
state.counter++;
yield state;
break;
case MyHomePageEvent.decrement:
state.counter--;
yield state;
break;
}
}
}
and finally here is my state
class MyHomePageState {
int counter;
MyHomePageState._();
factory MyHomePageState.initial(){
return MyHomePageState._()..counter = 0;
}
}
I know there is no need to use state class like this because I have just one variable. However this is the closest sample for real world app.
The problem here when I click the buttons it works counter increasing you can display it in debug mode but build function of blocbuilder does not reload.
I use this library
dependencies:
flutter_bloc: ^0.11.1

How to add button under text

I am new to flutter so here is my code where its printing one centre text but I need a button under the text.
import 'package:flutter/material.dart';
void main()
{
runApp(MaterialApp(
title: 'Hello Flutter',
home: HomeWidget(),
));
}
class HomeWidget extends StatelessWidget
{
#override
Widget build(BuildContext context)
{
return Material(
child: Container(child: Center(child: Text('Hello World Of Flutter Development'),),),
// Need Button Here beneath Text
);
} //Widget
} //End of Class
use - Column Widget.
Learn more about drawing Layouts:
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(
title: 'Hello Flutter',
home: HomeWidget(),
));
}
class HomeWidget extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[
Center(
child: Text('Hello World Of Flutter Development'),
),
RaisedButton(onPressed: (){},child: Text('Button'),) // Button under Text
]),
);
} //Widget
}
Use Column Widget
Column(
children: [
Text('Hello World Of Flutter Development'),
FlatButton(onPressed:() {}, child:Text('name on button')),
],
)

Splash screen implementation in flutter

I am new to Flutter and I wanted to have splash screen in my app. I used initState() and the navigator. But it didn't work. The app opens the splashscreen appears but after that it does not navigate to the next screen.
My main.dart
import 'package:flutter/material.dart';
import 'package:bmi/HomePage.dart';
import 'dart:async';
main(){
runApp(MyApp());
}
class MyApp extends StatelessWidget{
#override
Widget build(BuildContext context) {
return SplashScreen();
}
}
class SplashScreen extends StatefulWidget{
#override
State<StatefulWidget> createState() {
return SplashScreenState();
}
}
class SplashScreenState extends State<SplashScreen>{
#override
void initState() {
super.initState();
Future.delayed(
Duration(
seconds: 4
),
(){
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => HomePage(),
)
);
}
);
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Colors.red,
body: Text(
'Welcome to BMI Calculator',
style: new TextStyle(
fontSize: 15.0,
color: Colors.white,
fontWeight: FontWeight.bold
),
),
),
);
}
}
And my HomePage.dart
import 'package:flutter/material.dart';
class HomePage extends StatelessWidget{
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
backgroundColor: Colors.red,
title: Text(
'BMI Calculator',
style: new TextStyle(
color: Colors.white
),
),
),
),
);
}
}
How can I resolve this?
Since I am new to flutter I dont know whether this is the right way to implement splashScreen if there are any other easier ways can you please suggest that also.
Thank you in advance.
Code Corrected:
MaterialApp should be the parent(root) of all Widgets.
import 'package:flutter/material.dart';
import 'package:bmi/HomePage.dart';
import 'dart:async';
main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(home: SplashScreen()); // define it once at root level.
}
}
class SplashScreen extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return SplashScreenState();
}
}
class SplashScreenState extends State<SplashScreen> {
#override
void initState() {
super.initState();
Future.delayed(Duration(seconds: 4), () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => HomePage(),
));
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.red,
body: Text(
'Welcome to BMI Calculator',
style: new TextStyle(
fontSize: 15.0, color: Colors.white, fontWeight: FontWeight.bold),
),
);
}
}
class HomePage extends StatelessWidget{
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.red,
title: Text(
'BMI Calculator',
style: new TextStyle(
color: Colors.white
),
),
),
);
}
}
The splash screen implementation is provided by default.
You just need to change the code in respective platforms like below
For Android:
Go to android directory in your flutter project and find the res folder where you will have launch_background.xml under drawables , just replace your own splash image as below.
`
<?xml version="1.0" encoding="utf-8"?>
<!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#android:color/white" />
<!-- You can insert your own image assets here -->
<item>
<bitmap
android:gravity="center"
android:src="#drawable/hotel_logo_new" />
</item>
</layer-list>
For iOS
- just change the LaunchImage under ImageAssets.
You should use pushReplacement instead of push when you exit the splash screen to prevent it from showing again when you press the back button.
here's the anmol.majhail code with the correct behavior.
import 'package:flutter/material.dart';
import 'package:bmi/HomePage.dart';
import 'dart:async';
main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(home: SplashScreen()); // define it once at root level.
}
}
class SplashScreen extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return SplashScreenState();
}
}
class SplashScreenState extends State<SplashScreen> {
#override
void initState() {
super.initState();
Future.delayed(Duration(seconds: 4), () {
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => HomePage(),
));
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.red,
body: Text(
'Welcome to BMI Calculator',
style: new TextStyle(
fontSize: 15.0, color: Colors.white, fontWeight: FontWeight.bold),
),
);
}
}
class HomePage extends StatelessWidget{
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.red,
title: Text(
'BMI Calculator',
style: new TextStyle(
color: Colors.white
),
),
),
);
}
}
To use this package : add the dependency to your pubspec.yaml file.
dependencies:
flutter:
sdk: flutter
splashscreen:
How to use
import 'package:flutter/material.dart';
import 'package:splashscreen/splashscreen.dart';
main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: SplashScreen(
seconds: 10,
imageBackground: AssetImage('assets/images/a.jpg'),
navigateAfterSeconds: HomeScreen(),
),
); // define it once at root level.
}
}
class HomeScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.red,
title: Text(
'Home',
style: new TextStyle(color: Colors.white),
),
),
);
}
}
Simple solution which i use in every app.
Use Timer class in build method code snippet
class SplashScreen extends StatefulWidget {
#override
Splash createState() => Splash();
}
class Splash extends State<SplashScreen> {
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
Timer(
Duration(seconds: 3),
() =>
Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (BuildContext context) => LandingScreen())));
var assetsImage = new AssetImage(
'images/new_logo.png'); //<- Creates an object that fetches an image.
var image = new Image(
image: assetsImage,
height:300); //<- Creates a widget that displays an image.
return MaterialApp(
home: Scaffold(
/* appBar: AppBar(
title: Text("MyApp"),
backgroundColor:
Colors.blue, //<- background color to combine with the picture :-)
),*/
body: Container(
decoration: new BoxDecoration(color: Colors.white),
child: new Center(
child: image,
),
), //<- place where the image appears
),
);
}
}

Displaying an iframe in Dart

Is it possible to display an iframe in Dart?
Below is the code that I am using
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
final wordPair = WordPair.random();
return MaterialApp(
title: 'Welcome to Flutter',
home: Scaffold(
appBar: AppBar(
title: Text('Welcome to Flutter'),
),
body: Center(
child: Text(wordPair.asPascalCase), // With this highlighted text.
),
),
);
}
}
I am not sure how to add an iframe into this. Below is the snippet that is given in the documentation
factory IFrameElement() => JS(
'returns:IFrameElement;creates:IFrameElement;new:true',
'#.createElement(#)',
document,
"iframe");
I agree that using webview_flutter plugin shows HTML in Flutter. But, this plugin is currently supported in mobile but not yet for web. Here is an example of how you implement this on mobile:
Sample code using webview_flutter plugin:
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'dart:async';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final Completer<WebViewController> _controller =
Completer<WebViewController>();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: WebView(
initialUrl: 'https://flutter.dev/',
onWebViewCreated: (WebViewController webViewController) {
_controller.complete(webViewController);
},
javascriptMode: JavascriptMode.unrestricted,
),
);
}
}
Actual Output:
And regarding your question how to implement IFrameElement. There is actually an existing blog where it provides all the steps to understand this. But as mentioned, this is still in beta.
After I followed all the necessary steps, I've ended up in this example:
import 'package:flutter/material.dart';
import 'dart:ui' as ui;
import 'dart:html';
final Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: IframeDemo(),
),
),
);
}
}
class IframeDemo extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return MyWidget();
}
}
class MyWidget extends State<IframeDemo> {
String _url;
IFrameElement _iframeElement;
#override
initState() {
super.initState();
_url = 'https://flutter.dev/';
_iframeElement = IFrameElement()
..src = _url
..id = 'iframe'
..style.border = 'none';
//ignore: undefined_prefixed_name
ui.platformViewRegistry.registerViewFactory(
'iframeElement',
(int viewId) => _iframeElement,
);
}
#override
Widget build(BuildContext context) {
print('url is $_url');
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
),
SizedBox(
height: 600,
width: 600,
child: HtmlElementView(
viewType: 'iframeElement',
),
),
],
);
}
}
Sample Output:

Using Stream/Sink in Flutter

I'm trying to replace the increment flutter app code, by using Streams from Dart API without using scoped_model or rxdart.
So I read this and watched this, but could not get it work for me, my codes are:
StreamProvider.dart:
import 'package:flutter/widgets.dart';
import 'businessLogic.dart';
import 'dart:async';
class Something {
final _additionalContrllerr = StreamController<int>();
Sink<int> get addition => _additionalContrllerr.sink;
Stream<int> get itemCount => _additionalContrllerr.stream;
}
class StreemProvider extends InheritedWidget {
final Something myBloc; // Business Logic Component
StreemProvider({
Key key,
#required this.myBloc,
Widget child,
}) : super(key: key, child: child);
#override
bool updateShouldNotify(InheritedWidget oldWidget) => true;
static Something of(BuildContext context) =>
(context.inheritFromWidgetOfExactType(StreemProvider) as StreemProvider)
.myBloc;
}
main.dart:
import 'package:flutter/material.dart';
import 'package:flutter_app/StreemProvider.dart';
void main() => runApp(MyApp(
textInput: Text("Provided By the Main"),
));
class MyApp extends StatefulWidget {
final Widget textInput;
MyApp({this.textInput});
#override
State<StatefulWidget> createState() => MyAppState();
}
class MyAppState extends State<MyApp> {
bool checkBoxValue = false;
int _counter = 0;
#override
Widget build(BuildContext ctxt) {
var x = Something(); //// Not sure if have to use this!
return StreemProvider(
myBloc: x, //// Not sure about this!!
child: MaterialApp(
home: SafeArea(
child: Scaffold(
body: new Center(
child: new Column(
children: <Widget>[
widget.textInput,
Text("clickec $_counter times"),
Text("clickec ${x.itemCount.listen((int i) => i)} times"),
/// How to get the value of i??!
Checkbox(
value: checkBoxValue,
onChanged: (bool newValue){
setState(() {
checkBoxValue = newValue;
});
}
)
],
)),
floatingActionButton: Incrementer(_increment),
// floatingActionButton: Incrementer(x),
),
),
),
);
}
_increment() {
setState(() {
_counter += 1;
});
}
}
class Incrementer extends StatefulWidget {
final Function increment;
Incrementer(this.increment);
#override
State<StatefulWidget> createState() {
return IncrementerState();
}
}
class IncrementerState extends State<Incrementer>{
#override
Widget build(BuildContext ctxt) {
final myBloc = StreemProvider.of(context);
return new FloatingActionButton(
//onPressed: widget.increment,
// How ot get the latest value!!
onPressed: () async {
var y = await myBloc.itemCount.last;
if (y.isNaN) y = 0;
myBloc.addition.add(y+1);
},
child: new Icon(Icons.add),
);
}
}
don't know the restrictions on rx_dart, but I can only try to answer by you using it. lol
your bloc doesnt define wht to listen in your input stream, this is how I could get it to work
counter_bloc.dart
import 'package:rxdart/rxdart.dart';
import 'dart:async';
class CounterBloc {
int _count = 0;
ReplaySubject<int> _increment = ReplaySubject<int>();
Sink<int> get increment => _increment;
BehaviorSubject<int> _countStream = BehaviorSubject<int>(seedValue: 0);
Stream<int> get count => _countStream.stream;
CounterBloc() {
_increment.listen((increment) {
_count += increment;
_countStream.add(_count);
});
}
}
In the constructor the listen method is set for that stream. for each increment sent, it'll increment the counter and send the current count to another stream.
In main.dart, removed the _counter property since that's now being handled by the BLOC. and to display I used a stream builder.
also added a second fab, with a +2 increment to test the logic.
hope this helps you model your bloc class. :)
a good bloc reference: https://www.youtube.com/watch?v=PLHln7wHgPE
main.dart
import 'counter_bloc.dart';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
CounterBloc bloc = CounterBloc();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
StreamBuilder<int>(
stream: bloc.count,
initialData: 0,
builder: (BuildContext c, AsyncSnapshot<int> data) {
return Text(
'${data.data}',
style: Theme.of(context).textTheme.display1,
);
},
),
],
),
),
floatingActionButton: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
FloatingActionButton(
onPressed: () {
bloc.increment.add(2);
},
tooltip: 'Increment 2',
child: Text("+2"),
),
FloatingActionButton(
onPressed: () {
bloc.increment.add(1);
},
tooltip: 'Increment 1',
child: Text("+1"),
),
],
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
Thanks a lot to vbandrade his answer helped me figuring t out. the solution worked with me is:
I need to have 2 StreamController if I need to listen to a sink in my bloc Business Logic Component, then process and stream the output to other elements.
The counter_bloc.dart is:
import 'dart:async';
class CounterBloc {
int _count = 0;
// The controller to stream the final output to the required StreamBuilder
final _counter = StreamController.broadcast<int>();
Stream<int> get counter => _counter.stream;
// The controller to receive the input form the app elements
final _query = StreamController<int>();
Sink<int> get query => _query.sink;
Stream<int> get result => _query.stream;
// The business logic
CounterBloc() {
result.listen((increment) { // Listen for incoming input
_count += increment; // Process the required data
_counter.add(_count); // Stream the required output
});
}
void dispose(){
_query.close();
_counter.close();
}
}
And the main.dart is:
import 'counter_bloc.dart';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
State<StatefulWidget> createState() {
return _MyHomePageState();
}
}
class _MyHomePageState extends State<MyHomePage> {
var bloc = CounterBloc();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
StreamBuilder<int>( // Listen to the final output sent from the Bloc
stream: bloc.counter,
initialData: 0,
builder: (BuildContext c, AsyncSnapshot<int> data) {
return Text(
'${data.data}',
style: Theme.of(context).textTheme.display1,
);
},
),
],
),
),
floatingActionButton: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
FloatingActionButton(
onPressed: () {
bloc.query.add(2); // Send input to the Bloc
},
tooltip: 'Increment 2',
child: Text("+2"),
),
FloatingActionButton(
onPressed: () {
bloc.query.add(1); // Send input to the Bloc
},
tooltip: 'Increment 1',
child: Text("+1"),
),
],
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
A simple implementation
import 'dart:async';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Counter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
int _counter = 0;
final StreamController<int> _streamController =
StreamController<int>.broadcast();
Stream<int> get _stream => _streamController.stream;
void incrementCounter() {
_counter++;
_streamController.add(_counter);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter demo'),
),
body: Center(
child: StreamBuilder<int>(
stream: _stream,
builder: (ctxt, snapshot) {
if (snapshot.hasData) {
return Text(
'You have pushed this button ${snapshot.data} times');
}
return Text('You have pushed this button ${0} times');
}),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
incrementCounter();
},
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}

Resources