Why ion-infinite-scroll keeps calling on scrolling in Android? - android

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.

Related

Android AccessibilityService performAction() method not working

I am developing an accessibility service for Android. The service calls an app, and that app has a RecyclerView. Then I want to click on an element of the RecyclerView with performAction(AccessibilityNodeInfo.ACTION_CLICK) but it is not working. I know there are a few similar questions but none of them works for me. Also I checked the official documentation for the class of the performAction method https://developer.android.com/reference/android/view/accessibility/AccessibilityNodeInfo
This is my code:
#Override
public void onAccessibilityEvent(Accessibility event){
AccessibilityNodeInfo source = event.getSource();
if(source != null){
List<AccessibilityNodeInfo> list = source.findAccessibilityNOdeInfosByText("mystring");
list.get(0).performAction(AccessibilityNodeInfo.ACTION_CLICK);
}
}
This is my configuration xml file:
<accessibility-srvice xmlns...
android:accessibilityFeedbackType = "feedbackGeneric"
android:AccessibilityFlags = "flagDefault"
android:canPerformGestures = "true"
android:canRetrieveWIndowCOntent = "true"
I think I misunderstood something, but i don't know what can be. Any help is appreciated.
The simple answer is that while finding the node by text is fine, that particular node was not the node with the desired onClick event. The solution is to call
list.get(0).getParent().performAction(AccessibilityNodeInfo.ACTION_CLICK)
The clarifying discussion is below
I think .performAction(AccessibilityNodeInfo.ACTION_CLICK) is right, but there might be some other concerns. Sorry for posting as an answer but a comment is too small.
Are you sure the onAccessibilityEvent is being called? I don't think that is the right event, but I can't be sure. Maybe put a log in there to ensure it's calling the event when you expect it to be called.
Also, looking at the source might restrict your search, maybe instead of event.getSource() try using rootInActiveWindow (I use Kotlin so it might have a method, see https://developer.android.com/reference/android/accessibilityservice/AccessibilityService#getRootInActiveWindow(int))
EDIT: 28 March 2022
I have run this code on my own accessibility service and it does click the button. But it's very prone to overflow.
var ranOnce = false // prevent overflow
override fun onAccessibilityEvent(event: AccessibilityEvent?) {
if (event == null) return
if (event.eventType == TYPE_WINDOW_STATE_CHANGED) return
if (event.source != null && !ranOnce) {
val nodeList = rootInActiveWindow.findAccessibilityNodeInfosByText("Menu")
//event.source.findAccessibilityNodeInfosByText("Menu") // <-- always nothing in list
Log.d("onAccessibilityEvent", "List of nodes: $nodeList")
if (nodeList.size > 0) {
android.util.Log.d("onAccessibilityEvent", "Node info: ${nodeList[0]}")
ranOnce = true
nodeList[0].performAction(AccessibilityNodeInfo.ACTION_CLICK) //<-- caused an infinite loop!
} else {
Log.d("onAccessibilityEvent", "No nodes found")
}
} else {
Log.d("onAccessibilityEvent", "event.source is null!")
}
}

How to make case REMOVED fire when the last element is removed from Firestore?

I'm trying to listen for real-time updates and I'm using the following code in onEvent:
override fun onEvent(querySnapshot: QuerySnapshot?, e: FirebaseFirestoreException?) {
if (e != null) return
if (!querySnapshot!!.isEmpty) {
for (change in querySnapshot.documentChanges) {
value = when (documentChange.type) {
Type.ADDED -> change.document.toObject<Item>(Item::class.java)
Type.MODIFIED -> change.document.toObject<Item>(Item::class.java)
Type.REMOVED -> vchange.document.toObject<Item>(Item::class.java)
}
}
} else {
logErrorMessage("querySnapshot.isEmpty")
}
}
Let's assume we have 2 elements added in a collection. For each addition, case Type.ADDED is triggered. If I remove one of them, Type.REMOVED is triggered. The problem comes, when I try to remove the last item. Instead of having case Type.REMOVED triggered for the last time, I get an empty querySnapshot. So the Type.REMOVED case is not triggered anymore. How can I be notified when the last element is removed?
The problem could be that your code is only looking for document changes if the query results are not empty. If the results become empty, you're just not checking to see if there was a change that made it empty. Remove the check for !querySnapshot!!.isEmpty and just list each change regardless.
If your querySnapshot is empty then you won't satisfy the if condition, therefore, you won't enter any of the cases on your when statement.
Also, since your snapshot is empty, there is no data to map to your Item.class

how to delete an element in xamarin forms webview

i want to delete an element in Xamarin.forms WebView when it's loading but it return null and app crash . how can i do this?
i tried to check if an element exist but dont have any success.
this is my code
protected void OnNavigating(object sender, WebNavigatingEventArgs args)
{
Webview.Eval("const elements = document.getElementsByClassName(\"footer-section\"); while (elements.length > 0) elements[0].remove();");
}
please help me. thanks
You are getting a null exception because the WebView is not loaded when you try to execute Javascript.
In order to prevent this, you can subscribe to OnNavigated Event:
WebView.Navigated Event
Event that is raised after navigation completes.
So, here is a sample:
public YourWebViewPage()
{
InitializeComponent ();
Webview.Navigated += WebViewNavigated;
}
private void WebViewNavigated(object sender, WebNavigatedEventArgs e)
{
Webview.Eval("const elements = document.getElementsByClassName(\"footer-section\"); while (elements.length > 0) elements[0].remove();");
}
You can try to override function onPageCommitVisible
The Android documentation says:
This callback can be used to determine the point at which it is safe
to make a recycled WebView visible, ensuring that no stale content is
shown. It is called at the earliest point at which it can be
guaranteed that WebView#onDraw will no longer draw any content from
previous navigations. The next draw will display either the
WebView#setBackgroundColor of the WebView, or some of the contents of
the newly loaded page.
This method is called when the body of the HTTP response has started
loading, is reflected in the DOM, and will be visible in subsequent
draws. This callback occurs early in the document loading process, and
as such you should expect that linked resources (for example, CSS and
images) may not be available.
You can try the following code:
public override void OnPageCommitVisible(WebView view, string url)
{
string _javascript = "const elements =
document.getElementsByClassName('footer-section'); for(i=0;i<elements.length;i++) {
if(elements[i] != null){ elements[i].parentNode.removeChild(elements[i]); }}";
view.EvaluateJavascript(_javascript, null);
base.OnPageCommitVisible(view, url);
}

Xamarin Forms - Lagging ScrollView after updating UI with HTTP POST Request Results

I'm working in the PCL with the last stable version of Xamarin Forms. For the moment, the targeted platform is Android.
First, I get the results from my HTTP POST request which is working perfectly fine.
Then, when I try to update the UI, the scrollview in which the results are displayed is lagging when I scroll down.
I think it might be a threading problem : the update of the UI may not be executed in the right thread.
I tried to use Device.BeginInvokeOnMainThread(() => { //Update the UI }); but it is not working.
Thanks.
Here is some of my code to help us :
Main Method:
private async void Search() {
ResponseService results = await libSearch.getResults(this.searchEntry.Text);
if (results.error != true) {
List<Choice> list = (List<Choice>)results.obj;
if(list.Count != 0) {
foreach(Choice choice in list) {
Device.BeginInvokeOnMainThread(() => {
addNewChoice(choice);
});
}
}
}
AddNewChoice Method:
private void addNewChoiceOnUI(Choice choice) {
ChoiceTemplate Choice = new ChoiceTemplate(choice.name, choice.img, choice.address);
this.Choices.Children.Add(Choice);
}
The Web Service Call Method seems to work. It looks like this :
public async Task<ResponseService> getResults(string zipcode) {
(...)
JObject results = await JsonWebRequest.getDataFromService(queryString).ConfigureAwait(false);
(...)
As you can see, I'm using an await on the web service call method and on the main method only. I'm also using ConfigureAwait(false); on the web service call method. I already tried numerous solutions. I would be so grateful if we could find a solution to avoid the lag.

accessing data from concurrentHashMap while it gets updated in background android

I have a static concurrentHashMap object which is been updated in background. While it is getting updated, I want to access the values from it in another thread. I am using concurrentHashMap which I understand from the documentation and thinks that it would suit this scenrio
Here is what I am doing
for (Map.Entry<String, ArrayList<property>> entry : alldata.entrySet())
{
udata.put(entry.getKey(), new ArrayList<property>(entry.getValue()));
}
in above code I am updating udata on getting data from server but in background.
While in another thread I am accessing some info out of it ..
for (String s: sTypes)
{
if(jprocess.udata != null)
{
if (jprocess.udata.get(s) != null)
{
if (jprocess.udata.get(s).size() > 0) {
if (xcor < jprocess.udata.get(s).size())
if (xcor != -1) {
allData.add(jprocess.udata.get(s).get(xcor));
}
}
}
}
}
but when I try to access any indexfrom it I can not access anything I hope it is clear what I want..
I already tried ConcurrentHashMap which should work for this situation but may be I did not understand it well..
If you are using ConcurrentHashMap, then there is not point it will not work. I strongly doubt that you are trying to access wrong index or you do not have synchronization between inserting and accessing the particular index.
For that just check the size of udata and value of xcor in your code and in each if condition.
In addition, read this carefully and for sure you will be convinced that ConcurrentHashMap is right solution for your issue.

Categories

Resources