{ "id": "176199", "key": "TIMOB-28459", "fields": { "issuetype": { "id": "1", "description": "A problem which impairs or prevents the functions of the product.", "name": "Bug", "subtask": false }, "project": { "id": "10153", "key": "TIMOB", "name": "Titanium SDK/CLI", "projectCategory": { "id": "10100", "description": "Titanium and related SDKs used in application development", "name": "Client" } }, "fixVersions": [ { "id": "21199", "description": "", "name": "Release 10.0.1", "archived": false, "released": true, "releaseDate": "2021-07-28" } ], "resolution": { "id": "1", "description": "A fix for this issue is checked into the tree and tested.", "name": "Fixed" }, "resolutiondate": "2021-06-28T22:16:09.000+0000", "created": "2021-05-20T11:43:28.000+0000", "priority": null, "labels": [], "versions": [], "issuelinks": [ { "id": "59298", "type": { "id": "10003", "name": "Relates", "inward": "relates to", "outward": "relates to" }, "inwardIssue": { "id": "176249", "key": "TIMOB-28503", "fields": { "summary": "Android: ScrollableView UI does not render any more (10.0.1 regression)", "status": { "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.", "name": "Closed", "id": "6", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "priority": { "name": "Critical", "id": "1" }, "issuetype": { "id": "1", "description": "A problem which impairs or prevents the functions of the product.", "name": "Bug", "subtask": false } } } }, { "id": "59300", "type": { "id": "10003", "name": "Relates", "inward": "relates to", "outward": "relates to" }, "inwardIssue": { "id": "176250", "key": "TIMOB-28504", "fields": { "summary": "Android: ScrollableView \"views\" property not returning what was assigned during creation before window open as of 10.0.1", "status": { "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.", "name": "Closed", "id": "6", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "priority": { "name": "Critical", "id": "1" }, "issuetype": { "id": "1", "description": "A problem which impairs or prevents the functions of the product.", "name": "Bug", "subtask": false } } } } ], "assignee": { "name": "gmathews", "key": "gmathews", "displayName": "Gary Mathews", "active": true, "timeZone": "America/Los_Angeles" }, "updated": "2021-07-07T01:57:50.000+0000", "status": { "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.", "name": "Closed", "id": "6", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "components": [ { "id": "10202", "name": "Android", "description": "Android Platform" } ], "description": "When you add a ScrollableView inside a HeaderView with databinding the child views aren't visible. I've rebuild the generated classic code from my Alloy app to make it easier to test but here is the original Alloy part first:\r\n\r\nFor my initial test I've used mocx (https://github.com/jasonkneen/mocx/blob/master/mocx.js) inside the lib folder and this code inside alloy.js:\r\n{code}\r\nvar mocx = require(\"/mocx\");\r\nmocx.createCollection(\"contacts\", [{name : \"John Smith\"}, {name : \"Jane Doe\"}]);\r\n{code}\r\n\r\nmy xml:\r\n{code}\r\n\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n\r\n{code}\r\n\r\nmy controller \r\n{code}\r\nAlloy.Collections.contacts.fetch();\r\n$.index.open();\r\n{code}\r\n\r\nthe generated classic code looks like this:\r\n{code}\r\nfor (var __alloyId7, opts = __alloyId11.opts || {}, models = __alloyId10.models, len = models.length, views = [], i = 0; i < len; i++) {\r\n __alloyId7 = models[i], __alloyId7.__transform = transform(__alloyId7);\r\n var __alloyId9 = Ti.UI.createView({\r\n views: __alloyId6,\r\n apiName: \"Ti.UI.ScrollableView\",\r\n height: 200,\r\n classes: [],\r\n backgroundColor: \"red\"\r\n });\r\n views.push(__alloyId9);\r\n}\r\n$.__views.__alloyId5.views = views\r\n{code}\r\n\r\nIt is adding the views to an array and set it to {{scrollableview.views}}. So I've created a classic example that works in the same way (without databinding) which makes it easier to test:\r\n{code}\r\nconst win = Ti.UI.createWindow({\r\n\tbackgroundColor: '#fff',\r\n});\r\n\r\nconst sections = [];\r\n\r\nvar hv = Ti.UI.createView({\r\n\theight: 100,\r\n\tbackgroundColor: \"blue\"\r\n});\r\n\r\nvar sv = Ti.UI.createScrollableView({\r\n\theight: 100,\r\n\tbackgroundColor: \"yellow\"\r\n})\r\nvar views = [];\r\nfor (var i = 0; i < 10; ++i) {\r\n\tvar insideView = Ti.UI.createView({\r\n\t\theight: 100,\r\n\t\tbackgroundColor: \"rgba(\" + (i * 20) + \",\" + i + \",\" + i + \")\"\r\n\t});\r\n var lbl = Ti.UI.createLabel({\r\n text:\"should be visible\",\r\n color: \"#fff\"\r\n })\r\n insideView.add(lbl);\r\n\tsv.addView(insideView)\r\n}\r\nhv.add(sv);\r\nfor (let i = 0; i < 3; i++) {\r\n\tconst items = [];\r\n\r\n\tfor (let x = 0; x < 5; x++) {\r\n\t\titems.push({\r\n\t\t\tlabel: {\r\n\t\t\t\ttext: `Item #${x}`\r\n\t\t\t}\r\n\t\t});\r\n\t}\r\n\r\n\tsections.push(Ti.UI.createListSection({\r\n\t\theaderView: hv,\r\n\t\titems\r\n\t}));\r\n}\r\nconst listView = Ti.UI.createListView({\r\n\ttemplates: {\r\n\t\ttemplate: {\r\n\t\t\tproperties: {\r\n\t\t\t\tbackgroundColor: 'transparent'\r\n\t\t\t},\r\n\t\t\tchildTemplates: [{\r\n\t\t\t\ttype: 'Ti.UI.Label',\r\n\t\t\t\tbindId: 'label',\r\n\t\t\t\tproperties: {\r\n\t\t\t\t\tleft: 10,\r\n\t\t\t\t\tcolor: 'black'\r\n\t\t\t\t}\r\n\t\t\t}]\r\n\t\t}\r\n\t},\r\n\tbackgroundColor: \"#b3b3b3\",\r\n\tdefaultItemTemplate: 'template',\r\n\tsections: sections\r\n});\r\nwin.add(listView);\r\nwin.open();\r\n{code}\r\n\r\nThe result is the same: the scrollable child views won't appear.\r\n\r\nIf I'm not using the array and use {{sv.addView(insideView)}} inside the loop it works fine! If I compare both UIs in Android Studio I can see that the childviews are not added:\r\n\r\nusing views = array\r\n !no_childviews.png|thumbnail! \r\n\r\nusing addView\r\n !childviews.png|thumbnail! \r\n\r\n*Setup:*\r\n* Android 11/Pixel 4\r\n* Titanium SDK 10.1.0/10.0.0.GA", "attachment": [ { "id": "67926", "filename": "childviews.png", "author": { "name": "michael", "key": "michael", "displayName": "Michael Gangolf", "active": true, "timeZone": "Europe/Berlin" }, "created": "2021-05-20T11:41:41.000+0000", "size": 134489, "mimeType": "image/png" }, { "id": "67925", "filename": "no_childviews.png", "author": { "name": "michael", "key": "michael", "displayName": "Michael Gangolf", "active": true, "timeZone": "Europe/Berlin" }, "created": "2021-05-20T11:41:41.000+0000", "size": 94525, "mimeType": "image/png" }, { "id": "67929", "filename": "ScrollableViewAddRemoveTest.js", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2021-05-26T00:09:01.000+0000", "size": 3040, "mimeType": "application/x-javascript" } ], "flagged": false, "summary": "Android: ScrollableView with databinding in Footer/HeaderView not showing up", "creator": { "name": "michael", "key": "michael", "displayName": "Michael Gangolf", "active": true, "timeZone": "Europe/Berlin" }, "subtasks": [], "reporter": { "name": "michael", "key": "michael", "displayName": "Michael Gangolf", "active": true, "timeZone": "Europe/Berlin" }, "environment": null, "comment": { "comments": [ { "id": "458696", "author": { "name": "michael", "key": "michael", "displayName": "Michael Gangolf", "active": true, "timeZone": "Europe/Berlin" }, "body": "I'm currently debugging TiUIScrollableView.java to see if there is something wrong in the setViews code", "updateAuthor": { "name": "michael", "key": "michael", "displayName": "Michael Gangolf", "active": true, "timeZone": "Europe/Berlin" }, "created": "2021-05-20T11:44:08.000+0000", "updated": "2021-05-20T11:44:08.000+0000" }, { "id": "458697", "author": { "name": "michael", "key": "michael", "displayName": "Michael Gangolf", "active": true, "timeZone": "Europe/Berlin" }, "body": "Turns out that calling addView after the loop:\r\n{code}\r\nsv.addView(Ti.UI.createView({\r\n height: 100,\r\n backgroundColor: \"green\"\r\n}))\r\n{code}\r\nwill make it work. And running {{Alloy.Collections.contacts.fetch();}} in the Alloy example after the ListView is visible works, too. Might be some timing issue somewhere\r\n\r\n\r\nThis is some debug output when using Alloy.Collection.fetch():\r\n\r\n{noformat}\r\nProxy: views property <--- setViews() from ScrollableViewProxy\r\nprocess properties; views len: 0\r\nclear views\r\nset views; len: 0\r\nProxy: handle message\r\nclear views\r\nset views; len: 2\r\nProxy: views property <--- setViews() from ScrollableViewProxy\r\nProxy: handle message\r\nclear views\r\nset views; len: 2\r\nrelease list <---- release() from TiUIScrollableView\r\nprocess properties; views len: 0\r\nclear views\r\nset views; len: 0\r\n{noformat}\r\n\r\nI have two elements in my collection so len:2 is correct. I'm not sure why the whole {{setViews}} from ScrollableViewProxy is called twice! Then there is the {{release}} part from TiUIScrollableView at the bottom that is clearing the content at the end. ", "updateAuthor": { "name": "michael", "key": "michael", "displayName": "Michael Gangolf", "active": true, "timeZone": "Europe/Berlin" }, "created": "2021-05-20T12:21:41.000+0000", "updated": "2021-05-20T13:42:21.000+0000" }, { "id": "458698", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "body": "I haven't dived into this yet, but I'm wondering if it has something to do with us \"updating\" the HeaderView's activity object if it doesn't match the ListView's assigned activity object. We do this as of Titanium 10.0.0 so that dark/light theme switching will be applied to all child views which involves swapping out the old destroyed activity context with the new one.\r\nhttps://github.com/appcelerator/titanium_mobile/blob/master/android/modules/ui/src/java/ti/modules/titanium/ui/widget/listview/ListViewHolder.java#L302-L307\r\n\r\nI'm \"guessing\" that the ScrollableView or its children were initially assigned a different activity context. Like the previous activity window such as the splash and it's being swapped out immediately once the actual activity window that's hosting the ListView has been created/opened.", "updateAuthor": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2021-05-20T16:14:40.000+0000", "updated": "2021-05-20T16:14:40.000+0000" }, { "id": "458699", "author": { "name": "michael", "key": "michael", "displayName": "Michael Gangolf", "active": true, "timeZone": "Europe/Berlin" }, "body": "Your guess looks like the right direction:\r\n\r\nI've added\r\n{code}\r\nLog.i(\"----\", \"Context: \" + context + \" headerproxy act:\" + headerProxy.getActivity());\r\n\r\nif ((context instanceof Activity) && (headerProxy.getActivity() != context)) {\r\n\tLog.i(\"---\", \"release views\");\r\n\theaderProxy.releaseViews();\r\n\theaderProxy.setActivity((Activity) context);\r\n}\r\n{code}\r\n\r\nand got:\r\n\r\n{noformat}\r\nContext: org.appcelerator.titanium.TiActivity@92c8bbb headerproxy act:com.miga.random.TestAppActivity@af14391\r\nrelease views\r\nrelease list\r\nprocess properties; views len: 0\r\nclear views\r\nset views; len: 0\r\n{noformat}\r\n\r\nThis is AFTER the first the setViews part.", "updateAuthor": { "name": "michael", "key": "michael", "displayName": "Michael Gangolf", "active": true, "timeZone": "Europe/Berlin" }, "created": "2021-05-20T17:24:10.000+0000", "updated": "2021-05-20T17:24:10.000+0000" }, { "id": "458707", "author": { "name": "gmathews", "key": "gmathews", "displayName": "Gary Mathews", "active": true, "timeZone": "America/Los_Angeles" }, "body": "master: https://github.com/appcelerator/titanium_mobile/pull/12839", "updateAuthor": { "name": "gmathews", "key": "gmathews", "displayName": "Gary Mathews", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2021-05-25T00:14:46.000+0000", "updated": "2021-05-25T00:14:46.000+0000" }, { "id": "458822", "author": { "name": "cwilliams", "key": "cwilliams", "displayName": "Christopher Williams", "active": true, "timeZone": "America/New_York" }, "body": "merged to master", "updateAuthor": { "name": "cwilliams", "key": "cwilliams", "displayName": "Christopher Williams", "active": true, "timeZone": "America/New_York" }, "created": "2021-06-28T18:48:00.000+0000", "updated": "2021-06-28T18:48:00.000+0000" }, { "id": "458826", "author": { "name": "eharris", "key": "eharris", "displayName": "Ewan Harris", "active": true, "timeZone": "Europe/Dublin" }, "body": "10_0_X backport merged", "updateAuthor": { "name": "eharris", "key": "eharris", "displayName": "Ewan Harris", "active": true, "timeZone": "Europe/Dublin" }, "created": "2021-06-28T22:16:03.000+0000", "updated": "2021-06-28T22:16:03.000+0000" } ], "maxResults": 7, "total": 7, "startAt": 0 } } }