Nativescript-ui-feedback: [Android] RadListView Footer Crash when using Swipe Actions

Created on 12 Jul 2019  路  7Comments  路  Source: ProgressNS/nativescript-ui-feedback

Tell us about the problem

https://play.nativescript.org/?template=play-tsc&id=aJ7qoX

On a RadListView that has Swipe actions and uses a Footer template, swiping on the footer causes a crash

Which platform(s) does your issue occur on?

Android Only

Please provide the following version numbers that your issue occurs with:

  • Progress NativeScript UI plugin version: "nativescript-ui-listview": "6.4.0",
  • CLI: 5.4.2
  • Cross-platform modules: ^5.4.3
  • Runtime(s): tns-android-5.4.0

Please tell us how to recreate the issue in as much detail as possible.

  1. https://play.nativescript.org/?template=play-tsc&id=aJ7qoX Open this on Playground - Android
  2. Try swiping on the footer

Is there code involved? If so, please share the minimal amount of code needed to recreate the problem.

Crash Log

An uncaught Exception occurred on "main" thread.
java.lang.ClassCastException: android.widget.TextView cannot be cast to android.view.ViewGroup
    at com.telerik.widget.list.SwipeActionsBehavior.onShortPressDrag(SwipeActionsBehavior.java:417)
    at com.telerik.widget.list.ListViewGestureListener.onShortPressDrag(ListViewGestureListener.java:216)
    at com.telerik.widget.list.ListViewGestureListener.onTouchEvent(ListViewGestureListener.java:101)
    at com.telerik.widget.list.RadListView.onTouchEvent(RadListView.java:544)
    at android.view.View.dispatchTouchEvent(View.java:12593)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3028)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2705)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3034)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2719)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3034)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2719)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3034)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2719)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3034)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2719)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3034)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2719)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3034)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2719)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3034)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2719)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3034)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2719)
    at com.android.internal.policy.DecorView.superDispatchTouchEvent(DecorView.java:441)
    at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1850)
    at android.app.Activity.dispatchTouchEvent(Activity.java:3413)
    at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:69)
    at com.android.internal.policy.DecorView.dispatchTouchEvent(DecorView.java:399)
    at android.view.View.dispatchPointerEvent(View.java:12832)
    at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:5674)
    at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:5200)
    at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4680)
    at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4733)
    at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4699)
    at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4839)
    at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4707)
    at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4896)
    at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4680)
    at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4733)
    at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4699)
    at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4707)
    at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4680)
    at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:7704)
    at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:7673)
    at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:7606)
    at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:7807)
    at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:187)
    at android.view.InputEventReceiver.nativeConsumeBatchedInputEvents(Native Method)
    at android.view.InputEventReceiver.consumeBatchedInputEvents(InputEventReceiver.java:178)

at android.view.ViewRootImpl.doConsumeBatchedInput(ViewRootImpl.java:7778)
    at android.view.ViewRootImpl$ConsumeBatchedInputRunnable.run(ViewRootImpl.java:7830)
    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1172)
    at android.view.Choreographer.doCallbacks(Choreographer.java:984)
    at android.view.Choreographer.doFrame(Choreographer.java:803)
    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1158)
    at android.os.Handler.handleCallback(Handler.java:873)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:193)
    at android.app.ActivityThread.main(ActivityThread.java:6863)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:537)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858

While this is being fixed, if there is any possible workaround, please suggest it in this thread

bug listview android

All 7 comments

Here's my temporary workaround
https://play.nativescript.org/?template=play-tsc&id=aJ7qoX&v=2
Add a swipe handler to your footer template, and do nothing in it.

I was having a similar problem, however, adding a _swipe_ handler did not work for me.

I then tried wrapping my Label in a StackLayout - It throwed me an error in _node_modules/nativescript-ui-listview/ui-listview.android.js_ on line 57 telling me it cannot read eachChildView of undefined.

Therefore, I wrote a patch for the _node_modules/nativescript-ui-listview/ui-listview.android.js_ which prevents the crashes - did not encounter any negative side effects (yet) :)

Right now my footer looks like this (nativescript angular) - note I also have the swipe handler included but it was not preventing the crash - with the patch I can also remove the swipe handler

FOOTER

<ng-template tkListViewFooter>
    <StackLayout background="#F0F" (swipe)="preventCrash($event)">
        <Label height="100" text="This is list footer"></Label>
    </StackLayout>
</ng-template>

PATCH

--- node_modules/nativescript-ui-listview/ui-listview.android.js
+++ node_modules/nativescript-ui-listview/ui-listview.android.js
@@ -54,13 +54,18 @@ function ensureExtendedReorderWithHandlesBehavior() {
             var originalItemIndex = this.owner().getChildAdapterPosition(itemView);
             var nsViewForItem = this.nsOwner._listViewAdapter.getViewForItem(this.nsOwner.getItemAtIndex(originalItemIndex));
             var reorderHandle = undefined;
-            nsViewForItem.eachChildView(function (view) {
-                if (view instanceof ReorderHandle) {
-                    reorderHandle = view;
-                    return false;
-                }
-                return true;
-            });
+            // if android footer is touched nsViewForItem is undefined
+            if(nsViewForItem === undefined) {
+                return itemView;
+            } else {
+                nsViewForItem.eachChildView(function (view) {
+                    if (view instanceof ReorderHandle) {
+                        reorderHandle = view;
+                        return false;
+                    }
+                    return true;
+                });
+            }
             return reorderHandle === undefined ? itemView : reorderHandle.nativeViewProtected;
         };
         return ExtendedReorderWithHandlesBehavior;

I also added 2 Hooks so that the patch gets applied

after-prepare Hook:

patch-radlist-footer-swipeaction.js

module.exports = require("../before-livesync/patch-radlist-footer-swipeaction");

before-livesync Hook:

patch-radlist-footer-swipeaction.js

const exec = require("child_process").exec;

// This module patches the radListView so you can use footer in combination with items that have swipe actions.

module.exports = function(logger) {

    logger.info("Patch RadListView for Android - So you can use footer in combination with items that have swipe actions.");

    return new Promise((resolve, reject) => { 
        exec( 'patch -p0 -l -f -i patches/radlist-footer-swipeaction.patch', () => {
            resolve();
        });
    });
};

I wanted to share it - maybe it is useful for someone - or maybe you guys even come up with a proper solution :)

best regards mp

@mpht
And what are you doing in preventCrash method?

Sorry - I was not clear. The "preventCrash" is just an empty handler - as you have recommended

Here's my temporary workaround
https://play.nativescript.org/?template=play-tsc&id=aJ7qoX&v=2
Add a swipe handler to your footer template, and do nothing in it.

But that alone did not work on my side - I had to do the patch

Interesting. Thanks for reporting that :)

Hi all,
I tested the provided sample project, however, was unable to recreate the issue with the latest nativescript-ui-listview(v7.0.0). Can you check if the problem is resolved on your side?

@tsonevn
Yes, I can confirm that this issue has been resolved :)
thank you

Was this page helpful?
0 / 5 - 0 ratings