How do i create a rounded search bar in flutter that also shows the recent searches from the search bar? - flutter

I have been wanting to find a solution to create a rounded search bar in flutter which also shows the list of recent searches underneath it. How is it possible to create the previous widget?

Using the package below, you can save the information you want to the device memory and then withdraw it from there (username, password, search history, etc.). The sample code is in the document.
https://pub.dev/packages/shared_preferences
like this:
void handleRememberMe(bool? value) {
_isChecked = value!;
SharedPreferences.getInstance().then(
(prefs) {
prefs.setBool("remember_me", value);
prefs.setString('userName', userNameController.text);
prefs.setString('password', passwordController.text);
},
);
setState(() {
_isChecked = value;
});
}
void loadUserEmailPassword() async {
try {
SharedPreferences _prefs = await SharedPreferences.getInstance();
var _email = _prefs.getString("userName") ?? "";
var password = _prefs.getString("password") ?? "";
var _remeberMe = _prefs.getBool("remember_me") ?? false;
if (_remeberMe) {
setState(() {
_isChecked = true;
});
userNameController.text = _email;
passwordController.text = password;
} else {
userNameController.text = "";
passwordController.text = "";
setState(() {
_isChecked = false;
});
}
} catch (e) {
debugPrint(e.toString());
}
}

Related

Flutter QR-code scanner rapidly scan issue, how to control the second scan?

Does anyone know how to adjust the QR code scanner speed? since the second scan is so quick,
source example is down below, you can download it add and run it in your Flutter project to test!
What are the differenceis are in the controller.scannedDataStream.listen() function. I posted down below:
Barcode? result;
var qrText = "";
bool isValid = false;
bool isExpired = false;
QRViewController? controller;
controller.scannedDataStream.listen((scanData) async {
log(scanData.code);
if (!scanData.code.contains('?key=')) {
setState(() {
qrText = "This is not a correct code";
isValid = false;
});
} else {
var key_hash = scanData.code.split('?key=');
log('hash: ' + key_hash[1]);
await decrypt(key_hash[1]).then((String result) async {
if (result == "") {
log('result: ' + result);
await controller.stopCamera();
setState(() {
qrText = result;
isValid = true;
isExpired = true;
});
}
else {
log('result: ' + result);
await controller.pauseCamera();
await controller.stopCamera();
setState(() {
qrText = result;
isValid = true;
isExpired = false;
});
}
});
}
});
https://pub.dev/packages/qr_code_scanner/example

Dart the operator [] isn't defined for 'Future<Map<String,Object>> Function(String)'

I'm trying to set up Auth0 for my Flutter app from this demo, but I ran into this issue. I've only been using Flutter for a little while, and I fixed a few errors, but can't fix this one. I checked for other answers here, and tried the documentation too. The error message is;
The operator [] isn't defined for 'Future<Map<String,Object>> Function(String)'
This is the method with the error;
Future<void> loginAction() async {
setState(() {
isBusy = true;
errorMessage = '';
});
try {
final AuthorizationTokenResponse? result =
await appAuth.authorizeAndExchangeCode(
AuthorizationTokenRequest(
AUTH0_CLIENT_ID,
AUTH0_REDIRECT_URI,
issuer: 'https://$AUTH0_DOMAIN',
scopes: ['openid', 'profile', 'offline_access'],
promptValues: ['login']
),
);
Map<String, Object> parseIdToken(String idToken) {
final parts = idToken.split(r'.');
assert(parts.length == 3);
return jsonDecode(
utf8.decode(base64Url.decode(base64Url.normalize(parts[1]))));
}
Future<Map<String, Object>> getUserDetails(String accessToken) async {
final url = 'https://$AUTH0_DOMAIN/userinfo';
final response = await http.get(Uri.parse(
url,
));
if (response.statusCode == 200) {
return jsonDecode(response.body);
} else {
throw Exception('Failed to get user details');
}
}
await secureStorage.write(
key: 'refresh_token', value: result!.refreshToken);
setState(() {
isBusy = false;
isLoggedIn = true;
name = parseIdToken['name'];
picture = getUserDetails['picture'];
});
} catch (e, s) {
print('login error: $e - stack: $s');
setState(() {
isBusy = false;
isLoggedIn = false;
errorMessage = e.toString();
});
}
}
And the lines that are erroring are;
name = parseIdToken['name'];
picture = getUserDetails['picture'];
Can this be fixed?
getUserDetails is a function, and so it doesn't have a [] operator.
Instead, try: var userDetails = await getUserDetails("token..."); picture = userDetails["picture"];

How do I make Flutter Widget disappear after certain time (in days)?

I have few widgets on home screen, one of them is there only if user save some data, from that moment
I want to count 7 days and if nothing else happen widget will be deleted.
I tried something like this:
//When user save data to widget
_saveTime() async {
SharedPreferences pref = await SharedPreferences.getInstance();
pref.setString(
'StoreTime', DateTime.now().add(Duration(days: 8)).toString());
}
Then in the Home page
...
bool _thirdMenu;
String _difDays = '';
#override
initState() {
super.initState();
_thirdMenu = true;
WidgetsBinding.instance.addObserver(this);
_init();
}
_init() async {
SharedPreferences pref = await SharedPreferences.getInstance();
String oldTimePref = pref.getString('StoreTime') ?? '1969-07-20 20:18:04Z';
DateTime oldTime = DateTime.parse(oldTimePref);
DateTime newTime = DateTime.now();
var difference = oldTime.difference(newTime);
if (difference.inDays > 0) {
setState(() {
_thirdMenu = true;
_difDays = difference.inDays.toString();
});
} else {
setState(() {
_thirdMenu = false;
});
}
}
Not working, time stay the same and widget still showing...
If you want to work with days, I think you can work without hours and minutes.
You can isolate the days and check without using time difference.
int oldDay = oldTime.day;
int today = newTime.day;
if(today - oldDay >= 7) {
setState(() {
_thirdMenu = false;
});
} else {
setState(() {
_thirdMenu = true;
});
}

Display Loading spinner waitint for request to complete while using provider package

I am using a provider package. I want to display a loading spinner while waiting for a request to complete. The pattern below is too verbose. Please help me make it less verbose. Here is my code
class APIService with ChangeNotifier {
// Check for working API backend
bool isWorking = false;
bool isLoading = false;
set _isLoading(bool value) {
isLoading = value; <--
notifyListeners();
}
Future<bool> selectAPI(String input) async {
_isLoading = true; <-- 1
final uri = Uri.tryParse('https://$input$url')!;
final response = await http.get(uri);
if (response.statusCode == 200) {
final body = jsonDecode(response.body) as Map<String, dynamic>;
bool isTrue = body['info']['title'] == 'SamFetch';
_isLoading = false; <-- 2
notifyListeners();
return isWorking = isTrue;
}
_isLoading = false; <-- 3
throw response;
}
}
Here is my UI code
IconButton(
icon: apiService.isLoading
? CircularProgressIndicator()
: Icon(Icons.done),
onPressed: () async {
await addAPI(apiService, cache);
}),
}
Below is addAPI() method
Future<void> addAPI(APIService apiService, Cache cache) async {
if (api != null) {
try {
await apiService.selectAPI(api!);
if (apiService.isWorking) {
await cache.saveAppName(api!);
}
} on SocketException catch (e) {
print(e);
} catch (e) {
await cache.clearCache();
}
}
}
Is setState the final solution?
You can use Future Builder and set your Future Function in future attribute. You can control the visible widget based on the status of your function. So you dont have to use isloading variable.

Shared preference save location address from geolocator

i was able to get current location using geolocator, but i want to cache and restore the string address without using lastKnownLocation in geolocator. im using shared preferences but cannot make it work. i used shared preference several times on my other codes, but with geolocator its kind of complicated. and im super new to flutter/dart
code:
final Geolocator geolocator = Geolocator()..forceAndroidLocationManager;
Position _currentPosition;
String _currentAddress;
String _locationCache;
String key = "location_cache";
#override
void initState() {
super.initState();
_getCurrentLocation();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text("current location = " + _currentAddress),
Text("last location = " + __locationCache) // HERE GET STORED DATA ISNT WORKING
],
),
),
);
}
_getCurrentLocation() {
geolocator
.getCurrentPosition(desiredAccuracy: LocationAccuracy.best)
.then((Position position) {
setState(() {
_currentPosition = position;
});
_getAddressFromLatLng();
}).catchError((e) {
print(e);
});
}
_getAddressFromLatLng() async {
try {
List<Placemark> p = await geolocator.placemarkFromCoordinates(
_currentPosition.latitude, _currentPosition.longitude);
Placemark place = p[0];
setState(() {
_currentAddress = "${place.country}";
});
saveAddress();
} catch (e) {
print(e);
}
}
Future<bool> saveAddress() async {
final SharedPreferences prefs = await SharedPreferences.getInstance();
return await prefs.setString(key, _currentAddress);
}
Future<String> retrieveAddress() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
//Return String
return prefs.getString(key) ?? "";
}
loadAddress() {
retrieveAddress().then((value) {
setState(() {
_locationCache = value;
});
});
}
}
heres the working code without _locationCache:
Thank you for your time
If I understood you correctly, what you want to accomplish is to store the last address you caught and retrieve it if you don't have gps active.
To do so you could use SharedPreferences or SQLite, just check the documentation on how to use them.
found the solution. just replace loadAddress() function with
void save() {
String address = _currentAddress;
saveAddress(address);
}
void _updateName(String address) {
setState(() {
this.locationCache = address;
});
}
and then put retrieveAddress().then(updateName) inside initState()