My intent is to show the fragment if there is something to show and hide it if there isn't.
My problem is that, given the same coordinates:
On first attempt, mStreetView.getStreetViewPanorama().getLocation() has a non-null response and shows the view. However, the Fragment is black (blank).
On second attempt, mStreetView.getStreetViewPanorama().getLocation() has a null response and the view stays hidden.
My code:
mStreetView.getView().setVisibility(View.GONE);
mStreetView.getStreetViewPanorama().setPosition(customMarker.getPosition());
if (mStreetView.getStreetViewPanorama().getLocation() != null &&
mStreetView.getStreetViewPanorama().getLocation().links != null) {
mStreetView.getView().setVisibility(View.VISIBLE);
}
I'm not sure how to go about debugging this. It seems to me that the results shouldn't vary like this, especially since, even though it has non-null results, the results have (apparently) no valid value to allow something to be displayed.
Edit:
This coordinate functions as expected and shows the view properly populated: 33.6645598,-111.9253126
This coordinate shows the view, but it is black, then later returns null: 33.6492448,-111.9354228
These results are consistent.
Edit2:
I attempted to use the OnStreetViewPanoramaReadyCallback(), however the results were the same.
Code is now:
mStreetView.getView().setVisibility(View.GONE);
mStreetView.getStreetViewPanoramaAsync(new OnStreetViewPanoramaReadyCallback() {
#Override
public void onStreetViewPanoramaReady(StreetViewPanorama streetViewPanorama) {
streetViewPanorama.setPosition(customMarker.getPosition());
if (streetViewPanorama.getLocation() != null && streetViewPanorama.getLocation().links != null) {
mStreetView.getView().setVisibility(View.VISIBLE);
}
}
});
In one of my old projects found there is a race condition if you try to access the location too early
what I did was setup a handler and have a post delayed runnable fire after 1000 milliseconds then check the location. Doing this provided consistent results.
I dont know if this is still the current behavior but you can read what I did here
Android StreetView check if there is any view for given location
Edit
there appears to be a onStreetViewPanoramaReady callback now, are you using that?
If you use the 'getLocation()' before the view has been created, it will return null. It is recommended to wait until view has been created. Also, you have to create a callback to let you know when the streetview is ready.
getStreetViewPanoramaAsync(new OnStreetViewPanoramaReadyCallback(){
#Override
public void onStreetViewPanoramaReady(StreetViewPanorama streetViewPanorama) {
}
})
Related
I have a MutableLiveData variable in my AppRepository which is updated and contains my data. This I have no issues with. I also have the following observable to trigger a UI update with the data it holds in my onCreateView function:
viewModel.projectWithContent.observe(viewLifecycleOwner, {
pwc = it
counterList = it.counterList
})
When I tap either to increase or decrease the counter count and then try to push the update to my Room database, it skips it. I have the following check currently:
if(counterList != null) {
try {
for(counter: Counter in counterList!!) {
if(counter.counter_count != pwc?.counterList!![
pwc?.counterList!!.indexOf(counter)
].counter_count) {
Log.i(LOG_TAG, "Hello")
} else {
Log.i(LOG_TAG, "Goodbye")
}
}
} catch(e: IndexOutOfBoundsException) {
e.printStackTrace()
}
}
It'll always go to Goodbye.
Now. If I put the following just below try
Log.i(LOG_TAG, "PWC: ${pwc?.counterList!![0].counter_count}, " +
"CPWC: ${counterList!![0].counter_count}," +
"VMPWC: ${viewModel.projectWithContent.value?.counterList!![0].counter_count}")
It provides the following output:
PWC: 70, CPWC: 70,VMPWC: 70
Is this a side effect of what I'm doing or?
Thanks
Like #Tenfour04 says, your condition is actually checking they don't match, so "Goodbye" is the output when they do match.
If you don't mind (this is a little long), I just want to recommend some stuff because I feel like you're making life hard for yourself with all the null-checking that's going on - the logic of the code was really hard to read, and I'm guessing that's why you didn't notice the flipped logic too!
First: the ? null safety stuff (and !! which is the opposite of safe, never use it unless you know you have good reason) is there because you have nullable variable types. Normally the IDE would smart cast them to non-null once you've done a null check (like on your first line) - but because they're vars, they can be changed at any time.
That means that a variable that wasn't null before could be now, so you're forced to null-check every single time you access it. But even if the types weren't nullable, because they're vars, they can still change, and the thing you were looking at a moment ago is something different now.
The simple solution is to just make a new variable:
val counters = counterList
if (counters != null) {
...
}
// or if you want to use one of kotlin's scope functions
counterList?.let { counters ->
...
}
Because that new one is a val, it's not going to change what it's pointing at! Once it's null-checked, it's always going to be non-null, so you don't need to use ? anymore.
You have a couple of variables to make - you want to make sure pwc isn't null, and also their counterLists. A quick way to do that is with pwc?.counterList - if pwc is null, it will return null. Otherwise it will move to the next step, and return counterList, which may be null. (Using !! is saying that it definitely never will be null, in which case it shouldn't be nullable at all!)
And you don't actually care about pwc anyway - you're just comparing its counterList to the other, so why don't we pare it back to just those?
val counters = counterList
val pwcCounters = pwc?.counterList
if (counters != null && pwcCounters != null) {
try {
for(counter: Counter in counters) {
if(counter.counter_count != pwcCounters[
pwcCounters.indexOf(counter)
].counter_count) {
Log.i(LOG_TAG, "Hello")
} else {
Log.i(LOG_TAG, "Goodbye")
}
}
} catch(e: IndexOutOfBoundsException) {
e.printStackTrace()
}
}
There's more we could do here, but just by cleaning up those nulls and using the specific variables we want to work with, does that feel easier to read? And more importantly, easier to understand what's happening and what could happen?
Might be worth throwing it in a function too, stops the call site getting cluttered with these temp variables:
fun doThing(counters: List<Counter>?, pwcCounters: List<Counter>?) {
if (counters == null || pwcCounters == null) return
// do the stuff
}
// when you want to do the thing:
doThing(counterList, pwc?.counterList)
So all your null checking is out of the way, your "temp variables" are the fixed parameters passed to the function, it's all nice and neat.
I know this is a long post for such a short bit of code, but it's a good habit to get into - if you're writing code where you're working with nullable vars and you're wrestling with the null safety system, or you keep repeating yourself to access a particular variable nested inside another object, you can make things a lot easier for yourself! You can imagine how wild this could all get for more complex code.
Also if you care, this is how I'd personally write it, if it helps!
fun doThing(counters: List<Counter>?, pwcCounters: List<Counter>?) {
if (counters == null || pwcCounters == null) return
// for (counter in Counters) is fine too I just like this version
counters.forEach { counter ->
// find returns the first item that matches the condition, or null if nothing matches,
// so no need to handle any exceptions, just handle the potential null!
// (this is a really common Kotlin pattern, lots of functions have a "returns null on failure" version)
val pwcCounter = pwcCounters.find { it == counter }
// remember pwcCounter can be null, so we have to use ? to access its count safely.
// If it evaluates to null, the match just fails
if (counter.count == pwcCounter?.count) Log.i(LOG_TAG, "Hello")
else Log.i(LOG_TAG, "Goodbye")
}
}
I also renamed counter_count to just count since it's a property on a Counter anyway. I feel like counter.count is easier to read than counter.counter_count, y'know? It's the little things
I've a list of waypoint of type STOP_WAYPOINT and onStopoverReached is fired with the wrong index (the var1 parameter). The route has the following coordinates:
latitude:42.896241 longitude:13.894039
latitude:42.897784 longitude:13.894991
latitude:42.89753 longitude:13.892602
latitude:42.896667 longitude:13.893728
It always recognize the first or the second, even if I reach the other ones.
The same function works flawlessly on the iOS SDK. Any clue?
private NavigationManager.NavigationManagerEventListener m_navigationManagerEventListener = new NavigationManager.NavigationManagerEventListener() {
#Override
public void onStopoverReached(int var1)
{
//var1 is the wrong index
}
}
m_navigationManager.addNavigationManagerEventListener( new WeakReference<NavigationManager.NavigationManagerEventListener>(m_navigationManagerEventListener));
In general the index returned from the callback are in sync with the provided Route plan and the same should be used to get the stop over waypoint.
From Documentation: https://developer.here.com/documentation/android-premium/api_reference_java/com/here/android/mpa/guidance/NavigationManager.NavigationManagerEventListener.html#onStopoverReached-int-
public void onStopoverReached(int index)
Callback indicating that a route stopover has been reached.
Note that in addition to this, NavigationManager.ManeuverEventListener.onManeuverEvent() callback will also be received. Furthermore, note that a RouteWaypoint of type RouteWaypoint.Type.VIA_WAYPOINT is not considered to be a route stopover.
Parameters:
index - The index of the stopover that was reached, starting from 0. Stopovers can be retrieved by index from the RoutePlan.
See Also:
RoutePlan.getWaypoint(int)
Here the Text Area is constantly changing in terms of number and I want to trigger an event when the Text Area gets a particular number example I have tried this -
public void myfunction45(Canvas Panel)
{
if (Indicator = 45) {
Panel.enabled = false;.
}
} //(indicator- www.progress).
But it does not work(it does not read it nothing happens). how do I match the condition as the number is to be specific. please give an example for explanation. Thanks in advance.
That if statement would cause you problems.
You would want:
if(Indicator == 5)
instead. At the moment you're assigning the value without checking it, this would cause a compiler error. If it's just a typo, then update your answer, slightly confusing otherwise.
With regards to checking the text value. You'd have to grab the text value, for that you need a reference to the Text area. This approach assumes that the text area has it's value set by a user. Currently you're not grabbing any text values to compare, as a result, the if statement won't know what to compare.
Here's one approach:
public void myfunction5(Canvas Panel)
{
float result;
string textValue = yourTextArea.text;
if(Single.TryParse(textValue, out result))
{
if(result == Indicator)
{
Panel.enabled = false;
}
}
}
You use TryParse to avoid any potential exceptions that would be thrown if the user entered something that wasn't a number. This method will take the value from your text area, how you get your text area is up to you, and try to parse the text value into a float. The method will return true if the parse was a success, false otherwise.
Here's the reference for the TryParse stuff:
https://msdn.microsoft.com/en-us/library/26sxas5t(v=vs.110).aspx
If you wanted to parse it to an int, then you'd be using the Int32's version of TryParse, https://msdn.microsoft.com/en-us/library/system.int32_methods(v=vs.110).aspx
I'd also recommend having a peak at the Input Field documentation: https://docs.unity3d.com/Manual/script-InputField.html
You can subscribe your method to the Input-fields On Value Changed event, your function will need to tweaked slightly though:
public void myfunction5(string text)
{
float result;
if(Single.TryParse(text, out result))
{
if(result == Indicator)
{
CachedPanel.enabled = false;
}
}
}
Don't forget to store a reference to the panel you want to disable.
Hopefully this is what you're after.
Panel is already a Canvas type, it doesn't make any sense to GetComponent<Canvas> on the same type.
Try using Panel.enabled = false;.
For the rest, we don't know how you get the Indicator reference, or how you built the UI hierarchy, so we can't assess if the problem is there.
Edit: I could I miss the single = baffles me lol. I should avoid answering questions when I'm tired.
I am using 'ion-infinite-scroll' in html to load more items from server for this i am using below code
<ion-infinite-scroll immediate-check="false" on-infinite="getListOfAreas()" distance="1%">
</ion-infinite-scroll>
Here, getListOfAreas() function is called when I scroll screen to bottom and it fetches data from server.This is getListOfAreas() function defined on controller
$scope.getListOfAreas = function (shoudlShowLoader) {
AreaBusiness.getAreasListing(shoudlShowLoader, function(serviceResponse) {
$scope.$broadcast('scroll.infiniteScrollComplete');
if (serviceResponse != null) {
var isSuccess = serviceResponse.Success;
if (isSuccess) {
}
}
}
}
On browser, i have debugged some how
$scope.$broadcast('scroll.infiniteScrollComplete');
above line of code keeps calling and spinner keep rotating.I don't know the reason. Am I missing anything?
$scope.$broadcast('scroll.infiniteScrollComplete'); only lets ionic know that the current page of data has been fetched and that it's safe to now fetch the next page. This does not indicate that all data has finished loading.
Looks like the official recommendation is to add an ng-if to the scroll delegate and remove it from dom once there is not more data to load.
Example:
<ion-infinite-scroll
ng-if="moreDataCanBeLoaded()"
icon="ion-loading-c"
on-infinite="loadMoreData()">
</ion-infinite-scroll>
Source: https://ionicframework.com/docs/api/directive/ionInfiniteScroll/
I have resolved the issue, after spending sometime. The issue which I found, I was not adding those elements into the list which were to be shown on UI. So, list was not being updated on controller that is why it kept calling.So I updated my code and added those fetched items from service to list associated to ui as mentioned in my below code
$scope.$broadcast('scroll.infiniteScrollComplete');
if (serviceResponse != null) {
var isSuccess = serviceResponse.Success;
if (isSuccess) {
if ($scope.areas != undefined && $scope.areas.length > 0) {
pushDataToPOIList(serviceResponse.PointOfInterestData);
} else {
$scope.areas = serviceResponse.PointOfInterestData;
}
pushDataToVehiclesList() method I added that is pushing new data into list to update list and on UI as well. This helped me to sort out the problem.
I am having a method, handling the correct/incorrect answers entered in a quiz game:
public void answerButtonClickHandler(View v)
{
Answer answer = myAnswers.get(v.getId());
if (answer != null)
{
myQuestionsAnswered++;
if (answer.isCorrect())
{
myCorrectlyAnswered++;
v.setBackgroundResource(R.drawable.answer_button_correct);
}
else
{
v.setBackgroundResource(R.drawable.answer_button_incorrect);
}
}
What it is doing so far is to check if the answer is correct or not (this part works fine) and sets a corresponding template. What I'd want to add as functionality is when the wrong answer is marked, the correct one to be marked as well. I was trying to keep the state of the vies (v) in a new View variable, in both of the states, but have not done the trick so far. Thanks you!