Flutter - setState isn't working inside http response code - flutter

I am having a simple page to fetch data from server and parsing the response.
I am having two widgets that are visible to user, one is the _loadingWidget() widget another one is the errorWidget() widget.
I have added some print statements for showing up to where code is being executed. Everything is working fine but setState for errorWidget() is not working.
What i'm doing wrong here?
import 'package:flutter/material.dart';
import 'dart:io';
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:validators/validators.dart';
import '../strings.dart';
class FetchDataPage extends StatefulWidget {
final String text;
FetchDataPage({Key key, #required this.text}) : super(key: key);
#override
_FetchDataState createState() => _FetchDataState();
}
class _FetchDataState extends State<FetchDataPage> {
String _productUrl;
Widget pageWidget;
#override
Widget build(BuildContext context) {
pageWidget = _loadingWidget();
_productUrl = widget.text;
checkPrice(_productUrl);
return Scaffold(
body: Container(padding: EdgeInsets.all(20.0), child: pageWidget),
);
}
Widget _loadingWidget() {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Center(
child: CircularProgressIndicator(
backgroundColor: Colors.transparent,
valueColor: AlwaysStoppedAnimation<Color>(Colors.blueGrey),
),
),
SizedBox(height: 20.0),
Text(
"Checking Price...",
style: TextStyle(
color: Colors.blueGrey,
fontSize: 20.0,
fontWeight: FontWeight.w500,
),
),
],
);
}
Widget errorWidget() {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Center(
child: Icon(
Icons.sentiment_dissatisfied,
color: Colors.red,
size: 60.0,
),
),
SizedBox(height: 20.0),
Center(
child: Text(
"Product not found in database.\nPlease try again later.",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.blueGrey,
fontSize: 17.0,
fontWeight: FontWeight.w500,
),
),
),
],
);
}
void checkPrice(String productUrl) {
bool isUrl = isURL(productUrl, requireProtocol: true, requireTld: true);
if (!isUrl) {
RegExp regExp = new RegExp(r"((\w+:\/\/\S+)|(\w+[\.:]\w+\S+))[^\s,\.]");
setState(() {
productUrl = regExp.stringMatch(productUrl).toString();
});
}
/*
//setState is Working fine here!
setState(() {
pageWidget = errorWidget();
});
*/
var response = getLatestPrice(productUrl);
response.then((response) {
/*
//It's Not Working Here :(
setState(() {
pageWidget = errorWidget();
});
*/
print("Got Response: " + response.body.toString());
if (response.statusCode == 200) {
var loginData = json.decode(response.body);
bool status = loginData["status"];
print("STATUS: " + status.toString());
if (status) {
//This print statement is also working fine!
print(loginData["productUrl"]);
} else {
//This isn't working either
setState(() {
pageWidget = errorWidget();
});
}
} else {
//Not Working
setState(() {
pageWidget = errorWidget();
});
}
});
}
}
Future<http.Response> getLatestPrice(productUrl) async {
var url = Strings.baseUrl + 'api/checkPrice';
var response = await http.post(url, body: {
'product_url': productUrl,
}, headers: {
HttpHeaders.authorizationHeader:
"Basic " + base64Encode(utf8.encode('username:password'))
});
return response;
}

I fixed it by setting a bool instead:
import 'package:flutter/material.dart';
import 'dart:io';
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:validators/validators.dart';
import '../strings.dart';
class FetchDataPage extends StatefulWidget {
final String text;
FetchDataPage({Key key, #required this.text}) : super(key: key);
#override
_FetchDataState createState() => _FetchDataState();
}
class _FetchDataState extends State<FetchDataPage> {
String _productUrl;
bool showError = false;
#override
Widget build(BuildContext context) {
_productUrl = widget.text;
if (_productUrl != null) {
checkPrice(_productUrl);
}
return Scaffold(
body: Container(padding: EdgeInsets.all(20.0), child: pageWidget()),
);
}
Widget pageWidget() {
if (showError == false) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Center(
child: CircularProgressIndicator(
backgroundColor: Colors.transparent,
valueColor: AlwaysStoppedAnimation<Color>(Colors.blueGrey),
),
),
SizedBox(height: 20.0),
Text(
"Checking Price...",
style: TextStyle(
color: Colors.blueGrey,
fontSize: 20.0,
fontWeight: FontWeight.w500,
),
),
],
);
} else {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Center(
child: Icon(
Icons.sentiment_dissatisfied,
color: Colors.red,
size: 60.0,
),
),
SizedBox(height: 20.0),
Center(
child: Text(
"Product not found in database.\nPlease try again later.",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.blueGrey,
fontSize: 17.0,
fontWeight: FontWeight.w500,
),
),
),
],
);
}
}
void checkPrice(String productUrl) {
bool isUrl = isURL(productUrl, requireProtocol: true, requireTld: true);
if (!isUrl) {
RegExp regExp = new RegExp(r"((\w+:\/\/\S+)|(\w+[\.:]\w+\S+))[^\s,\.]");
setState(() {
productUrl = regExp.stringMatch(productUrl).toString();
});
}
var response = getLatestPrice(productUrl);
response.then((response) {
if (response.statusCode == 200) {
var loginData = json.decode(response.body);
bool status = loginData["status"];
if (status) {
print(loginData["productUrl"]);
} else {
setState(() {
showError = true;
});
}
} else {
setState(() {
showError = true;
});
}
});
}
}
Future<http.Response> getLatestPrice(productUrl) async {
var url = Strings.baseUrl + 'api/checkPrice';
var response = await http.post(url, body: {
'product_url': productUrl,
}, headers: {
HttpHeaders.authorizationHeader:
"Basic " + base64Encode(utf8.encode('username:password'))
});
return response;
}

Related

Failed host lookup from rest.coinapi.io

I am trying to fetch network data from the coinAPI to get the exchange rate for 1btc to usd.. but after fetching the api and awaiting it in price screen so the ui will give the exchange rate... I get failed host lookup
This is the coin_data.dart file... contains the api and networking
import 'dart:convert';
import 'package:http/http.dart' as http;
const List<String> currenciesList = [
'AUD',
'BRL',
'CAD',
'CNY',
'EUR',
'GBP',
'HKD',
'IDR',
'ILS',
'INR',
'JPY',
'MXN',
'NOK',
'NZD',
'PLN',
'RON',
'RUB',
'SEK',
'SGD',
'USD',
'ZAR'
];
const List<String> cryptoList = [
'BTC',
'ETH',
'LTC',
];
const coinAPIUrl = 'https://rest.coinapi.io/v1/exchangerate';
const apiKey = 'APIKEY';
class CoinData {
Future<dynamic> getCoinData() async {
// http.Response response = await http.get(Uri.parse('$coinAPIUrl/BTC/USD?apikey=$apiKey'));
http.Response response = await http.get(Uri.parse('$coinAPIUrl/BTC/USD?apikey=$apiKey'));
if (response.statusCode == 200) {
var decodedData = jsonDecode(response.body);
var lastPrice = decodedData['rate'];
return lastPrice;
} else {
print(response.statusCode);
throw 'Problem with the get request';
}
}
}
This is the price_screen.dart file.. the actual UI and display of the exchange rate
import 'dart:io' show Platform;
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:ticker_bitcoin/coin_data.dart';
class PriceScreen extends StatefulWidget {
const PriceScreen({super.key});
#override
State<PriceScreen> createState() => _PriceScreenState();
}
class _PriceScreenState extends State<PriceScreen> {
late String selectedCurrency = 'USD';
DropdownButton<String> androidDropdown() {
List<DropdownMenuItem<String>> dropdownItems = [];
for (int i = 0; i < currenciesList.length; i++) {
String currency = currenciesList[i];
var newItem = DropdownMenuItem(
value: currency,
child: Text(currency),
);
dropdownItems.add(newItem);
}
return DropdownButton(
value: selectedCurrency,
items: dropdownItems,
onChanged: (value) {
setState(() {
selectedCurrency = value!;
});
},
);
}
CupertinoPicker iOSPicker() {
List<Text> pickerItems = [];
for (String currency in currenciesList) {
Text(currency);
pickerItems.add(Text(currency));
}
return CupertinoPicker(
itemExtent: 32.0,
onSelectedItemChanged: (selectedIndex) {
print(selectedIndex);
},
children: pickerItems,
);
}
// Widget getPicker() {
// if (Platform.isIOS) {
// return iOSPicker();
// } else if (Platform.isAndroid) {
// return androidDropdown();
// }
// return getPicker();
// }
String bitcoinValueInUSD = '?';
void getData() async {
try {
double data = await CoinData().getCoinData();
setState(() {
bitcoinValueInUSD = data.toStringAsFixed(0);
});
} catch (e) {
print(e);
}
}
#override
void initState() {
super.initState();
getData();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('🤑 Coin Ticker'),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Padding(
padding: const EdgeInsets.fromLTRB(18.0, 18.0, 18.0, 0),
child: Card(
color: Colors.lightBlueAccent,
elevation: 5.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 15.0, horizontal: 28.0),
child: Text(
'1 BTC = $bitcoinValueInUSD USD',
textAlign: TextAlign.center,
style: const TextStyle(
fontSize: 20.0,
color: Colors.white,
),
),
),
),
),
Container(
height: 125.0,
alignment: Alignment.center,
padding: const EdgeInsets.only(bottom: 30.0),
color: Colors.lightBlue,
child: Platform.isIOS ? iOSPicker() : androidDropdown(),
),
],
),
);
}
}
It means your device/emulator got disconnected to the internet. If your host is connected to internet but emulator is disconnected then a cold reboot will do the trick. You'll find that under Device Manager > vertical ellipsis (⋮) > Cold Boot Now button.

Flutter - Variable in function available when building Widget

If I understood correctly (but clearly I don't) when you need a var available when you build the widget you need to call the function in the initState(). The function is 'void getDevices()'
I need var _documentsIds to build DropdownMenuItem.
var _documentsIds is docs ID from a query I make to FirebaseFirestore
How do I make _documentsIds available to be used in my Widget?
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart';
import 'package:safegaurd/constants.dart';
import 'package:flutter_time_picker_spinner/flutter_time_picker_spinner.dart';
import 'package:safegaurd/screens/log_in_page.dart';
import 'package:safegaurd/components/buttons_navigate.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'new_device_page.dart';
class DeviceSelectionPage extends StatefulWidget {
const DeviceSelectionPage({Key? key}) : super(key: key);
static const String id = 'device_selection_page';
#override
State<DeviceSelectionPage> createState() => _DeviceSelectionPageState();
}
class _DeviceSelectionPageState extends State<DeviceSelectionPage> {
final _auth = FirebaseAuth.instance;
User? loggedInUser;
final firestoreInstance = FirebaseFirestore.instance;
final String devices = 'devices';
List? _documentsIds;
bool showSpinner = false;
String? selectedValue;
final bool checkOne = false;
Color sDeviceAlways = Colors.white54;
Color sDeviceTime = Colors.white54;
FontWeight sDeviceAlwaysW = FontWeight.normal;
FontWeight sDeviceTimeW = FontWeight.normal;
#override
void initState() {
super.initState();
getCurrentUser();
getDevices();
}
void getCurrentUser() async {
try {
final user = await _auth.currentUser;
if (user != null) {
getDevices();
};
} catch (e) {
print(e);
}
}
void getDevices() async {
var firebaseUser = FirebaseAuth.instance.currentUser?.email;
print('firebaseUser: $firebaseUser');
var query = await firestoreInstance
.collection(devices)
.where('email', isEqualTo: '$firebaseUser')
.get();
var _documentsIds = query.docs.map((doc) => doc.id).toList();
print('_documentsIds: $_documentsIds');
}
#override
Widget build(BuildContext context) {
print('_documentsIds: $_documentsIds');
return Scaffold(
appBar: AppBar(
leading: null,
actions: [
IconButton(
onPressed: () {
_auth.signOut();
Navigator.pop(context);
},
icon: Icon(Icons.close))
],
title: const Text('Device Selection page'),
),
body: ModalProgressHUD(
inAsyncCall: showSpinner,
child: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const SizedBox(
height: 40,
child: Text(
'SAFEGAURD',
style: kAppTextStyle,
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 380,
padding: const EdgeInsets.symmetric(horizontal: 24.0),
decoration: BoxDecoration(
border: Border.all(
color: Colors.lightBlueAccent, width: 1.0),
borderRadius: kBorderRadius),
child: DropdownButtonHideUnderline(
child: DropdownButton(
hint: const Text(
'Safegaurd Devices',
style: TextStyle(color: Colors.white54, fontSize: 25),
),
style:
const TextStyle(color: Colors.orange, fontSize: 25),
borderRadius: kBorderRadius,
iconSize: 40,
elevation: 16,
onChanged: (value) {
setState(() {
selectedValue = value.toString();
setState(() {
selectedValue;
print(selectedValue);
});
});
},
value: selectedValue,
items: _documentsIds?.map((itemsList) {
return DropdownMenuItem<String>(
value: itemsList,
child: Text(itemsList),
);
}).toList(),
),
),
)
],
),
Row(
children: [
Buttons_Navigate(
colour: Colors.teal,
title: 'Save Settings',
onPressed: () {},
width: 200,
),
],
),
Row(
children: [
Buttons_Navigate(
colour: Colors.teal,
title: 'Claim new Device',
onPressed: () {
Navigator.pushNamed(context, NewDevicePage.id);
},
width: 200,
)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Buttons_Navigate(
colour: Colors.orange,
title: 'Back',
onPressed: () {
Navigator.pushNamed(context, LogInPage.id);
},
width: 40)
],
)
],
)),
));
}
}
wall, you can use futureBuilder and show A CircularProgressBar until the query is done check the documentation here: FutureBuilder
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart';
import 'package:safegaurd/constants.dart';
//import 'package:flutter_time_picker_spinner/flutter_time_picker_spinner.dart';
import 'package:safegaurd/screens/log_in_page.dart';
import 'package:safegaurd/components/buttons_navigate.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'new_device_page.dart';
class DeviceSelectionPage extends StatefulWidget {
const DeviceSelectionPage({Key? key}) : super(key: key);
static const String id = 'device_selection_page';
#override
State<DeviceSelectionPage> createState() => _DeviceSelectionPageState();
}
class _DeviceSelectionPageState extends State<DeviceSelectionPage> {
final _auth = FirebaseAuth.instance;
User? loggedInUser;
final firestoreInstance = FirebaseFirestore.instance;
final String devices = 'devices';
List? _documentsIds;
bool showSpinner = false;
//bool _isSelected1 = false;
//bool _isSelected2 = false;
//DateTime _dateTime = DateTime.now();
String? selectedValue;
final bool checkOne = false;
Color sDeviceAlways = Colors.white54;
Color sDeviceTime = Colors.white54;
FontWeight sDeviceAlwaysW = FontWeight.normal;
FontWeight sDeviceTimeW = FontWeight.normal;
#override
void initState() {
super.initState();
getCurrentUser();
getDevices();
}
void getCurrentUser() async {
try {
final user = await _auth.currentUser;
if (user != null) {
getDevices();
};
} catch (e) {
print(e);
}
}
Future<List<dynamic>> getDevices() async {
var firebaseUser = FirebaseAuth.instance.currentUser?.email;
print('firebaseUser: $firebaseUser');
var query = await firestoreInstance
.collection(devices)
.where('email', isEqualTo: '$firebaseUser')
.get();
List<String> _documentsIds = query.docs.map((doc) => doc.id).toList();
print('_documentsIds: $_documentsIds');
return _documentsIds;
}
#override
Widget build(BuildContext context) {
print('_documentsIds: $_documentsIds');
return Scaffold(
appBar: AppBar(
leading: null,
actions: [
IconButton(
onPressed: () {
_auth.signOut();
Navigator.pop(context);
},
icon: Icon(Icons.close))
],
title: const Text('Device Selection page'),
),
body: ModalProgressHUD(
inAsyncCall: showSpinner,
child: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const SizedBox(
height: 40,
child: Text(
'SAFEGAURD',
style: kAppTextStyle,
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 380,
padding: const EdgeInsets.symmetric(horizontal: 24.0),
decoration: BoxDecoration(
border: Border.all(
color: Colors.lightBlueAccent, width: 1.0),
borderRadius: kBorderRadius),
child: DropdownButtonHideUnderline(
child: FutureBuilder<List> (
future: getDevices(),
builder: (BuildContext context, AsyncSnapshot<List> snapshot){
if (!snapshot.hasData) {
return const Text('Waiting Devices',style: TextStyle(color: Colors.white54, fontSize: 25));
} else {
return DropdownButton(
hint: const Text(
'Safegaurd Devices',
style: TextStyle(color: Colors.white54, fontSize: 25),
),
style:
const TextStyle(color: Colors.orange, fontSize: 25),
borderRadius: kBorderRadius,
iconSize: 40,
elevation: 16,
onChanged: (value) {
setState(() {
selectedValue = value.toString();
setState(() {
selectedValue;
print(selectedValue);
});
});
},
value: selectedValue,
items: snapshot.data?.map((_documentsIds) =>
DropdownMenuItem<String>(
value: _documentsIds,
child: Text(_documentsIds),
)
).toList(),
);
}
}
)
),
)
],
),
Row(
children: [
Buttons_Navigate(
colour: Colors.teal,
title: 'Save Settings',
onPressed: () {},
width: 200,
),
],
),
Row(
children: [
Buttons_Navigate(
colour: Colors.teal,
title: 'Claim new Device',
onPressed: () {
Navigator.pushNamed(context, NewDevicePage.id);
},
width: 200,
)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Buttons_Navigate(
colour: Colors.orange,
title: 'Back',
onPressed: () {
Navigator.pushNamed(context, LogInPage.id);
},
width: 40)
],
)
],
)),
));
}

How can i remove html tags from a variable which i am calling from rest api and display it?

So basically I am calling get request on a rest API in flutter. I can display the data perfectly in listview but while doing so this particular data have lots of html tags in it. How can I possible remove the html tags after I have got the data in a variable?. The data has tag in between two strings and there are other html tags as well. Here is my code
import 'package:flutter/material.dart';
import 'package:flutter_on_field/API/api.dart';
import 'package:flutter_on_field/Add/AddAttendance.dart';
import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:http/http.dart' as http;
class Attendance extends StatefulWidget {
#override
_AttendanceState createState() => _AttendanceState();
}
class _AttendanceState extends State<Attendance> {
List users = [];
bool isLoading = false;
#override
void initState() {
// TODO: implement initState
super.initState();
this.fetchUser();
}
fetchUser() async {
setState(() {
isLoading = true;
});
var uri = Uri.parse('https://hirana.in/cdnhira/Serv_onfield_v1/attendance_list?session=');
var url = uri.replace(queryParameters: <String, String>{'session': session});
print(url);
var response = await http.get(url);
// print(response.body);
if(response.statusCode == 200){
var items = json.decode(response.body)['data'];
setState(() {
users = items;
isLoading = false;
});
}else{
users = [];
isLoading = false;
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: new AppBar(
title:Text("Attendance list",
textAlign: TextAlign.center,
),
backgroundColor: Colors.blue,
),
body:Stack(
children: [
Align(
alignment: Alignment.bottomCenter,
child: Container(
color: Colors.green,
width: 2000.0,
child: RaisedButton(onPressed: () {
Navigator.push(context,new MaterialPageRoute(
builder: (BuildContext context)=>AddAttendance())
);
},
color: Colors.green,
child: Text('Add Attendance',style: TextStyle(color: Colors.black),)),
),
),
SizedBox(height: 10),
Container(
height: 720,
child:getBody(),
),
]
),
);
}
Widget getBody(){
if(users.contains(null) || users.length < 0 || isLoading){
return Center(child: CircularProgressIndicator(valueColor: new AlwaysStoppedAnimation<Color>(Colors.white),));
}
return ListView.builder(
itemCount: users.length,
itemBuilder: (context,index){
return display(users[index]);
});
}
Widget display(item){
var date = item["attend_date"];
var inTime = item['intime'];
var outTime = item['outtime'];
print(date);
print("hi");
return Card(
elevation: 1.5,
child: ListTile(
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Column(
children: [
Text("Date(Name)",style: TextStyle(fontSize: 17, fontWeight:FontWeight.bold)),
Text(date),
],
),
Column(
children: [
Text("In Time", style: TextStyle(fontSize: 17, fontWeight:FontWeight.bold)),
Text(inTime),
],
),
Column(
children: [
Text("Out Time", style: TextStyle(fontSize: 17, fontWeight:FontWeight.bold)),
Text(outTime),
],
),
],
),
),
);
}
}
I am not able to add it to the code without the errors. Can you edit the code or write how to call my variable in the function.
You can use it like this:
import ‘package:html/parser.dart’;
// Some of the code.
String parseHtmlString(String htmlString) {
var document = parse(htmlString);
String parsedString = parse(document.body.text).documentElement.text;
return parsedString;
}
// Some of the code again.
if(response.statusCode == 200){
var items = json.decode(response.body)['data'];
items = parseHtmlString(items);
setState(() {
users = items;
isLoading = false;
});
}else{
users = [];
isLoading = false;
}
You can use the HTML package (https://pub.dev/packages/html), which already includes a parser:
import 'package:html/parser.dart' show parse;
import 'package:html/dom.dart';
main() {
var document = parse(
'<body>Hello world! <a href="www.html5rocks.com">HTML5 rocks!');
print(document.outerHtml);
}

Flutter : share a record

Im using record_mp3 package to record an audio file, can i share this record via whatsapp and other social media ?
Thanks in advance
You can copy paste run full code below
You can use package https://pub.dev/packages/esys_flutter_share
code snippet
onPressed: () async {
print('recordFilePath ${recordFilePath}');
File file = File(recordFilePath);
Uint8List bytes = await file.readAsBytes() as Uint8List;
await Share.file(
'yourmusic', 'yourmusic.mp3', bytes, 'audio/mpeg');
}
working demo
full code
import 'dart:io';
import 'package:audioplayers/audioplayers.dart';
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:record_mp3/record_mp3.dart';
import 'dart:io';
import 'dart:typed_data';
import 'package:esys_flutter_share/esys_flutter_share.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String statusText = "";
bool isComplete = false;
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Plugin example app'),
),
body: Column(children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Expanded(
child: GestureDetector(
child: Container(
height: 48.0,
decoration: BoxDecoration(color: Colors.red.shade300),
child: Center(
child: Text(
'start',
style: TextStyle(color: Colors.white),
),
),
),
onTap: () async {
startRecord();
},
),
),
Expanded(
child: GestureDetector(
child: Container(
height: 48.0,
decoration: BoxDecoration(color: Colors.blue.shade300),
child: Center(
child: Text(
RecordMp3.instance.status == RecordStatus.PAUSE
? 'resume'
: 'pause',
style: TextStyle(color: Colors.white),
),
),
),
onTap: () {
pauseRecord();
},
),
),
Expanded(
child: GestureDetector(
child: Container(
height: 48.0,
decoration: BoxDecoration(color: Colors.green.shade300),
child: Center(
child: Text(
'stop',
style: TextStyle(color: Colors.white),
),
),
),
onTap: () {
stopRecord();
},
),
),
],
),
Padding(
padding: const EdgeInsets.only(top: 20.0),
child: Text(
statusText,
style: TextStyle(color: Colors.red, fontSize: 20),
),
),
GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
play();
},
child: Container(
margin: EdgeInsets.only(top: 30),
alignment: AlignmentDirectional.center,
width: 100,
height: 50,
child: isComplete && recordFilePath != null
? Text(
"播放",
style: TextStyle(color: Colors.red, fontSize: 20),
)
: Container(),
),
),
]),
floatingActionButton: FloatingActionButton(
onPressed: () async {
print('recordFilePath ${recordFilePath}');
File file = File(recordFilePath);
Uint8List bytes = await file.readAsBytes() as Uint8List;
await Share.file(
'yourmusic', 'yourmusic.mp3', bytes, 'audio/mpeg');
},
child: Icon(Icons.share),
backgroundColor: Colors.green,
)),
);
}
Future<bool> checkPermission() async {
Map<PermissionGroup, PermissionStatus> map = await new PermissionHandler()
.requestPermissions(
[PermissionGroup.storage, PermissionGroup.microphone]);
print(map[PermissionGroup.microphone]);
return map[PermissionGroup.microphone] == PermissionStatus.granted;
}
void startRecord() async {
bool hasPermission = await checkPermission();
if (hasPermission) {
statusText = "正在录音中...";
recordFilePath = await getFilePath();
isComplete = false;
RecordMp3.instance.start(recordFilePath, (type) {
statusText = "录音失败--->$type";
setState(() {});
});
} else {
statusText = "没有录音权限";
}
setState(() {});
}
void pauseRecord() {
if (RecordMp3.instance.status == RecordStatus.PAUSE) {
bool s = RecordMp3.instance.resume();
if (s) {
statusText = "正在录音中...";
setState(() {});
}
} else {
bool s = RecordMp3.instance.pause();
if (s) {
statusText = "录音暂停中...";
setState(() {});
}
}
}
void stopRecord() {
bool s = RecordMp3.instance.stop();
if (s) {
statusText = "录音已完成";
isComplete = true;
setState(() {});
}
}
void resumeRecord() {
bool s = RecordMp3.instance.resume();
if (s) {
statusText = "正在录音中...";
setState(() {});
}
}
String recordFilePath;
void play() {
if (recordFilePath != null && File(recordFilePath).existsSync()) {
AudioPlayer audioPlayer = AudioPlayer();
audioPlayer.play(recordFilePath, isLocal: true);
}
}
int i = 0;
Future<String> getFilePath() async {
Directory storageDirectory = await getApplicationDocumentsDirectory();
String sdPath = storageDirectory.path + "/record";
var d = Directory(sdPath);
if (!d.existsSync()) {
d.createSync(recursive: true);
}
return sdPath + "/test_${i++}.mp3";
}
}

How do I create a button for a QR code to open a link?

Is it possible to add a button that opens the scanned link or make the text as a link to click?
My source code:
import 'package:flutter/material.dart';
import 'package:barcode_scan/barcode_scan.dart';
import 'package:flutter/services.dart';
class QrScan extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return QrScanState();
}
}
class QrScanState extends State<QrScan> {
String _barcode = "";
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('QR Scanner'),
),
body: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Image.asset(
'assets/barcode.png',
height: 150,
),
SizedBox(
height: 20,
),
Padding(
padding:
EdgeInsets.symmetric(horizontal: 80, vertical: 10.0),
child: RaisedButton(
color: Colors.lightBlue[700],
textColor: Colors.black,
splashColor: Colors.blueGrey,
onPressed: scan,
child: const Text('Scansiona il codice QR.'),
),
),
Padding(
padding:
EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
child: Text(
_barcode,
textAlign: TextAlign.center,
style: TextStyle(color: Colors.red),
),
),
],
),
));
}
Future scan() async {
try {
String barcode = await BarcodeScanner.scan();
setState(() => this._barcode = barcode);
} on PlatformException catch (e) {
if (e.code == BarcodeScanner.CameraAccessDenied) {
setState(() {
this._barcode = 'Scusami, mi dai il permesso di usare la fotocamera?';
});
} else {
setState(() => this._barcode = 'Errore sconosciuto $e');
}
} on FormatException {
setState(() => this._barcode =
'null, hai premuto il pulsante per tornare indietro prima di scansionare qualcosa');
} catch (e) {
setState(() => this._barcode = 'Errore sconosciuto : $e');
}
}
}
You can use package flutter_linkify
https://pub.dev/packages/flutter_linkify
and url_launcher
https://pub.dev/packages/url_launcher#-installing-tab-
I have made some changes in your code
import 'package:barcode_scan/barcode_scan.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_linkify/flutter_linkify.dart';
import 'package:url_launcher/url_launcher.dart';
class QrScan extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return QrScanState();
}
}
class QrScanState extends State<QrScan> {
String _barcode = "";
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('QR Scanner'),
),
body: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Image.asset(
'assets/barcode.png',
height: 150,
),
SizedBox(
height: 20,
),
Padding(
padding: EdgeInsets.symmetric(horizontal: 80, vertical: 10.0),
child: RaisedButton(
color: Colors.lightBlue[700],
textColor: Colors.black,
splashColor: Colors.blueGrey,
onPressed: scan,
child: const Text('Scansiona il codice QR.'),
),
),
Padding(
padding: EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
child: Linkify(
onOpen: (link) async {
if (await canLaunch(link.url)) {
await launch(link.url);
} else {
throw 'Could not launch $link';
}
},
text: _barcode,
style: TextStyle(color: Colors.yellow),
linkStyle: TextStyle(color: Colors.blue),
),
),
],
),
),
);
}
Future scan() async {
try {
String barcode = await BarcodeScanner.scan();
setState(() => this._barcode = barcode);
} on PlatformException catch (e) {
if (e.code == BarcodeScanner.CameraAccessDenied) {
setState(() {
this._barcode = 'Scusami, mi dai il permesso di usare la fotocamera?';
});
} else {
setState(() => this._barcode = 'Errore sconosciuto $e');
}
} on FormatException {
setState(() => this._barcode =
'null, hai premuto il pulsante per tornare indietro prima di scansionare qualcosa');
} catch (e) {
setState(() => this._barcode = 'Errore sconosciuto : $e');
}
}
}