I am working on an application to set wallpapers, which comes to the application through the link "imgUrl", but when I want to set a specific image as wallpaper it gives me this error,
[ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: MissingPluginException(No implementation found for method requestPermissions on channel flutter.baseflow.com/permissions/methods)
I hope you will give me an easy way to set an image as a wallpaper and also a way to save the image inside the device,
Note: I am using flutter for Android only
import 'package:flutter/material.dart';
import 'package:gallery_saver/gallery_saver.dart';
import 'package:get/get.dart';
import 'package:image_downloader/image_downloader.dart';
import 'package:flutter/services.dart';
import 'dart:async';
import 'dart:io';
import 'dart:async';
import 'dart:typed_data';
import 'package:dio/dio.dart';
import 'package:image_gallery_saver/image_gallery_saver.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:wallpaper/wallpaper.dart';
class ImgDetails extends StatefulWidget {
#override
_ImgDetailsState createState() => _ImgDetailsState();
}
class _ImgDetailsState extends State<ImgDetails> {
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
var imgPath ;
String home = "Home Screen",
lock = "Lock Screen",
both = "Both Screen",
system = "System";
String _title = Get.arguments['title'];
String _imgUrl = Get.arguments['url'];
#override
Widget build(BuildContext context) {
final snackBar = SnackBar(
content: Text(_title),
duration: const Duration(seconds:3),
);
return Scaffold(
appBar: AppBar(
title: Text(_title),
centerTitle: true,
),
key: _scaffoldKey,
body: Stack(
alignment: Alignment.bottomCenter,
children: [
Container(
height: double.infinity,
child: InteractiveViewer(
maxScale: 6,
child: FadeInImage(
image: NetworkImage(_imgUrl),
placeholder: AssetImage('assets/img/img_ot_found.jpg'),
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
width: MediaQuery.of(context).size.width*0.8,
height: MediaQuery.of(context).size.height*0.08,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50),
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [Colors.purple , Colors.purpleAccent]
)
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
IconButton(icon: Icon(Icons.save_alt_rounded , color: Colors.white,size: 32), onPressed: (){
}),
IconButton(icon: Icon(Icons.imagesearch_roller, color: Colors.white,size: 32), onPressed: (){
_modal();
}),
IconButton(icon: Icon(Icons.info_outline, color: Colors.white,size: 32,), onPressed: (){
_scaffoldKey.currentState.showSnackBar(snackBar);
}),
],
),
),
),
],
),
);
}
_askPermission() async {
if (Platform.isAndroid) {
await PermissionHandler().requestPermissions([
PermissionGroup.storage,
PermissionGroup.camera,
PermissionGroup.location,
]);
} else {
await PermissionHandler()
.checkPermissionStatus(PermissionGroup.storage);
}
}
_modal() {
showModalBottomSheet(
backgroundColor: Colors.white.withOpacity(0.2),
elevation: 0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30,)),
context: context,
builder: (BuildContext context) {
return Container(
height: 130,
decoration: BoxDecoration(
color: Colors.black.withOpacity(0.8),
borderRadius: BorderRadius.only(
topLeft: Radius.circular(30),
topRight: Radius.circular(30),
)
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
_createTile(context, 'Home Screen', Icons.home, _action1),
SizedBox(height: 10,),
_createTile(context, 'Lock Screen', Icons.lock, _action2),
],
),
);
}
);
}
ListTile _createTile(BuildContext context, String name, IconData icon,
Function action) {
return ListTile(
leading: Icon(icon,
color: Colors.blueAccent,),
title: Text(name,
style: TextStyle(
color: Colors.white, fontWeight: FontWeight.w500, fontSize: 20),),
onTap: () {
Navigator.pop(context);
action();
},
);
}
_action1() async {
if (Platform.isAndroid) {
await _askPermission();
}
var response = await Dio()
.get(_imgUrl, options: Options(responseType: ResponseType.bytes));
//await ImageGallerySaver.saveImage(Uint8List.fromList(response.data));
home = await Wallpaper.homeScreen(_imgUrl);
final result = home = home;
print(result);
}
_action2() async {
if (Platform.isAndroid) {
await _askPermission();
}
var response = await Dio()
.get(_imgUrl, options: Options(responseType: ResponseType.bytes));
//await ImageGallerySaver.saveImage(Uint8List.fromList(response.data));
home = await Wallpaper.lockScreen(_imgUrl);
final result = home = lock;
print(result);
}
}
You are having a problem with the permission. You need to add a permission code to the AndroidManifest file. Can you send me all the error logs so I can figure out what privilege is missing?
Related
I get this error: Undefined name 'mounted' in the future fetchoffers widget. Can anyone help me with this problem? I want to use this to make in app purchases work in my flutter app.
import 'package:flutter/material.dart';
import 'package:AnyKnower/chatgpt.dart';
import 'package:AnyKnower/privacypolicy.dart';
import 'package:AnyKnower/purchase_api.dart';
import 'package:AnyKnower/utils.dart';
import 'package:glassfy_flutter/models.dart';
import 'package:provider/provider.dart';
import 'chat_screen.dart';
import 'package:page_transition/page_transition.dart';
import 'glassfy_provider.dart';
class NavBar extends StatelessWidget {
bool isSubscribed = false;
#override
Widget build(BuildContext context) {
return Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: [
ClipRRect(
borderRadius: BorderRadius.only(
topRight: Radius.circular(15),
),
child: UserAccountsDrawerHeader(
accountName: Text('AnyKnower'),
accountEmail: Text(''),
currentAccountPicture: CircleAvatar(
child: ClipOval(
child: Image.asset('assets/logo4.jpg', width: 100, height: 100, fit: BoxFit.cover),
),
),
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/background1.jpg"),
fit: BoxFit.cover,
),
),
),
),
ListTile(
leading: Icon(Icons.chat_rounded,color: Colors.blueGrey,),
title: Text("AnyKnower Chat"),
onTap: () {
Navigator.of(context).push(PageTransition(child: ChatScreen(), type: PageTransitionType.fade));
}
),
ListTile(
leading: Icon(Icons.shopping_cart_outlined,color: Colors.blueGrey,),
title: Text("The AnyKnower Shop"),
onTap: () {
fetchOffers(context);
}
),
ListTile(
leading: Icon(Icons.chat_outlined,color: Colors.blueGrey,),
title: Text("Beta Premium chat"),
onTap: () {
Navigator.of(context).push(PageTransition(child: chatgpt(), type: PageTransitionType.fade));
}
),
ListTile(
leading: Icon(Icons.privacy_tip_outlined,color: Colors.blueGrey,),
title: Text("Privacy Policy"),
onTap: () {
Navigator.of(context).push(PageTransition(child: privacypolicy(), type: PageTransitionType.fade));
}
),
],
)
);
}
Future fetchOffers(BuildContext context) async {
final offerings = await PurchaseApi.fetchOffers();
final offer = offerings.singleWhere((offering) => offering.offeringId == '100AnyKnowerCredit');
if(!mounted) return;
Utils.showSheet(
context,
(context) => PayWallWidget(
title: 'Upgrade your plan',
description: 'kkdkdd',
offer: offer,
onClickedSku: (sku) async {
final transaction = await PurchaseApi.purchaseSku(sku);
if (mounted!) return;
if (transaction != null) {
final provider = context.read<GlassfyProvider>();
provider.add10Coins();
}
Navigator.pop(context);
},
)
);
}
}
Do i maybe need to import something? I saw by an other post that it needed to be an statefullwidget but what do i need to change to make that happen then?
Thank You Yeasin Sheikh for the right solution.
My solution is to use if (!context.mounted) return; instead of if(!mounted) return;
im new to flutter and i got a problem on my app,
firstly i was creating a button on my "ReminderPage" to navigate to a different page "AddReminder". it works before, so i try to add BottomNavigator in my "MainPage", but when i add a bottom navigatation from "HomePage" to "ReminderPage" all of the sudden the button didnt work, i also have an icon to change the theme, but the button didnt work and the background all of the sudden become blue, i dont know how this error happen so i need help from all of you guys, thank you
here is my "ReminderPage" code
import 'package:date_picker_timeline/date_picker_timeline.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:medreminder/Reminder/services/notification_services.dart';
import 'package:medreminder/Reminder/services/theme_services.dart';
import 'package:intl/intl.dart';
import 'package:medreminder/Reminder/ui/theme.dart';
import 'package:medreminder/Reminder/ui/widgets/add_remindbar.dart';
import 'package:medreminder/Reminder/ui/widgets/button.dart';
import 'package:medreminder/Reminder/ui/widgets/add_remindbar.dart';
class ReminderHomePage extends StatefulWidget {
const ReminderHomePage({super.key});
#override
State<ReminderHomePage> createState() => _ReminderHomePageState();
}
class _ReminderHomePageState extends State<ReminderHomePage> {
DateTime _selectedDate = DateTime.now();
var notifyHelper;
#override
void initState() {
// TODO: implement initState
super.initState();
notifyHelper=NotifyHelper();
notifyHelper.initializeNotification();
}
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: _appBar(),
backgroundColor: context.theme.backgroundColor,
body: Column(
children: [
_addTaskBar(),
_addDateBar(),
],
),
);
}
_addDateBar(){
return Container(
margin: const EdgeInsets.only(top: 20, left: 20),
child: DatePicker(
DateTime.now(),
height: 100,
width: 80,
initialSelectedDate: DateTime.now(),
selectionColor: Color(0xFFAAB6FB),
selectedTextColor: Colors.white,
dateTextStyle: GoogleFonts.lato(
textStyle: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w600,
color:Colors.grey
),
),
dayTextStyle: GoogleFonts.lato(
textStyle: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
color:Colors.grey
),
),
monthTextStyle: GoogleFonts.lato(
textStyle: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w600,
color:Colors.grey
),
),
onDateChange: (date){
_selectedDate=date;
},
),
);
}
_addTaskBar(){
return Container(
margin: const EdgeInsets.only(left: 20, right: 20, top: 5),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
margin: const EdgeInsets.symmetric(horizontal: 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(DateFormat.yMMMMd().format(DateTime.now()),
style: subHeadingStyle,
),
Text("Today",
style: headingStyle,
)
],
),
),
MyButton(label: "Add Reminder", onTap: ()=>Get.to(AddReminderPage()))
],
),
);
}
_appBar(){
return AppBar(
elevation: 0,
backgroundColor: context.theme.backgroundColor,
leading: GestureDetector(
onTap: (){
ThemeService().switchTheme();
notifyHelper.displayNotification(
title:"Theme Changed!",
body: Get.isDarkMode?"Activated Light Theme!":"Activated Dark Theme!"
);
notifyHelper.scheduledNotification();
},
child: Icon(Get.isDarkMode ?Icons.wb_sunny_outlined:Icons.nightlight_round,
size: 20,
color:Get.isDarkMode ? Colors.white:Colors.black
),
),
actions: [
CircleAvatar(
backgroundImage: AssetImage(
"images/profile.png"
),
),
// Icon(Icons.person,
// size: 20,),
SizedBox(width: 20,),
],
);
}
}
here is my BottomNavigator code
import 'package:flutter/material.dart';
import 'package:medreminder/Reminder/ui/home_reminder.dart';
import 'package:medreminder/Reminder/ui/widgets/add_remindbar.dart';
import 'package:medreminder/home_page.dart';
import 'package:medreminder/profile_page.dart';
import 'package:medreminder/settings_page.dart';
import 'package:get/get.dart';
import 'package:intl/intl.dart';
import 'package:medreminder/Reminder/ui/theme.dart';
void main() => runApp(MaterialApp(home: MainPage()));
class MainPage extends StatefulWidget {
const MainPage({super.key});
#override
State<MainPage> createState() => _MainPageState();
}
class _MainPageState extends State<MainPage> {
List <Widget> pages = [
HomePage(),
SettingPage(),
ProfilePage()
];
int currentIndex = 0;
void onTap(int index){
setState(() {
currentIndex = index;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
width: MediaQuery.of(context).size.width,
//height: MediaQuery.of(context).size.height * 0.4,
child: pages[currentIndex]
),
bottomNavigationBar: BottomNavigationBar(
type: BottomNavigationBarType.shifting,
onTap: onTap,
currentIndex: currentIndex,
selectedItemColor: bluishClr,
unselectedItemColor: Colors.black,
showUnselectedLabels: false,
showSelectedLabels: false,
items: [
BottomNavigationBarItem(label: "Home", icon: Icon(Icons.home)),
BottomNavigationBarItem(label: "Settings", icon: Icon(Icons.settings)),
BottomNavigationBarItem(label: "Profile", icon: Icon(Icons.account_circle)),
],
),
);
}
}
and lastly here is my HomePage code
import 'package:flutter/material.dart';
import 'package:get/get_core/src/get_main.dart';
import 'package:get/get_navigation/get_navigation.dart';
import 'Reminder/ui/home_reminder.dart';
import 'Reminder/ui/widgets/button.dart';
void main() {
// debugPaintSizeEnabled = true;
runApp(const HomePage());
}
class HomePage extends StatelessWidget {
const HomePage({super.key});
#override
Widget build(BuildContext context) {
return GetMaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(
title: const Text('Medicine Reminder App'),
),
body: Column(children: [
Stack(
children: [
Image.asset(
'images/MenuImg.jpg',
width: 600,
height: 200,
fit: BoxFit.cover,
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
TextButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(Colors.black)),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const ReminderHomePage()),
);
},
child: Text("Button1"),
),
TextButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(Colors.black)),
onPressed: () {},
child: Text("Button2"),
),
TextButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(Colors.black)),
onPressed: () {},
child: Text("Button3"),
),
],
)
]),
),
);
}
}
i really need a help, so every help would mean so much to me, thankyou guys
here is my app working perfectly when i run only the ReminderPage
https://i.stack.imgur.com/JqcZp.png
and here's how it look if i run it with BottomNavigationBar (the add reminder button and moon icon cant be clicked)
https://i.stack.imgur.com/9hVr8.png
Try the following code:
Navigator.of(context, rootNavigator: true).push(
MaterialPageRoute(builder: (context) => const ReminderHomePage())
);
try this
Navigator.of(context, rootNavigator: true).push(
context,
MaterialPageRoute(builder: (context) => const ReminderHomePage()),
);
So basically I wanted to disable the button at first until or if the user enters a certain radius then the button would be enabled again but I'm not sure how to do it so here's the example of my code which i wanted to disable the button on the 'Reserve parking' button. Here's the code to the page.
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:parkingtechproject/Screens/reportfeedback.dart';
import 'package:parkingtechproject/authenticate/sign_in.dart';
import 'package:parkingtechproject/model/parking.dart';
import 'car_reservation.dart';
import 'maps.dart';
import 'profile_page.dart';
class Home extends StatefulWidget{
#override
State<Home> createState() => _HomeState();
}
class _HomeState extends State<Home> {
late String _timeString;
bool isButtonActive = true;
//firebase instance
User? user = FirebaseAuth.instance.currentUser;
Parking loginuser = Parking();
#override
void initState(){
super.initState();
FirebaseFirestore.instance
.collection('parkingTech')
.doc(user!.uid)
.get()
.then((value){
this.loginuser = Parking.fromMap(value.data());
setState(() {});
});
}
//Sign Out
Future <void> logout(BuildContext context) async {
await FirebaseAuth.instance.signOut();
Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (context) => LoginScreen()));
}
// void initState(){
// _timeString = "${DateTime.now().hour} : ${DateTime.now().minute} :${DateTime.now().second}";
// Timer.periodic(Duration(seconds:1), (Timer t)=>_getCurrentTime());
// super.initState();
// }
Widget build(BuildContext context){
return Scaffold(
backgroundColor: Colors.amber,
appBar: AppBar(
backgroundColor: Colors.amber,
elevation: 0.0,
title: Text('Parking Tech',
style:TextStyle(
color: Color(0xFF121212),
fontWeight: FontWeight.bold,
),
),
centerTitle:true,
actions: [
IconButton(onPressed: (){
logout(context);
},
icon: Icon(
Icons.logout,
size: 25,
),
),
]
),
body: Column(
children:[
Expanded(
child: Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage(
'assets/images/Parkingtech.png'
),
// image: NetworkImage(
// 'https://www.istockphoto.com/photo/car-icon-special-black-square-button-gm624404280-109743191?utm_source=unsplash&utm_medium=affiliate&utm_campaign=srp_photos_top&utm_content=https%3A%2F%2Funsplash.com%2Fs%2Fphotos%2Fcar-icon&utm_term=car%20icon%3A%3Asearch-explore-top-affiliate-outside-feed%3Aenabled'),
fit: BoxFit.fill),
),
),
),
Expanded(
child:Container(
color: Color(0xFF121212),
width: double.infinity,
child: Padding(
padding: const EdgeInsets.all(15.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: 20),
Text("Welcome, ${loginuser.name}",
style: const TextStyle(
color: Colors.white,
fontWeight:FontWeight.normal,
fontSize: 15,
),
),
const SizedBox( height: 10),
Text("Car Plate : ${loginuser.car}",
style: const TextStyle(
color: Colors.white,
fontWeight:FontWeight.normal,
fontSize: 15,
),
),
const SizedBox( height: 10),
ClipRRect(
borderRadius: BorderRadius.circular(4),
child: Stack(
children: <Widget>[
Positioned.fill(
child: Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
colors: <Color>[
Color(0xFFF59539),
Color(0xFFF59222),
Color(0xFFD97503),
],
),
),
),
),
TextButton(
style: TextButton.styleFrom(
padding: const EdgeInsets.all(10.0),
primary: Colors.white,
textStyle: const TextStyle(fontSize: 13.1),
),
onPressed: isButtonActive?() {
setState(() {
isButtonActive = false;
});
Navigator.push(context,MaterialPageRoute(builder: (context) => Reservation()));
} : null,
child: const Text('Reserve parking? '),
),
],
),
),
const SizedBox(height: 15,),
ClipRRect(
borderRadius: BorderRadius.circular(4),
child: Stack(
children: <Widget>[
Positioned.fill(
child: Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
colors: <Color>[
Color(0xFFF62626),
Color(0xFFDB1010),
Color(0xFFC60505),
],
),
),
),
),
TextButton(
style: TextButton.styleFrom(
padding: const EdgeInsets.all(10.0),
primary: Colors.white,
textStyle: const TextStyle(fontSize: 15),
),
onPressed: () {
showDialog(context: context, builder: (context) => const FeedbackDialog());
},
child: const Text('Make a report ?'),
),
],
),
),
const SizedBox(height: 12,),
],
)
),
),
),
],
),
);
}
And here is the code to the maps page.
import 'package:easy_geofencing/easy_geofencing.dart';
import 'package:easy_geofencing/enums/geofence_status.dart';
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:provider/provider.dart';
import 'dart:async';
import 'package:geolocator/geolocator.dart';
import '../provider/location_provider.dart';
class GoogleMapPage extends StatefulWidget {
#override
_GoogleMapPageState createState() => _GoogleMapPageState();
}
class _GoogleMapPageState extends State<GoogleMapPage> {
late StreamSubscription<GeofenceStatus> geofenceStatusStream;
Geolocator geolocator = Geolocator();
String geofenceStatus = '';
bool isReady = false;
late Position position;
TextEditingController latitudeController = new TextEditingController();
TextEditingController longitudeController = new TextEditingController();
TextEditingController radiusController = new TextEditingController();
#override
void initState(){
getCurrentPosition();
super.initState();
// tz.initializeTimeZones();
Provider.of<LocationProvider>(context,listen:false).initalization();
}
getCurrentPosition() async {
position = await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.high);
print("LOCATION => ${position.toJson()}");
isReady = (position != null) ? true : false;
EasyGeofencing.startGeofenceService(
// pointedLatitude: "2.2276356",
// pointedLongitude: "102.4568397",
pointedLatitude: "2.221395",
pointedLongitude: "102.453115",
radiusMeter: "30",
eventPeriodInSeconds: 5
);
StreamSubscription<GeofenceStatus> geofenceStatusStream = EasyGeofencing.getGeofenceStream()!.listen(
(GeofenceStatus status) {
print(status.toString());
});
}
setLocation() async {
await getCurrentPosition();
print("POSITION => ${position.toJson()}");
latitudeController =
TextEditingController(text: position.latitude.toString());
longitudeController =
TextEditingController(text: position.longitude.toString());
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Hotspot Checker"),
),
body: googleMapUI(),
);
}
}
Widget googleMapUI(){
EasyGeofencing.startGeofenceService(
pointedLatitude: "2.2741204",
pointedLongitude: "102.4448842",
radiusMeter: "10",
eventPeriodInSeconds: 5
);
Set<Circle> mycircles = Set.from([Circle(
circleId: CircleId('0'),
center: LatLng(2.221395, 102.453115),
radius: 6,
strokeWidth: 1,
fillColor:(Colors.red),
),
Circle(
circleId: CircleId('1'),
center: LatLng(2.2065488, 102.2244857),
radius: 4,
strokeWidth: 1,
fillColor:(Colors.yellow),
)]);
return Consumer<LocationProvider>(
builder:(consumerContext,model,child){
if(model.locationPosition != null)
{
return Column(
children: [
Expanded(
child: GoogleMap(
mapType:MapType.normal,
initialCameraPosition: CameraPosition(
target: model.locationPosition,
zoom: 18,
),
circles: mycircles,
myLocationEnabled: true,
myLocationButtonEnabled: true,
onMapCreated: (GoogleMapController controller){
},
),
),
],
);
}
return Container(
child: Center(child: CircularProgressIndicator(),),
);
}
);
}
Basically, I'm not sure how to make both of these pages combine together.
so i want to print user name and user username in the profile page and in the end it shows it but for a few seconds there is a red screen that says The following _TypeError was thrown building Profile_page(dirty, state: _Profile_pageState#68414):
type 'Null' is not a subtype of type 'String'
this is the code of main.dart
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:gp1_7_2022/screen/auth/signup/userInfo/name.dart';
import 'package:gp1_7_2022/screen/auth/signup/Questions/question1.dart';
import 'package:gp1_7_2022/screen/auth/signup/Questions/question2.dart';
import 'package:gp1_7_2022/screen/auth/signup/Questions/question3.dart';
import 'package:gp1_7_2022/screen/auth/signup/Questions/question4.dart';
import 'package:gp1_7_2022/screen/auth/signup/Questions/question5.dart';
import 'package:gp1_7_2022/screen/auth/signup/userInfo/photo.dart';
import 'package:gp1_7_2022/screen/home/Profile_Page.dart';
import 'package:firebase_core/firebase_core.dart';
/*pages */
import 'package:gp1_7_2022/screen/auth/signup_login.dart';
import 'package:gp1_7_2022/screen/auth/signup/userAuth/signup.dart';
import 'package:gp1_7_2022/screen/auth/Login/login.dart';
import 'package:gp1_7_2022/screen/auth/signup/userAuth/signupConfirmationCode.dart';
import 'package:gp1_7_2022/screen/auth/signup/userAuth/signupPassword.dart';
import 'package:gp1_7_2022/screen/auth/signup/userInfo/signupBirthday.dart';
import 'package:gp1_7_2022/screen/auth/signup/userInfo/signupUsername.dart';
import 'package:gp1_7_2022/screen/auth/Login/forget_password.dart';
import 'package:gp1_7_2022/screen/settings.dart';
void main() async{
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(
MaterialApp(
initialRoute: "/",
routes: {
"/": (context) => MainPage(),
"/signup": (context)=> Signup(),
'/login':(context)=>Login(),
'/Profile_Page':(context) => Profile_page(uid: FirebaseAuth.instance.currentUser!.uid),
// '/confirmationCode':(context) => ConfirmationCode(),
// '/signupPassword':(context) => signupPassword(),
'/signupBirthday':(context) => SignupBirthday(),
'/signupUsername':(context) => SignupUsername(),
'/forget_password':(context) => forget_password(),
'/name':(context) => name(),
'/question1':(context) => question1(),
'/question2':(context) => question2(),
'/question3':(context) => question3(),
'/question4':(context) => question4(),
'/question5':(context) => question5(),
'/photo':(context) => Photo(),
'/settings':(context) => settings(),
}
)
);
}
class MainPage extends StatelessWidget {
const MainPage({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
body: StreamBuilder<User?>(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, snapshot){
if(snapshot.connectionState==ConnectionState.waiting){
return const Center(child: CircularProgressIndicator());
}else if(snapshot.hasError){
return const Center(child: Text("Something went wrong!"));
}else if(snapshot.hasData){
if(FirebaseAuth.instance.currentUser!.emailVerified && FirebaseAuth.instance.currentUser!.uid != null ){
String uid = FirebaseAuth.instance.currentUser!.uid;
return Profile_page(uid: uid );
}else{
String? x = FirebaseAuth.instance.currentUser!.email;
String y= x??" ";
return ConfirmationCode(email: y);
}
} else{
return const Signup_Login();
}
},
),
);
}
}
this is the code of profile_page.dart
// import 'dart:html';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:focused_menu/focused_menu.dart';
import 'package:focused_menu/modals.dart';
/*pages */
/*colors */
import 'package:gp1_7_2022/config/palette.dart';
import 'package:gp1_7_2022/Widgets/follow_button.dart';
import 'package:rflutter_alert/rflutter_alert.dart';
import 'package:gp1_7_2022/screen/settings.dart';
class Profile_page extends StatefulWidget {
final uid;
const Profile_page({Key? key, required this.uid}) : super(key: key);
#override
State<Profile_page> createState() => _Profile_pageState();
}
class _Profile_pageState extends State<Profile_page> {
var padding= 0.8;
var userData = {};
#override
void initState() {
super.initState();
getData();
}
/* get data method */
getData() async {
try {
if (widget.uid != null) {
var userSnap = await FirebaseFirestore.instance.collection('users').doc(
widget.uid).get();
userData = userSnap.data()!;
setState(() {
});
}
}
catch(e){
Alert(
context: context,
title: "Something went wrong!",
desc: e.toString(),
).show();
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Palette.backgroundColor,
appBar: AppBar(
//appBar style
elevation: 0,
backgroundColor: Palette.backgroundColor,
automaticallyImplyLeading: false,//no arrow
//username
title: Padding(
padding: EdgeInsets.fromLTRB(5, 0, 0, 0),
child: Text(
userData['username'],
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 24,
),
),
),
//setting icon
actions:[
FocusedMenuHolder(
//
menuWidth: MediaQuery.of(context).size.width * 0.4,
menuOffset: 0,
menuItemExtent: 49,
//list
menuItems: [
FocusedMenuItem(
title: const Text("Log out"),
trailingIcon: const Icon(Icons.logout),
onPressed: (){
/*go to sign up page*/
Navigator.pushNamed(context, '/');
return FirebaseAuth.instance.signOut();
}
),
FocusedMenuItem(
title: const Text("Settings"),
trailingIcon: const Icon(Icons.settings),
onPressed: (){
Navigator.of(context).popAndPushNamed('/settings');
},
),
],
openWithTap: true,
onPressed: (){},
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 24),
child: Image.asset(
"assets/menu-icon.png",
height: 25,
width: 25,
),
),
),
],
),
body: ListView(
children: [
Container(
margin: const EdgeInsets.all(16),
child: Column(
children: [
Row(
children: [
//user photo
const Padding(
padding: EdgeInsets.fromLTRB(0, 0, 40, 0),
child: CircleAvatar(
backgroundColor: Colors.white ,
child: Icon(
Icons.account_circle_sharp,
color: Colors.grey,
size: 90,
),
),
),
//end user photo
Expanded(
flex: 7,
child: Column(
children: [
SizedBox(height:40,),
//post, followers and following
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
buildStatColumn(20, "posts"),
buildStatColumn(150, "Followers"),
buildStatColumn(10, "Following"),
],
),
//end post, followers and following
],
),
),
],
),
//username
Container(
alignment: Alignment.centerLeft,
padding: EdgeInsets.fromLTRB(10, 40, 0, 0),
child: Text(
userData['name'],
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16,
),
),
),
//end of username
//bio
Container(
alignment: Alignment.centerLeft,
padding: const EdgeInsets.fromLTRB(10, 1, 0, 0),
child: const Text(
'bio',
style: TextStyle(
fontSize: 16,
),
),
),
//end of bio
//edit profile button
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
// mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
FollowButton(
text: 'Edit profile',
backgroundColor: Palette.backgroundColor,
borderColor: Palette.grey,
textColor: Colors.black,
function: () {},
)
],
),
//end of button
],
),
),
],
),
);
}
}
// function to show following/followers/# of posts
Column buildStatColumn(int num, String label) {
return Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
num.toString(),
style: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
Container(
margin: const EdgeInsets.only(top: 4),
child: Text(
label,
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.w400,
color: Colors.grey,
),
),
),
],
);
}
enter image description here
Show some other widgets until data is not fully loaded.
class _Profile_pageState extends State<Profile_page> {
...
bool _isloaded = false; // Add this boolean
In getData function
getData() async {
try {
...
setState(() {
_isloaded = true; // when data is loaded update state
});
}
...
In build, return widget according to data(user)
#override
Widget build(BuildContext context) {
return _isloaded == false ?
Center(
child: CircularProgressIndicator(), // Show indicator
)
: Scaffold(
backgroundColor: Palette.backgroundColor,
...
); //Scaffold
You're assuring flutter that the data isn't null which will result in a momentary error. You can try either setting a load bool that sets to true when the data arrives or using the ?? operator. e.g userData['name'] ?? "loading" which will print loading incase the userData['name'] is null
I hope you all are doing well today. I have another flutter issue that I have been stuck on for the past few days now. I'm attempting to upload this data to my firestore instance, but my post button never seems to be triggering. I have attempted to print a statement from the method that it evokes, but I can't seem to get that to work either. I'm attempting to create a social media app, and any and all help would be appreciated.
My main goal is to get the post button to execute in upload.dart.
I have also included home.dart since the two classes are connected in terms of performance.
upload.dart
import 'dart:io';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:fluttermedia/models/user.dart';
import 'package:fluttermedia/pages/home.dart';
import 'package:fluttermedia/widgets/progress.dart';
import 'package:image_picker/image_picker.dart';
import 'package:path_provider/path_provider.dart';
import 'package:image/image.dart' as Im;
import 'package:uuid/uuid.dart';
class Upload extends StatefulWidget {
final User currentUser;
Upload({this.currentUser});
#override
_UploadState createState() => _UploadState();
}
class _UploadState extends State<Upload> {
TextEditingController locationController = TextEditingController();
TextEditingController captionController = TextEditingController();
File file;
bool isUploading = false;
String postId = Uuid().v4();
handleChooseFromGallery() async{
Navigator.pop(context);
File file = await ImagePicker.pickImage(source: ImageSource.gallery);
setState(() {
this.file = file;
});
}
handleTakePhoto() async {
Navigator.pop(context);
File file = await ImagePicker.pickImage(source: ImageSource.camera,maxHeight: 675,maxWidth: 960);
setState(() {
this.file = file;
});
}
selectImage(parentContext){
return showDialog(
context: parentContext,
builder: (context) {
return SimpleDialog(
title: Text("Create Post"),
children: <Widget>[
SimpleDialogOption(
child: Text("Photo With Camera"),
onPressed: handleTakePhoto,
),
SimpleDialogOption(
child: Text("Image from Gallery"),
onPressed: handleChooseFromGallery,
),
SimpleDialogOption(
child: Text("Cancel"),
onPressed: () => Navigator.pop(context),
),
],
);
}
);
}
Container buildSplashScreen(){
return Container(
color: Theme.of(context).accentColor.withOpacity(0.6),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SvgPicture.asset('assets/images/upload.svg',height: 260.0,),
Padding(
padding: EdgeInsets.only(top:20.0),
child: RaisedButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0),
),
child: Text(
"Upload Image",
style: TextStyle(
color: Colors.white,
fontSize: 22.0,
),
),
color: Colors.deepOrange,
onPressed: () => selectImage(context),
),
)
],
),
);
}
clearImage(){
setState(() {
file = null;
});
}
//This compresses images for firebase
compressImage() async{
final tempDir = await getTemporaryDirectory();
final path = tempDir.path;
Im.Image imageFile = Im.decodeImage(file.readAsBytesSync());
final compressedImageFile = File('$path/img_$postId.jpg')..writeAsBytesSync(Im.encodeJpg(imageFile,quality: 85));
setState(() {
file = compressedImageFile;
});
}
Future<String> uploadImage(imageFile) async{
StorageUploadTask uploadTask = storageRef.child("post_$postId.jpg").putFile(imageFile);
StorageTaskSnapshot storageSnap = await uploadTask.onComplete;
String downloadUrl = await storageSnap.ref.getDownloadURL();
return downloadUrl;
}
//upload new info to firestore that creates a new collection
createPostInFirestore({String mediaUrl, String location, String description}){
postsRef.document(widget.currentUser.id)
.collection("userPosts")
.document(postId)
.setData({
"postId": postId,
"ownerId": widget.currentUser.id,
"username": widget.currentUser.username,
"mediaUrl": mediaUrl,
"description": description,
"location": location,
"timestamp": timeStamp,
"likes":{}
});
}
//Getting the info from the caption, location and pic
handleSubmit() async{
setState(() {
isUploading = true;
});
await compressImage();
String mediaUrl = await uploadImage(file);
createPostInFirestore(
mediaUrl: mediaUrl,
location: locationController.text,
description: captionController.text,
);
captionController.clear();
locationController.clear();
setState(() {
file = null;
isUploading = false;
});
}
Scaffold buildUploadForm(){
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.white70,
leading: IconButton(
icon: Icon(Icons.arrow_back,color: Colors.black,),
onPressed: clearImage,
),
title: Text(
"Caption Post",
style: TextStyle(color: Colors.black),
),
actions: <Widget>[
FlatButton(
onPressed: () => isUploading ? null : () => handleSubmit(),
child: Text(
"Post",
style: TextStyle(
color: Colors.blueAccent,
fontWeight: FontWeight.bold,
fontSize: 20.0,
),
),
)
],
),
body: ListView(
children: <Widget>[
isUploading ? linearProgress(context):Text(""),
Container(
height: 220.0,
width: MediaQuery.of(context).size.width*0.8,
child: Center(
child: AspectRatio(
aspectRatio: 16/9,
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
fit: BoxFit.cover,
image: FileImage(file),
)
),
),
),
),
),
Padding(
padding: EdgeInsets.only(top:10),
),
ListTile(
leading: CircleAvatar(
backgroundImage: CachedNetworkImageProvider(widget.currentUser.photoUrl),
),
title: Container(
width: 250.0,
child: TextField(
controller: captionController,
decoration: InputDecoration(
hintText: "Write a Caption...",
border: InputBorder.none,
),
),
),
),
Divider(),
ListTile(
leading: Icon(Icons.pin_drop,color: Colors.orange,size: 35.0),
title: Container(
width: 250.0,
child: TextField(
controller: locationController,
decoration: InputDecoration(
hintText: "Where was this photo taken",
border: InputBorder.none,
),
),
),
),
Container(
width: 200.0,
height: 100.0,
alignment: Alignment.center,
child: RaisedButton.icon(
label: Text(
"Use Current Location",
style: TextStyle(color: Colors.white),
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30.0),
),
color: Colors.blue,
onPressed: () => print("Get user location"),
icon: Icon(
Icons.my_location,
color: Colors.white,
),
),
)
],
),
);
}
#override
Widget build(BuildContext context) {
return file == null ? buildSplashScreen() : buildUploadForm();
}
}
home.dart
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:fluttermedia/models/user.dart';
import 'package:fluttermedia/pages/activity_feed.dart';
import 'package:fluttermedia/pages/create_account.dart';
import 'package:fluttermedia/pages/profile.dart';
import 'package:fluttermedia/pages/search.dart';
import 'package:fluttermedia/pages/upload.dart';
import 'package:google_sign_in/google_sign_in.dart';
final GoogleSignIn googleSignIn = GoogleSignIn();
final StorageReference storageRef = FirebaseStorage.instance.ref();
final usersRef = Firestore.instance.collection('users');
final postsRef = Firestore.instance.collection('posts');
final DateTime timeStamp = DateTime.now();
User currentUser;
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
bool isAuth = false;
PageController pageController;
int pageIndex = 0;
#override
void initState() {
super.initState();
pageController = PageController();
// Detects if user signs in
googleSignIn.onCurrentUserChanged.listen((account) {
handleSignIn(account);
}, onError: (err){
print('Error sigining in: $err');
});
//Reauthenticate user when app is opened
googleSignIn.signInSilently(suppressErrors: false)
.then((account) =>
handleSignIn(account)).catchError((err){
print('Error signing in on retry: $err');
});
}
#override
Widget build(BuildContext context) {
return isAuth ? buildAuthScreen() : buildUnAuthScreen();
}
#override
void dispose(){
pageController.dispose();
super.dispose();
}
//Helper Functions
//The sign in section of the code
handleSignIn(GoogleSignInAccount account){
if(account != null){
createUserInFirestore();
setState(() {
isAuth = true;
});
}else{
setState(() {
isAuth = false;
});
}
}
login(){
googleSignIn.signIn();
}
logout(){
googleSignIn.signOut();
}
onPageChanged(int pageIndex){
setState(() {
this.pageIndex = pageIndex;
});
}
createUserInFirestore() async{
// 1) Check if user exists in users collection in database (According to id)
final GoogleSignInAccount user = googleSignIn.currentUser;
DocumentSnapshot doc = await usersRef.document(user.id).get();
if(!doc.exists){
// 2) If the user doesn't exist, take them to create account page
final username = await Navigator.push(context, MaterialPageRoute(builder: (context) => CreateAccount()));
// 3) get username from create account, use it to make new user document in users collection
usersRef.document(user.id).setData({
"id":user.id,
"username":username,
"photoUrl": user.photoUrl,
"email":user.email,
"displayName": user.displayName,
"bio":"",
"timeStamp": timeStamp,
});
doc = await usersRef.document(user.id).get();
}
currentUser = User.fromDocument(doc);
//print(currentUser);
//print(currentUser.username);
}
onTap(int pageIndex){
//This what you would use to animate in between the different screens
pageController.animateToPage(
pageIndex,
duration: Duration(milliseconds: 300),
curve: Curves.easeInOut
);
}
//UI Code
Widget buildAuthScreen() {
return Scaffold(
body: PageView(
children: <Widget>[
//Timeline(),
RaisedButton(
child: Text('Logout'),
onPressed: logout,
),
ActivityFeed(),
Upload(currentUser: currentUser),
Search(),
Profile(),
],
controller: pageController,
onPageChanged: onPageChanged,
physics: NeverScrollableScrollPhysics(),
),
bottomNavigationBar: CupertinoTabBar(
currentIndex: pageIndex,
onTap: onTap,
activeColor: Theme.of(context).primaryColor,
items: [
BottomNavigationBarItem(icon: Icon(Icons.whatshot),),
BottomNavigationBarItem(icon: Icon(Icons.notifications_active),),
BottomNavigationBarItem(icon: Icon(Icons.photo_camera, size: 34.0,),),
BottomNavigationBarItem(icon: Icon(Icons.search),),
BottomNavigationBarItem(icon: Icon(Icons.account_circle),),
],
),
);
/*return RaisedButton(
child: Text('Logout'),
onPressed: logout,
);*/
}
Scaffold buildUnAuthScreen() {
return Scaffold(
body: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topRight,
end: Alignment.bottomLeft,
colors: [
Theme.of(context).primaryColor,
Theme.of(context).accentColor,
]
)
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text('FlutterMedia',
style: TextStyle(
fontFamily: "Signatra",
fontSize: 90.0,
color: Colors.white
),
),
GestureDetector(
onTap:() => login(),
child: Container(
width: 260,
height: 60,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/google_signin_button.png'),
fit: BoxFit.cover,
),
),
),
)
],
),
),
);
}
}
onPressed: () => isUploading ? null : () => handleSubmit(),
Well, there's your problem. You meant to have a tertiary condition that makes onPressed call handleSubmit when isUploading is false. Instead, you have made onPressed into a function that returns a function.
To hopefully make that more clear, let's blow this function up into proper non-lambda functions and if/else blocks:
onPressed: () {
if (isUploading) {
return null;
} else {
return () {
handleUpload();
}
}
}
So consider what happens when the button is pressed. It calls the outer function, which checks isUploading. If true, the function returns null, and if false, it returns another function that, if called, calls handleUpload. So how this plays out is that onPressed will never be null (it just returns null sometimes) and handleUpload never gets called (since the inner function that is returned is never then called itself).
Remove the outer lambda and it will work:
onPressed: isUploading ? null : () => handleSubmit(),