04-26-2018 23:12
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

04-26-2018 23:12
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
I want to implement a really long list and found VirtualTileList but I can't figure out how to implement it.
Someone has a simple example how to use it? Thanks!
https://dev.fitbit.com/build/reference/device-api/document/#interface-virtualtilelist

04-26-2018 23:46 - edited 04-26-2018 23:51
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

04-26-2018 23:46 - edited 04-26-2018 23:51
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Hi Gollygosh,
here you go!
GUI:
<svg> <symbol id='colour-item' href='#tile-list-item' class="tile-item" height='50' display='none' focusable="false" pointer-events="none" system-events="all">
<g id='transform'> <!-- here you can animate your tile-->
<rect id='bg' height='100%' width='100%' />
<text id='title-text' fill='white' y='35' x='5' text-length="20"></text>
<rect id='tile-divider-bottom' class='list-separator' />
</g>
</symbol>
<symbol id='separate-item' href='#tile-list-item' height='5' display='none'>
<rect id='bg' height='100%' width='100%' fill='black' />
<rect id='tile-divider-bottom' class='list-separator' />
</symbol>
<use id="my-list" href="#tile-list" y="0" x="0" width="100%" height="100%">
<var id="separator-height-bottom" value="2" />
<var id='virtual' value='1' />
<var id="reorder-enabled" value="1" />
<var id="peek-enabled" value="1" />
<use id='colour-pool' href='#tile-list-pool'>
<use id='colour-pool[1]' href='#colour-item' />
<use id='colour-pool[2]' href='#colour-item' />
<use id='colour-pool[3]' href='#colour-item' />
<use id='colour-pool[4]' href='#colour-item' />
<use id='colour-pool[5]' href='#colour-item' />
<use id='colour-pool[6]' href='#colour-item' />
<use id='colour-pool[7]' href='#colour-item' />
<use id='colour-pool[8]' href='#colour-item' />
<use id='colour-pool[9]' href='#colour-item' />
<use id='colour-pool[10]' href='#colour-item' />
<use id='colour-pool[11]' href='#colour-item' />
<use id='colour-pool[12]' href='#colour-item' />
<use id='colour-pool[13]' href='#colour-item' />
</use>
</use>
</svg>
Javascript:
var NUM_ELEMS = 100; this.list.delegate = { getTileInfo : function(index) {
let tile_tile = "lorem ipsum";
let tile_type = "my-type"; return { type : tile_type, title: tile_title, color : '#FF0000', //or which color you prefere index : index }; }, configureTile : function(tile, info) { tile.getElementById('bg').style.fill = info.color; tile.getElementById('title-text').text = info.title; tile.info = info;
tile.onclick = (evt) => {
// do what ever you want
tile.align({alignment: 'top', animate: true, redraw: true });
} } }; // KNOWN ISSUE: It is currently required that VTList.length be set AFTER VTList.delegate this.list.length = NUM_ELEMS;

04-27-2018 02:03
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

04-27-2018 02:03
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Please look at JonFitbit answer if you want more deteils

04-29-2018 03:04
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

04-29-2018 03:04
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Regardless whether I'm using this example, the original example or my own implementation I always get "Error 0 Critical glue error" in the console and a black screen on the simulator. Whenever I scroll (on the black screen) I get a bunch of new glue errors. Anybody has a clue?

05-01-2018 23:47
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post


05-01-2018 23:47
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
You could try this example: https://www.dropbox.com/s/rmmqalb6klmdcej/VirtualTileList.zip?dl=0

05-03-2018 06:29
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

05-03-2018 06:29
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
I can get it working now. I do get a strange bug (perhaps in my own code) where on one launch the virtual list will work fine, while on another launch of the app it will be limited to the number of tiles predefined in the SVG. Restarting the app most often fixes the issue. Perhaps some kind of race condition?

05-03-2018 08:31
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post


05-03-2018 08:31
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Would need to see what you're doing in code. Can you put it on github?

12-23-2018 09:04 - edited 12-27-2018 12:04
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

12-23-2018 09:04 - edited 12-27-2018 12:04
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
I am getting this at the moment. My virtual tile list will only display the number of tiles predefined in the pool in the .gui and frequently/normally refuses to show index 0 also. The length variable is showing as the actual size I want it to be (15) if I console.log this at runtime, but the app refuses to draw tiles 0 and 9-14 when my .gui has 8 pool indexes predefined.
I have tried this on the simulator and my Ionic, and have tried uninstalling the app and rebuilding, but always the same.
I'm using the code from Virtual Tile List on https://dev.fitbit.com/build/guides/user-interface/svg-components/views/ but I have changed some of the variable names to fit my own. I am also using the Ionic Views framework, but no idea if this matters...
@JonFitbit The sample .zip linked-to above also seems to be broken now. All I get is:
My .gui
<svg id="PickExerciseGUI" display="none"> <defs> <symbol id="tile" href="#tile-list-item" focusable="false" pointer-events="none" system-events="all" display="none"> <text id="text" /> <rect id="tile-divider-bottom" class="tile-divider-bottom" /> <rect id="touch-me" pointer-events="all" x="0" y="0" width="100%" height="100%-2" opacity="0" /> </symbol> </defs> <use id="list" href="#tile-list"> <var id="reorder-enabled" value="0" /> <var id="peek-enabled" value="1" /> <var id="separator-height-bottom" value="2" /> <var id="virtual" value="1" /> <use id="pool" href="#tile-list-pool"> <use id="pool[0]" href="#tile" class="tile-list-item" /> <use id="pool[1]" href="#tile" class="tile-list-item" /> <use id="pool[2]" href="#tile" class="tile-list-item" /> <use id="pool[3]" href="#tile" class="tile-list-item" /> <use id="pool[4]" href="#tile" class="tile-list-item" /> <use id="pool[5]" href="#tile" class="tile-list-item" /> <use id="pool[6]" href="#tile" class="tile-list-item" /> <use id="pool[7]" href="#tile" class="tile-list-item" /> </use> </use> </svg>
My .js
import document from "document"; import { View, $at, Application } from './view' import { log } from './log'; import { exercisesList } from './savedata' const $ = $at( '#PickExerciseGUI' ); export class PickExercise extends View { el = $(); list = $('#list'); onMount() { this.list.delegate = { getTileInfo: function(index) { log("Getting info for tile " + index); return { type: "pool", value: exercisesList.exercise[index].name, index: index }; }, configureTile: function(tile, info) { log("Configuring tile " + info.index + ": " + info.value); if (info.type == "pool") { tile.getElementById("text").text = info.value; let touch = tile.getElementById("touch-me"); touch.onclick = evt => { log("Selected Exercise: " + info.value); }; } } }; // list.length must be set AFTER list.delegate this.list.length = exercisesList.exercise.length; log("pickExercise list length = " + this.list.length); this.onKeyUp = () => { console.log("PickExercise: Up "); } this.onKeyDown = () => { console.log("PickExercise: Down"); } this.onKeyBack = () => { console.log( "PickExercise -> BuildWorkout"); Application.switchTo('BuildWorkout'); } } onRender(){} onUnmount(){} }
My .css
.tile-list-item { height: 55; } .tile-list-item text { height: 24; font-family: System-Regular; fill: white; } .tile-divider-bottom { x: 0; y: 100%-2; width: 100%; height: 2; fill: fb-extra-dark-gray; }
@

12-23-2018 16:09
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

12-23-2018 16:09
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Actually, I now suspect that it might be the Ionic Views framework which is breaking this... Finally have a working test project, and the only real difference I can see is that in this project I don't have to mark the svg in index.gui as display="none", as I don't need to stop it rendering.
Will see if it's possible to change this within the Ionic Views system tomorrow...

12-26-2018 04:31
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

12-26-2018 04:31
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
No, it wasn't that - it's that your pool seems to need to be a minimum of 10 tiles (i.e., 0-9 are all declared in your .gui file) before the system works properly... Simply adding two more slots into my pool has fixed the list in my main app and so now all 15 exercises show each time.
Will see if the pool size needs to grow further as I add more exercises into my text file.

12-30-2018 17:40
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

12-30-2018 17:40
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
I have just hacked a toy app which uses a VirtualTile list ... in a complex way.
There are 2 templates for each list item...and there is also a marquee in the mix 🙂
You can see the code at https://github.com/adiroiban/fitbit-os-assistant-relay
App Screenshot

06-24-2020 19:09
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

06-24-2020 19:09
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Reopening this after, what, two years! 🙂
I have my virtual tile list implemented and basic functionality is there. I tried adding:
<var id="reorder-enabled" value="1"/>
to the invocation in index.gui (not really expecting it to work) and it doesn't work, of course.
I guess I could attach my own mouse down and mouse up routines, but it's not clear how I could use this to reorder the list. Is there an example of reordering somewhere?

06-25-2020 16:07
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

06-25-2020 16:07
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Ok, I'll quickly mention here that it is entirely possible to attach routines to the onmouseup and onmousedown events of a tile, inside the configureTile() function. Using this, you can then save away the time when the mouse tile was touched, check it against when the tile was un-touched, and if that difference is more than, e.g., 1 second, you can scoot down all fo the tiles (in our list) and move this one to the top.
Having done that, you can then generate a refresh of the display by simply setting the VTList.length to something other than what it is. (I simply have it cycle between two values.)
You can also scroll the list to a particular item by setting VTList.value (Thanks "Sergio") to the item number which you want centered. (Of course, if you're moving the item to the top, then the autoscroll isn't needed so much.)

