Topener / nl.fokkezb.pullToRefresh

Widget to implement a table pull-to-refresh header in Titanium Alloy
184 stars 60 forks source link

App crash #39

Closed mikaelpopowicz closed 9 years ago

mikaelpopowicz commented 9 years ago

Hi,

I follow steps in ReadMe. The view contains an empty TableView that is filled with myRefresher function. Without the widget the loadAllNews function works fine. The module is installed. I installed the widget with gittio.

View

<Alloy>
    <Widget id="ptr" src="nl.fokkezb.pullToRefresh" onRelease="myRefresher">
        <TableView id="newsList" backgroundcolor="#f1f2ef">
        </TableView>
    </Widget>
</Alloy>

Controller

var loadAllNews = function() {
    var loaderArgs = {
        callbackFunction : callBackLoadAllNews,
        url              : Alloy.CFG.Urls.baseURL + Alloy.CFG.Urls.getAllNews 
    };
    loader.get(loaderArgs);
};

var callBackLoadAllNews = function(argsNews) {
    if(argsNews != null) {
        Ti.API.log(argsNews);
        $.newsList.setData([]);
        $.newsList.removeAllChildren();
        var rows = [];
        for (var i = 0; i < argsNews.result; ++i)
        {
            var row = Alloy.createController("newsRow", argsNews.data[i]).getView("newsItem");
            rows.push(row);
        }
        $.newsList.setData(rows);
    }
};

function myRefresher(e) {
    loadAllNews();
    e.hide();
}

$.ptr.refresh();

Log

[WARN] :   dalvikvm: threadid=1: thread exiting with uncaught exception (group=0xb0d72b20)
[ERROR] :  TiApplication: (main) [16292,16292] Sending event: exception on thread: main msg:java.lang.ClassCastException: java.util.HashMap cannot be cast to org.appcelerator.titanium.proxy.TiViewProxy; Titanium 3.5.0,2015/01/12 15:33,0014f83
[ERROR] :  TiApplication: java.lang.ClassCastException: java.util.HashMap cannot be cast to org.appcelerator.titanium.proxy.TiViewProxy
[ERROR] :  TiApplication:   at org.appcelerator.titanium.proxy.TiViewProxy.handleMessage(TiViewProxy.java:230)
[ERROR] :  TiApplication:   at android.os.Handler.dispatchMessage(Handler.java:98)
[ERROR] :  TiApplication:   at android.os.Looper.loop(Looper.java:136)
[ERROR] :  TiApplication:   at android.app.ActivityThread.main(ActivityThread.java:5017)
[ERROR] :  TiApplication:   at java.lang.reflect.Method.invokeNative(Native Method)
[ERROR] :  TiApplication:   at java.lang.reflect.Method.invoke(Method.java:515)
[ERROR] :  TiApplication:   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
[ERROR] :  TiApplication:   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
[ERROR] :  TiApplication:   at dalvik.system.NativeStart.main(Native Method)
FokkeZB commented 9 years ago

I'm not sure if it will fix your issue, but there are some things wrong in your controller code. See this improved (but unchecked) version.

See readme for more info.

function myRefresher(e) {
  loader.get({
    callbackFunction: function(argsNews) {
      if (argsNews !== null) {
        var rows = [];
        for (var i = 0; i < argsNews.result; ++i) {
          var row = Alloy.createController("newsRow", argsNews.data[i]).getView("newsItem");
          rows.push(row);
        }
        $.newsList.setData(rows);
        e.hide(); // or call e.done() if there are no more rows
      } else {
        e.error();
      }
    },
    url: Alloy.CFG.Urls.baseURL + Alloy.CFG.Urls.getAllNews
  });
}

$.ptr.refresh();
mikaelpopowicz commented 9 years ago

First, thank you for this fast answer.

I tried your solution, unfortunatly it doesn't work. Il also try to remove the trigger function and the fisrt call ($.ptr.refresh()). It seems that just have the widget in the view causes the crash.

Do you have a demo app which I could check differences with mine ?

FokkeZB commented 9 years ago

Yep, the test branch: https://github.com/FokkeZB/nl.fokkezb.pullToRefresh/tree/test

mikaelpopowicz commented 9 years ago

I find a solution !

I add a Window to wrap my View, it works fine now. Thanks again.

FokkeZB commented 9 years ago

Good one, I'll add a note the widget can't be the root element.

mikaelpopowicz commented 9 years ago

In my case the widget was added to a View, already inside a Window. It works with Window -> View -> Window -> Widget

FokkeZB commented 9 years ago

WTF! That can't be right. Could you enlight me on the exact hierarchy of views and required controllers/widget?

mikaelpopowicz commented 9 years ago

Don't forget I'm new in Ti.

In index I use your drawer module which uses Views (for Android). I load other contents in the center view. So in my news case I have View (from index, Center role) -> Window -> Widget. Without the Window it doesn't work.

FokkeZB commented 9 years ago

A Window should only be used a as a top level view. Replace it with a View.

Any chance you could give me access to the project so I can have a look what is going wrong?

mikaelpopowicz commented 9 years ago

Hi,

There is a lite copy of my project here : https://github.com/miko91/test-widget

I was wrong about one thing, the widget should be wrapped by Window or View in the in the xml file. See by yourself.

FokkeZB commented 9 years ago

Seems that you've found an Alloy bug. Without a parent view/window the news.xml compiles to:

    $.__views.ptr = Alloy.createWidget("nl.fokkezb.pullToRefresh", "widget", {
        id: "ptr",
        targetId: "newsList",
        children: [ $.__views.newsList ],
        __parentSymbol: __parentSymbol
    });
    $.__views.ptr && $.addTopLevelView($.__views.ptr);

The last line should be:

    $.__views.ptr && $.addTopLevelView($.__views.ptr.getView());

I'll create a ticket.

FokkeZB commented 9 years ago

JIRA ticket to follow: https://jira.appcelerator.org/browse/ALOY-1256

FokkeZB commented 9 years ago

Closing as not our bug.

nuno commented 9 years ago

@FokkeZB, @miko91 there is a temporary fix for this situation? Im with the same issue.

<View class="container">
<Widget id="ptr" src="nl.fokkezb.pullToRefresh" onRelease="myRefresher">
<ListView id="listView" backgroundColor="white" defaultItemTemplate="template" module="CollectionView" method="createCollectionView">
.....
</Widget>
</View>

still fails with the view.`

P.S Just in Android

FokkeZB commented 9 years ago

Are you sure that is the same issue? In your example the widget is not the root view.

nuno commented 9 years ago

I will make a test case, yeah not sure if is this problem or not, is hard to me read the compiler alloy files, so no better person than you to take a look :)

nuno commented 9 years ago

As I can see the man issue is nl.fokkezb.pullToRefresh with kr.yostudio.drawer and CollectionView Module If remove the <Widget id="ptr" src="nl.fokkezb.pullToRefresh" onRelease="myRefresher"> part works ok, can be the problem widget inside widgets, @FokkeZB ?

FokkeZB commented 9 years ago

Widgets in widgets should be fine. It's just controllers. But there can be troubles with toplevel selection.

I'd suggest making a minimal test case that reproduces and then drop it somewhere including Resources so we can investigate the compiled source code for errors.

nuno commented 9 years ago

All the problems above that I mentioned is related to this issue, odd!!! Since when the order of modules in tiapp.xml is very very important?

Where is comment out not work, the other block just works.

The order is important?

    <modules>
        <module platform="iphone">de.marcelpociot.collectionview</module>
        <module platform="android">de.marcelpociot.collectionview</module>
        <module platform="android">com.rkam.swiperefreshlayout</module>
        <module platform="android">com.tripvi.drawerlayout</module>
    </modules>
    <!--  <modules>
        <module platform="android">com.tripvi.drawerlayout</module>
        <module platform="android">com.rkam.swiperefreshlayout</module>
        <module platform="android">de.marcelpociot.collectionview</module>
        <module platform="iphone">de.marcelpociot.collectionview</module>
    </modules> -->

All weekend debuging to the app error and then somehow I changed the order of modules and worked WTF.

Thanks anyway :) You can close this, sorry :+1:

FokkeZB commented 9 years ago

For Android it might be important indeed and you should see messages about conflicting (duplicate) resources in the different JAR files in that case.