如何重新创建Android Facebook应用程序's浏览用户体验

How to Recreate the Android Facebook app's view swiping UX?

本文关键字:浏览 用户 体验 创建 何重新 Android Facebook 应用程序      更新时间:2023-09-26

我想做一些与Facebook安卓应用程序的用户体验完全一样的东西,用于在新闻推送、好友请求、消息和通知之间滑动。你应该能够通过向左或向右平移来"窥视"下一个视图,如果超过了某个阈值或滑动时,它应该在释放时捕捉到下一页。

我见过的每个滚动快照解决方案都只在滚动停止后进行快照,而我只想一次滚动一页。

编辑:这是我目前为止所拥有的。在谷歌Chrome中模拟安卓设备时,它似乎工作得很好,但当我在运行4.4.2的Galaxy S4上运行它时,它就不起作用了。仔细观察一下,似乎在第一次触摸移动事件之后就触发了触摸取消,这似乎是一个错误。有什么办法绕过这个吗?

var width = parseInt($(document.body).width());
var panThreshold = 0.15;
var currentViewPage = 0;
$('.listContent').on('touchstart', function(e) {
  console.log("touchstart");
  currentViewPage = Math.round(this.scrollLeft / width);
});
$('.listContent').on('touchend', function(e) {
  console.log("touchend");
  var delta = currentViewPage * width - this.scrollLeft;
  if (Math.abs(delta) > width * panThreshold) {
    if (delta < 0) {
      currentViewPage++;
    } else {
      currentViewPage--;
    }
  }
  $(this).animate({
    scrollLeft: currentViewPage * width
  }, 100);
});

如果将来有人想这样做,我发现真正做到这一点的唯一方法是手动控制所有触摸事件,然后重新实现正常的本地垂直滚动。

它可能不是最漂亮的,但下面是我最终所做的事情(编辑为使用鼠标事件而不是触摸事件):http://jsfiddle.net/xtwzcjhL/

$(function () {
    var width = parseInt($(document.body).width());
    var panThreshold = 0.15;
    var currentViewPage = 0;
    var start; // Screen position of touchstart event
    var isHorizontalScroll = false; // Locks the scrolling as horizontal
    var target; // Target of the first touch event
    var isFirst; // Is the first touchmove event
    var beginScrollTop; // Beginning scrollTop of ul
    var atanFactor = 0.6; // atan(0.6) = ~31 degrees (or less) from horizontal to be considered a horizontal scroll
    var isMove = false;
    $('body').on('mousedown', '.listContent', function (e) {
        isMove = true;
        isFirst = true;
        isHorizontalScroll = false;
        target = $(this);
        currentViewPage = Math.round(target.scrollLeft() / width);
        beginScrollTop = target.closest('ul').scrollTop();
        start = {
            x: e.originalEvent.screenX,
            y: e.originalEvent.screenY
        }
    }).on('mousemove', '.listContent', function (e) {
        if (!isMove) {
            return false;
        }
        e.preventDefault();
        var delta = {
            x: start.x - e.originalEvent.screenX,
            y: start.y - e.originalEvent.screenY
        }
        // If already horizontally scrolling or the first touchmove is within the atanFactor, horizontally scroll, otherwise it's a vertical scroll of the ul
        if (isHorizontalScroll || (isFirst && Math.abs(delta.x * atanFactor) > Math.abs(delta.y))) {
            isHorizontalScroll = true;
            target.scrollLeft(currentViewPage * width + delta.x);
        } else {
            target.closest('ul').scrollTop(beginScrollTop + delta.y);
        }
        isFirst = false;
    }).on('mouseup mouseout', '.listContent', function (e) {
        isMove = false;
        isFirst = false;
        if (isHorizontalScroll) {
            var delta = currentViewPage * width - target.scrollLeft();
            if (Math.abs(delta) > width * panThreshold) {
                if (delta < 0) {
                    currentViewPage++;
                } else {
                    currentViewPage--;
                }
            }
            $(this).animate({
                scrollLeft: currentViewPage * width
            }, 100);
        }
    });
});