am new to flutter, and stuck logically on this problem :
i have a dropdown menu where the user will choose a gate from,
then show the chosen gate in the google map.
i've tried having the longitude and latitudes as global vairiables, but it didn't work . as if google map widget doesn't see it after it changes,
i also tried passing the longitude and latitudes using the navigator, with this the attributes does change in the google map but the dropdown menu stops showing the chosen item in the front.
i just want to change the google map depending on the choice of the dropdown menu.
heres my full code
import 'package:flutter/src/widgets/container.dart';
import 'package:flutter/src/widgets/framework.dart';
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import '../widgets/My_wedgits.dart';
// shmalyh 3 LatLng(21.489191114466923, 39.24285294444855)
//shmalyh 1 LatLng( 21.490190928284374, 39.24029335794148)
//west 2 LatLng(21.489312801215913, 39.239637004938416)
//double lat = 21.48880614639443;
//double leng = 39.24159501940586;
String dropdownvalue = "";
const List<String> gatelist = <String>[
'NorthGate 1',
'NorthGate 3',
'WestGate 2'
];
class homepage extends StatefulWidget {
//const homepage({super.key});
double lat;
double lan;
homepage({Key? mykey, required this.lan, required this.lat})
: super(key: mykey);
#override
State<homepage> createState() => _homepageState();
}
class _homepageState extends State<homepage> {
DropdownButtonExample mydropdown = DropdownButtonExample();
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
toolbarHeight: 60,
centerTitle: true,
title: const Text(
'Wajeeh',
style: TextStyle(
fontSize: 28,
),
),
elevation: 10,
backgroundColor: const Color.fromARGB(255, 4, 105, 55),
leading: Padding(
padding: const EdgeInsets.all(6.0),
child: Image.asset(
'images/logo2.png',
height: 30,
),
),
),
backgroundColor: Colors.white,
body: Column(
children: [
const SizedBox(
height: 70,
),
Row(
// ignore: prefer_const_literals_to_create_immutables
children: [
Expanded(
child: Align(
alignment: Alignment.topCenter,
child: SizedBox(
width: 250,
child: mydropdown,
),
)),
],
),
const SizedBox(
height: 45,
),
Row(
children: [
Expanded(
child: Column(
children: [
Image.asset('images/full.jpg'),
const Text(
'Total Parking',
style: TextStyle(
fontSize: 22.0,
fontWeight: FontWeight.bold,
color: Color.fromARGB(255, 0, 0, 0)),
),
const Text(
'33',
style: TextStyle(
fontSize: 22.0,
fontWeight: FontWeight.bold,
color: Color.fromARGB(255, 4, 105, 55)),
),
],
)),
Expanded(
child: Column(
children: [
Image.asset('images/remain.jpg'),
const Text(
'Available Parking',
style: TextStyle(
fontSize: 22.0,
fontWeight: FontWeight.bold,
color: Color.fromARGB(255, 0, 0, 0)),
),
const Text(
"100",
style: TextStyle(
fontSize: 22.0,
fontWeight: FontWeight.bold,
color: Color.fromARGB(255, 4, 105, 55)),
),
],
))
],
),
//here where the map should be
const SizedBox(
height: 70,
),
Row(
// ignore: prefer_const_literals_to_create_immutables
children: [
Expanded(
child: Align(
alignment: Alignment.topCenter,
child: SizedBox(
width: 355,
height: 315,
child: Stack(
children: [
GoogleMap(
initialCameraPosition: CameraPosition(
target: LatLng(widget.lan, widget.lat),
zoom: 16,
),
),
Container(
alignment: Alignment.topLeft,
child: const Icon(
Icons.star,
color: Color.fromARGB(255, 231, 210, 23),
size: 40,
),
),
],
),
),
)),
],
),
],
));
}
// ignore: unused_element
}
class DropdownButtonExample extends StatefulWidget {
const DropdownButtonExample({super.key});
#override
State<DropdownButtonExample> createState() => _DropdownButtonExampleState();
/*Widget goodglemap() {
return GoogleMap(
initialCameraPosition: CameraPosition(
target: LatLng(lat, leng),
zoom: 16,
),
);
}*/
}
class _DropdownButtonExampleState extends State<DropdownButtonExample> {
double lat = 21.48880614639443;
double leng = 39.24159501940586;
String dropdownValue = gatelist.first;
// ignore: avoid_print
#override
Widget build(BuildContext context) {
return DropdownButton<String>(
hint: const Text("Choose a Gate"),
isExpanded: true,
value: dropdownValue,
icon: const Icon(Icons.arrow_drop_down_sharp),
style: const TextStyle(color: const Color.fromARGB(255, 4, 105, 55)),
underline: Container(
height: 2,
color: const Color.fromARGB(255, 4, 105, 55),
),
onChanged: (String? value) {
// This is called when the user selects an item.
setState(() {
dropdownValue = value!;
//see if i can reach the other classs from here
if (identical(dropdownValue, "NorthGate 1")) {
lat = 21.490190928284374;
leng = 39.24029335794148;
}
//see if i can reach the other classs from here
if (identical(dropdownValue, "NorthGate 3")) {
lat = 21.489191114466923;
leng = 39.24285294444855;
}
if (identical(dropdownValue, "WestGate 2")) {
lat = 21.489312801215913;
leng = 39.239637004938416;
}
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => homepage(lat: lat, lan: leng)));
});
},
items: gatelist.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(
value,
),
);
}).toList(),
);
}
Widget goodglemap() {
return GoogleMap(
initialCameraPosition: CameraPosition(
target: LatLng(lat, leng),
zoom: 16,
),
);
}
}
Related
I ran into a snag while using the scroll_date_picker package. I succeeded in marking the scroll as shown in the figure below, but I want only the year to be displayed and scrolled, not all of the year, month, and day. How would I recommend changing _selectedDate in this case?
This is my code.
import 'package:flutter/material.dart';
import 'package:scroll_date_picker/scroll_date_picker.dart';
import 'package:shipda/constants.dart';
class BuiltYearChoice extends StatefulWidget {
const BuiltYearChoice({Key? key}) : super(key: key);
#override
State<BuiltYearChoice> createState() => _BuiltYearChoiceState();
}
class _BuiltYearChoiceState extends State<BuiltYearChoice> {
DateTime _selectedDate = DateTime.now();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: baseColor10,
elevation: 0,
leading: TextButton(
onPressed: () {},
child: Text('Reset'),
),
title: Text(
'Example',
style: titleMediumBase50(),
),
centerTitle: true,
actions: [
IconButton(
onPressed: () {
Navigator.pop(context);
},
icon: Icon(
Icons.close,
color: baseColor50,
),
),
],
),
body: Padding(
padding: const EdgeInsets.fromLTRB(48, 16, 48, 16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Column(
children: [
Text(
'min',
// '최소진수년도',
style: TextStyle(
fontSize: bodyMedium,
fontFamily: 'regular',
color: Colors.grey.shade500,
),
),
marginHeight4,
Text(
'0000',
style: TextStyle(
fontSize: 32,
fontFamily: 'bold',
),
),
],
),
Column(
children: [
Text(''),
Text(
'~',
style: TextStyle(
fontSize: 32,
fontFamily: 'bold',
color: Colors.grey.shade400,
),
),
],
),
Column(
children: [
Text(
'max',
// '최대진수년도',
style: TextStyle(
fontSize: bodyMedium,
fontFamily: 'regular',
color: Colors.grey.shade500,
),
),
marginHeight4,
Text(
'0000',
style: TextStyle(
fontSize: 32,
fontFamily: 'bold',
),
),
],
),
],
),
SizedBox(
height: 300,
child: ScrollDatePicker(
locale: Locale('ko'),
selectedDate: _selectedDate,
onDateTimeChanged: (DateTime value) {
setState(() {
_selectedDate = value;
});
}),
)
],
),
),
);
}
}
You can make your CustomPicker, something like this:
import 'package:flutter/material.dart';
class CustomPicker extends StatelessWidget {
final List<DateTime> list;
const CustomPicker(this.list, {Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
// define item height
double itemHeight = 30;
var middleIndex = (list.length / 2).floor(); // index of the middle item
var scrollController = ScrollController(
// if you want middle item to be pre-selected
initialScrollOffset: middleIndex * itemHeight,
);
int numberOfItemsToBeVisible = 5;
double pickerHeight = itemHeight * numberOfItemsToBeVisible;
// or you can pass index of the item you want to be visible
var selectedItem = ValueNotifier(list[middleIndex]);
// changing selected item on scroll
scrollController.addListener(() {
selectedItem.value = list[(scrollController.offset / itemHeight).round()];
});
return Column(
children: [
Stack(
children: [
Positioned.fill(
child: Center(
child: Container(
height: itemHeight,
width: MediaQuery.of(context).size.width,
decoration: ShapeDecoration(
color: Colors.grey.shade300,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5),
),
),
),
),
),
// picker
SizedBox(
height: pickerHeight,
child: ListWheelScrollView(
diameterRatio: 1.2,
itemExtent: itemHeight,
controller: scrollController,
children: list
.map(
(element) => Align(
alignment: Alignment.center,
child: Text('${element.year}'),
),
)
.toList(),
),
),
],
),
// selected item
ValueListenableBuilder(
valueListenable: selectedItem,
builder: (context, DateTime value, _) =>
Text('selected year: ${value.year}'),
),
],
);
}
}
Then you can use it like this:
SizedBox(
height: 300,
child: CustomPicker(
List.generate(21, (index) => DateTime(2000 + index)),
),
)
The result is:
Need to display icon with checkmark based on a String value that comes dynamically.
Like
this image is its pending show first widget with tick and rest are blank.
if delivered show with tick and the rest are blank.
Facing problems in creating logic using enums.
Currently, it displays the icons on button clicks
based on four constants which is fine with the widget CheckStatus.
Need to make in a way based on a boolean check if it's true and pending that pending tick widget displayed
and similar with other values.
Here is the complete code for it currently.
import 'package:dotted_border/dotted_border.dart';
import 'package:dotted_line/dotted_line.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:matab/models/order.dart';
import 'package:matab/ui/general_widgets/check_status.dart';
import 'package:matab/ui/pages/styles.dart';
import '../../general_widgets/custom_gradient_button.dart';
class TrackOrder extends StatefulWidget {
const TrackOrder({Key? key, required this.order}) : super(key: key);
final Order order;
#override
State<TrackOrder> createState() => _TrackOrderState();
}
enum Status { Pending, Confirmed, Shipped, Received }
class _TrackOrderState extends State<TrackOrder> {
static const darkGreyColor = Colors.grey;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Center(child: Text('Track Order')),
leading: IconButton(
icon: const Icon(Icons.arrow_back),
onPressed: () => Get.back(),
),
),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
const SizedBox(height: 50),
Text(
"Order ID:" + widget.order.orderID,
style: const TextStyle(
color: darkGreyColor,
fontSize: 18,
fontWeight: FontWeight.bold),
),
const SizedBox(height: 50),
const Text('Sat, 12 Mar 2022',
style: TextStyle(
color: darkGreyColor,
fontSize: 18,
fontWeight: FontWeight.bold)),
const SizedBox(
height: 15,
),
Container(
margin: const EdgeInsets.fromLTRB(15, 0, 0, 0),
child: const Text('Estimated Time: 07 Days',
style: TextStyle(fontSize: 23, fontWeight: FontWeight.bold)),
),
const SizedBox(height: 30),
SizedBox(
width: 200,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
OrderStatusBar(title: widget.order.orderStatus, status: true),
dottedLine(),
OrderStatusBar(
title: widget.order.orderStatus, status: false),
dottedLine(),
OrderStatusBar(
title: widget.order.orderStatus, status: false),
dottedLine(),
OrderStatusBar(
title: widget.order.orderStatus, status: false),
],
),
),
const SizedBox(
height: 40,
),
Container(
margin: const EdgeInsets.fromLTRB(15, 0, 0, 0),
child: const Text('Shipping Address',
style: TextStyle(fontSize: 23, fontWeight: FontWeight.bold)),
),
Center(
child: Text(widget.order.deliveryAddress.address,
style: const TextStyle(
color: Colors.grey,
fontSize: 18,
fontWeight: FontWeight.bold)),
),
Center(
child: Padding(
padding: const EdgeInsets.all(
50.0,
),
child: CustomGradientButton(
buttonText: "Track Order".tr, buttonFunction: () => {}),
),
),
Center(
child: Padding(
padding: const EdgeInsets.only(top: 18.0),
child: GestureDetector(
child: Text(
'Back to Home'.tr,
style: TextStyle(
color: mainColor,
fontSize: 23,
fontWeight: FontWeight.bold),
),
onTap: () => {
Get.off(CheckStatus(
order: widget.order,
))
},
),
),
)
],
),
),
);
}
}
class OrderStatusBar extends StatefulWidget {
const OrderStatusBar({Key? key, required this.title, required this.status})
: super(key: key);
final String title;
final bool status;
#override
State<OrderStatusBar> createState() => _OrderStatusBarState();
}
class _OrderStatusBarState extends State<OrderStatusBar> {
#override
Widget build(BuildContext context) {
return Directionality(
textDirection: TextDirection.rtl,
child: Row(
children: [
widget.status ? dottedCircleWithCheckMark() : dottedCircle(),
const SizedBox(width: 30),
Text(
widget.title.tr,
style: TextStyle(
fontSize: 20,
fontWeight: widget.status ? FontWeight.bold : null,
),
),
],
),
);
}
}
const size = 25.0;
const strokeWidth = 1.0;
const checkedColor = Color.fromRGBO(232, 113, 65, 1);
Widget dottedLine() {
return Directionality(
textDirection: TextDirection.rtl,
child: Align(
alignment: Alignment.topRight,
child: Container(
margin: const EdgeInsets.fromLTRB(0, 0, size / 2, 0),
child: const Padding(
padding: EdgeInsets.only(left: 27 / 2),
child: SizedBox(
height: size,
child: DottedLine(
dashColor: Colors.black,
direction: Axis.vertical,
lineLength: size,
lineThickness: strokeWidth,
dashLength: 5,
dashGapLength: 5,
),
),
),
),
),
);
}
dottedCircle() {
return DottedBorder(
borderType: BorderType.Circle,
dashPattern: const [5, 5],
child: Container(
height: size,
width: size,
decoration: const BoxDecoration(shape: BoxShape.circle),
));
}
dottedCircleWithCheckMark() {
return Container(
height: size + strokeWidth * 2,
width: size + strokeWidth * 2,
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: checkedColor,
),
child: const Icon(
Icons.check,
color: Colors.white,
size: size / 4 * 3,
),
);
}
// ignore_for_file: constant_identifier_names
class CheckStatus extends StatefulWidget {
const CheckStatus({Key? key, required this.order}) : super(key: key);
final Order order;
#override
State<CheckStatus> createState() => _CheckStatusState();
}
class _CheckStatusState extends State<CheckStatus> {
int selectedItemIndex = 0;
var pending = Status.Pending;
List<bool> orderStatus = [true,true,true,false];
#override
void initState() {
// TODO: implement initState
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
for (int i = 0; i < Status.values.length; i++)
ElevatedButton(
onPressed: () {
selectedItemIndex = i;
setState(() {});
},
child: Text("Order Status ${Status.values[i]}"),
),
Row(
children: [
for (int i = 0; i <= selectedItemIndex; i++)
Container(
height: size + strokeWidth * 2,
width: size + strokeWidth * 2,
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: checkedColor,
),
child: const Icon(
Icons.check,
color: Colors.white,
size: size / 4 * 3,
),
),
ElevatedButton(onPressed: () {}, child: Text("Back"))
],
)
],
),
);
}
}
function description: when an item is clicked, change the background color of this item 。
I defined the variable color in the List.generate function and used the setState function in onTapDown to modify this value, but it has no effect. what should I do?
my code is as follows
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
class Homepage extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Homepage> {
final titles = ["AAA", "BBB", "CCC", "DDD"];
final subtitles = [
"我去,额度这么高?",
"XX,你上次给我兑换的烤箱还不错哦",
"抱歉,我觉得我们不是很合适",
"邻居你好,你家的租户最近有点吵"
];
final date = ["昨天 18:08", "星期二", "7月21日", "7月19日"];
final avatar = [
"WechatIMG325.jpeg",
"WechatIMG326.jpeg",
"WechatIMG327.jpeg",
"WechatIMG328.jpeg"
];
// final icons = [Icons.ac_unit, Icons.access_alarm, Icons.access_time];
#override
Widget build(BuildContext context) {
return Column(
children: [
...List.generate(titles.length, (index) {
var color = Colors.white;
return GestureDetector(
behavior: HitTestBehavior.opaque,
onTapDown: (TapDownDetails details) {
setState(() {
color = Colors.grey;
});
debugPrint("presed GestureDetector");
},
onTapUp: (TapUpDetails details) {
setState(() {
color = Colors.white;
});
debugPrint("presed GestureDetector");
},
child: Container(
color: color,
margin: const EdgeInsets.fromLTRB(10, 0, 10, 0),
child: Row(children: [
SizedBox(
width: 50,
child: Container(
margin: const EdgeInsets.fromLTRB(0, 10, 0, 10),
child: ClipRRect(
borderRadius: BorderRadius.circular(5.0),
child: Image.asset("assets/images/${avatar[index]}",
height: 50, width: 50),
),
),
),
//const SizedBox(width: 10),
IntrinsicWidth(
child: Container(
margin: const EdgeInsets.fromLTRB(10, 0, 0, 0),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(
titles[index],
style: const TextStyle(
fontSize: 18,
color: Colors.black,
fontWeight: FontWeight.w300,
),
),
const SizedBox(height: 5),
Text(
subtitles[index],
style: const TextStyle(
fontSize: 15,
color: Colors.black54,
fontWeight: FontWeight.w300,
),
),
],
),
),
),
]),
),
);
}),
],
);
}
}
try this code will help you to start in OOP and make model to data in your app and you can add any thing to class like Icon ....
class FakeData {
final String title, subTitle, avatar, data;
bool onTapDown;
FakeData(
{required this.title,
this.onTapDown = false,
required this.subTitle,
required this.avatar,
required this.data});
}
this class collect data app and state for all item
class HomeState extends State<Homepage> {
final fakeData = [
FakeData(
title: 'AAA',
subTitle: '我去,额度这么高?',
avatar: "WechatIMG325.jpeg",
data: "昨天 18:08",
),
FakeData(
title: 'BBB',
subTitle: "XX,你上次给我兑换的烤箱还不错哦",
avatar: "WechatIMG326.jpeg",
data: "星期二",
),
FakeData(
title: 'CCC',
subTitle: "抱歉,我觉得我们不是很合适",
avatar: "WechatIMG327.jpeg",
data: "7月21日",
),
FakeData(
title: 'DDD',
subTitle: "邻居你好,你家的租户最近有点吵",
avatar: "WechatIMG328.jpeg",
data: "7月19日",
),
];
// final icons = [Icons.ac_unit, Icons.access_alarm, Icons.access_time];
#override
Widget build(BuildContext context) {
return Column(
children: [
...List.generate(fakeData.length, (index) {
return GestureDetector(
behavior: HitTestBehavior.opaque,
onTapDown: (TapDownDetails details) {
setState(() {
fakeData[index].onTapDown = !fakeData[index].onTapDown;
});
debugPrint("presed GestureDetector");
},
onTapUp: (TapUpDetails details) {
setState(() {
fakeData[index].onTapDown = !fakeData[index].onTapDown;
});
debugPrint("presed GestureDetector");
},
child: Container(
color: fakeData[index].onTapDown ? Colors.grey : Colors.white,
margin: const EdgeInsets.fromLTRB(10, 0, 10, 0),
child: Row(children: [
SizedBox(
width: 50,
child: Container(
margin: const EdgeInsets.fromLTRB(0, 10, 0, 10),
child: ClipRRect(
borderRadius: BorderRadius.circular(5.0),
child: Image.asset(
"assets/images/${fakeData[index].avatar}",
height: 50,
width: 50),
),
),
),
//const SizedBox(width: 10),
IntrinsicWidth(
child: Container(
margin: const EdgeInsets.fromLTRB(10, 0, 0, 0),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(
fakeData[index].title,
style: const TextStyle(
fontSize: 18,
color: Colors.black,
fontWeight: FontWeight.w300,
),
),
const SizedBox(height: 5),
Text(
fakeData[index].subTitle,
style: const TextStyle(
fontSize: 15,
color: Colors.black54,
fontWeight: FontWeight.w300,
),
),
],
),
),
),
]),
),
);
}),
],
);
}
}
The variable color needs to be outside the build method of the State, this code will reset the color to Colors.white on each build.
import 'package:flutter/material.dart';
class Homepage extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Homepage> {
final titles = ["AAA", "BBB", "CCC", "DDD"];
final subtitles = [
"我去,额度这么高?",
"XX,你上次给我兑换的烤箱还不错哦",
"抱歉,我觉得我们不是很合适",
"邻居你好,你家的租户最近有点吵"
];
final date = ["昨天 18:08", "星期二", "7月21日", "7月19日"];
final avatar = [
"WechatIMG325.jpeg",
"WechatIMG326.jpeg",
"WechatIMG327.jpeg",
"WechatIMG328.jpeg"
];
var color = Colors.white;
// final icons = [Icons.ac_unit, Icons.access_alarm, Icons.access_time];
#override
Widget build(BuildContext context) {
return Column(
children: [
...List.generate(titles.length, (index) {
return GestureDetector(
behavior: HitTestBehavior.opaque,
onTapDown: (TapDownDetails details) {
setState(() {
color = Colors.grey;
});
debugPrint("presed GestureDetector");
},
onTapUp: (TapUpDetails details) {
setState(() {
color = Colors.white;
});
debugPrint("presed GestureDetector");
},
child: Container(
color: color,
margin: const EdgeInsets.fromLTRB(10, 0, 10, 0),
child: Row(children: [
SizedBox(
width: 50,
child: Container(
margin: const EdgeInsets.fromLTRB(0, 10, 0, 10),
child: ClipRRect(
borderRadius: BorderRadius.circular(5.0),
child: Image.asset("assets/images/${avatar[index]}",
height: 50, width: 50),
),
),
),
//const SizedBox(width: 10),
IntrinsicWidth(
child: Container(
margin: const EdgeInsets.fromLTRB(10, 0, 0, 0),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(
titles[index],
style: const TextStyle(
fontSize: 18,
color: Colors.black,
fontWeight: FontWeight.w300,
),
),
const SizedBox(height: 5),
Text(
subtitles[index],
style: const TextStyle(
fontSize: 15,
color: Colors.black54,
fontWeight: FontWeight.w300,
),
),
],
),
),
),
]),
),
);
}),
],
);
}
}
The code above should work as our state is extracted outside of the build method and it would update correctly with each setState.
i am fairly new in flutter and i am trying to make a music player app.
the app works fine and all but the problem is it doesnot play in background/lockscreen.
i went through some docs and it says to use audio_service package for that but i am currently using flutter_audio_query package...all the docs i went through shows a solution which results in entirely changing the code...
so my question is ...is there any way to make the app play in background without changing the code entirely?
heres what my code looks like
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_audio_query/flutter_audio_query.dart';
import 'package:just_audio/just_audio.dart';
class MusicPlayer extends StatefulWidget {
SongInfo songInfo;
Function changeTrack;
final GlobalKey<MusicPlayerState> key;
MusicPlayer({required this.songInfo, required this.changeTrack, required this.key}):super(key: key);
#override
MusicPlayerState createState() => MusicPlayerState();
}
class MusicPlayerState extends State<MusicPlayer> {
double minimumValue = 0.0, maximumValue = 0.0, currentValue = 0.0;
String currentTime = '', endTime = '';
bool isPlaying = false;
final AudioPlayer player = AudioPlayer();
void initState() {
super.initState();
setSong(widget.songInfo);
}
void dispose(){
super.dispose();
player?.dispose();
}
void setSong(SongInfo songInfo) async {
widget.songInfo = songInfo;
await player.setUrl(widget.songInfo.uri);
currentValue = minimumValue;
maximumValue = player.duration!.inMilliseconds.toDouble();
setState(() {
currentTime = getDuration(currentValue);
endTime = getDuration(maximumValue);
});
isPlaying=false;
changeStatus();
player.positionStream.listen((duration) {
currentValue=duration.inMilliseconds.toDouble();
setState((){
currentTime=getDuration(currentValue);
});
});
}
void changeStatus(){
setState((){
isPlaying=!isPlaying;
});
if(isPlaying){
player.play();
}else{
player.pause();
}
}
String getDuration(double value) {
Duration duration = Duration(milliseconds: value.round());
return [duration.inMinutes, duration.inSeconds]
.map((e) => e.remainder(60).toString().padLeft(2, '0'))
.join(':');
}
Widget build(context) {
return Scaffold(
backgroundColor: Colors.black38,
appBar: AppBar(
backgroundColor: Colors.black,
leading: IconButton(
onPressed: () {
Navigator.of(context).pop();
},
icon: Icon(
Icons.arrow_back,
color: Colors.white,
),
),
title: const Text(
'Now Playing',
style: TextStyle(color: Colors.white),
),
),
body: Container(
margin: EdgeInsets.fromLTRB(15, 50, 5, 0),
child: Column(
children: <Widget>[
CircleAvatar(
backgroundImage: widget.songInfo.albumArtwork == null
? AssetImage('assets/images/album_image.jpg')
: FileImage(
File(widget.songInfo.albumArtwork),
) as ImageProvider,
radius: 95,
),
Container(
color: Colors.black,
margin: EdgeInsets.fromLTRB(0, 10, 0, 7),
child: Text(
widget.songInfo.title,
style: TextStyle(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.w600),
),
),
Container(
color: Colors.black,
margin: EdgeInsets.fromLTRB(0, 0, 0, 15),
child: Text(
widget.songInfo.artist,
style: TextStyle(
color: Colors.white,
fontSize: 12,
fontWeight: FontWeight.w500),
),
),
Slider(
value: currentValue,
min: minimumValue,
max: maximumValue,
onChanged: (value) {
currentValue = value;
player.seek(Duration(milliseconds: currentValue.round()));
},
inactiveColor: Colors.grey,
activeColor: Colors.green,
),
Container(
transform: Matrix4.translationValues(0, -5, 0),
margin: EdgeInsets.fromLTRB(5, 0, 5, 15),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
currentTime,
style: TextStyle(
color: Colors.white,
fontSize: 12,
fontWeight: FontWeight.w500),
),
Text(
endTime,
style: TextStyle(
color: Colors.white,
fontSize: 12,
fontWeight: FontWeight.w500),
),
],
),
),
Container(
margin: EdgeInsets.fromLTRB(0, 0, 0, 0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
GestureDetector(
child: Icon(Icons.skip_previous,
color: Colors.white, size: 55,),
behavior: HitTestBehavior.translucent,
onTap: () {
widget.changeTrack(false);
},
),
GestureDetector(
child: Icon(isPlaying?Icons.pause:Icons.play_arrow,
color: Colors.white, size: 75,),
behavior: HitTestBehavior.translucent,
onTap: () {
changeStatus();
},
),
GestureDetector(
child: Icon(Icons.skip_next,
color: Colors.white, size: 55,),
behavior: HitTestBehavior.translucent,
onTap: () {
widget.changeTrack(true);
},
),
],
),
),
],
),
),
);
}
}
appreciate any help that i can get...thank you
The description of "flutter_audio_query" says clearly that it is no audio player. It is a library to fetch music albums and covers.
"audio_service" on the other hand says clearly that it is for playing audio.
I would suggest to start again if you won't cause problems which could be avoided
Use the dependency assets_audio_player. it has a built-in function for this no need to even code. there is a little one-screen player for you. Just copy paste the code below and must add all the dependencies. Music will be played in background, on notification bar and on lock screen.
import 'dart:convert';
import 'package:assets_audio_player/assets_audio_player.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:musiccontrol/MusicPlayerModel.dart';
class Home extends StatefulWidget {
Home({
super.key,
t,
});
MusicPlaylist? _musicPlaylist;
#override
State<Home> createState() => _HomeState();
}
class _HomeState extends State<Home> {
List SongsList = [];
bool MuteVolume = false;
// Fetch content from the json file
final AssetsAudioPlayer audioplayer = AssetsAudioPlayer();
double screenwidth = 0;
double screenheight = 0;
#override
void initState() {
super.initState();
setupPlaylist();
}
// songs paths and links
void setupPlaylist() async {
await audioplayer.open(
showNotification: true,
Playlist(audios: [
// Audio(SongsList[2].,
// metas: Metas(
// title: "Bazz01",
// artist: 'Talha',
// )),
Audio.network(
'https://audio-ssl.itunes.apple.com/itunes-assets/AudioPreview125/v4/09/17/bb/0917bbe1-58c3-6252-d00e-9b70d42ef5dc/mzaf_2269500085377778268.plus.aac.p.m4a',
metas: Metas(
id: 'Online',
title: 'Online',
artist: 'Florent Champigny',
album: 'OnlineAlbum',
// image: MetasImage.network('https://www.google.com')
image: const MetasImage.network(
'https://i.dawn.com/large/2021/09/61399fb500900.png'),
),
),
Audio.network(
'https://audio-ssl.itunes.apple.com/itunes-assets/AudioPreview125/v4/09/17/bb/0917bbe1-58c3-6252-d00e-9b70d42ef5dc/mzaf_2269500085377778268.plus.aac.p.m4a',
metas: Metas(
id: 'Online',
title: 'Online',
artist: 'Florent Champigny',
album: 'OnlineAlbum',
// image: MetasImage.network('https://www.google.com')
image: const MetasImage.network(
'https://i.dawn.com/large/2021/09/61399fb500900.png'),
),
),
]),
autoStart: true,
loopMode: LoopMode.playlist,
);
}
var forward= AssetImage('assets/forward.png');
#override
void dispose() {
super.dispose();
setupPlaylist();
}
Widget slider(RealtimePlayingInfos realtimePlayingInfos) {
return SliderTheme(
data: const SliderThemeData(
thumbShape: RoundSliderThumbShape(enabledThumbRadius: 8),
),
child: Slider.adaptive(
activeColor: const Color.fromARGB(255, 241, 241, 241),
inactiveColor: const Color.fromARGB(255, 219, 217, 217),
thumbColor: const Color.fromARGB(255, 255, 255, 255),
value: realtimePlayingInfos.currentPosition.inSeconds.toDouble(),
max: realtimePlayingInfos.duration.inSeconds.toDouble(),
onChanged: (value) {
audioplayer.seek(Duration(seconds: value.toInt()));
}));
}
Widget timeStamps(RealtimePlayingInfos realtimePlayingInfos) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
transformString(realtimePlayingInfos.currentPosition.inSeconds),
style: const TextStyle(color: Colors.white),
),
Text(transformString(realtimePlayingInfos.duration.inSeconds),
style: const TextStyle(color: Colors.white)),
],
);
}
// slider timings
String transformString(int seconds) {
String minuteString =
'${(seconds / 60).floor() < 10 ? 0 : ''}${(seconds / 60).floor()}';
String secondString = '${seconds % 60 < 10 ? 0 : ' '}${seconds % 60}';
return '$minuteString:$secondString';
}
//control buttons of music player
Widget playBar(RealtimePlayingInfos realtimePlayingInfos) {
return SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Icon_Button(
icon: Icons.compare_arrows_rounded,
size: 21,
passedfunc: () {
audioplayer.toggleShuffle();
}),
Icon_Button(
icon: Icons.fast_rewind_rounded,
size: 21,
passedfunc: () {
audioplayer.seekBy(const Duration(seconds: -15));
}),
Icon_Button(
icon: Icons.skip_previous_rounded,
size: 21,
passedfunc: () => audioplayer.previous()),
Icon_Button(
icon: realtimePlayingInfos.isPlaying
? Icons.pause_circle_filled_rounded
: Icons.play_circle_fill_rounded,
size: 50,
passedfunc: () => audioplayer.playOrPause()),
Icon_Button(
icon: Icons.skip_next_rounded,
size: 21,
passedfunc: () => audioplayer.next()),
Icon_Button(
icon: Icons.fast_forward_rounded,
size: 21,
passedfunc: () {
setState(() {
audioplayer.seekBy(const Duration(seconds: 15));
});
}),
Icon_Button(
icon: MuteVolume == true
? Icons.volume_off_outlined
: Icons.volume_up,
size: 21,
passedfunc: () {
if (MuteVolume == true) {
setState(() {
audioplayer.setVolume(1);
MuteVolume = !MuteVolume;
});
} else {
audioplayer.setVolume(0);
MuteVolume = !MuteVolume;
}
},
),
],
),
);
}
#override
Widget build(BuildContext context) {
// screenheight = MediaQuery.of(context).size.height;
// screenwidth = MediaQuery.of(context).size.width;
return Scaffold(
backgroundColor: const Color.fromARGB(31, 142, 111, 253),
body: audioplayer.builderRealtimePlayingInfos(
builder: (context, realtimePlayingInfos) {
// ignore: unnecessary_null_comparison
if (realtimePlayingInfos != null) {
return Column(
//Designing Texts and image
children: [
Padding(
padding: const EdgeInsets.all(23.0),
child: Row(
children: [
ClipRRect(
borderRadius: BorderRadius.circular(40),
child: Image.network(
'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTUyCn1ItXdchQzeH8MkPEtQJcKttTplAw7oDrBuQI&s',
height: 70,
width: 70,
)),
Padding(
padding: const EdgeInsets.all(12.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Sound Cloud',
style: TextStyle(color: Colors.white, fontSize: 18),
),
const Text(
'Name Goes',
style: TextStyle(color: Colors.white, fontSize: 15),
),
const Text(
'Song Name Goes here',
style: TextStyle(color: Colors.white, fontSize: 20),
),
],
),
),
],
),
),
// slider code is here
Stack(
children: [
Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
slider(realtimePlayingInfos),
SizedBox(
height: screenheight * 0.05,
),
timeStamps(realtimePlayingInfos),
SizedBox(
height: screenheight * 0.05,
),
playBar(realtimePlayingInfos),
],
)
],
),
],
);
} else {
return Column();
}
}),
);
}
}
// Icon_Button custom widget
// ignore: camel_case_types, must_be_immutable
class Icon_Button extends StatelessWidget {
Icon_Button(
{super.key,
required this.icon,
required this.size,
required this.passedfunc});
IconData icon;
double size;
final passedfunc;
#override
Widget build(BuildContext context) {
return IconButton(
onPressed: passedfunc,
icon: Icon(icon),
iconSize: size,
color: Colors.grey,
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
);
}
}
**Hello everyone ,I want to integrate google maps in my flutter application but isn't working somoene can help me please ,somoene have an idea please---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- **
here is the code
import 'package:flutter/material.dart';
import 'package:flutter/painting.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:pharmaciemobile/src/Widget/autocomplete_textfield.dart';
import 'Widget/bezierBotContainer.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'jsonParser/pharmacies.dart' as pharmacies;
class PharmacyPage extends StatefulWidget {
PharmacyPage({Key key, this.title}) : super(key: key);
final String title;
#override
_PharmacyPageState createState() => _PharmacyPageState();
}
class _PharmacyPageState extends State<PharmacyPage> {
List<String> suggetions=[];
Widget _backButton() {
return InkWell(
onTap: () {
Navigator.pop(context);
},
child: Container(
padding: EdgeInsets.symmetric(horizontal: 10),
child: Row(
children: <Widget>[
Container(
padding: EdgeInsets.only(left: 0, top: 10, bottom: 10),
child: Icon(Icons.arrow_back_ios, color: Color(0xffe46b10)),
),
],
),
),
);
}
Widget _divider() {
return Container(
margin: EdgeInsets.symmetric(vertical: 10),
child: Row(
children: <Widget>[
SizedBox(
width: 20,
),
SizedBox(
width: 20,
),
],
),
);
}
Widget _title() {
return RichText(
textAlign: TextAlign.center,
text: TextSpan(
text: 'My',
style: GoogleFonts.portLligatSans(
textStyle: Theme.of(context).textTheme.display1,
fontSize: 30,
fontWeight: FontWeight.w700,
color: Color(0xffe46b10),
),
children: [
TextSpan(
text: 'Ph',
style: TextStyle(color: Colors.black, fontSize: 30),
),
TextSpan(
text: 'armacy',
style: TextStyle(color: Color(0xffe46b10), fontSize: 30),
),
]),
);
}
final Map<String, Marker> _markers = {};
Future<void> _onMapCreated(GoogleMapController controller) async {
final mypharmacies = await pharmacies.getPharmacies();
setState(() {
_markers.clear();
for (final pharmacy in mypharmacies.pharmacies) {
if(!suggetions.contains(pharmacy.city)) suggetions.add(pharmacy.city); // add cities name
final marker = Marker(
markerId: MarkerId(pharmacy.createdAt),
position: LatLng(pharmacy.latitude, pharmacy.longitude),
infoWindow: InfoWindow(
title: pharmacy.name,
snippet: pharmacy.address,
),
);
_markers[pharmacy.name] = marker;
}
});
}
GoogleMapController controller;
void changeMapCamera(String city) async{
final mypharmacies = await pharmacies.getPharmacies();
for(final pharmacy in mypharmacies.pharmacies){
if(pharmacy.city == city){
await controller.animateCamera(CameraUpdate.newCameraPosition(CameraPosition(
target: LatLng(pharmacy.latitude, pharmacy.longitude),
zoom: 12.0,
)));
/*await controller.animateCamera(CameraUpdate.newCameraPosition(CameraPosition(
target: LatLng(pharmacy.latitude, pharmacy.longitude);
)));*/
}
}
}
Widget mapCard(){
return GoogleMap(
onMapCreated: _onMapCreated,
initialCameraPosition: CameraPosition(
target: LatLng(33.4347305, -5.2318879),
zoom: 14.0,
),
markers: _markers.values.toSet(),
);
}
Widget _main() {
final height = MediaQuery.of(context).size.height;
final width = MediaQuery.of(context).size.width;
return Container(
child: Column(
children: <Widget>[
/* RichText(
text: TextSpan(
text: "Enter a city name:",
style: GoogleFonts.portLligatSans(
textStyle: Theme.of(context).textTheme.display1,
fontSize: 25,
fontWeight: FontWeight.w400,
color: Colors.black,
),
),
),*/
SimpleAutoCompleteTextField(
suggestions: suggetions,
decoration: InputDecoration(
filled: false,
fillColor: Colors.black12,
hintText: 'Entrez le nom de la ville',
alignLabelWithHint: true,
),
textSubmitted: (city) {
changeMapCamera(city);
},
),
SizedBox(
height: height / 20,
),
SizedBox(
width: height* .8,
height: width * 1.2,
child: mapCard(),
),
],
),
);
}
#override
Widget build(BuildContext context) {
final height = MediaQuery.of(context).size.height;
final width = MediaQuery.of(context).size.width;
return Scaffold(
body: Container(
height: height,
child: Stack(
children: <Widget>[
Positioned(
top: -height * .29,
right: -MediaQuery.of(context).size.width * .4,
child: BezierBotContainer()),
Container(
padding: EdgeInsets.symmetric(horizontal: 20),
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SizedBox(height: height * .06),
_title(),
_divider(),
SizedBox(height: height * .06),
_main(),
],
),
),
),
Positioned(top: 40, left: 0, child: _backButton()),
Positioned(
bottom: 30,
right: 30,
child: Icon(
Icons.info,
color: Color(0xffe46b10),
size: width * .09,
),
),
],
),
));
}
}