Android:两个不同 View 的同步滚动

标签 android gridview scroll scrollview

我有一个与两个同步滚动相关的棘手问题 不同的看法。 我制作了自己的自定义 GridView 小部件,它具有“粘性” View 左侧和顶部仅在一个方向上带有网格。想一个 顶部有时间的日历,左侧有日期,以及何时 你水平滚动时间,日期 View 应该保持不变, 当您垂直滚动日期时,时间 View 应该 留在原地。

网格本身是使用嵌套的水平 ScrollView 实现的 垂直 ScrollView 。网格工作得很好,所以没问题。 由于粘性 View 不在实际网格中,我已经覆盖 onScrollChanged 在网格 ScrollView 中并以编程方式调用 当用户滚动网格时,粘性 View 上的 scrollTo。

这按预期工作,除了有轻微的时间偏移 到两个不同的 View 开始滚动和结束滚动的时间。它 当您认为滚动可能已执行时才有意义 我想在 UI 线程上是线性的..

所有 View 都是 ScrollView ,我启用了平滑滚动 并使用 smoothScrollTo 等来尝试改进这一点,但它 尽管如此,同样的问题。这个问题特别明显 更大的屏幕,例如 Samsung Galaxy Tab,而它几乎 在中小屏幕设备上很明显。

感谢任何帮助!如果有一个简单的解决方法,那就太好了……如果这意味着 新设计(满足上面的粘性 View 用例),那就这样吧。

触发程序的代码。滚动,水平相同

@Override  
protected void onScrollChanged(int x, int y, int oldx, int oldy) {  
   mListener.onScrollY(y);  
   super.onScrollChanged(x, y, oldx, oldy);  
}  
// which leads to,  
// Handle vertical scroll  
public void onScrollY(final int y) {  
   mCurrentY = y;  
   mVerticalScroll.smoothScrollTo(0, y);  
}  

下面的 XML 布局,如果有帮助的话

实际的网格,是一个水平 ScrollView 包裹在一个垂直 ScrollView 中,网格项是在嵌套的线性布局中垂直添加的
>

  < com.....VerticalScrollView  
    android:id="@+id/gridscroll" 
    android:layout_width="fill_parent"  
    android:layout_height="fill_parent" 
    android:layout_below="@id/timescroll"
    android:layout_toRightOf="@id/vertscroll"  
    android:layout_alignTop="@id/vertscroll"  
    android:layout_marginLeft="2dp" android:scrollbars="none"  
    android:fadingEdge="none">   

    < com....HorizScrollView
    android:id="@+id/horizscroll"
    android:layout_width="fill_parent"  
    android:layout_height="fill_parent"
    android:scrollbars="none"  
    android:fadingEdge="none">  

    < LinearLayout android:id="@+id/grid"  
      android:layout_width="fill_parent"  
      android:layout_height="fill_parent"  
      android:orientation="vertical">  

      < /LinearLayout>  

      < /com.....HorizScrollView>  

      < /com.....VerticalScrollView>  

水平粘性 View

 < com.....GridTimeScrollView
    android:id="@+id/timescroller" 
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:scrollbars="none"
    android:fadingEdge="none">

    < LinearLayout android:id="@+id/timelist"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="horizontal" />
    < /com.....GridTimeScrollView>

垂直粘性 View

< com....GridVertListScrollView
android:id="@+id/vertscroller"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scrollbars="none" 
android:fadingEdge="none">

< LinearLayout
android:id="@+id/vertitemlist"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" />
< /com.....GridVertListScrollView>

最佳答案

首先,我想你应该意识到这一点:ScrollView Inside ScrollView

简而言之:在 ScrollView 中使用 ScrollView 是一件坏事,会破坏许多优化。

现在,进入你的问题。

我和你描述的情况有类似的需求。我最终实现了一个自定义 View 及其 onDraw 方法。这在一定程度上是因为我正在画一些不平凡的东西,你可能不必这样做。

无论如何,我认为您最好的选择是:

  1. 实现扩展相对布局的自定义 View
  2. 使用将成为可滚动组件的顶部、左侧和“主” View 创建此 View 的布局
  3. 添加 OnGestureListener到此 View 并将 Activity 中的触摸事件传递到自定义 View 中
  4. 当您的手势监听器检测到滑动或滚动时,在每个 ScrollView 中调用 scrollBy。执行此操作时,如果您希望顶 View 仅水平滚动,请将 0 作为垂直滚动距离。
  5. 为了实现流畅的 throw Action ,您需要创建一个 scroller (在您的自定义 View 中)。当手势监听器检测到一个滑动事件时,设置滚动条。然后,覆盖自定义 View 的 computeScroll() 方法并更新每个 subview 中的滚动。 检查这个example知道如何实现它。抱歉,我会尽可能发布一个更好的示例。 检查下面的代码...它更简单:)

更新:示例代码

@Override
    public void computeScroll() {
        if (scroller.computeScrollOffset()) {
            if (!scrolledLastFrame) {
                lastX = scroller.getStartX();
                lastY = scroller.getStartY();
            }

            int dx = scroller.getCurrX() - lastX;
            int dy = scroller.getCurrY() - lastY;

            lastX = scroller.getCurrX();
            lastY = scroller.getCurrY();

            doScroll(dx, dy);
            scrolledLastFrame = true;
        } else {
            scrolledLastFrame = false;
        }

    }

关于Android:两个不同 View 的同步滚动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4591083/

相关文章:

java - 从android中的Json String中删除反斜杠

c# - 将 Lambda 函数传递给 Xamarin.Android 绑定(bind)库中的 Kotlin 的 C# 生成代码

java - 恢复倒计时

c# - 如何将 onclick 事件添加到 gridview 的第一列而不是整行?

Android gridview 项目更改

android - gridview点击效果

html - pagepiling.js 中特定部分的鼠标滚动问题

android - 带有 AppCompat 主题的日期选择器对话框

ios - UIslider 滚动和 tableview 滚动 ios

html - 每个屏幕尺寸的最大高度 - bootstrap