Back to index

Building a Grid Demo using Rikulo


Continued from the previous post, this time we are going to build a grid sample, with scrolling on both directions. In addition, we would like to try the events on ScrollView and Scroller control functions, by contructing multiple ScrollViews whose scrolling are "linked" to each others.

The Outcome

Grag or swipe on the each area to scroll.

Prepare ScrollView and Their Contents.

The ScrollView and content preparation itself is quite straightforward. You can refer to the previous blog post or the source code. Here is an overview of what we do:

final int barSize = 50, barInnerSize = 40;
final Size msize = new DOMQuery(mainView).innerSize;

final View container = new View();
container.profile.text = "location: center center; width: 80%; height: 80%";
final csize = new DOMQuery(container).innerSize;

final ScrollView view = new ScrollView();
view.profile.text = 
    "location: bottom right; width: ${csize.width - barSide}px; height: ${csize.height - barSide}px";

final ScrollView hbar = new ScrollView(direction: Dir.HORIZONTAL);
hbar.profile.anchorView = view;
hbar.profile.text = "location: north center; width: 100%; height: ${barSize}px";
hbar.classes.add("list-view list-view-hbar");

final ScrollView vbar = new ScrollView(direction: Dir.VERTICAL);
vbar.profile.anchorView = view;
vbar.profile.text = "location: west center; width: ${barSize}px; height: 100%";
vbar.classes.add("list-view list-view-vbar");

// fill children
// ...

Cling Together

To link these parts, there are two things we need to handle: 1. When user starts scrolling on one ScrollView, stop current scrollings on the others, if any. 2. While scrolling, update scroll position of linked ScrollViews as well.

view.on.scrollStart.add((ScrollEvent event) {
view.on.scrollMove.add((ScrollEvent event) {
    hbar.scroller.scrollPosition = vbar.scroller.scrollPosition = event.state.position;

hbar.on.scrollStart.add((ScrollEvent event) {
hbar.on.scrollMove.add((ScrollEvent event) {
    view.scroller.scrollPosition = 
        new Offset(event.state.position.x, view.scroller.scrollPosition.y);

vbar.on.scrollStart.add((ScrollEvent event) {
vbar.on.scrollMove.add((ScrollEvent event) {
    view.scroller.scrollPosition = 
        new Offset(view.scroller.scrollPosition.x, event.state.position.y);

Be Responsive

In the current code, the size depends on browser window size. However, if we resize the window after the page is loaded, some of the component sizes will not change. To make it responsive, we have to intercept the size setting in the pre-layout event:

final ScrollView view = new ScrollView();
view.profile.text = "location: bottom right";

view.on.preLayout.add((LayoutEvent event) {
    final cs = new DOMQuery(container).innerSize;
    view.width = cs.width - barSize;
    view.height = cs.height - barSize;

In the future we may come up with a more natural and intuitive way to support responsive design implementation.


Many of the motion/gesture related constructions come with the same lifecycle callbacks: start, move, and end.

For example, you may often consider:

  • Interrupt some current actions when a gesture/motion starts.
  • Update the state of some element when a gesture/motion is running.
  • When a gesture/motion ends, trigger another motion.

The homogeneity makes it easy chain or link these constructions together to compose them into a larger unit, and we believe these patterns should be quite friendly to web effect/animation designers.

comments powered by Disqus