I want to launch my App to the Playstore.
So I changed my minSdkVersion in the app\build.gradle from 16 to 31.
But now, when I build my Appbundle I encountered this error.
Execution failed for task ':app:processReleaseMainManifest'.
Manifest merger failed : android:exported needs to be explicitly specified for element <activity#com.example.debt.MainActivity>.
Apps targeting Android 12 and higher are required to specify an explicit value for android:exported when the corresponding compon
ent has an intent filter defined. See https://developer.android.com/guide/topics/manifest/activity-element#exported for details.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.debt">
<application
android:label="Money Reminder"
android:icon="#mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:launchMode="singleTop"
android:theme="#style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="#style/NormalTheme"
/>
<!-- Displays an Android View that continues showing the launch screen
Drawable until Flutter paints its first frame, then this splash
screen fades out. A splash screen is useful to avoid any visual
gap between the end of Android's launch screen and the painting of
Flutter's first frame. -->
<meta-data
android:name="io.flutter.embedding.android.SplashScreenDrawable"
android:resource="#drawable/launch_background"
/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>
</manifest>
`
import 'package:flutter/material.dart';
import 'package:debt/colors.dart';
import 'package:debt/add.dart';
import 'package:debt/data.dart';
import 'package:flutter/foundation.dart';
import 'package:hive_flutter/hive_flutter.dart';
late Box box;
List<Data>datalist=[];
Future <void> main() async{
WidgetsFlutterBinding.ensureInitialized();
await Hive.initFlutter();
Hive.registerAdapter(DataAdapter());
box = await Hive.openBox("infos");
//wandelt die daten für die Anzeige um
Map<dynamic, dynamic> data2 = box.toMap();
//macht aus map liste
data2.forEach((key, value) {
if(kDebugMode){
Data w =Data (key, value);
datalist.add(w);
}
});
runApp(const MaterialApp(
home: debt(),
debugShowCheckedModeBanner: false,
));}
// ignore: camel_case_types
class debt extends StatefulWidget {
const debt({Key? key}) : super(key: key);
#override
_debtState createState() => _debtState();
}
// ignore: camel_case_types
class _debtState extends State<debt> {
Map<String, dynamic> values = {};
String text = 'Text';
double w = 100;
double h = 20;
Widget quoteTemplate(data){
return ValueListenableBuilder<Box>(
valueListenable: Hive.box('infos').listenable(),
builder: (context, box, widget) {
return
Card(
margin: const EdgeInsets.fromLTRB(16, 16, 16, 0),
child:Row(
mainAxisAlignment: MainAxisAlignment.spaceAround, // x Achse
crossAxisAlignment: CrossAxisAlignment.center, // y Achse
children: <Widget>[
Column(
mainAxisAlignment: MainAxisAlignment.spaceAround, // x Achse
crossAxisAlignment: CrossAxisAlignment.center,// y Achse
children: <Widget>[
Container(alignment: Alignment.center,
width: 100,
height: h,
child: Text(
data.people,
style: TextStyle(
fontSize: 18,
color: Colors.grey[600],
)
),
),
const SizedBox(height: 6,),
Container(
alignment: Alignment.center,
child: Text(
data.money,
style: TextStyle(
fontSize: 14,
color: Colors.grey[800],
)
),
),
],
)
,Container(//delete
alignment: Alignment.center,
child: TextButton(style: TextButton.styleFrom(
),
onPressed: (){
box.delete(data.people);
setState(() {
Map<dynamic, dynamic> data2 = box.toMap();
datalist=[];
data2.forEach((key, value) {
if(kDebugMode){
Data w =Data (key, value);
datalist.add(w);
}
});
});
},
child: const Icon(Icons.delete,color: lightblue,),
),
),
Container(//minusbutton
alignment: Alignment.center,
child: TextButton(style: TextButton.styleFrom(//Minus Butten
),
onPressed: (){
var zwischenspeicher = box.get(data.people);
double zwischenspeicher2= double.parse(zwischenspeicher) - 1.0;
var schulden = zwischenspeicher2.toString();
box.put(data.people,schulden);
//Updatet das widget
setState(() {
Map<dynamic, dynamic> data2 = box.toMap();
datalist=[];
data2.forEach((key, value) {
if(kDebugMode){
Data w =Data (key, value);
datalist.add(w);
}
});
});
},
child: const Icon(Icons.remove,color: darkblue,),
),
),
Container(//plus Button
alignment: Alignment.center,
child: TextButton(style: TextButton.styleFrom(
),
onPressed: (){
var zwischenspeicher = box.get(data.people);
var zwischenspeicher2= double.parse(zwischenspeicher) + 1;
var schulden = zwischenspeicher2.toString();
box.put(data.people,schulden);
setState(() {
Map<dynamic, dynamic> data2 = box.toMap();
datalist=[];
data2.forEach((key, value) {
if(kDebugMode){
Data w =Data (key, value);
datalist.add(w);
}
});
});
},
child: const Icon(Icons.add,color: darkbrown,),
),
),
],
),
);});
}Widget buttond(){
return
Padding(
padding: const EdgeInsets.all(8.0),
child: Expanded(child: Align(
alignment: FractionalOffset.bottomRight,
child:
FloatingActionButton(
onPressed: () {
_awaitReturnValueFromSecondScreen(context);
},
child: const Icon(Icons.add),backgroundColor: lightbrown,
),),),
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
backgroundColor: lightblue ,
title: const Text("Money Reminder"),
centerTitle: true,
),
body:
Padding(
padding: const EdgeInsets.all(8.0),
child: ListView(
children: [
Column(
children: datalist.map((data)=> quoteTemplate(data)).toList(),
),
],
),
),bottomNavigationBar: Padding(
padding: const EdgeInsets.fromLTRB(20,0,20,10),
child:
ElevatedButton(
onPressed: () {
_awaitReturnValueFromSecondScreen(context);
},
//child: const Icon(Icons.add,color: Colors.white,),
child: const Text('add/edit debt',style: TextStyle(fontSize: 18,fontFamily: "Futura",color: Colors.white),),
style: ElevatedButton.styleFrom( backgroundColor:lightbrown,)
)
),
);
}
void _awaitReturnValueFromSecondScreen(BuildContext context) async {
// start the SecondScreen and wait for it to finish with a result
final result = await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const add(),
));
// after the SecondScreen result comes back update the Text widget with it
setState(() {
datalist = result;
});
}
}
`
The Problems of the manifest:
https://i.stack.imgur.com/kcZWN.png
https://i.stack.imgur.com/7lkfx.png
I tryed to Invalidate the cashe.
Write like this in your AndroidManifest.xml file activity.
<activity
android:name=".MainActivity"
android:launchMode="singleTop"
android:theme="#style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize"
android:exported="true"
tools:node="merge">
Related
I'm trying to launch a URL link in ElevatedButton but it doesn't work if I press the button it does not do anything, is there a different thing that works with ElevatedButton or should I write a different label
import 'package:url_launcher/url_launcher.dart';
import 'package:flutter/material.dart';
class MyAppThree extends StatefulWidget {
const MyAppThree({super.key});
#override
State<StatefulWidget> createState() => _MyAppThreeState();
}
class _MyAppThreeState extends State<StatefulWidget> {
_launchURL() async {
const url = 'https://www.youtube.com/';
final uri = Uri.parse(url);
if (await canLaunchUrl(uri)) {
await launchUrl(uri);
} else {
throw 'Could not launch $url';
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.black,
title: const Text(''),
),
body: Container(
child: Column(
children: <Widget>[
ElevatedButton(
onPressed: _launchURL,
child: Text(
'TAG Here',
style: TextStyle(
color: Colors.white,
fontSize: 20,
),
),
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(
const Color.fromARGB(255, 55, 55, 55)),
),
),
Starting on Android 11 (API 30), you must add a element in the Android manifest as a child of the root element:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.yourapp">
<queries>
<!-- If your app checks for https -->
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="https" />
</intent>
</queries>
/* rest of the manifest */
</manifest>
For instance: I have a main Icon so when you click on it, it opens a pop-up window with smaller icons/images to select from. So if you select one of the pictures from that pop-up it replaces the main Icon to that specific image.
I have spent hours trying to figure out how to replace icon images but nothing seems to work.
I have created an example (I have used flutter_speed_dial to make expandable buttons but it's not necessary). You can adjust it to your needs:
class _TestState extends State<Test> {
var fabIcon = Icons.expand_less;
var button1Icon = Icons.home;
var button2Icon = Icons.shop;
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
floatingActionButton: SpeedDial(
icon: fabIcon,
backgroundColor: Color(0xFF801E48),
visible: true,
curve: Curves.bounceIn,
children: [
// FAB 1
SpeedDialChild(
child: Icon(button1Icon),
backgroundColor: Color(0xFF801E48),
onTap: () {
var temp = fabIcon;
setState(() {
fabIcon = button1Icon;
button1Icon = temp;
});
},
labelStyle: TextStyle(
fontWeight: FontWeight.w500,
color: Colors.white,
fontSize: 16.0),
labelBackgroundColor: Color(0xFF801E48)),
// FAB 2
SpeedDialChild(
child: Icon(button2Icon),
backgroundColor: Color(0xFF801E48),
onTap: () {
var temp = fabIcon;
setState(() {
fabIcon = button2Icon;
button2Icon = temp;
});
},
labelStyle: TextStyle(
fontWeight: FontWeight.w500,
color: Colors.white,
fontSize: 16.0),
labelBackgroundColor: Color(0xFF801E48))
],
),
),
);
}
}
Using showDialog(...) is the solution.
Hope this will help you and others.
you can look at this example:
import 'package:flutter/material.dart';
class IconDialogScreen extends StatefulWidget {
const IconDialogScreen({Key? key}) : super(key: key);
#override
State<IconDialogScreen> createState() => _IconDialogScreenState();
}
class _IconDialogScreenState extends State<IconDialogScreen> {
IconData icon = Icons.abc;
List<IconData> icons = [
Icons.abc,
Icons.person_add,
Icons.person,
Icons.person_remove,
];
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Center(
child: TextButton(
onPressed: onIconClicked,
child: Wrap(
crossAxisAlignment: WrapCrossAlignment.center,
spacing: 20,
children: [Icon(icon, size: 50), const Text("change icon")],
),
),
)
],
),
);
}
void onIconClicked() async {
IconData? _icon = await showDialog<IconData?>(
context: context,
builder: (context) {
return AlertDialog(
title: const Text('Select one icon'),
content: Wrap(
spacing: 10,
runSpacing: 10,
children: icons.map<Widget>((e) {
return ElevatedButton(
onPressed: () {
Navigator.of(context).pop(e);
},
child: Icon(e, size: 50));
}).toList(),
),
);
},
);
if (_icon != null) {
setState(() {
icon = _icon;
});
}
}
}
Im trying to create a way to add a list of favourite names. When I submit a name it will update a list. then when i press save it should write the list to a text file. but when i run it i get the error (OS Error: No such file or directory, errno = 2)
How do i create the missing text file?
I cannot locate the file path in my demo device either. the code is given below ..
import 'dart:io';
import 'package:appoint/navigationDrawer/navigationDrawer.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:path_provider/path_provider.dart';
TextEditingController FavController = TextEditingController();
List<String> Favs = [];
TextEditingController TAController = TextEditingController();
class Favourite extends StatefulWidget {
static const String routeName = '/Favourite';
const Favourite({Key? key}) : super(key: key);
#override
_FavouriteState createState() => _FavouriteState();
}
class _FavouriteState extends State<Favourite> {
List _content = [];
Future<String> _getDirPath() async {
final _dir = await getApplicationDocumentsDirectory();
return _dir.path;
}
Future<File> get _localfile async {
final path = await _getDirPath();
return File ("$path/favs.txt");
}
Future<void> _readData() async {
final file = await _localfile;
String _data = await file.readAsString();
setState(() {
_content = [];
_content.add(_data);
});
}
Future<void> _writeData(pass) async {
final _dirPath = await _getDirPath();
final _myFile = File('$_dirPath/data.txt');
await _myFile.writeAsString('\n' + '$pass');
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Add Favourites',style: TextStyle(fontSize: 20.0, color: Colors.orange)),
),
drawer: navigationDrawer(),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.only(right: 8.0, left: 8.0),
child: Column(
children: [
Padding(
padding: const EdgeInsets.only(bottom: 30.0, top: 10.0),
child: TextField(
decoration: InputDecoration(border: OutlineInputBorder(), hintText: 'Enter New Favourite Name'),
controller: FavController,
onSubmitted: (text){
_readData();
print (_content);
Favs.add(text);
FavController.clear();
setState(() {
});
},
),
),
//addfields
Container(
child: ListView.builder(
physics: ClampingScrollPhysics(),
shrinkWrap: true,
itemCount: Favs.length,
itemBuilder: (BuildContext ctxt, int index) {
return Container(
decoration: BoxDecoration(border: Border.all(color: Colors.white54), borderRadius: BorderRadius.all(Radius.circular(8.0))),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'$index . ' + Favs[index],
style: TextStyle(fontSize: 20.0),),
IconButton(
onPressed: (){
Favs.remove(Favs[index]);
setState(() {});
},
tooltip: 'Clear name',
icon: Icon(Icons.clear, color: Colors.red,),
),
],
),
),
);
}
),
),
RaisedButton(
child: Text ('Save'),
onPressed: (){
for (String i in Favs) {
_writeData(i);
}
}
),
],
),
),
),
);
}
}
if you create file you must have permission
put your "AndroidManifest.xml"
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION"/>
<uses-permission android:name="android.permission.READ_INTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
use "permission_handler" plugin.
var status = await Permission.storage.status;
if (!status.isGranted) {
await Permission.storage.request();
}
if (await Permission.storage.request().isGranted) {
try {
await _writeData(pass);
} catch (e) {
print(e);
}
}
I am using Geolocator package for one of my flutter project, and I want to get my current location in periodic cycle of time.
To get the permission, I edited AndroidManifest.xml and added those line:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
All things are working just fine, but when I use the apk in one of android 10 phone, everything go south!
First of all whenever I am checking the status of permission for the first time of app using
await Geolocator.checkPermission();
It returns .denied in android 9, and .deniedForever in android 10, and when to check permission, the android permission seeking popup raised, in android 9 or bellow, the allow button set the permission to the .always but in android 10, is set to .whileInUse and I cannot find any option in setting to set it to .always manually.
After some research, I learn that, I have to add
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
I added them, but still android 10 does not act like android 9, still the "always" option in app manager are missing!
The main problem I am encountering is , whenever I off the screen, the Geolocator.getCurrentPosition() just stopped working but the same code works perfectly in android 9.
Simulation -
class _MyHomePageState extends State<MyHomePage> {
List _loc = [];
bool _isSwitchon = false;
int _sec = 0;
String _permissonStatus = "";
Future _incrementCounter() async {
Timer.periodic(Duration(seconds: 1), (timer) async {
setState(() {
_sec++;
});
if (_isSwitchon == false) {
timer.cancel();
setState(() {});
} else if (_isSwitchon == true) {
Position currentPosition = await Geolocator.getCurrentPosition();
setState(() {
_loc.add(currentPosition.toString());
});
}
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text("Time Elapsed"),
Text(_sec.toString() + " sec"),
Text(
'current Location',
),
Container(
height: 300,
child: ListView.builder(
itemCount: _loc.length,
itemBuilder: (BuildContext context, int i) {
return Text(
_loc[i],
);
},
),
),
Row(
children: [
Expanded(
child: Container(),
),
Column(
children: [
FloatingActionButton(
onPressed: () {
setState(() {
_isSwitchon = true;
});
_incrementCounter();
},
child: Icon(Icons.play_arrow),
),
Text("Start")
],
),
SizedBox(
width: 50,
),
Column(
children: [
FloatingActionButton(
onPressed: () {
setState(() {
_isSwitchon = false;
});
},
child: Icon(Icons.cancel),
),
Text("Stop")
],
),
Expanded(
child: Container(),
)
],
),
Text(_permissonStatus),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
children: [
FloatingActionButton(
onPressed: () async {
await Geolocator.checkPermission().then((value) =>
setState(
() => _permissonStatus = value.toString()));
},
child: Icon(Icons
.signal_wifi_statusbar_connected_no_internet_4_sharp),
),
Text("status")
],
),
Column(
children: [
FloatingActionButton(
onPressed: () {
setState(() {
_loc = [];
});
},
tooltip: 'Increment',
child: Icon(Icons.add),
),
Text("clear Location")
],
),
Column(
children: [
FloatingActionButton(
onPressed: () async {
await Geolocator.requestPermission();
},
tooltip: 'Increment',
child: Icon(Icons.gps_fixed),
),
Text("Permission Seeking")
],
),
],
)
],
),
),
);
}
}
Scenario in my manifest -
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.gps_test">
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
<application
You were talking about android 10, I dont see why there is not the right button, but to be future proof this method is outdated anyways.
Android docs:
On Android 11 (API level 30) and higher, however, the system dialog
doesn't include the Allow all the time option. Instead, users must
enable background location on a settings page, [...].
You should be able to open the permission settings with this package, either via .openLocationSettings() or .openAppSettings() and then the user has to navigate to permissions.
Hello friends I am creating learning app I need little help here I have array list when anyone click any word it goes to next sacreen user go to next sacreen instead user come back to pervious sacreen for next word I want user click on next button or pervious button to show next word pervious word on same sacreen.instead coming back to my previous word how it possible and remember array word must shown from right left because it an Hebrew language app here my image and code?
enter image description here
enter image description here
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'Sounds.dart';
class Kamiz extends StatefulWidget {
#override
_KamizState createState() => _KamizState();
}
class _KamizState extends State<Kamiz> {
var kamiz=['פָּרָ','חָםָ','נָבָּ','עָוָ','אָםָ','מָרָ','כָּכָּ','מָמָ','פָּפָּ','בָּרָ','קָרָ','דָּרָ','וָרָ','הָרָ','תָּרָ','בָּם','כָּלָ','כָּר','שָׁלָ','סָרָ','כָּכָּ','אָםָ','חָםָ','אָל','כָּלָ'];
var list=['57.wav','48.wav','47.wav','46.wav','45.wav','55.wav','54.wav','53.wav','51.wav','50.wav','60.wav','61.wav','58.wav',
'57.wav','61.wav','65.wav','64.wav','63.wav','62.wav','missing.wav','70.wav','69.wav','48.wav','67.wav','66.wav'
];
var urduvowel=['پارا','خاما','نابا','عاوا','آما','مارا','کاکا','ماما','پاپا','بارا','قارا','دارا','وارا','ہارا','تارا','باما',
'کالا','کارا','شالا','سارا','کاکا','آما','خاما','الا','کالا'];
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
'Kamatz',style:GoogleFonts.davidLibre(
fontSize: 24,
fontWeight: FontWeight.bold,
)),
),
body: GridView.builder(
itemCount: kamiz.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 5,
),
itemBuilder: (BuildContext context,int index){
return Padding(
padding:EdgeInsets.all(10.0),
child: GestureDetector(
onTap: () {
Navigator.push (
context,
MaterialPageRoute(builder: (context) => Sounds(kamiz[index],list[index],urduvowel[index])),
);
},
child: Container(
decoration: BoxDecoration(
color: Colors.black12,
border: Border.all(color: Colors.blueAccent)
),
child: Center(
child: Directionality(
textDirection: TextDirection.rtl,
child: Column(
children: [
Text(kamiz[index],style:GoogleFonts.davidLibre(
fontSize: 16,
fontWeight: FontWeight.bold,
)),
Text(urduvowel[index],style:GoogleFonts.davidLibre(
fontSize: 16,
fontWeight: FontWeight.bold,
)),
],
),
),
),
),
),
) ;
}
)
);
}
}
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:audioplayers/audioplayers.dart';
import 'package:flutter_cache_manager_firebase/flutter_cache_manager_firebase.dart';
class Sounds extends StatefulWidget {
#override
_SoundsState createState() => _SoundsState();
String word;
var sounds;
var urdu;
Sounds(this.word,this.sounds,this.urdu);
}
class _SoundsState extends State<Sounds> {
final Completer<WebViewController> _controller = Completer<WebViewController>();
var audio;
AudioPlayer audioPlayer = AudioPlayer();
#override
void initState() {
super.initState();
audio='''
<!DOCTYPE html>
<html>
<body>
<audio id="englishAudio">
<source src="https://firebasestorage.googleapis.com/v0/b/hebrewapp-453d2.appspot.com/o/practicesounds%2F${widget.sounds}?alt=media&token=603fc7fc-6794-424d-84c6-3627d0d81d68" type="audio/mpeg">
Your browser does not support the audio element.
</audio>
<button onclick="UrduAudio()" type="button">Listen Word</button>
<button onclick="pauseAudio()" type="button">Pause Audio</button>
<script>
var x = document.getElementById("englishAudio");
var y = document.getElementById("urduAudio");
function UrduAudio() {
x.play();
}
function englishAudio() {
y.play();
}
function pauseAudio() {
x.pause();
y.pause();
}
</script>
</body>
</html>
''';
}
#override
Widget build(BuildContext context) {
#override
String audioplay='''
<!DOCTYPE html>
<html>
<body>
<audio id="englishAudio">
<source src="https://firebasestorage.googleapis.com/v0/b/hebrewapp-453d2.appspot.com/o/practicesounds%2F${widget.sounds}?alt=media&token=603fc7fc-6794-424d-84c6-3627d0d81d68" type="audio/mpeg">
Your browser does not support the audio element.
</audio>
<button onclick="UrduAudio()" type="button">Listen Word</button>
<button onclick="pauseAudio()" type="button">Pause Audio</button>
<script>
var x = document.getElementById("englishAudio");
var y = document.getElementById("urduAudio");
function UrduAudio() {
x.play();
}
function englishAudio() {
y.play();
}
function pauseAudio() {
x.pause();
y.pause();
}
</script>
</body>
</html>
''';
return Scaffold(
appBar: AppBar(
title: Text(
'Kamatz',style:GoogleFonts.davidLibre(
fontSize: 24,
fontWeight: FontWeight.bold,
)),
),
body: Center(
child: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
widget.urdu+'/'+widget.word,style:GoogleFonts.davidLibre(
fontSize: 70,
)),
SizedBox(height: 30,),
Center(
child: Padding(
padding:EdgeInsets.only(left: 90),
child: Container(
constraints: BoxConstraints(maxHeight: 100,),
child: WebView(
initialUrl:Uri.dataFromString(audio, mimeType: 'text/html').toString(),
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController webViewController) {
_controller.complete(webViewController);
}, //
)
),
),
),
Padding(
padding:EdgeInsets.only(left: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('PERV'),
Icon(
Icons.arrow_left,
size: 70.0,
),
Icon(
Icons.arrow_right,
size: 70.0,
),
Text('Next'),
],
),
)
],
),
),
),
);
}
}
use - for previous and + for next
var kamiz=['פָּרָ','חָםָ','נָבָּ','עָוָ','אָםָ','מָרָ','כָּכָּ','מָמָ','פָּפָּ','בָּרָ','קָרָ','דָּרָ','וָרָ','הָרָ','תָּרָ','בָּם','כָּלָ','כָּר','שָׁלָ','סָרָ','כָּכָּ','אָםָ','חָםָ','אָל','כָּלָ'];
int index = 0;
int prev = kamiz[index-1];
int next = kamiz[index+1];
Make sure to check bounds.