Streambuilder did not update Flutter - flutter

STREAMBUILDER
Did not update.
I already tried to work with initState.
On another page the data changes and when you go back to this HOMEPAGE the Streambuilder did not update.
I would be really happy, when you can give me an advice.
I think thats right to use a stateful widget isn't it.
........................................................................................................................................................................skldladlkjsdlkjslkdjsdklsdjlkasjdlajdljasldjjlkadjaskdjlkasjdlkjasdjlsajdlaskjdasdlkasjkdasjkdlkasjdskajdlsajdlsajdlkasjlkJLADJLKASJDJalksjjfaskldjfkdfjdslkfjlksdafjlködsfjdjflkdsjfjljfldskjfldskflksfljsdfj
class Homepage extends StatefulWidget {
#override
HomepageState createState() => _HomepageState();
}
class _HomepageState extends State<Homepage> {
UserLevelStandGrossKlein lus = UserLevelStandGrossKlein();
SharedPreferences prefs;
UserLevelStand usl = UserLevelStand();
String name = 'Tom';
#override
void initState() {
super.initState();
}
#override
void dispose() {
lus.startWork();
usl.startWork();
super.dispose();
}
#override
Widget build(BuildContext context) {
setState(() {
lus.startWork();
usl.startWork();
});
return Scaffold(
backgroundColor: Colors.white,
body: SafeArea(
child: Column(
children: [
Row(children: [
Padding(
padding: const EdgeInsets.fromLTRB(30, 60, 0, 0),
child: RichText(
text: TextSpan(
style: TextStyle(
fontSize: 25,
color: Colors.black
),
children: <TextSpan>[
TextSpan(text: 'Guten Tag,', style: TextStyle(fontWeight: FontWeight.normal)),
TextSpan(text:'\n'+ name, style: TextStyle(fontWeight: FontWeight.bold)),
],
),
), ),
Spacer(),
GestureDetector(
onTap: (){
Navigator.push(context, MaterialPageRoute(builder: (context) => Profil()));
},
child: Padding(
padding: const EdgeInsets.fromLTRB(0, 60, 40, 0),
child: Image.asset("assets/pic.jpg",
width: 80,),
),
)
]
),
StreamBuilder(
initialData:User(1, 'Lädt'),
stream: usl.stream(),
builder: (BuildContext context, AsyncSnapshot snapchot){
User lus = snapchot.data;
String stand2 = lus.userD <=25 ? 'Beginner': 'Fortgeschritten';
return
Padding(
padding: const EdgeInsets.fromLTRB(30, 0, 0, 0),
child: Stack(
alignment: Alignment.topLeft,
children: [Container(
height: 6,
width: 150,
decoration: BoxDecoration(
color: Colors.grey,
borderRadius: BorderRadius.all(Radius.circular(9)),
Container(color: Colors.black,),
AnimatedContainer(
duration: Duration(seconds: 5),
width: lus.userD,
height: 6,
decoration:
BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.all(Radius.circular(9)))
)],
),
);
}

Related

GestureDetector Not working in Listview Builder Flutter

This is the Animation Class where MoviesListView Widget Calls When i apply Animation on listViewBuilder GestureDetector not get Call
import 'package:autoscroll/MoviesListView.dart';
import 'package:autoscroll/data.dart';
import 'package:flutter/material.dart';
class HomeScreen extends StatefulWidget {
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
ScrollController _scrollController1 = ScrollController();
ScrollController _scrollController2 = ScrollController();
ScrollController _scrollController3 = ScrollController();
#override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
double minScrollExtent1 = _scrollController1.position.minScrollExtent;
double maxScrollExtent1 = _scrollController1.position.maxScrollExtent;
double minScrollExtent2 = _scrollController2.position.minScrollExtent;
double maxScrollExtent2 = _scrollController2.position.maxScrollExtent;
double minScrollExtent3 = _scrollController3.position.minScrollExtent;
double maxScrollExtent3 = _scrollController3.position.maxScrollExtent;
//
animateToMaxMin(maxScrollExtent1, minScrollExtent1, maxScrollExtent1, 1,
_scrollController1);
animateToMaxMin(maxScrollExtent2, minScrollExtent2, maxScrollExtent2, 15,
_scrollController2);
animateToMaxMin(maxScrollExtent3, minScrollExtent3, maxScrollExtent3, 20,
_scrollController3);
});
}
animateToMaxMin(double max, double min, double direction, int seconds,
ScrollController scrollController) {
scrollController
.animateTo(direction,
duration: Duration(seconds: seconds), curve: Curves.linear)
.then((value) {
direction = direction == max ? min : max;
animateToMaxMin(max, min, direction, seconds, scrollController);
});
}
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
backgroundColor: Colors.white,
body: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Column(
children: [
MoviesListView(
scrollController: _scrollController1,
images: movies1,
),
MoviesListView(
scrollController: _scrollController2,
images: movies2,
),
MoviesListView(
scrollController: _scrollController3,
images: movies3,
),
],
),
Text(
'30 days for free',
style: TextStyle(
fontSize: 35,
fontWeight: FontWeight.bold,
),
),
Material(
elevation: 0,
color: Color(0xfff2c94c),
borderRadius: BorderRadius.circular(20),
child: MaterialButton(
onPressed: () {},
minWidth: 340,
height: 60,
child: Text(
'Continue',
style: TextStyle(
color: Colors.white,
fontSize: 25,
fontWeight: FontWeight.bold,
),
),
),
)
],
),
),
);
}
}
Gesture Detector is not working when i apply animation on List view Builder it didn't let the Gesture Detector work how can I resolve this issue
import 'package:flutter/material.dart';
class MoviesListView extends StatelessWidget {
final ScrollController scrollController;
final List images;
const MoviesListView({Key key, this.scrollController, this.images})
: super(key: key);
#override
Widget build(BuildContext context) {
return Container(
height: 120,
child: ListView.builder(
controller: scrollController,
scrollDirection: Axis.horizontal,
shrinkWrap: true,
itemCount: images.length,
itemBuilder: (context, index) {
return Container(
margin: EdgeInsets.all(10),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(25),
),
child: GestureDetector(
onTap: (){
print('Func Called');
},
child: ClipRRect(
borderRadius: BorderRadius.circular(25),
child: Image.asset(
'assets/${images[index]}',
width: 150,
fit: BoxFit.cover,
),
),
),
);
}),
);
}
}
Without Animation Gesture detector working perfectly
Try wrapping outer Container with GestureDetector()
return GestureDetector(
onTap: () {
print('Func Called');
},
child: Container(
margin: EdgeInsets.all(10),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(25),
),
child: ClipRRect(
borderRadius: BorderRadius.circular(25),
child: Image.asset(
'assets/${images[index]}',
width: 150,
fit: BoxFit.cover,
),
),
),
);

Why is Flutter BloC UI not updating after app restart despite state change in observer?

I concede that there are many questions similar to mine, but I have not found a satisfactory answer from those questions. So I decided to make my own question specifying my problem. I have 3 BloCs in my program each with different purposes. They all share similar problems, as such I will ask on one of those BloCs with the hope that one solution will fix all of the BloCs.
The problem is this, if I just started the application and have logged in, the BloC will update the UI. If I have logged in, exited the app, and restarted it, the Bloc will not update the UI. The Bloc in question is called DetailpersonilBloc with 1 event called Detail and 2 states called DetailpersonilInitial and Loaded. At the event of Detail, the state Loaded should be emitted.
I called Detail at LoginPage and at GajiPage at initState. This works when I just opened the app, but does not work when I restart the app. I also have equatable thinking that it will help me but apparently it changes nothing.
Note: The "..." at the GajiPage is just some code that I believe is not necessary for reproduction.
DetailpersonilBloc
part 'detailpersonil_event.dart';
part 'detailpersonil_state.dart';
class DetailpersonilBloc
extends Bloc<DetailpersonilEvent, DetailpersonilState> {
DetailpersonilBloc() : super(const DetailpersonilInitial()) {
on<Detail>((event, emit) async {
SharedPreferences pref = await SharedPreferences.getInstance();
String name = pref.getString('nama');
String nrp = pref.getString('NRP');
String pangkat = pref.getString('pangkat');
String jabatan = pref.getString('jabatan');
String satker = pref.getString('satker');
String polda = pref.getString('polda');
String npwp = pref.getString('NPWP');
String rekening = pref.getString('rekening');
String bank = pref.getString('bank');
emit(Loaded(
name,
nrp,
pangkat,
jabatan,
satker,
polda,
npwp,
rekening,
bank,
));
});
}
}
DetailpersonilEvent
part of 'detailpersonil_bloc.dart';
#immutable
abstract class DetailpersonilEvent extends Equatable {}
class Detail extends DetailpersonilEvent {
#override
List<Object> get props => [];
}
DetailpersonilState
part of 'detailpersonil_bloc.dart';
#immutable
abstract class DetailpersonilState extends Equatable {
final String nama;
final String nrp;
final String pangkat;
final String jabatan;
final String satker;
final String polda;
final String npwp;
final String rekening;
final String bank;
const DetailpersonilState(
{this.nama,
this.nrp,
this.pangkat,
this.jabatan,
this.satker,
this.polda,
this.npwp,
this.rekening,
this.bank});
}
class DetailpersonilInitial extends DetailpersonilState {
const DetailpersonilInitial()
: super(
nama: 'Nama',
nrp: 'NRP',
pangkat: 'Pangkat',
jabatan: 'Jabatan',
satker: 'Satker',
polda: 'Polda',
npwp: 'NPWP',
rekening: 'No Rekening',
bank: 'Nama Bank',
);
#override
List<Object> get props =>
[nama, nrp, pangkat, jabatan, satker, polda, npwp, rekening, bank];
}
class Loaded extends DetailpersonilState {
const Loaded(
String nama,
String nrp,
String pangkat,
String jabatan,
String satker,
String polda,
String npwp,
String rekening,
String bank,
) : super(
nama: nama,
nrp: nrp,
pangkat: pangkat,
jabatan: jabatan,
satker: satker,
polda: polda,
npwp: npwp,
rekening: rekening,
bank: bank);
#override
List<Object> get props =>
[nama, nrp, pangkat, jabatan, satker, polda, npwp, rekening, bank];
}
LoginPage
class LoginPage extends StatefulWidget {
const LoginPage({Key key}) : super(key: key);
#override
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
double width = 0;
double height = 0;
TextEditingController nrpController = TextEditingController();
TextEditingController sandiController = TextEditingController();
final formKey = GlobalKey<FormState>();
DetailpersonilBloc detailPersonilBloc;
GajiBloc gajiBloc;
TunkinBloc tunkinBloc;
bool passwordVisible = false;
#override
void initState() {
super.initState();
checkToken();
}
void checkToken() async {
SharedPreferences pref = await SharedPreferences.getInstance();
if (pref.getString('token') != null) {
detailPersonilBloc = DetailpersonilBloc();
gajiBloc = GajiBloc();
tunkinBloc = TunkinBloc();
detailPersonilBloc.add(Detail());
gajiBloc.add(Gaji());
tunkinBloc.add(Tunkin());
Navigator.push(
context, MaterialPageRoute(builder: (context) => const MainPage()));
}
}
onLogin(DetailpersonilBloc detailPersonilBloc) async {
if (formKey.currentState.validate()) {
var token = await APIService.generateToken(
nrpController.text, sandiController.text);
if (token != null) {
SharedPreferences pref = await SharedPreferences.getInstance();
await pref.setString('token', token.token);
var detail = await APIService.getDetailPersonil(token.token);
await pref.setString('nama', detail.nMPEG);
await pref.setString('NRP', detail.nRP);
await pref.setString('pangkat', detail.nMGOL1);
await pref.setString('jabatan', detail.sEBUTJAB);
await pref.setString('satker', detail.nMSATKER);
await pref.setString('polda', detail.nMUAPPAW);
await pref.setString('NPWP', detail.nPWP);
await pref.setString('rekening', detail.rEKENING);
await pref.setString('bank', detail.nMBANK);
nrpController.clear();
sandiController.clear();
detailPersonilBloc.add(Detail());
Navigator.push(
context, MaterialPageRoute(builder: (context) => const MainPage()));
} else {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text('Error'),
content: Text('Login Gagal'),
actions: [
ElevatedButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text('Tutup'),
),
],
);
},
);
}
}
}
#override
Widget build(BuildContext context) {
var detailPersonilBloc = BlocProvider.of<DetailpersonilBloc>(context);
width = MediaQuery.of(context).size.width;
height = MediaQuery.of(context).size.height;
return Scaffold(
body: Stack(
children: [
Column(
mainAxisAlignment: MainAxisAlignment.end,
children: const [
Opacity(
opacity: 0.5,
child: Image(
image: AssetImage('images/bg-map-min.png'),
),
),
],
),
SingleChildScrollView(
padding: EdgeInsets.only(top: 100),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(
height: 100,
width: width,
child: const Image(
image: AssetImage('images/login-logo.png'),
alignment: Alignment.center,
),
),
Container(
padding: const EdgeInsets.all(15),
child: const Text(
'GAJI DAN TUNKIN',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
),
Form(
key: formKey,
child: Column(
children: [
Container(
margin: const EdgeInsets.all(20 - 2.6),
child: Card(
elevation: 10,
child: Container(
padding: const EdgeInsets.all(20),
child: Column(
children: [
Container(
alignment: Alignment.topLeft,
padding: const EdgeInsets.only(bottom: 20),
child: const Text(
'LOGIN',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
Container(
padding: const EdgeInsets.only(bottom: 25),
child: TextFormField(
validator: (value) {
if (value == null || value.isEmpty) {
return 'Masukkan NRP/NIP';
}
return null;
},
controller: nrpController,
decoration: InputDecoration(
labelText: 'NRP/NIP',
hintText: 'Masukkan NRP/NIP',
prefixIcon: Icon(Icons.person,
color: Colors.blue.shade700),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
),
),
),
),
TextFormField(
obscureText: !passwordVisible,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Masukkan Kata Sandi';
}
return null;
},
controller: sandiController,
decoration: InputDecoration(
labelText: 'Kata Sandi',
hintText: 'Masukkan Kata Sandi',
prefixIcon: Icon(Icons.lock,
color: Colors.blue.shade700),
suffixIcon: IconButton(
onPressed: () {
setState(() {
passwordVisible = !passwordVisible;
});
},
icon: Icon(
passwordVisible
? Icons.visibility
: Icons.visibility_off,
color: Colors.blue.shade700,
),
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
),
),
)
],
),
),
),
),
ElevatedButton(
onPressed: () async {
await onLogin(detailPersonilBloc);
},
child: const Text('LOGIN'),
style: ElevatedButton.styleFrom(
primary: Colors.blue.shade700,
minimumSize: const Size(200, 40),
),
)
],
),
),
],
),
),
],
),
);
}
}
GajiPage
class GajiPage extends StatefulWidget {
const GajiPage({Key key}) : super(key: key);
#override
_GajiPageState createState() => _GajiPageState();
}
class _GajiPageState extends State<GajiPage> {
double width = 0;
double height = 0;
var currentYear = DateTime.now().year;
var currentMonth = DateTime.now().month;
DetailpersonilBloc detailPersonilBloc;
GajiBloc gajiBloc;
#override
void initState() {
setState(() {
detailPersonilBloc = DetailpersonilBloc();
detailPersonilBloc.add(Detail());
setMonth();
setYear();
gajiBloc = GajiBloc();
gajiBloc.add(Gaji());
});
super.initState();
}
#override
Widget build(BuildContext context) {
var detailPersonilBloc = BlocProvider.of<DetailpersonilBloc>(context);
width = MediaQuery.of(context).size.width;
height = MediaQuery.of(context).size.height;
return Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
title: Image(
image: const AssetImage('images/header-logo.png'),
width: width / 2,
),
flexibleSpace: Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
colors: [
Color.fromARGB(255, 170, 177, 175),
Color.fromARGB(255, 197, 217, 212)
],
),
),
),
),
body: Stack(
children: [
BlocBuilder<GajiBloc, GajiState>(
builder: (context, state) {
return state is GajiLoaded
? ListView(
children: [
Container(
height: 100,
),
Card(
color: const Color.fromARGB(255, 74, 50, 152),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20)),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
margin: const EdgeInsets.all(10),
child: const Text(
'Gaji Bersih',
style: TextStyle(
fontSize: 20,
color: Colors.white,
),
),
),
Container(
margin: const EdgeInsets.all(10),
child: Text(
NumberFormat.currency(
locale: 'en',
symbol: 'RP ',
decimalDigits: 0)
.format(state.bersih),
style: TextStyle(
fontWeight: FontWeight.w700,
fontSize: 40,
color: Colors.white,
),
),
),
],
),
),
Card(
child: Column(
children: [
Container(
color: const Color.fromARGB(255, 238, 238, 238),
width: width,
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Container(
margin: const EdgeInsets.fromLTRB(
10, 10, 0, 10),
width: (width / 2) - 25,
child: const Text(
'Detail Gaji',
textAlign: TextAlign.start,
style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 20,
),
),
),
Container(
margin: const EdgeInsets.fromLTRB(
5, 10, 20, 10),
width: (width / 2) - 18,
child: Text(
'${state.bulan} - ${state.tahun}',
textAlign: TextAlign.end,
style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 20,
),
),
)
],
),
),
...
],
),
),
Container(
height: 50,
),
],
)
: Center(
child: Text(
'Tidak ada data. Data gaji bulan ${state.bulan} belum diproses'),
);
},
),
Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Center(
child: BlocBuilder<DetailpersonilBloc, DetailpersonilState>(
builder: (context, state) {
return Card(
child: Row(
children: [
Container(
margin: const EdgeInsets.all(10),
child: const CircleAvatar(
backgroundImage: AssetImage('images/Profpic.PNG'),
radius: 30,
),
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: 250,
padding: const EdgeInsets.all(5),
child: Text(
state.nama,
style: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold),
)),
Container(
padding: const EdgeInsets.all(5),
child: Text(
state.nrp,
style: const TextStyle(fontSize: 15),
)),
],
),
GestureDetector(
onTap: () {
detailPersonilBloc.add(Detail());
showModalBottomSheet(
backgroundColor: Colors.transparent,
isScrollControlled: true,
context: context,
builder: (context) => detailsBottomSheet(),
);
},
child: const Text(
'DETAILS',
style: TextStyle(color: Colors.blue),
),
)
],
),
);
},
),
),
GestureDetector(
onTap: () {
showModalBottomSheet(
backgroundColor: Colors.transparent,
isScrollControlled: true,
context: context,
builder: (context) {
return StatefulBuilder(
builder: (context, StateSetter setState) {
return filterBottomSheet();
},
);
},
);
},
child: Container(
height: 50,
width: width,
decoration: const BoxDecoration(
color: Color.fromARGB(255, 244, 244, 244),
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
margin: const EdgeInsets.only(right: 3),
child: const Icon(
Icons.tune,
color: Color.fromARGB(255, 45, 165, 217),
),
),
const Text(
'Filter',
textAlign: TextAlign.center,
style: TextStyle(
fontWeight: FontWeight.w500,
fontSize: 20,
color: Color.fromARGB(255, 45, 165, 217),
),
),
],
),
),
)
],
)
],
),
);
}
}
Note 2: The "..." is a bunch of code not needed for reproduction.
The answer is surprisingly simple as I would learn from my internship. The reason the Bloc is not updating is because I was not using the context of the application. So when I generated a new Bloc inside my pages, it was "empty". So the solution is to use context.read().add(BlocEvent()) or create a new bloc with BlocProvider.of(context) then add the event. Basically the bloc has to be provided with the original context of the application.

Calling a page using a provider inside a bottom navigation bar in flutter

Am using a provider for each page in my flutter application like so :
class HolidayListState extends State<HolidayListView>{
#override
Widget build(BuildContext context) {
final vm = Provider.of<HolidayListViewModel>(context);
if(vm.holidaysviews == null){
return Align(child: CircularProgressIndicator());
}else if(vm.holidaysviews.isEmpty) {
return Align(child: Text("No holidays found."));
}else{
return Scaffold(
backgroundColor: Color(0xfff0f0f0),
body:SingleChildScrollView(
child: Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: Stack(
children: [
Container(
padding: EdgeInsets.only(top: 145),
height: MediaQuery.of(context).size.height,
width: double.infinity,
child: ChangeNotifierProvider(
create: (_) => HolidayListViewModel(),
child: ListView.builder(
itemCount: vm.holidaysviews.length,
itemBuilder: (context, index) {
final holiday = vm.holidaysviews[index];
final item = holiday.toString();
return Dismissible(
key: UniqueKey(),
background: Container(
alignment: AlignmentDirectional.centerEnd,
color: Colors.red,
child: Icon(
Icons.delete,
color: Colors.white,
),
),
direction: DismissDirection.endToStart,
confirmDismiss:
(DismissDirection direction) async {
return await showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text("Confirm"),
content: const Text(
"Are you sure you wish to delete this item?"),
actions: <Widget>[
FlatButton(
onPressed: () async {
await HolidayWebServices().deleteHoliday(holiday.id.toString());
Navigator.of(context).pop(true);
},
child: const Text("DELETE")),
FlatButton(
onPressed: () =>
Navigator.of(context).pop(false),
child: const Text("CANCEL"),
),
],
);
},
);
},
onDismissed: (direction) {
if (!mounted) {
setState(() {
vm.holidaysviews.removeAt(index);
});
}
},
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(25),
color: Colors.white,
),
width: double.infinity,
height: 110,
margin: EdgeInsets.symmetric(
vertical: 10, horizontal: 20),
padding: EdgeInsets.symmetric(
vertical: 10, horizontal: 20),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
width: 30,
height: 30,
margin: EdgeInsets.only(right: 15),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30),
border: Border.all(
width: 3, color: Colors.deepPurple),
),
child: Text(
holiday.duration
.toString(),
textAlign: TextAlign.center,
),
),
Expanded(
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: <Widget>[
ConditionalBuilder(
condition:
holiday.status ==
"PENDING",
builder: (context) {
return Container(
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(25),
color: Colors.white,
),
foregroundDecoration:
BadgeDecoration(
badgeColor: Colors.orange,
badgeSize: 70,
textSpan: TextSpan(
text:holiday.status,
style: TextStyle(
color: Colors.white,
fontSize: 12),
),
),
);
},
),
ConditionalBuilder(
condition:
holiday.status ==
"ACCEPTED",
builder: (context) {
return Container(
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(25),
color: Colors.white,
),
foregroundDecoration:
BadgeDecoration(
badgeColor: Colors.green,
badgeSize: 70,
textSpan: TextSpan(
text: holiday.status,
style: TextStyle(
color: Colors.white,
fontSize: 12),
),
),
);
},
),
ConditionalBuilder(
condition:
holiday.status ==
"REFUSED",
builder: (context) {
return Container(
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(25),
color: Colors.white,
),
foregroundDecoration:
BadgeDecoration(
badgeColor: Colors.red,
badgeSize: 70,
textSpan: TextSpan(
text: holiday.status,
style: TextStyle(
color: Colors.white,
fontSize: 12),
),
),
);
},
),
Row(
children: <Widget>[
Icon(
Icons.calendar_today,
color: Colors.deepPurple,
size: 20,
),
Text(
holiday.startDate,
style: TextStyle(
color: primary,
fontSize: 13,
letterSpacing: .3)),
],
),
SizedBox(
height: 6,
),
Row(
children: <Widget>[
Icon(
Icons.calendar_today,
color: Colors.deepPurple,
size: 20,
),
Text(holiday.endDate,
style: TextStyle(
color: primary,
fontSize: 13,
letterSpacing: .3)),
],
),
SizedBox(
height: 6,
),
Row(
children: <Widget>[
Icon(
Icons.assignment,
color: Colors.deepPurple,
size: 20,
),
SizedBox(
width: 5,
),
Text(holiday.type,
style: TextStyle(
color: primary,
fontSize: 13,
letterSpacing: .3)),
],
),
],
),
)
],
),
),
);
},
),
),
),
Container(
height: 140,
width: double.infinity,
decoration: BoxDecoration(
color: primary,
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(30),
bottomRight: Radius.circular(30))),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 30),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
"Holidays",
textAlign: TextAlign.center,
style: TextStyle(color: Colors.white, fontSize: 24),
),
],
),
),
),
Container(
child: Column(
children: <Widget>[
SizedBox(
height: 110,
),
],
),
)
],
),
),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
backgroundColor: kPrimaryColor,
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return StepperDemo();
},
),
);
},
)
);
}}
}
class BadgeDecoration extends Decoration {
final Color badgeColor;
final double badgeSize;
final TextSpan textSpan;
const BadgeDecoration(
{#required this.badgeColor,
#required this.badgeSize,
#required this.textSpan});
#override
BoxPainter createBoxPainter([onChanged]) =>
_BadgePainter(badgeColor, badgeSize, textSpan);
}
class _BadgePainter extends BoxPainter {
static const double BASELINE_SHIFT = 1;
static const double CORNER_RADIUS = 4;
final Color badgeColor;
final double badgeSize;
final TextSpan textSpan;
_BadgePainter(this.badgeColor, this.badgeSize, this.textSpan);
#override
void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) {
canvas.save();
canvas.translate(
offset.dx + configuration.size.width - badgeSize, offset.dy);
canvas.drawPath(buildBadgePath(), getBadgePaint());
// draw text
final hyp = math.sqrt(badgeSize * badgeSize + badgeSize * badgeSize);
final textPainter = TextPainter(
text: textSpan,
textDirection: TextDirection.ltr,
textAlign: TextAlign.center);
textPainter.layout(minWidth: hyp, maxWidth: hyp);
final halfHeight = textPainter.size.height / 2;
final v = math.sqrt(halfHeight * halfHeight + halfHeight * halfHeight) +
BASELINE_SHIFT;
canvas.translate(v, -v);
canvas.rotate(0.785398); // 45 degrees
textPainter.paint(canvas, Offset.zero);
canvas.restore();
}
Paint getBadgePaint() => Paint()
..isAntiAlias = true
..color = badgeColor;
Path buildBadgePath() => Path.combine(
PathOperation.difference,
Path()
..addRRect(RRect.fromLTRBAndCorners(0, 0, badgeSize, badgeSize,
topRight: Radius.circular(CORNER_RADIUS))),
Path()
..lineTo(0, badgeSize)
..lineTo(badgeSize, badgeSize)
..close());
}
and I want to call the page in a navigation bar , right now this is the navigation bar page :
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:helium/views/holiday/holidayList.dart';
import 'package:helium/views/login/login_screen.dart';
import 'package:helium/views/profile/profile_home.dart';
import 'package:helium/views/time_tracking/time_tracking_home.dart';
class MainMenu extends StatefulWidget {
#override
_MainMenuState createState() => _MainMenuState();
void signOut() {}
}
class _MainMenuState extends State<MainMenu> {
PageController _pageController;
int _page = 0;
List icons = [
Icons.home,
Icons.event,
Icons.beach_access_rounded
// Icons.ac_unit,
];
List<Widget> _widgetOptions = <Widget>[
Profile(),
MyCalendarPage(),
HolidayListView()
];
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).primaryColor,
actions: <Widget>[
IconButton(
onPressed: () {
signOut();
},
icon: Icon(Icons.lock_open),
)
],
),
body: PageView(
physics: NeverScrollableScrollPhysics(),
controller: _pageController,
onPageChanged: onPageChanged,
children: _widgetOptions,
),
bottomNavigationBar: bottomMenu(),
floatingActionButtonAnimator: FloatingActionButtonAnimator.scaling,
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
);
}
Widget bottomMenu(){
return BottomAppBar(
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
SizedBox(width: 2),
buildTabIcon(0),
buildTabIcon(1),
buildTabIcon(2),
SizedBox(width: 2),
],
),
color: Theme.of(context).primaryColor,
shape: CircularNotchedRectangle(),
);
}
void navigationTapped(int page) {
_pageController.jumpToPage(page);
}
signOut() {
setState(() {
widget.signOut();
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => LoginScreen()),
);
print("signed out");
});
}
#override
void initState() {
super.initState();
// getPref();
_pageController = PageController();
}
#override
void dispose() {
super.dispose();
_pageController.dispose();
}
void onPageChanged(int page) {
setState(() {
this._page = page;
});
}
buildTabIcon(int index) {
return IconButton(
icon: Icon(
icons[index],
size: 24.0,
),
color: Colors.grey,
//_page == index
//? Theme.of(context).accentColor
//: Theme.of(context).textTheme.caption.color,
onPressed: () => _pageController.jumpToPage(index),
);
}
}
apparently I have to call the provider somewhere in the bottom nav bar page but I don't know how to do it , right now am getting this error , so if anyone knows what seems to be wrong , I would appreciate so me help , here's the stack trace :
Error: Could not find the correct Provider<HolidayListViewModel> above this HolidayListView Widget
This happens because you used a `BuildContext` that does not include the provider
of your choice. There are a few common scenarios:
- You added a new provider in your `main.dart` and performed a hot-reload.
To fix, perform a hot-restart.
- The provider you are trying to read is in a different route.
Providers are "scoped". So if you insert of provider inside a route, then
other routes will not be able to access that provider.
- You used a `BuildContext` that is an ancestor of the provider you are trying to read.
Make sure that HolidayListView is under your MultiProvider/Provider<HolidayListViewModel>.
This usually happens when you are creating a provider and trying to read it immediately.
For example, instead of:
Widget build(BuildContext context) {
return Provider<Example>(
create: (_) => Example(),
// Will throw a ProviderNotFoundError, because `context` is associated
// to the widget that is the parent of `Provider<Example>`
child: Text(context.watch<Example>()),
),
}
consider using `builder` like so:
Widget build(BuildContext context) {
return Provider<Example>(
create: (_) => Example(),
// we use `builder` to obtain a new `BuildContext` that has access to the provider
builder: (context) {
// No longer throws
return Text(context.watch<Example>()),
}
),
}

How do I add Items to a List with a button I created in another stateful widget?

I have an integer in one class and I want to use it in another class to remove or add containers to the List when the buttons "+" or "-" are pressed. I don´t know if that is the right approach to achieve what I want but I couldn't come up with any working solution. I am pretty new to flutter and coding in general and I tried for hours to fix this issue so I would be more than thankful for any solution.
import 'package:flutter/material.dart';
void main() => runApp(MaterialApp(home: Home()));
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
var addcontainers = AddContainers();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Home')),
body: new Column(
children: [
new Expanded(
child: GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4),
itemCount: addcontainers.q,
itemBuilder: (context, i) {
return Container(
child: Text(
"A",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20.0,
fontWeight: FontWeight.w600,
fontFamily: "Arial",
),
),
color: Colors.blue,
padding: EdgeInsets.all(20.0),
margin: EdgeInsets.all(20.0),
);
}),
),
AddContainers()
],
),
);
}
}
class AddContainers extends StatefulWidget {
#override
_AddContainersState createState() => _AddContainersState();
final int q;
AddContainers({this.q});
}
class _AddContainersState extends State<AddContainers> {
int q = 8;
#override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
Container(
child: Text(
"Container",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 15.0,
fontWeight: FontWeight.w600,
fontFamily: "Arial",
),
),
color: Colors.blue,
padding: EdgeInsets.all(15.0),
margin: EdgeInsets.all(20.0),
height: 70,
width: MediaQuery.of(context).size.width * 0.2),
Positioned(
bottom: 20,
right: 20,
child: InkWell(
onTap: () {
setState(() {
q++;
});
},
child: Container(
child: Icon(Icons.add),
decoration: BoxDecoration(
border: Border.all(color: Colors.black, width: 2)),
width: MediaQuery.of(context).size.width * 0.1,
height: 30,
),
),
),
Positioned(
bottom: 20,
left: 20,
child: InkWell(
onTap: () {
setState(() {
if (q != 0) q--;
});
},
child: Container(
child: Icon(Icons.remove),
decoration: BoxDecoration(
border: Border.all(color: Colors.black, width: 2)),
width: MediaQuery.of(context).size.width * 0.1,
height: 30,
),
),
),
],
);
}
}
You can copy paste run full code below
You can use ValueNotifier<int> and pass refresh() callback
Step 1: Initialize ValueNotifier<int> q and refresh() callback
Step 2: pass to AddContainers(q: q, callback: refresh)
Step 3: In _AddContainersState, you can call widget.q.value++ widget.q.value-- and widget.callback()
code snippet
class _HomeState extends State<Home> {
final ValueNotifier<int> q = ValueNotifier<int>(8);
refresh() {
setState(() {});
}
#override
Widget build(BuildContext context) {
...
child: GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4),
itemCount: q.value,
...
),
AddContainers(q: q, callback: refresh)
...
class _AddContainersState extends State<AddContainers> {
...
child: InkWell(
onTap: () {
setState(() {
widget.q.value++;
print(widget.q.value);
});
widget.callback();
},
...
child: InkWell(
onTap: () {
setState(() {
if (widget.q.value != 0) widget.q.value--;
});
widget.callback();
},
...
);
}
}
working demo
full code
import 'package:flutter/material.dart';
void main() => runApp(MaterialApp(home: Home()));
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
final ValueNotifier<int> q = ValueNotifier<int>(8);
refresh() {
setState(() {});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Home')),
body: Column(
children: [
Expanded(
child: GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4),
itemCount: q.value,
itemBuilder: (context, i) {
return Container(
child: Text(
"A",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20.0,
fontWeight: FontWeight.w600,
fontFamily: "Arial",
),
),
color: Colors.blue,
padding: EdgeInsets.all(20.0),
margin: EdgeInsets.all(20.0),
);
}),
),
AddContainers(q: q, callback: refresh)
],
),
);
}
}
class AddContainers extends StatefulWidget {
#override
_AddContainersState createState() => _AddContainersState();
final ValueNotifier<int> q;
final VoidCallback callback;
AddContainers({this.q, this.callback});
}
class _AddContainersState extends State<AddContainers> {
//int q = 8;
#override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
Container(
child: Text(
"Container",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 15.0,
fontWeight: FontWeight.w600,
fontFamily: "Arial",
),
),
color: Colors.blue,
padding: EdgeInsets.all(15.0),
margin: EdgeInsets.all(20.0),
height: 70,
width: MediaQuery.of(context).size.width * 0.2),
Positioned(
bottom: 20,
right: 20,
child: InkWell(
onTap: () {
setState(() {
widget.q.value++;
print(widget.q.value);
});
widget.callback();
},
child: Container(
child: Icon(Icons.add),
decoration: BoxDecoration(
border: Border.all(color: Colors.black, width: 2)),
width: MediaQuery.of(context).size.width * 0.1,
height: 30,
),
),
),
Positioned(
bottom: 20,
left: 20,
child: InkWell(
onTap: () {
setState(() {
if (widget.q.value != 0) widget.q.value--;
});
widget.callback();
},
child: Container(
child: Icon(Icons.remove),
decoration: BoxDecoration(
border: Border.all(color: Colors.black, width: 2)),
width: MediaQuery.of(context).size.width * 0.1,
height: 30,
),
),
),
],
);
}
}
Your code is not working because the home widget does not know when the q value is changing. It is not notified when the value changes, so
addcontainers.q always has the same value.
To make the code work, you need to use a callback.
AddContainers(callback: (value){
setState(() {
itemCount = value;
});
},)
That way the home widget can know when the value has changed.
import 'package:flutter/material.dart';
void main() => runApp(MaterialApp(home: Home()));
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
int itemCount = 0;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Home')),
body: new Column(
children: [
new Expanded(
child: GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4),
itemCount: itemCount,
itemBuilder: (context, i) {
return Container(
child: Text(
"A",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20.0,
fontWeight: FontWeight.w600,
fontFamily: "Arial",
),
),
color: Colors.blue,
padding: EdgeInsets.all(20.0),
margin: EdgeInsets.all(20.0),
);
}),
),
AddContainers(callback: (value){
setState(() {
itemCount = value;
});
},)
],
),
);
}
}
class AddContainers extends StatefulWidget {
AddContainers({this.callback});
final Function(int) callback;
#override
_AddContainersState createState() => _AddContainersState();
}
class _AddContainersState extends State<AddContainers> {
int q = 8;
#override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
Container(
child: Text(
"Container",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 15.0,
fontWeight: FontWeight.w600,
fontFamily: "Arial",
),
),
color: Colors.blue,
padding: EdgeInsets.all(15.0),
margin: EdgeInsets.all(20.0),
height: 70,
width: MediaQuery.of(context).size.width * 0.2),
Positioned(
bottom: 20,
right: 20,
child: InkWell(
onTap: () {
setState(() {
widget.callback(q++);
});
},
child: Container(
child: Icon(Icons.add),
decoration: BoxDecoration(
border: Border.all(color: Colors.black, width: 2)),
width: MediaQuery.of(context).size.width * 0.1,
height: 30,
),
),
),
Positioned(
bottom: 20,
left: 20,
child: InkWell(
onTap: () {
setState(() {
if (q != 0) widget.callback(q--);
});
},
child: Container(
child: Icon(Icons.remove),
decoration: BoxDecoration(
border: Border.all(color: Colors.black, width: 2)),
width: MediaQuery.of(context).size.width * 0.1,
height: 30,
),
),
),
],
);
}
}

how to add flexible height to showGeneralDialog on Flutter?

I added padding for transparent outside. But fixed height. How to change it?
padding: EdgeInsets.fromLTRB(20, 50, 20, 50),
Is it possible to remove above this line and flexible(center)?
I am expected like this flexible height alert. click here
onPressed: () {
showGeneralDialog(
context: context,
barrierColor: Palette.black.withOpacity(.3),
barrierDismissible: true,
transitionDuration: Duration(milliseconds: 400),
pageBuilder: (_, __, ___) {
return ChangePropertyPage(
propertyModel: propertyModel);
},
);
},
change Property Page
class ChangePropertyPage extends StatelessWidget {
final List<PropertyModel> propertyModel;
const ChangePropertyPage({Key key, this.propertyModel}) : super(key: key);
#override
Widget build(BuildContext context) {
final double width = CustomMediaQuery.width(context);
return Padding(
padding: EdgeInsets.fromLTRB(20, 50, 20, 50),
child: Material(
borderRadius: BorderRadius.all(Radius.circular(10)),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
PropertyListTileWidget(
mainTitle: 'USER\'S Name', subTitle: 'USER\'S Email'),
VerticalSpacing(height: 10),
CustomLine(
height: 1,
width: (width - 40) - 20,
color: Palette.black.withOpacity(.2),
),
Expanded(
child: ListView.builder(
itemCount: propertyModel.length,//now length is 1
shrinkWrap: true,
itemBuilder: (BuildContext context, int index) {
return InkWell(
onTap: ()async{
},
child: PropertyListTileWidget(
mainTitle: '${propertyModel[index].propertyName}',
subTitle: '${propertyModel[index].ownerUId}'),
);
}),
)
],
),
),
),
);
}
}
if you are expecting this:
then
full code:
import 'package:flutter/material.dart';
class CustomDialogBox extends StatefulWidget {
#override
_CustomDialogBoxState createState() => _CustomDialogBoxState();
}
class _CustomDialogBoxState extends State<CustomDialogBox> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Custom Dialog Box"),
centerTitle: true,
),
body:Center(
child:FlatButton(
color: Colors.blue,
onPressed: (){
showDialog(
context: (context),
child: ShowCustomDialogBox()
);
},
child: Text("Show Dialog")
)
) ,
);
}
}
class ShowCustomDialogBox extends StatefulWidget {
#override
State<StatefulWidget> createState() => ShowCustomDialogBoxState();
}
class ShowCustomDialogBoxState extends State<ShowCustomDialogBox>with SingleTickerProviderStateMixin {
AnimationController controller;
Animation<double> scaleAnimation;
#override
void initState() {
super.initState();
controller = AnimationController(vsync: this, duration: Duration(milliseconds: 450));
scaleAnimation =CurvedAnimation(parent: controller, curve: Curves.decelerate);
controller.addListener(() {
setState(() {});
});
controller.forward();
}
#override
Widget build(BuildContext context) {
return Center(
child: Material(
color: Colors.transparent,
child: ScaleTransition(
scale: scaleAnimation,
child: Container(
margin: EdgeInsets.all(20.0),
padding: EdgeInsets.all(8.0),
height: MediaQuery.of(context).size.height/2.5, //Change height of dialog box.
width: MediaQuery.of(context).size.width,
decoration: ShapeDecoration(
color: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0))),
child: Column(
children: <Widget>[
Expanded(
flex: 4,
child: ListView.builder(
itemCount: 10,
itemBuilder: (context, index){
return Column(
// mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text((index+1).toString(),style: TextStyle(color:Colors.blue,fontSize:40),),
Divider()
],
);
}
)
),
Padding(
padding: const EdgeInsets.only(
left: 20.0, right: 10.0, top: 0.0,),
child: ButtonTheme(
height: 35.0,
minWidth: MediaQuery.of(context).size.width/3.5,
child: RaisedButton(
color: Colors.blue,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5.0)),
splashColor: Colors.white.withAlpha(40),
child: Text(
'Next',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 13.0),
),
onPressed: () {
setState(() {
Navigator.pop(context);
});
},
)
)
),
],
)
),
),
),
);
}
}