I have this StreamSubscription field called followSubscribtion. It listens if there is a new follower and then calls populateFollower to load follower profile.
followsSubscription =
getBloc(context).followsHandler.stream.listen((value) async {
if (value.status == Status.success) {
await populateFollows();
}
});
});
populateFollows() async{
if (getBloc(context).followsModel.length > 0) {
for (var i = 0; i < getBloc(context).followsModel.length; i++) {
getBloc(context).loadFollowsProfile(getBloc(context).followsModel[i].userId);
break;
}
}
}
This works fine, But I want each profile that will be loaded to be added to a list, How do I do that?
loadFollowsProfile method
loadFollowsProfile(int id , List<UserProfileModel> profileList) {
getFollowsProfileHandler.addNetworkTransformerStream(
Network.getInstance().getUserProfile(id), (_) {
userProfileModelBloc = UserProfileModel.fromJson(_);
profileList.add(userProfileModelBloc);
return userProfileModelBloc;
});
}
You can do this by setting up loadFollowsProfile() to return a UserProfileModel, adding that to a list in the for loop of populateFollows(), and then returning that list from populateFollows().
List<ProfileObject> populateFollows() async{
List<ProfileObject> profileList = [];
if (getBloc(context).followsModel.length > 0) {
for (var i = 0; i < getBloc(context).followsModel.length; i++){
profileList.add(getBloc(context).loadFollowsProfile(
getBloc(context).followsModel[i].userId
));
break;
}
}
return profileList;
}
followsSubscription =
getBloc(context).followsHandler.stream.listen((value) async {
if (value.status == Status.success) {
profileList = await populateFollows();
}
});
});
I have var hasActivatedIndex = false.obs; and
#override
void onInit() {
super.onInit();
ever(hasActivatedIndex, (callback) {
print('hasActivatedIndex !!== $hasActivatedIndex'); // not activated
});
}
with following method I changed hasActivatedIndex true or false, and hope every time this ever() will get this boolean changed state and print something
int updateActivatedIndex({double scrollPy}){
activatedIndex = eventPyList.indexWhere((element) {
if (scrollPy >= element && scrollPy <= element + 20) {
hasActivatedIndex.value = true;
return true;
} else {
hasActivatedIndex.value = false;
showEventCard = false;
return false;
}
});
return activatedIndex;
}
The hasActivatedIndex.value has indeed changed to true or false, but ever() in onInit does not react to this change, why? thanks in advance for the explanation!
In main.dart I call Quiz's function getQuestionText and getQuestionAnswer, getQuestionText works as expected but the other doesn't work, if returns me always the first result of the list. I just placed a debugPrint() and as expected getQuestionText() prints the correct number, getQuestionAnswer() always print 0, how is that possible?
class Quiz {
int _questionNumber = 0;
List<Question> _questions = [
Question('Some cats are actually allergic to humans', true),
Question('You can lead a cow down stairs but not up stairs.', false),
];
void nextQuestion() {
if (_questionNumber < _questions.length - 1) {
_questionNumber++;
}
}
String getQuestionText() {
print('$_questionNumber'); // <-- print the correct number
return _questions[_questionNumber].questionText;
}
bool getQuestionAnswer() {
print('$_questionNumber'); // <-- always print 0
return _questions[_questionNumber].questionAnswer;
}
}
Here how I call the functions
void checkAnswer(bool userAnswer) {
bool correctAnswer = Quiz().getQuestionAnswer();
setState(() {
if (userAnswer == correctAnswer) {
// right answer
} else {
// wrong pick
);
}
quiz.nextQuestion();
});
}
The problem is that you always create a fresh instance of your class Quiz by calling bool correctAnswer = Quiz().getQuestionAnswer(); inside checkAnswer().
Try to store the Quiz instance ouside:
const myQuiz = Quiz();
void checkAnswer(bool userAnswer) {
bool correctAnswer = myQuiz.getQuestionAnswer();
setState(() {
if (userAnswer == correctAnswer) {
// right answer
} else {
// wrong pick
}
myQuiz.nextQuestion();
});
}
I am looking to use the HERE Geocoding Autosuggest. I understand how the API works and it is the implementation in Flutter I seek guidance on.
There is a Javascript example for the previous version
https://developer.here.com/documentation/examples/rest/geocoding_suggestions
This demonstrates the call and Json return, but I wondered if there were any Flutter examples/ guidance on implementation when it comes to displaying the data.
For example, the API returns address results for 'London', does Flutter have build in functionality to display these to the user (Such as TypeAheadField), in a dropdown style box below entry field for example, like the HERE screenshot below, where the user can select the correct suggestion? How would the call be implemented with this function?
I presume I will utilise an onChanged/SetState style function to call and display, but it is how to make the call as user types and then display the returned suggestion that I would find an example useful.
Any resources/ tips welcome
Thank you
Please check the below code ,which explains the use of auto suggest in the flutter.
import 'dart:typed_data';
import 'package:flutter/services.dart';
import 'package:here_sdk/core.dart';
import 'package:here_sdk/core.errors.dart';
import 'package:here_sdk/gestures.dart';
import 'package:here_sdk/mapview.dart';
import 'package:here_sdk/search.dart';
import 'SearchResultMetadata.dart';
// A callback to notify the hosting widget.
typedef ShowDialogFunction = void Function(String title, String message);
class SearchExample {
HereMapController _hereMapController;
MapCamera _camera;
MapImage? _poiMapImage;
List<MapMarker> _mapMarkerList = [];
late SearchEngine _onlineSearchEngine;
late OfflineSearchEngine _offlineSearchEngine;
bool useOnlineSearchEngine = true;
ShowDialogFunction _showDialog;
SearchExample(ShowDialogFunction showDialogCallback, HereMapController hereMapController)
: _showDialog = showDialogCallback,
_hereMapController = hereMapController,
_camera = hereMapController.camera {
double distanceToEarthInMeters = 5000;
MapMeasure mapMeasureZoom = MapMeasure(MapMeasureKind.distance, distanceToEarthInMeters);
_camera.lookAtPointWithMeasure(GeoCoordinates(52.520798, 13.409408), mapMeasureZoom);
try {
_onlineSearchEngine = SearchEngine();
} on InstantiationException {
throw ("Initialization of SearchEngine failed.");
}
try {
// Allows to search on already downloaded or cached map data.
_offlineSearchEngine = OfflineSearchEngine();
} on InstantiationException {
throw ("Initialization of OfflineSearchEngine failed.");
}
_setTapGestureHandler();
_setLongPressGestureHandler();
_showDialog("Note", "Long press on the map to get the address for that location with reverse geocoding.");
}
Future<void> searchButtonClicked() async {
// Search for "Pizza" and show the results on the map.
_searchExample();
// Search for auto suggestions and log the results to the console.
_autoSuggestExample();
}
Future<void> geocodeAnAddressButtonClicked() async {
// Search for the location that belongs to an address and show it on the map.
_geocodeAnAddress();
}
void useOnlineSearchEngineButtonClicked() {
useOnlineSearchEngine = true;
_showDialog('Switched to SearchEngine', 'Requests will be calculated online.');
}
void useOfflineSearchEngineButtonClicked() {
useOnlineSearchEngine = false;
// Note that this app does not show how to download offline maps. For this, check the offline_maps_app example.
_showDialog(
'Switched to OfflineSearchEngine', 'Requests will be calculated offline on cached or downloaded map data.');
}
void _searchExample() {
String searchTerm = "Pizza";
print("Searching in viewport for: " + searchTerm);
_searchInViewport(searchTerm);
}
void _geocodeAnAddress() {
// Set map to expected location.
GeoCoordinates geoCoordinates = GeoCoordinates(52.53086, 13.38469);
double distanceToEarthInMeters = 1000 * 5;
MapMeasure mapMeasureZoom = MapMeasure(MapMeasureKind.distance, distanceToEarthInMeters);
_camera.lookAtPointWithMeasure(geoCoordinates, mapMeasureZoom);
String queryString = "Invalidenstraße 116, Berlin";
print("Finding locations for: $queryString. Tap marker to see the coordinates.");
_geocodeAddressAtLocation(queryString, geoCoordinates);
}
void _setTapGestureHandler() {
_hereMapController.gestures.tapListener = TapListener((Point2D touchPoint) {
_pickMapMarker(touchPoint);
});
}
void _setLongPressGestureHandler() {
_hereMapController.gestures.longPressListener = LongPressListener((GestureState gestureState, Point2D touchPoint) {
if (gestureState == GestureState.begin) {
GeoCoordinates? geoCoordinates = _hereMapController.viewToGeoCoordinates(touchPoint);
if (geoCoordinates == null) {
return;
}
_addPoiMapMarker(geoCoordinates);
_getAddressForCoordinates(geoCoordinates);
}
});
}
Future<void> _getAddressForCoordinates(GeoCoordinates geoCoordinates) async {
SearchOptions reverseGeocodingOptions = SearchOptions.withDefaults();
reverseGeocodingOptions.languageCode = LanguageCode.enGb;
reverseGeocodingOptions.maxItems = 1;
if (useOnlineSearchEngine) {
_onlineSearchEngine.searchByCoordinates(geoCoordinates, reverseGeocodingOptions,
(SearchError? searchError, List<Place>? list) async {
_handleReverseGeocodingResults(searchError, list);
});
} else {
_offlineSearchEngine.searchByCoordinates(geoCoordinates, reverseGeocodingOptions,
(SearchError? searchError, List<Place>? list) async {
_handleReverseGeocodingResults(searchError, list);
});
}
}
// Note that this can be called by the online or offline search engine.
void _handleReverseGeocodingResults(SearchError? searchError, List<Place>? list) {
if (searchError != null) {
_showDialog("Reverse geocoding", "Error: " + searchError.toString());
return;
}
// If error is null, list is guaranteed to be not empty.
_showDialog("Reverse geocoded address:", list!.first.address.addressText);
}
void _pickMapMarker(Point2D touchPoint) {
double radiusInPixel = 2;
_hereMapController.pickMapItems(touchPoint, radiusInPixel, (pickMapItemsResult) {
if (pickMapItemsResult == null) {
// Pick operation failed.
return;
}
List<MapMarker>? mapMarkerList = pickMapItemsResult.markers;
if (mapMarkerList.length == 0) {
print("No map markers found.");
return;
}
MapMarker topmostMapMarker = mapMarkerList.first;
Metadata? metadata = topmostMapMarker.metadata;
if (metadata != null) {
CustomMetadataValue? customMetadataValue = metadata.getCustomValue("key_search_result");
if (customMetadataValue != null) {
SearchResultMetadata searchResultMetadata = customMetadataValue as SearchResultMetadata;
String title = searchResultMetadata.searchResult.title;
String vicinity = searchResultMetadata.searchResult.address.addressText;
_showDialog("Picked Search Result", title + ". Vicinity: " + vicinity);
return;
}
}
double lat = topmostMapMarker.coordinates.latitude;
double lon = topmostMapMarker.coordinates.longitude;
_showDialog("Picked Map Marker", "Geographic coordinates: $lat, $lon.");
});
}
Future<void> _searchInViewport(String queryString) async {
_clearMap();
GeoBox viewportGeoBox = _getMapViewGeoBox();
TextQueryArea queryArea = TextQueryArea.withBox(viewportGeoBox);
TextQuery query = TextQuery.withArea(queryString, queryArea);
SearchOptions searchOptions = SearchOptions.withDefaults();
searchOptions.languageCode = LanguageCode.enUs;
searchOptions.maxItems = 30;
if (useOnlineSearchEngine) {
_onlineSearchEngine.searchByText(query, searchOptions, (SearchError? searchError, List<Place>? list) async {
_handleSearchResults(searchError, list, queryString);
});
} else {
_offlineSearchEngine.searchByText(query, searchOptions, (SearchError? searchError, List<Place>? list) async {
_handleSearchResults(searchError, list, queryString);
});
}
}
// Note that this can be called by the online or offline search engine.
void _handleSearchResults(SearchError? searchError, List<Place>? list, String queryString) {
if (searchError != null) {
// Note: When using the OfflineSearchEngine, the HERE SDK searches only on cached map data and
// search results may not be available for all zoom levels.
// Please also note that it may take time until the required map data is loaded.
// Subsequently, the cache is filled when a user pans and zooms the map.
_showDialog("Search", "Error: " + searchError.toString());
return;
}
// If error is null, list is guaranteed to be not empty.
int listLength = list!.length;
_showDialog("Search for $queryString", "Results: $listLength. Tap marker to see details.");
// Add new marker for each search result on map.
for (Place searchResult in list) {
Metadata metadata = Metadata();
metadata.setCustomValue("key_search_result", SearchResultMetadata(searchResult));
// Note: getGeoCoordinates() may return null only for Suggestions.
_addPoiMapMarkerWithMetadata(searchResult.geoCoordinates!, metadata);
}
}
Future<void> _autoSuggestExample() async {
GeoCoordinates centerGeoCoordinates = _getMapViewCenter();
SearchOptions searchOptions = SearchOptions.withDefaults();
searchOptions.languageCode = LanguageCode.enUs;
searchOptions.maxItems = 5;
TextQueryArea queryArea = TextQueryArea.withCenter(centerGeoCoordinates);
if (useOnlineSearchEngine) {
// Simulate a user typing a search term.
_onlineSearchEngine.suggest(
TextQuery.withArea(
"p", // User typed "p".
queryArea),
searchOptions, (SearchError? searchError, List<Suggestion>? list) async {
_handleSuggestionResults(searchError, list);
});
_onlineSearchEngine.suggest(
TextQuery.withArea(
"pi", // User typed "pi".
queryArea),
searchOptions, (SearchError? searchError, List<Suggestion>? list) async {
_handleSuggestionResults(searchError, list);
});
_onlineSearchEngine.suggest(
TextQuery.withArea(
"piz", // User typed "piz".
queryArea),
searchOptions, (SearchError? searchError, List<Suggestion>? list) async {
_handleSuggestionResults(searchError, list);
});
} else {
// Simulate a user typing a search term.
_offlineSearchEngine.suggest(
TextQuery.withArea(
"p", // User typed "p".
queryArea),
searchOptions, (SearchError? searchError, List<Suggestion>? list) async {
_handleSuggestionResults(searchError, list);
});
_offlineSearchEngine.suggest(
TextQuery.withArea(
"pi", // User typed "pi".
queryArea),
searchOptions, (SearchError? searchError, List<Suggestion>? list) async {
_handleSuggestionResults(searchError, list);
});
_offlineSearchEngine.suggest(
TextQuery.withArea(
"piz", // User typed "piz".
queryArea),
searchOptions, (SearchError? searchError, List<Suggestion>? list) async {
_handleSuggestionResults(searchError, list);
});
}
}
void _handleSuggestionResults(SearchError? searchError, List<Suggestion>? list) {
if (searchError != null) {
print("Autosuggest Error: " + searchError.toString());
return;
}
// If error is null, list is guaranteed to be not empty.
int listLength = list!.length;
print("Autosuggest results: $listLength.");
for (Suggestion autosuggestResult in list) {
String addressText = "Not a place.";
Place? place = autosuggestResult.place;
if (place != null) {
addressText = place.address.addressText;
}
print("Autosuggest result: " + autosuggestResult.title + " addressText: " + addressText);
}
}
Future<void> _geocodeAddressAtLocation(String queryString, GeoCoordinates geoCoordinates) async {
_clearMap();
AddressQuery query = AddressQuery.withAreaCenter(queryString, geoCoordinates);
SearchOptions geocodingOptions = SearchOptions.withDefaults();
geocodingOptions.languageCode = LanguageCode.deDe;
geocodingOptions.maxItems = 30;
if (useOnlineSearchEngine) {
_onlineSearchEngine.searchByAddress(query, geocodingOptions, (SearchError? searchError, List<Place>? list) async {
_handleGeocodingResults(searchError, list, queryString);
});
} else {
_offlineSearchEngine.searchByAddress(query, geocodingOptions,
(SearchError? searchError, List<Place>? list) async {
_handleGeocodingResults(searchError, list, queryString);
});
}
}
// Note that this can be called by the online or offline search engine.
void _handleGeocodingResults(SearchError? searchError, List<Place>? list, String queryString) {
if (searchError != null) {
_showDialog("Geocoding", "Error: " + searchError.toString());
return;
}
String locationDetails = "";
// If error is null, list is guaranteed to be not empty.
for (Place geocodingResult in list!) {
// Note: getGeoCoordinates() may return null only for Suggestions.
GeoCoordinates geoCoordinates = geocodingResult.geoCoordinates!;
Address address = geocodingResult.address;
locationDetails = address.addressText +
". GeoCoordinates: " +
geoCoordinates.latitude.toString() +
", " +
geoCoordinates.longitude.toString();
print("GeocodingResult: " + locationDetails);
_addPoiMapMarker(geoCoordinates);
}
int itemsCount = list.length;
_showDialog("Geocoding result for $queryString. Results: $itemsCount", locationDetails);
}
Future<MapMarker> _addPoiMapMarker(GeoCoordinates geoCoordinates) async {
// Reuse existing MapImage for new map markers.
if (_poiMapImage == null) {
Uint8List imagePixelData = await _loadFileAsUint8List('poi.png');
_poiMapImage = MapImage.withPixelDataAndImageFormat(imagePixelData, ImageFormat.png);
}
MapMarker mapMarker = MapMarker(geoCoordinates, _poiMapImage!);
_hereMapController.mapScene.addMapMarker(mapMarker);
_mapMarkerList.add(mapMarker);
return mapMarker;
}
Future<Uint8List> _loadFileAsUint8List(String fileName) async {
// The path refers to the assets directory as specified in pubspec.yaml.
ByteData fileData = await rootBundle.load('assets/' + fileName);
return Uint8List.view(fileData.buffer);
}
Future<void> _addPoiMapMarkerWithMetadata(GeoCoordinates geoCoordinates, Metadata metadata) async {
MapMarker mapMarker = await _addPoiMapMarker(geoCoordinates);
mapMarker.metadata = metadata;
}
GeoCoordinates _getMapViewCenter() {
return _camera.state.targetCoordinates;
}
GeoBox _getMapViewGeoBox() {
GeoBox? geoBox = _camera.boundingBox;
if (geoBox == null) {
print(
"GeoBox creation failed, corners are null. This can happen when the map is tilted. Falling back to a fixed box.");
GeoCoordinates southWestCorner = GeoCoordinates(
_camera.state.targetCoordinates.latitude - 0.05, _camera.state.targetCoordinates.longitude - 0.05);
GeoCoordinates northEastCorner = GeoCoordinates(
_camera.state.targetCoordinates.latitude + 0.05, _camera.state.targetCoordinates.longitude + 0.05);
geoBox = GeoBox(southWestCorner, northEastCorner);
}
return geoBox;
}
void _clearMap() {
_mapMarkerList.forEach((mapMarker) {
_hereMapController.mapScene.removeMapMarker(mapMarker);
});
_mapMarkerList.clear();
}
}
For more details please check enter link description here
I am trying to achieve a direct task, I want to autoplay the next track after the current track finishes, but sometimes the onComplete event is triggered before even the track is completed which lead to skip one of the tracks
the package I am using is: audioplayers ^0.14.2
the tracks are fetched from the database they are not local tracks
void play(List<SoundTrack> tracks){
audioPlayer.play(tracks[currentIndex].url);
setIsTalking = true;
audioPlayer.onPlayerCompletion.listen((event) {
if(currentIndex < tracks.length-1) {
next(tracks);
} else {
audioPlayer.release();
setIsTalking = false;
setPlayerState = PlayerState.paused;
}
print('completed this track, current index is' + currentIndex.toString());
});
}
void next(List<SoundTrack> tracks){
setCurrentIndex = currentIndex +1;
play(tracks);
}```
Try something like this:
define
int currentIndex = 0;
and
play(List<String> urlList, int currentIndex) async {
int result = await audioPlayer.play(urlList[currentIndex]);
if (result == 1) {
print('Success: is playing');
} else {
print('Error on audio play');
}
audioPlayer.onPlayerCompletion.listen((event) {
if(currentIndex < urlList.length-1){
currentIndex = currentIndex + 1;
nextTrack(urlList, currentIndex);
print("NEXT AUDIO! $currentIndex");
} else {
print("AUDIO COMPLETED PLAYING");
}
});
}
void nextTrack(List<String> urlList, int currentIndex) {
play(urlList, currentIndex);
}
In your play botton you call
nextTrack(urlList, currentIndex)
I tested and for me it is working.