iskugor / Ti.SwipeRefreshLayout

Titanium module for Android's SwipeRefreshLayout.
56 stars 19 forks source link

app crashs on thrid navigation to View "the specified child already has a parent" #9

Open lukemcredmond opened 9 years ago

lukemcredmond commented 9 years ago

SDK 3.3.0 OSX Titanium Studio, build: 3.4.1

view

<Alloy>
    <View id="Wrapper">
        <Require type="widget" src="com.mcongrove.navigationBar" id="NavigationBar" image="logo.png" />
        <View id="content">
            <View id="NonRows">
                <Label id="heading" />
                <Label id="text" />
            </View>
            <Widget id="ptr" src="nl.fokkezb.pullToRefresh" onRelease="refreshList">
                <TableView id="container">
                    <Widget id="is" src="nl.fokkezb.infiniteScroll" onEnd="nextbatch" />
                </TableView>
            </Widget>
        </View>
    </View>
</Alloy>

controler

$.init = function() {
    $.is.init($.container);
    $.ptr.refresh();
};

function refreshList(e) {
    var callback = function(result) {
        ProcessResults(result);//builds up array and set it with this call  $.container.setData(rows);
        if (e) {
            e.hide();
        }
    };
    rows = [];
    _params.StartIndex = 0;
    _params.Force = true;
    $.GetData(e, callback);//Calls rest api to get the data
}

$.init();

using com.mcongrove.tabs for navigation and on selection i call a handleNavigation function,

handleNavigation : function(_id) {
            APP.Tabs.setIndex(_id);
            APP.currentStack = _id;

            // Create new controller stack if it doesn't exist
            if ( typeof APP.controllerStacks[_id] === "undefined") {
                APP.controllerStacks[_id] = [];
            }

            // Set current controller stack
            var controllerStack = APP.controllerStacks[_id];

            // If we're opening for the first time, create new screen
            // Otherwise, add the last screen in the stack (screen we navigated away from earlier on)
            var screen;

            APP.hasDetail = false;
            APP.previousDetailScreen = null;

            if (controllerStack.length > 0) {
                // Retrieve the last screen

                    screen = controllerStack[controllerStack.length - 1];

                    controllerStack[0].fireEvent("APP:screenAdded");

            } else {
                // Create a new screen
                var type = APP.Nodes[_id].type.toLowerCase();
                screen = Alloy.createController(type, APP.Nodes[_id]).getView();

                // Add screen to the controller stack
                controllerStack.push(screen);

                    screen.fireEvent("APP:screenAdded");

            }

            // Add the screen to the window
            addScreen(screen);

            // Reset the modal stack
            APP.modalStack = [];
        }
    }

addScreen : function(_screen) {
        if (_screen) {

                APP.ContentWrapper.add(_screen);

                if (APP.previousScreen) {
                    APP.removeScreen(APP.previousScreen);
                }

                APP.previousScreen = _screen;

        }
    }

the above code works perfect the first time, after navigating away and returning the 2nd time no error but list does not appear,

navigate away again and return to the view and exception is threw, in the processProperties function in the SwipeRefresh.java

i changed the function to

@Override
    public void processProperties(KrollDict d) {
        if (d.containsKey(PROPERTY_VIEW)) {
            Object view = d.get(PROPERTY_VIEW);
            if (view != null && view instanceof TiViewProxy) {
                this.view = (TiViewProxy) view;
                // view is table
                // layout is the SwipeRefreshLayout

                this.layout.setNativeView(this.view.getOrCreateView()
                        .getNativeView());

                try {
                    //this.layout.addView(this.view.getOrCreateView().getOuterView());
                    ViewGroup p = (ViewGroup)this.view.getOrCreateView().getNativeView().getParent();
                    if(p != null){
                        p.removeView(this.view.getOrCreateView().getNativeView());
                    }
                    this.layout.addView(this.view.getOrCreateView().getOuterView());

                } catch (Exception ex) {
                    Log.e("TiAPI", ex.getMessage());

                    ViewGroup p = (ViewGroup)this.view.getOrCreateView().getNativeView().getParent();
                    p.removeView(this.view.getOrCreateView().getNativeView());

                    this.layout.addView(this.view.getOrCreateView().getOuterView());
                }
                // this.layout.setVisibility(View.VISIBLE);
                // this.view.getOrCreateView().getOuterView().setVisibility(View.VISIBLE);

                this.layout.setColorScheme(color1, color2, color3, color4);
            }
        }
        super.processProperties(d);
    }

exception no longer occurs but the list is not displaying

mikefogg commented 9 years ago

@lukemcredmond @dyan02 Hmm, I seem to be getting the same thing! Aside from the workaround, any progress on this? I'm going to take a look and see if i can figure out why it's happening but figured I'd double check before I do :)

tlenclos commented 9 years ago

Same for me, multiple ListView in a ScrollableView... :( @mikefogg @iskugor any idea ?

kilikdudu commented 9 years ago

Same for me.

iskugor commented 8 years ago

Please check latest 0.6 module version.

koolll commented 8 years ago

me facing this issue also. any solution? try 0.6 module for android . same crash :(

DFoxinator commented 8 years ago

Has anyone found a solution to this?

tlenclos commented 8 years ago

It should be fixed with https://github.com/iskugor/Ti.SwipeRefreshLayout/pull/17

DFoxinator commented 8 years ago

@tlenclos thanks for the response. I'm not sure if it's maybe a different error, but I've been getting a lot of crash reports that look like this (using the latest version):

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.myappname/org.appcelerator.titanium.TiActivity}: java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2413)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2471)
    at android.app.ActivityThread.access$900(ActivityThread.java:175)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1308)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:146)
    at android.app.ActivityThread.main(ActivityThread.java:5602)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
    at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:132)
    at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
    at android.view.ViewGroup.addViewInner(ViewGroup.java:3770)
    at android.view.ViewGroup.addView(ViewGroup.java:3623)
    at de.robv.android.xposed.XposedBridge.invokeOriginalMethodNative(Native Method)
    at de.robv.android.xposed.XposedBridge.handleHookedMethod(XposedBridge.java:631)
    at android.view.ViewGroup.addView(Native Method)
    at android.view.ViewGroup.addView(ViewGroup.java:3568)
    at de.robv.android.xposed.XposedBridge.invokeOriginalMethodNative(Native Method)
    at de.robv.android.xposed.XposedBridge.handleHookedMethod(XposedBridge.java:631)
    at android.view.ViewGroup.addView(Native Method)
    at android.view.ViewGroup.addView(ViewGroup.java:3544)
    at de.robv.android.xposed.XposedBridge.invokeOriginalMethodNative(Native Method)
    at de.robv.android.xposed.XposedBridge.handleHookedMethod(XposedBridge.java:631)
    at android.view.ViewGroup.addView(Native Method)
    at com.rkam.swiperefreshlayout.SwipeRefresh.processProperties(SwipeRefresh.java:67)
    at org.appcelerator.kroll.KrollProxy.setModelListener(KrollProxy.java:1219)
    at org.appcelerator.titanium.proxy.TiViewProxy.realizeViews(TiViewProxy.java:509)
    at org.appcelerator.titanium.proxy.TiViewProxy.handleGetView(TiViewProxy.java:500)
    at org.appcelerator.titanium.proxy.TiViewProxy.getOrCreateView(TiViewProxy.java:478)
    at org.appcelerator.titanium.proxy.TiViewProxy.realizeViews(TiViewProxy.java:516)
    at org.appcelerator.titanium.proxy.TiViewProxy.handleGetView(TiViewProxy.java:500)
    at org.appcelerator.titanium.proxy.TiViewProxy.getOrCreateView(TiViewProxy.java:478)
    at org.appcelerator.titanium.proxy.TiViewProxy.realizeViews(TiViewProxy.java:516)
    at org.appcelerator.titanium.proxy.TiViewProxy.handleGetView(TiViewProxy.java:500)
    at org.appcelerator.titanium.proxy.TiViewProxy.getOrCreateView(TiViewProxy.java:478)
    at org.appcelerator.titanium.proxy.TiViewProxy.handleAdd(TiViewProxy.java:679)
    at org.appcelerator.titanium.proxy.TiViewProxy.add(TiViewProxy.java:573)
    at ti.modules.titanium.ui.WindowProxy.windowCreated(WindowProxy.java:258)
    at org.appcelerator.titanium.TiActivityWindows.windowCreated(TiActivityWindows.java:33)
    at org.appcelerator.titanium.TiBaseActivity.windowCreated(TiBaseActivity.java:524)
    at org.appcelerator.titanium.TiBaseActivity.onCreate(TiBaseActivity.java:638)
    at org.appcelerator.titanium.TiActivity.onCreate(TiActivity.java:18)
    at android.app.Activity.performCreate(Activity.java:5451)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1093)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2377)
    ... 12 more
DFoxinator commented 7 years ago

Bumping this, anyone ever figure this out? This still happens :/