Skip to content

Instantly share code, notes, and snippets.

@Jei
Forked from jpriebe/NestedScrollViewManager.js
Created February 20, 2018 16:53
Show Gist options
  • Save Jei/b89b918991b84a8d58b7eecc66455557 to your computer and use it in GitHub Desktop.
Save Jei/b89b918991b84a8d58b7eecc66455557 to your computer and use it in GitHub Desktop.
Appcelerator Titanium code for managing scrollviews inside of scrollviews
function NestedScrollViewManager (parent_view, child_views)
{
// Appcelerator Titanium code for managing scrollviews inside of scrollviews (not true Android
// NestedScrollViews, but just a horizontal scrollview inside of a vertical scrollview).
//
// If you want to put a horizontal scrollview inside a vertical scrollview (like the Netflix app UI),
// it seems to work reasonably well on iOS. But on android, the user experience is very janky.
// Unless the user's drag movements are nearly exactly horizontal, there will be some movement of
// the parent scrollview, and then it becomes very difficult to scroll the child view. Flinging is
// almost impossible.
//
// With a little code to detect the horizontal movement, we can temporarily lock the parent view
// from scrolling, making the behavior closer to that of ios.
//
// call it like this:
//
// var NestedScrollViewManager = require ('/path/to/NestedScrollViewManager');
// var nsvm = new NestedScrollViewManager (vertical_scrollview, horizontal_scrollview);
//
// (assuming vertical_scrollview is the parent scrollview containing horizontal_scrollview)
if (Ti.Platform.osname !== 'android')
{
return;
}
if (!_.isArray(child_views)) {
child_views = [child_views];
}
var startx,
starty,
direction_detected = false;
parent_view.addEventListener ('touchstart', function (e) {
parent_view.scrollingEnabled = true;
_.each(child_views, function(child_view) {
child_view.scrollingEnabled = true;
});
});
_.each(child_views, function(child_view) {
child_view.addEventListener('touchstart', function (e) {
startx = e.x;
starty = e.y;
direction_detected = false;
parent_view.scrollingEnabled = false;
child_view.scrollingEnabled = true;
e.cancelBubble = true;
});
child_view.addEventListener('touchmove', function (e) {
if (direction_detected)
{
return;
}
var deltax = Math.abs (e.x - startx);
var deltay = Math.abs (e.y - starty);
var distance = Math.sqrt (deltax * deltax + deltay * deltay);
if (distance > 10)
{
if (deltax > deltay)
{
parent_view.scrollingEnabled = false;
child_view.scrollingEnabled = true;
}
if (deltay > deltax)
{
parent_view.scrollingEnabled = true;
child_view.scrollingEnabled = false;
}
direction_detected = true;
}
});
});
}
module.exports = NestedScrollViewManager;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment