Flutter Randomizing - How to prevent from displaying the previous element shown - flutter

Upon clicking, my app shows either yes, no, or maybe. How do I set the subsequent result strictly different from the previous one? For example, the current result is 'no', how do I randomize and make sure that the next result would ONLY either be 'yes' or 'maybe'?
This is the code
import 'package:flutter/material.dart';
import 'dart:math';
void main() => runApp(
MaterialApp(
debugShowCheckedModeBanner: false,
home: MyApp(),
),
);
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Welcome to Flutter',
home: Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
centerTitle: true,
title: Text(
'Ask Me Anything',
style: TextStyle(fontFamily: 'Lobster', fontSize: 25),
),
),
body: picker(),
),
);
}
}
class picker extends StatefulWidget {
#override
_pickerState createState() => _pickerState();
}
class _pickerState extends State<picker> {
List yourList = ["Yes", "No", "Maybe"];
int randomIndex;
_pickerState() {
randomIndex = Random().nextInt(yourList.length);
}
#override
Widget build(BuildContext context) {
return Center(
child: TextButton(
onPressed: () {
setState(() {
randomIndex = Random().nextInt(yourList.length);
print("What's showing is '${yourList[randomIndex]}'");
});
},
child: Stack(
children: <Widget>[
Center(child: Image.asset('images/blu.png')),
Center(
child: Text(
yourList[randomIndex],
style: TextStyle(fontSize: 40, fontFamily: 'Lobster'),
),
),
],
),
),
);
}
}

You could just do a while loop which keeps trying for a new answer as long as the answer is equal to the current answer:
_pickerState() {
oldIndex = randomIndex;
randomIndex = Random().nextInt(yourList.length);
while (oldIndex == randomIndex){
randomIndex = Random().nextInt(yourList.length);
}
And then in your onPressed:
setState(() {
randomIndex = _pickerState();
print("What's showing is '${yourList[randomIndex]}'");
});

Related

Flutter: Update text on screen when MaterialButton is clicked

I'm new to Flutter. I'm trying to build a basic dice app with a button. When the button is clicked, the displayed text gets updated with a random number.
import 'package:flutter/material.dart';
import 'dart:math';
int dice = 0;
void main() {
int dice = 0;
runApp(
MaterialApp(
home: Scaffold(
backgroundColor: Colors.white70,
appBar: AppBar(
title: const Text('Quick Dice'),
backgroundColor: Colors.blueGrey,
),
body: Center(
child: MaterialButton(
onPressed: () {
rollDice();
},
child: new Text('$dice'),
),
),
),
),
);
}
void rollDice(){
dice = Random().nextInt(6) + 1;
print('In Roll Dice()');
print('$dice');
}
When the button is clicked, I can see that the function rollDice() is being called and the value of $dice is being updated but on the screen, the value never gets updated.
Is there something I'm missing? Should the child text element be refreshed somehow to to show the new value on button press?
Do like this ( StatefulWidget ) :
void main(){
runApp(MaterialApp(
home: UpdateScreen(),
));
}
class UpdateScreen extends StatefulWidget{
#override
UpdateScreenState createState() => UpdateScreenState();
}
class UpdateScreenState extends State<UpdateScreen>{
int dice = 0;
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white70,
appBar: AppBar(
title: const Text('Quick Dice'),
backgroundColor: Colors.blueGrey,
),
body: Center(
child: MaterialButton(
onPressed: () {
rollDice();
},
child: new Text('$dice'),
),
),
);
}
void rollDice(){
setState(() {
dice = Random().nextInt(6) + 1;
print('In Roll Dice()');
print('$dice');
});
}
}
Try below code hope its helpful to you.
Refer Random here
and use dart.math library here
import 'package:flutter/material.dart';
import 'dart:math';
void main() {
runApp(MaterialApp(
home: DiceApp(),
));
}
class DiceApp extends StatefulWidget {
#override
DiceAppState createState() => DiceAppState();
}
var randomNo = new Random();
var dice = randomNo.nextInt(6) + 1;
class DiceAppState extends State<DiceApp> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Dice App'),
),
body: Center(
child: MaterialButton(
color: Colors.blue,
onPressed: () {
setState(() {
dice = randomNo.nextInt(6) + 1;
});
},
child: Text(
dice.toString(),
),
),
),
);
}
}
Your result screen-> |
For updating your data on screen you have to use state management like provider, Getx , block etc. Or you can use the setState method in your rollDice() function then the the widget will rebuild and your data will be updated. Something like this--
void rollDice(){
setState(() {
dice = Random().nextInt(6) + 1
});
print('In Roll Dice()');
print('$dice');
}

Flutter how to load new screen by tap on navigation bar

I have created a custom bottom navigation bar for my app but I messed up my code. Right now its just shifting screen by true false value. I want to load screen but what I done is simple showing screen in body by bool.
My code
bottomNavigationBar: CustomBottomNavigationBar(
iconList: [
'images/ichome.png',
'images/icservice.png',
'images/icstore.png',
'images/Component 7 – 1#2x.png',
],
iconList2: [
'images/ichomeactive.png',
'images/icserviceactive.png',
'images/icstoreactive.png',
'images/icaccount.png',
],
onChange: (val) {
setState(() {
_selectedItem = val;
print(val);
if (val == 0) {
setState(() {
home = true;
service = false;
shop = false;
account = false;
});
}
if (val == 1) {
home = false;
service = true;
shop = false;
account = false;
}
if (val == 2) {
home = false;
service = false;
shop = true;
account = false;
}
if (val == 3) {
home = false;
service = false;
shop = false;
account = true;
}
});
},
defaultSelectedIndex: 0,
),
You can see on click I am changing bool value and in body show my widget. I know its wrong I do very stupid thing. That's why I need to know how I can load the page instead of just show and hide ? Also I need to show the navigation bar also on each page.
Please refer below code of Navigation bar
import 'package:flutter/material.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,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: SettingView(),
);
}
}
class SettingView extends StatefulWidget {
#override
_SettingViewState createState() => _SettingViewState();
}
class _SettingViewState extends State<SettingView> {
final tabs = [DashboardView(), NotificationView(), ProfileView()];
int _currentIndex = 0;
#override
void initState() {
setState(() {});
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
toolbarHeight: 40.0,
elevation: 0,
centerTitle: true,
backgroundColor: Colors.blue,
title: Text("Navigation Bar"),
),
bottomNavigationBar: BottomNavigationBar(
backgroundColor: Colors.blue,
currentIndex: _currentIndex,
type: BottomNavigationBarType.fixed,
selectedItemColor: Colors.white,
unselectedItemColor: Colors.white.withOpacity(0.5),
items: [
BottomNavigationBarItem(
icon: InkResponse(
focusColor: Colors.transparent,
hoverColor: Colors.transparent,
highlightColor: Colors.transparent,
child: Container(
padding: EdgeInsets.only(
left: 10,
),
child: Icon(
Icons.dashboard,
),
),
),
title: Padding(padding: EdgeInsets.zero),
backgroundColor: Colors.blue,
),
BottomNavigationBarItem(
icon: Container(
padding: EdgeInsets.only(
right: 10,
),
child: Icon(Icons.notifications),
),
title: Padding(padding: EdgeInsets.zero),
backgroundColor: Colors.blue,
),
BottomNavigationBarItem(
icon: Container(
padding: EdgeInsets.only(
right: 10,
),
child: Icon(Icons.account_box),
),
title: Padding(padding: EdgeInsets.zero),
backgroundColor: Colors.blue,
)
],
onTap: (index) {
setState(() {
_currentIndex = index;
});
},
),
body: tabs[_currentIndex],
);
}
}
/*Dashboard*/
class DashboardView extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container(
child: Center(
child: Text("Dashboard"),
),
);
}
}
/*Notification*/
class NotificationView extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container(
child: Center(
child: Text("Notification"),
),
);
}
}
/*Profile*/
class ProfileView extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container(
child: Center(
child: Text("Profile"),
),
);
}
}
You can do something like that:
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'app name',
home: HomeScreen(),
routes: <String, WidgetBuilder>{
'/route1': (BuildContext context) => FirstScreen(),
'/route2': (BuildContext context) => SecondScreen(),
},
);
}
Create reusable navigation bar Widget and for selected content just tell navigator where it needs to bring you:
Navigator.pushNamed(context, '/route1');

TypeAhead different widgets flutter

I'm trying to create different widgets in TypeAhead suggestion depends on suggestion.subName.length
1. ListTile with a subTitle
2. ListTile without subTitle
TypeAhead(
...
itemBuilder: (context, suggestion) {
return ListTile(
dense: true,
title: AutoSizeText(
suggestion.primeName,
maxLines: 1,
overflow: TextOverflow.ellipsis,
minFontSize: 20,
),
subtitle: suggestion.subName.length == 0 ? null:AutoSizeText(
suggestion.subName.join(', '),
maxLines: 1,
overflow: TextOverflow.ellipsis,
minFontSize: 15,
),
);
},
...
But everything comes back with a subtitle.
What could cause that? Is it possible to make 2 different types of widgets in TypeAhead?
You can copy paste run full code below
I use the following example to simulate this case
You can return Container() not null
subtitle: suggestion.subName.length == 0 ? Container() : AutoSizeText(
or put condition in itemBuilder, for more complex condition you can use if
itemBuilder: (context, suggestion) {
return suggestion.subName.length == 0 ? ListTile(...) : ListTile(...);
working demo
full code
import 'package:flutter/material.dart';
import 'dart:math';
import 'package:flutter_typeahead/flutter_typeahead.dart';
class BackendService {
static Future<List> getSuggestions(String query) async {
await Future.delayed(Duration(seconds: 1));
return List.generate(3, (index) {
return {'name': query + index.toString(), 'price': Random().nextInt(100)};
});
}
}
class CitiesService {
static final List<String> cities = [
'Beirut',
'Damascus',
'San Fransisco',
'Rome',
'Los Angeles',
'Madrid',
'Bali',
'Barcelona',
'Paris',
'Bucharest',
'New York City',
'Philadelphia',
'Sydney',
];
static List<String> getSuggestions(String query) {
List<String> matches = List();
matches.addAll(cities);
matches.retainWhere((s) => s.toLowerCase().contains(query.toLowerCase()));
return matches;
}
}
class NavigationExample extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.all(32.0),
child: Column(
children: <Widget>[
SizedBox(
height: 10.0,
),
TypeAheadField(
textFieldConfiguration: TextFieldConfiguration(
autofocus: true,
style: DefaultTextStyle.of(context)
.style
.copyWith(fontStyle: FontStyle.italic),
decoration: InputDecoration(
border: OutlineInputBorder(),
hintText: 'What are you looking for?'),
),
suggestionsCallback: (pattern) async {
return await BackendService.getSuggestions(pattern);
},
itemBuilder: (context, suggestion) {
return ListTile(
leading: Icon(Icons.shopping_cart),
title: Text(suggestion['name']),
subtitle: suggestion['price'] < 20
? Container()
: Text('\$${suggestion['price']}'),
);
},
onSuggestionSelected: (suggestion) {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => ProductPage(product: suggestion)));
},
),
],
),
);
}
}
class ProductPage extends StatelessWidget {
final Map<String, dynamic> product;
ProductPage({this.product});
#override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: const EdgeInsets.all(50.0),
child: Column(
children: [
Text(
this.product['name'],
style: Theme.of(context).textTheme.headline,
),
Text(
this.product['price'].toString() + ' USD',
style: Theme.of(context).textTheme.subhead,
)
],
),
),
);
}
}
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> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
NavigationExample(),
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}

In flutter, can you set the appbar backgorund to change base on the value of a dropdown box?

my drop down box cycles through 5 strings
['blue','red','yellow','orange','grey']
I want my appbar title to be that dropdown box and for the value in the dropdown to determine the appbar color
DropDownWidget ddw = DropDownWidget();
var color = {
"blue": Colors.blue,
"red": Colors.red,
"yellow": Colors.yellow,
"orange": Colors.orange,
"grey": Colors.grey,
};
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: ddw,
backgroundColor: color[ddw],
),
}
The dropdown (ddw) shows up as the title, no problem.
I made a dictionary with those strings as the keys and the corresponding color as the value, but I am not able to use the string value of the dropdown to change the background.
Any suggestions?
You can copy paste run full code below
You can call setState in onChanged of DropdownButton
code snippet
appBar: AppBar(
backgroundColor: _appbarColor,
...
DropdownButton<Item>(
hint: Text("Select item"),
value: selectedColor,
onChanged: (Item Value) {
setState(() {
selectedColor = Value;
_appbarColor = selectedColor.color;
});
},
working demo
full code
import 'package:flutter/material.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 Item {
const Item(this.name, this.color);
final String name;
final Color color;
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
Color _appbarColor = Colors.blue;
Item selectedColor;
List<Item> colorList = <Item>[
const Item('blue', Colors.blue),
const Item('red', Colors.red),
const Item('yellow', Colors.yellow),
];
void _incrementCounter() {
setState(() {
_counter++;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: _appbarColor,
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
DropdownButton<Item>(
hint: Text("Select item"),
value: selectedColor,
onChanged: (Item Value) {
setState(() {
selectedColor = Value;
_appbarColor = selectedColor.color;
});
},
items: colorList.map((Item item) {
return DropdownMenuItem<Item>(
value: item,
child: Row(
children: <Widget>[
Container(
height: 15,
width: 15,
color: item.color,
),
SizedBox(
width: 10,
),
Text(
item.name,
style: TextStyle(color: Colors.black),
),
],
),
);
}).toList()),
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}

Change color of Theme

I wanted to change the color of the counter in my app. I want to do that: change the color of the counter to blue when counter bigger than 0. if counter smaller than 0 change the color of the counter to red.if counter equal to 0 change the color of the counter to green. is it possible? I did just for 2 colors.
it is my codes :
import 'package:flutter/material.dart';
void main() {
runApp(Myapp());
}
class Myapp extends StatefulWidget {
#override
_MyappState createState() => _MyappState();
}
class _MyappState extends State<Myapp> {
#override
Widget build(BuildContext context) {
// TODO: implement build
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Myhomepage(
title: "My Home Page",
),
);
}
}
class Myhomepage extends StatefulWidget {
final String title;
Myhomepage({this.title});
#override
_MyhomepageState createState() => _MyhomepageState();
}
class _MyhomepageState extends State<Myhomepage> {
int counter = 0;
#override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
centerTitle: true,
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
backgroundColor: Colors.grey[850],
onPressed: () {
setState(() {
counter++;
});
}),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
RaisedButton(
child: Text(
"Increase",
),
color: Colors.green,
onPressed: () {
setState(() {
counter++;
});
},
),
Text("The count of press button:"),
Text(
"$counter",
style: Theme.of(context).textTheme.display2.copyWith(color: counter<=0 ? Colors.red : Colors.blue)
),
RaisedButton(
child: Text(
"Decrease",
),
color: Colors.red,
onPressed: () {
setState(() {
counter--;
});
},
),
],
),
),
);
}
}
it is my results :
Here's one way you can implement the system you want. I just made a function that returns the desired color.
class _MyhomepageState extends State<Myhomepage> {
int counter = 0;
Color _getCounterColor() {
if (counter > 0) return Colors.blue;
else if (counter < 0) return Colors.red;
else return Colors.green;
}
#override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
centerTitle: true,
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
backgroundColor: Colors.grey[850],
onPressed: () {
setState(() {
counter++;
});
}),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
RaisedButton(
child: Text(
"Increase",
),
color: Colors.green,
onPressed: () {
setState(() {
counter++;
});
},
),
Text("The count of press button:"),
Text(
"$counter",
style: Theme.of(context).textTheme.display2.copyWith(color: _getCounterColor()),
),
RaisedButton(
child: Text(
"Decrease",
),
color: Colors.red,
onPressed: () {
setState(() {
counter--;
});
},
),
],
),
),
);
}
}