i am trying to access this controller but i don't know why it crashes. as a mistake he gives me that:
no material widget found
iconButtonwidget require a material widget
is a simple view showing the map with various saved points
do I initialize the view badly?
Can anyone tell me what am I wrong?
this is the code I use
class MapTab extends StatefulWidget {
#override
_MapTabState createState() => _MapTabState();
}
class _MapTabState extends State<MapTab> {
Size _size;
MapboxMapController _mapController;
StreamController<Restaurant> _bottomCardStreamController;
_onMapCreated(MapboxMapController controller) {
_mapController = controller;
contentManager.getMerchants().then(
(restaurants) => restaurants.forEach(
(restaurant) => controller.addSymbol(
SymbolOptions(
geometry: LatLng(double.parse(restaurant.coordinates.lat),
double.parse(restaurant.coordinates.long)),
iconImage: "assets/images/map_pin.png",
),
restaurant.toJson(),
),
),
);
controller.onSymbolTapped.add((symbol) async {
Restaurant restaurant = Restaurant.fromJson(symbol.data);
_toggleBottomCard(restaurant);
});
_bottomCardStreamController.stream.listen((restaurant) {
if (restaurant == null) return;
List<CameraUpdate> updates = [
CameraUpdate.zoomTo(15),
CameraUpdate.newLatLng(LatLng(
double.parse(restaurant.coordinates.lat),
double.parse(restaurant.coordinates.long),
)),
];
updates
.forEach((element) async => await controller.animateCamera(element));
});
}
_toggleBottomCard(Restaurant data) {
_bottomCardStreamController.sink.add(data);
}
#override
void initState() {
super.initState();
_bottomCardStreamController = StreamController<Restaurant>.broadcast();
}
#override
void dispose() {
_bottomCardStreamController.close();
super.dispose();
}
#override
Widget build(BuildContext context) {
_size = MediaQuery.of(context).size;
return Stack(
alignment: AlignmentDirectional.center,
children: [
FutureBuilder<Position>(
future: PositionService.getCurrentPosition(),
builder: (context, AsyncSnapshot<Position> positionSnap) {
if (positionSnap.hasError)
return Center(
child: Text(localization.err_localization),
);
if (positionSnap.connectionState != ConnectionState.done)
return Container(
child: Center(
child: CircularProgressIndicator(valueColor: new AlwaysStoppedAnimation<Color>(appColors.yellow)),
),
);
var data = positionSnap.data;
var latLng = LatLng(data.latitude, data.longitude);
return FutureBuilder<String>(
future: contentManager.getMapBoxKey(),
builder: (context, tokenSnap) {
if (tokenSnap.hasError)
return Container(
child: Center(
child: Text(localization.err_mapbox_key),
),
);
if (tokenSnap.connectionState != ConnectionState.done)
return Container(
child: Center(
child: CircularProgressIndicator(valueColor: new AlwaysStoppedAnimation<Color>(appColors.yellow)),
),
);
return Container(
height: _size.height,
width: _size.width,
child: MapboxMap(
rotateGesturesEnabled: false,
myLocationEnabled: true,
onStyleLoadedCallback: () {},
zoomGesturesEnabled: true,
onMapClick: (_, __) {
// fa scomparire la bottomCard
_bottomCardStreamController.sink.add(null);
},
accessToken: tokenSnap.data,
onMapCreated: _onMapCreated,
compassEnabled: false,
initialCameraPosition: CameraPosition(
target: latLng,
zoom: 15,
bearing: 0,
tilt: 0,
),
),
);
});
}),
Positioned(
bottom: 10,
right: 10,
height: 50,
width: 50,
child: GestureDetector(
child: Container(
decoration: BoxDecoration(
color: Color.fromARGB(255, 255, 255, 255),
shape: BoxShape.circle,
),
child: Icon(Icons.my_location),
),
onTap: () async {
var position = await PositionService.getCurrentPosition();
var latLng = LatLng(position.latitude, position.longitude);
_mapController.animateCamera(CameraUpdate.newLatLng(latLng));
},
),
),
Positioned(
top: 10,
left: 0,
width: _size.width,
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
IconButton(
icon: Icon(
Icons.list,
),
onPressed: () {},
),
Flexible(
child: GestureDetector(
onTap: () async {
await showSearch<Restaurant>(
context: context,
delegate: CustomSearchDelegate(),
query: "",
).then(
(value) => _bottomCardStreamController.sink.add(value),
);
},
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20),
),
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: 3,
vertical: 2,
),
child: TextField(
enabled: false,
decoration: InputDecoration(
icon: Icon(
Icons.search,
color: Colors.grey,
),
hintText: localization.find,
border: InputBorder.none,
),
),
),
),
),
),
IconButton(
icon: Icon(
Icons.filter_alt,
),
onPressed: () {},
)
],
),
),
Positioned(
bottom: 25,
width: _size.width,
child: StreamBuilder<Restaurant>(
stream: _bottomCardStreamController.stream,
builder: (_, snap) {
if (snap.data == null)
return Container();
else
return RestaurantMapCard(snap.data,
mapController: _mapController);
},
),
),
],
);
}
}
Wrap your root(first widget) with the MaterialApp widget.
Widget build(BuidContext context){
return MaterialApp(
home: Stack() // your stack and other widgets are here.
);
}
Related
I have created a dialog with StatefulBuilder. Setstate works perfectly within the StatefulBuilder. But I want to change that state from initstate too. But the set state from initstate is not called.
My code:
#override
void initState() {
super.initState();
rest_controller = AnimationController(
vsync: this,
duration: Duration(seconds: 15),
);
rest_controller.addListener(() {
if (rest_controller.isAnimating) {
setState(() {
print("rp"+rest_progress.toString());
rest_progress = rest_controller.value;
});
} else {
setState(() {
print("rp2"+rest_progress.toString());
rest_progress = 1.0;
rest_isPlaying = false;
});
}
});
}
Dialog open function:
showDataAlert() {
showDialog(
context: context,
builder: (context) {
return StatefulBuilder(
builder: (context, setState) {
return AlertDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(
20.0,
),
),
),
backgroundColor: kMainColor,
contentPadding: EdgeInsets.only(
top: 10.0,
),
title: Text(
"Take Rest",
style: TextStyle(fontSize: 24.0, color: kTextColor),
),
content:
Center(
child: Column(
children: [
SizedBox(
height: 10,
),
Expanded(
child: Stack(
alignment: Alignment.center,
children: [
SizedBox(
width: 260,
height: 260,
child: CircularProgressIndicator(
backgroundColor: Colors.grey.shade300,
value: rest_progress,
strokeWidth: 6,
),
),
AnimatedBuilder(
animation: rest_controller,
builder: (context, child) => Text(
restCountText,
style: TextStyle(
fontSize: 50,
fontWeight: FontWeight.bold,
color: kTextColor,
),
),
),
],
),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
GestureDetector(
onTap: () {
if (rest_controller.isAnimating) {
rest_controller.stop();
setState(() {
rest_isPlaying = false;
});
} else {
rest_controller.reverse(from: rest_controller.value == 0 ? 1.0 : rest_controller.value);
setState(() {
rest_isPlaying = true;
});
}
},
child: RoundButton(
icon: rest_isPlaying == true ? Icons.pause : Icons.play_arrow,
),
),
GestureDetector(
onTap: () {
rest_controller.reset();
setState(() {
rest_isPlaying = false;
});
},
child: RoundButton(
icon: Icons.stop,
),
),
],
),
)
],
),
),
);
}
);
});
}
Basically, setstate from the initstate is not changing the state. I have tried to change the state from showDataAlert function also, but no luck. Only the state changes if I click the button inside the showdialog.
i am working with PageView but if i swipe to change it will change the page But if i put onPageChanged to setState for me to get to current index it will not change the page.
here is my code
int _indicatorsPages = 0;
final PageController controller =
PageController(initialPage: 0);
change(int page) {
setState(() {
_indicatorsPages = page;
}); }
code from build
Scaffold(
backgroundColor: Colors.black,
appBar: AppBar(
leading: Row(
children: [
SizedBox(
width: 10,
),
GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => SettingsFMC(),
),
);
},
child: Container(
height: 40,
width: 40,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.5),
spreadRadius: 1, blurRadius: 2,
offset: Offset(0, 3), // i change position of shadow
),
],
),
child: Center(
child: Icon(
FontAwesomeIcons.slidersH,
size: 20,
color: Colors.black,
)),
),
),
],
),
elevation: 0,
backgroundColor: Colors.transparent,
actions: [
GestureDetector(
onTap: () async {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Actitvities(),
),
);
final doc = await firestore
.collection('feeds')
.doc(auth.currentUser.uid)
.collection('feedsItems')
.get();
if (doc.docs.isNotEmpty) {
firestore
.collection('feeds')
.doc(auth.currentUser.uid)
.collection('feedsItems')
.get()
.then((value) {
value.docs.forEach((doc) {
doc.reference.update({'seen': true});
});
});
}
},
child: Container(
height: 40,
width: 40,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.5),
spreadRadius: 1, blurRadius: 2,
offset: Offset(0, 3), // i change position of shadow
),
],
),
child: StreamBuilder(
stream: firestore
.collection('feeds')
.doc(auth.currentUser.uid)
.collection('feedsItems')
.where('seen', isEqualTo: false)
.snapshots(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: Icon(
Icons.notifications_none_outlined,
size: 20,
color: Colors.black,
));
}
if (snapshot.data.docs.isEmpty) {
return Center(
child: Icon(
Icons.notifications_none_outlined,
size: 20,
color: Colors.black,
));
}
return Badge(
animationType: BadgeAnimationType.scale,
badgeContent: Text('${snapshot.data.docs.length}'),
position: BadgePosition.topStart(),
showBadge: true,
child: Center(
child: Icon(
Icons.notifications_none_outlined,
size: 20,
color: Colors.black,
)),
);
}),
),
),
SizedBox(
width: 10,
),
],
),
extendBodyBehindAppBar: true,
body: userProfileLoading
? Center(
child: CircularProgressIndicator(),
)
: Stack(
children: [
Container(
height: MediaQuery.of(context).size.height / 1.6,
child: StreamBuilder(
stream: firestore
.collection('Image')
.doc(widget.viewId)
.collection('Photos')
.orderBy('timestap', descending: false)
.snapshots(),
builder: (context, AsyncSnapshot snapshot) {
int idx = 0;
List<Widget> list = [];
if (snapshot.connectionState ==
ConnectionState.waiting) {
return Center(
child: CircularProgressIndicator(),
);
}
if (!snapshot.hasData) {
return Center(
child: Text("No image Found, Add images"),
);
} else {
if (snapshot.hasError) {
return Center(child: Text("fetch error"));
} else {
for (int i = 0;
i < snapshot.data.docs.length;
i++) {
// print('the lent of the document is $idx');
list.add(
FullScreenWidget(
child: Hero(
tag: "customTag",
child: Image.network(
snapshot.data.docs[idx]
.data()['picture'],
fit: BoxFit.cover,
),
),
),
);
idx++;
}
return Stack(
children: [
PageView(
key: _key,
scrollDirection: Axis.horizontal,
controller: controller,
onPageChanged: change,
// onImageChange: (pre, current) {
// print('this current : $current');
// setState(() {
// indicatorsPages = current;
// });
// },
// boxFit: BoxFit.cover,
// autoplay: false,
// animationCurve: Curves.fastOutSlowIn,
// animationDuration:
// Duration(milliseconds: 1000),
// dotIncreasedColor: Colors.orange,
// dotBgColor: Colors.transparent,
// dotPosition: DotPosition.bottomCenter,
// dotVerticalPadding:
// MediaQuery.of(context).size.height / 15,
//showIndicator: false,
// indicatorBgPadding: 7.0,
children: list,
),
Positioned(
right:
MediaQuery.of(context).size.width / 2,
bottom: 75,
child: Container(
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(20),
color: Colors.white),
child: indicat.DotsIndicator(
dotsCount: list.length,
position: _indicatorsPages.toDouble(),
decorator: DotsDecorator(
color:
Colors.grey, // Inactive color
activeColor: Colors.black,
),
)),
)
],
);
}
}
}),
),
You are wrong. When you use pageView, it will call onPageChnaged function after page changed. If you want to change page programmatically, you should use pageView.animateToPage() function.
import 'package:flutter/material.dart';
class OnBoarding extends StatefulWidget {
#override
_OnBoardingState createState() => _OnBoardingState();
}
class _OnBoardingState extends State<OnBoarding> {
PageController controller;
int currentIndex = 0;
#override
void initState() {
controller = PageController();
super.initState();
}
#override
void dispose() {
controller.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.blueAccent[200],
body: Stack(
children: [
PageView(
onPageChanged: onchahged,
controller: controller,
children: [
Container(
child: Image.asset('assets/fierceninja.png'),
),
Container(
child: Image.asset('assets/ninja.png'),
),
Container(
child: Image.asset('assets/ninjahead.jpg'),
),
],
),
],
),
);
}
onchahged(int index) {
setState(() {
currentIndex = index;
});
}
}
Here's a complete example.
I have an issue with my General Dialog Box. I would like to display a star. Then I would like to change it state when the star is taped and replace the icon by a yellow Star.
But is does not work. The Dialog Box is not refreshed so the icon is not changing. Please, can you look at the source code below and point me into the right direction please?
Many thanks.
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:date_time_picker/date_time_picker.dart';
import 'package:gtd_official_sharped_focused/snackbar.dart';
String _isImportantInboxTask ;
String _isUrgentInboxTask ;
String inboxTaskDisplayed;
String isImportant = "false" ;
String isUrgent = "false" ;
String myProjectName ;
var taskSelectedID;
//---------------
//String _initialValue;
//_-----------------
var documentID;
var textController = TextEditingController();
var popUpTextController = TextEditingController();
class Inbox extends StatefulWidget {
Inbox({Key key}) : super(key: key);
#override
_InboxState createState() => _InboxState();
}
class _InboxState extends State<Inbox> {
GlobalKey<FormState> _captureFormKey = GlobalKey<FormState>();
bool isOn = true;
#override
Widget build(BuildContext context) {
void showAddNote() {
TextEditingController _noteField = new TextEditingController();
showDialog(
context: context,
builder: (BuildContext context) {
return CustomAlertDialog(
content: Container(
width: MediaQuery.of(context).size.width / 1.3,
height: MediaQuery.of(context).size.height / 4,
child: Column(
children: [
TextField(
controller: _noteField,
maxLines: 4,
decoration: InputDecoration(
border: const OutlineInputBorder(
borderSide:
const BorderSide(color: Colors.black, width: 1.0),
),
),
),
SizedBox(height: 10),
Material(
elevation: 5.0,
borderRadius: BorderRadius.circular(25.0),
color: Colors.white,
child: MaterialButton(
minWidth: MediaQuery.of(context).size.width / 1.5,
onPressed: () {
Navigator.of(context).pop();
CollectionReference users = FirebaseFirestore.instance
.collection('Users')
.doc(FirebaseAuth.instance.currentUser.uid)
.collection('allTasks');
users
.add({'task_Name': _noteField.text,'task_Status': 'Inbox' })
.then((value) => print("User Document Added"))
.catchError((error) =>
print("Failed to add user: $error"));
},
padding: EdgeInsets.fromLTRB(10.0, 15.0, 10.0, 15.0),
child: Text(
'Add Note',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20.0,
color: Colors.black,
fontWeight: FontWeight.bold,
),
),
),
),
],
),
),
);
});
}
return Scaffold(
appBar: new AppBar(
title: new Text('Inbox Page'),
actions: <Widget>[
IconButton(
icon: Icon(
Icons.add_circle_outline,
color: Colors.white,
),
onPressed: () {
showAddNote();
// do something
},
),
],
),
drawer: MyMenu(),
backgroundColor: Colors.white,
body: Column(
//mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
height: MediaQuery.of(context).size.height / 1.4,
width: MediaQuery.of(context).size.width,
child: StreamBuilder(
stream: FirebaseFirestore.instance
.collection('Users')
.doc(FirebaseAuth.instance.currentUser.uid)
.collection('allTasks')
.where('task_Status', isEqualTo: 'Inbox')
.snapshots(),
builder: (BuildContext context,
AsyncSnapshot<QuerySnapshot> snapshot) {
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(),
);
}
return ListView(
children: snapshot.data.docs.map((document) {
return Wrap(
children: [Card(
child: SwipeActionCell(
key: ObjectKey(document.data()['task_Name']),
actions: <SwipeAction>[
SwipeAction(
title: "delete",
onTap: (CompletionHandler handler) {
CollectionReference users = FirebaseFirestore
.instance
.collection('Users')
.doc(
FirebaseAuth.instance.currentUser.uid)
.collection('allTasks');
users
.doc(document.id)
.delete()
.then((value) => print("Note Deleted"))
.catchError((error) => print(
"Failed to delete Task: $error"));
},
color: Colors.red),
],
child: Padding(
padding: const EdgeInsets.all(0.0),
child: ListTile(
leading: ConstrainedBox(
constraints: BoxConstraints(
minWidth: leadingIconMinSize,
minHeight: leadingIconMinSize,
maxWidth: leadingIconMaxSize,
maxHeight: leadingIconMaxSize,
),
child: Image.asset('assets/icons/inbox.png'),
),
title: GestureDetector(
child: Text(
//'task_Name' correspond au nom du champ dans la table
document.data()['task_Name'],
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
// Pour editer task
onDoubleTap: (){
taskSelectedID = FirebaseFirestore
.instance
.collection('Users')
.doc(
FirebaseAuth.instance.currentUser.uid)
.collection('allTasks')
.doc(document.id);
//Dialog
return showGeneralDialog(
context: context,
barrierDismissible: true,
barrierLabel: MaterialLocalizations.of(context)
.modalBarrierDismissLabel,
barrierColor: Colors.black45,
transitionDuration: const Duration(milliseconds: 20),
pageBuilder: (BuildContext buildContext,
Animation animation,
Animation secondaryAnimation) {
return Scaffold(
appBar: AppBar(
title: Text ('Edit Task'),
leading: InkWell(
child: Icon(Icons.close),
onTap:(){Navigator.of(context).pop();}
),
actions: [Padding(
padding: const EdgeInsets.fromLTRB(0, 0,16.0,0),
child: InkWell(
child: Icon(Icons.save),
onTap: () {
final loFormInbox = _captureFormKey
.currentState;
if (loFormInbox.validate()) {
loFormInbox.save();
CollectionReference users = FirebaseFirestore
.instance
.collection(
'Users')
.doc(FirebaseAuth
.instance
.currentUser.uid)
.collection(
'allTasks');
users
.add({
'task_Name': _valueTaskNameSaved,
})
.then((value) =>
print(
"Task Created"))
.catchError((
error) =>
print(
"Failed to add task: $error"));
showSimpleFlushbar(
context,
'Task Saved',
_valueTaskNameSaved,
Icons
.mode_comment);
loFormInbox.reset();
isImportant = 'false';
isUrgent = 'false';
}
}
),
)],
),
body: Center(
child: Container(
width: MediaQuery.of(context).size.width - 10,
height: MediaQuery.of(context).size.height - 80,
padding: EdgeInsets.all(20),
color: Colors.white,
child: Column(
children: [
Theme(
data: ThemeData(
inputDecorationTheme: InputDecorationTheme(
border: InputBorder.none,
)
),
child: Padding(
padding: const EdgeInsets.fromLTRB(8.0, 0.0, 15.0, 1.0),
child: TextFormField(
initialValue: document.data()['task_Name'],
decoration: InputDecoration(hintText: "Task Name"),
maxLength: 70,
maxLines: 2,
onChanged: (valProjectName) => setState(() => _valueTaskNameChanged = valProjectName),
validator: (valProjectName) {
setState(() => _valueTaskNameToValidate = valProjectName);
return valProjectName.isEmpty? "Task name cannot be empty" : null;
},
onSaved: (valProjectName) => setState(() => _valueTaskNameSaved = valProjectName),
),
)),
//Test Energy et Time / Important /urgent
Material(
child:
Container(
// color: Colors.red,
alignment: Alignment.center,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children:[
//Important
FlatButton(
child:
InkWell(
child: Container(
// color: Colors.white,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
isImportant =="true" ? Icon(Icons.star,color: Colors.orange,) :
Icon(Icons.star_border, color: Colors.grey,),
// Icon(Icons.battery_charging_full),
Text('Important'),
],
)
),
onTap: () {
setState(() {
if (isImportant=='true'){
isImportant = 'false';}
else
{isImportant= 'true';
}
});
},
),
),
RaisedButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text(
"Close",
style: TextStyle(color: Colors.white),
),
color: const Color(0xFF1BC0C5),
)
//++++++++++++++++
],
),
),
),
);
});
},
),
),
),
),
),
),
]
);
}).toList(),
);
}),
),
],
),
bottomNavigationBar: MyBottomAppBar(), //PersistentBottomNavBar(),
);
}
}
#override
Widget build(BuildContext context){
return _widget();
}
}
Thanks to your solution, I am able to do what I was willing to do. But now, I have an other issue. In the version 1 of my code, I am using this code
Theme(
data: ThemeData(
inputDecorationTheme: InputDecorationTheme(
border: InputBorder.none,
)
),
child: Padding(
padding: const EdgeInsets.fromLTRB(8.0, 0.0, 15.0, 1.0),
child: TextFormField(
initialValue: document.data()['task_Name'],
decoration: InputDecoration(hintText: "Task Name"),
maxLength: 70,
maxLines: 2,
onChanged: (valProjectName) => setState(() => _valueTaskNameChanged = valProjectName),
validator: (valProjectName) {
setState(() => _valueTaskNameToValidate = valProjectName);
return valProjectName.isEmpty? "Task name cannot be empty" : null;
},
onSaved: (valProjectName) => setState(() => _valueTaskNameSaved = valProjectName),
),
)),
This part was working well. But after the modifications, I am getting an error. The error is about document.
Undefined name 'document'. Try correcting the name to one that is defined, or defining the name.
Please, can you help me with this so I can finalize this page. Thank you
So you want to change the color of icon on clicking it inside dialogBox,
but unfortunately you are using stateless widget Scaffold in return of showGeneralDialog builder so one thing that can possibly help is to make a separate StateFull Widget RatingDialogBox and use that in the builder.
Also instead of InkWell you can use IconButton
I will suggest you to use this package it is great
flutter_rating_bar
also feel free to comment is this doesn't satisfy your need
My Scrollview not Responding, can someone tell what I am missing in code:
Please Suggest me how to add scroll view listener I'm beginner.
import 'package:flutter/material.dart';
import 'package:share/share.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:url_launcher/url_launcher.dart';
import '../main.dart';
import 'favourite_articles.dart';
import 'coin_system.dart';
class Settings extends StatefulWidget {
#override
_SettingsState createState() => _SettingsState();
}
class _SettingsState extends State<Settings> {
bool _notification = false;
ScrollController _controller;
#override
void initState() {
super.initState();
checkNotificationSetting();
}
checkNotificationSetting() async {
final prefs = await SharedPreferences.getInstance();
final key = 'notification';
final value = prefs.getInt(key) ?? 0;
if (value == 0) {
setState(() {
_notification = false;
});
} else {
setState(() {
_notification = true;
});
}
}
saveNotificationSetting(bool val) async {
final prefs = await SharedPreferences.getInstance();
final key = 'notification';
final value = val ? 1 : 0;
prefs.setInt(key, value);
if (value == 1) {
setState(() {
_notification = true;
});
} else {
setState(() {
_notification = false;
});
}
Future.delayed(const Duration(milliseconds: 500), () {
Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (BuildContext context) => MyHomePage()));
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
centerTitle: true,
title: Text(
'More',
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 20,
fontFamily: 'Poppins'),
),
elevation: 5,
backgroundColor: Colors.white,
actions: <Widget>[
IconButton(
icon: Icon(Icons.mail),
color: Colors.black,
tooltip: 'Song Request',
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => CoinSystem(),
),
);
})
],
),
body: Container(
decoration: BoxDecoration(color: Colors.white),
child: SingleChildScrollView(
controller: _controller,
scrollDirection: Axis.vertical,
child: Column(
children: <Widget>[
Container(
alignment: Alignment.center,
padding: EdgeInsets.fromLTRB(0, 20, 0, 10),
child: Image(
image: AssetImage('assets/icon.png'),
height: 50,
),
),
Container(
alignment: Alignment.center,
padding: EdgeInsets.fromLTRB(0, 10, 0, 20),
child: Text(
"Version 2.1.0 \n ",
textAlign: TextAlign.center,
style: TextStyle(height: 1.6, color: Colors.black87),
),
),
Divider(
height: 10,
thickness: 2,
),
//ListWheelScrollView(
ListView(
//itemExtent: 75,
shrinkWrap: true,
children: <Widget>[
InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => FavouriteArticles(),
),
);
},
child: ListTile(
leading: Image.asset(
"assets/more/favourite.png",
width: 30,
),
title: Text('Favourite'),
subtitle: Text("See the saved songs"),
),
),
//Song Request Code
InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => CoinSystem(),
),
);
},
child: ListTile(
leading: Image.asset(
"assets/more/songrequest.png",
width: 30,
),
title: Text('Songs Request'),
subtitle: Text("Request your favourite songs"),
),
),
//Song Request Code End
ListTile(
leading: Image.asset(
"assets/more/notification.png",
width: 30,
),
isThreeLine: true,
title: Text('Notification'),
subtitle: Text("Change notification preference"),
trailing: Switch(
onChanged: (val) async {
await saveNotificationSetting(val);
},
value: _notification),
),
],
)
],
),
),
),
//),
);
//);
}
}
So, I have tried SingleChildScrollView, in that I have Container and Listview. But Listview doesn't response on scrolling action in landscape mode.
I have added ScrollController _controller; Do i have to create _controller class that listern the scrolling action?
In my understanding, you want to be able to get 2 scrolling. 1. using SingleChildScrollView and inside that Widget, you want to be able to scroll the bottom layer, thus you use ListView. To make it work, you have to place your ListView inside widget that has certain height. Example this implementation is:
SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Column(
children: <Widget>[
SizedBox(child: Text('Upper scrollable'), height: 450),
Divider(
height: 10,
thickness: 2,
),
Container(
height: 350,
child: ListView(
shrinkWrap: true,
children: <Widget>[
Container(
color:Colors.red,
child: SizedBox(child: Text('Bottom scrollable'), height: 450),
),
],
),
)
],
),
),
If you don't want to use 2 scroll, don't use ListView inside SingleChildScrollView.
ListView cannot be wrapped with SingleChildScrollView remove it
surround ListView with Expanded Widget
try one of the two alternatives.
I'm a guy from android development and I'm in love with flutter. But I have experienced some issues with ListView, with this kind of problem is like the Main Thread is doing a lot of jobs and I resolve this using AsyncTask on android but in Flutter, this is giving to me in official documents.
Since Flutter is single threaded and runs an event loop (like
Node.js), you don’t have to worry about thread management or spawning
background threads. If you’re doing I/O-bound work, such as disk
access or a network call, then you can safely use async/await and
you’re all set. If, on the other hand, you need to do computationally
intensive work that keeps the CPU busy, you want to move it to an
Isolate to avoid blocking the event loop, like you would keep any sort
of work out of the main thread in Android.
In my home it is a stateful widget and here is the code :
return new WillPopScope(
onWillPop: () async => false,
child: Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
automaticallyImplyLeading: false,
centerTitle: true,
backgroundColor: ThemeColor.AppPrimaryColor, // status bar color
brightness: Brightness.dark, // status bar brightness
elevation: 5,
title: AppBarContent(),
),
drawer: MenuBar(),
body: Container(
child: SingleChildScrollView(
controller: _scrollController,
child: Column(
children: <Widget>[
Column(
children: <Widget>[
Container(
child: CategorySlider(),
),
SizedBox(
height: screenHeight * 0.02,
),
Container(
child: BannerSlider(),
),
SizedBox(
height: screenHeight * 0.03,
),
Container(
child: Container(
margin: EdgeInsets.only(left: 20.0),
child: Row(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Text(
'Vitrines em destaque',
style: CustomFontStyle.titleList(),
),
],
),
),
),
Padding(
padding: const EdgeInsets.all(9.0),
child: CompanyList(true),
),
],
),
],
),
),
),
),
);
In bottom I have this line that calls a widget CompanyList:
Padding(
padding: const EdgeInsets.all(9.0),
child: CompanyList(true),
),
And this is my CompanyList class
class CompanyList extends StatefulWidget {
final filtered;
final isShrink;
final MasterCategoryModel masterCategoryModel;
CompanyList(
[this.isShrink = false, this.masterCategoryModel, this.filtered = false]);
// const CompanyList({Key key}) : super(key: key);
#override
State<StatefulWidget> createState() => new CompanyListState();
}
class CompanyListState extends State<CompanyList> {
CompanyController companyController = new CompanyController();
CompanyService companyService;
Map<String, dynamic> companyList = {};
bool loadingData = true;
bool loadData = true;
bool loadMoreData = false;
int pageCounter = 1;
#override
void initState() {
super.initState();
companyService = Provider.of<CompanyService>(context, listen: false);
companyService.loadMoreData$.listen((value) {
if (value) {
if (loadData) {
loadData = false;
getMoreData();
}
}
});
widget.filtered
? getCompanyByMsCateg(widget.masterCategoryModel)
: getRandomActiveCompanys();
}
#override
void dispose() {
super.dispose();
}
getRandomActiveCompanys() {
setState(() {
loadingData = true;
});
companyController.getRandomActiveCompanys(pageCounter).then((value) {
setState(() {
pageCounter++;
companyList = value;
loadingData = false;
});
}).catchError((error) {
print(error);
setState(() {
loadingData = false;
});
});
}
getMoreData() {
setState(() {
loadMoreData = true;
});
companyController.getRandomActiveCompanys(pageCounter).then((value) {
setState(() {
pageCounter++;
companyList['data'] = companyList['data']..addAll(value['data']);
loadMoreData = false;
});
}).catchError((error) {
print(error);
setState(() {
loadMoreData = false;
});
});
}
getCompanyByMsCateg(MasterCategoryModel masterCategoryModel) {
setState(() {
loadingData = true;
});
companyController
.getCompanysByMsgCateg(masterCategoryModel.master_category_id)
.then((value) {
setState(() {
companyList.addAll(value);
loadingData = false;
});
}).catchError((error) {
print(error);
setState(() {
loadingData = false;
});
});
}
getMoreCompanyData() {
setState(() {
// companyList.add(totalCompanyList[i]);
});
Future.delayed(const Duration(milliseconds: 3000), () {
loadData = true;
});
}
getCompanyData(company) {
Navigator.push(
context,
PageTransition(
type: PageTransitionType.rightToLeft,
child: CompanyScreen(
company: company,
),
),
);
}
#override
Widget build(BuildContext context) {
final double screenHeight = MediaQuery.of(context).size.height;
final double screenWidth = MediaQuery.of(context).size.width;
return !loadingData
? ListView.builder(
addAutomaticKeepAlives: true,
shrinkWrap: widget.isShrink ? true : false,
physics: ClampingScrollPhysics(),
padding: const EdgeInsets.all(8),
itemCount: companyList['data'].length,
itemBuilder: (BuildContext context, int index) {
return GestureDetector(
onTap: () => getCompanyData(companyList['data'][index]),
child: Container(
child: Column(
children: <Widget>[
Row(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Flexible(
flex: 2,
child: Container(
height: screenHeight * 0.12,
decoration: new BoxDecoration(
border: Border.all(
color: ThemeColor.AppBorderGrey,
),
borderRadius: new BorderRadius.only(
topLeft: const Radius.circular(5.0),
bottomLeft: const Radius.circular(5.0),
),
),
child: Center(
child:
companyList['data'][index]['image'] != null
? Container(
height: 45,
width: 45,
child: ClipRRect(
borderRadius: BorderRadius.all(
Radius.circular(20.0)),
child: Image.network(
'${MainConfig.storageDoc + companyList['data'][index]['image']}',
width: 42,
height: 42,
cacheWidth: 42,
cacheHeight: 42,
fit: BoxFit.cover,
),
),
)
: new Container(
width: screenWidth * 0.13,
height: screenWidth * 0.13,
decoration: new BoxDecoration(
shape: BoxShape.circle,
image: new DecorationImage(
fit: BoxFit.fill,
image: AssetImage(
'assets/icons/error/no_image_v2.png'),
),
),
),
),
),
),
Flexible(
flex: 3,
child: Container(
height: screenHeight * 0.12,
decoration: new BoxDecoration(
border: Border.all(
color: ThemeColor.AppBorderGrey,
),
borderRadius: new BorderRadius.only(
topRight: const Radius.circular(5.0),
bottomRight: const Radius.circular(5.0),
),
),
child: Center(
child: Text(
'${companyList['data'][index]['storename']}',
),
),
),
),
],
),
SizedBox(
height: 10.0,
),
],
),
),
);
})
: Center(
child: Column(
children: <Widget>[
SizedBox(
height: 10.0,
),
Center(
child: SpinKitThreeBounce(
color: ThemeColor.AppPrimaryColor,
size: 30.0,
),
),
],
),
);
}
}
If I change page and go back, my application always junk and close so I make some research and find that problem was a problem with CacheImages so in GitHub I find a solution for put a fixed cacheWidth and cacheHeight and this make my app don't crash but have junk. So I'm thinking of isolating the function that load this widget. What I must do?
child: Image.network(
'${MainConfig.storageDoc + companyList['data'][index]['image']}',
width: 42,
height: 42,
cacheWidth: 42,
cacheHeight: 42,
fit: BoxFit.cover,
),