Android:同步滚动两个不同的视图

And*_*eas 2 android scroll gridview scrollview

我有一个棘手的问题,涉及两个不同视图的同步滚动.我已经创建了自己的自定义网格视图窗口小部件,左侧和顶部都有"粘性"视图,只有在网格的一个方向上.想想一个日历,你有时间在顶部,日期在左边,当你水平滚动时间时,日期视图应保持不变,当你垂直滚动日期时,时间视图应保持不变.

网格本身是使用垂直滚动视图中的嵌套水平滚动视图实现的.电网运行良好,所以没问题.由于粘性视图不在实际网格中,因此我在网格滚动视图中覆盖了onScrollChanged,并在用户滚动网格时以编程方式调用粘贴视图上的scrollTo.

这可以按预期工作,除了两个不同的视图开始滚动和结束滚动时有一个小的时间偏移.当您考虑滚动可能是在UI线程上线性执行时,我认为这是有道理的.

所有的视图都是滚动视图,我已经启用了平滑滚动和使用smoothScrollTo等,而不是尝试改进这一点,但它仍然是同样的问题.这个问题在较大的屏幕上尤为明显,例如三星Galaxy Tab,而在中小屏幕设备上则难以察觉.

任何帮助表示赞赏!如果有一个简单的解决方案,很好..如果它意味着新设计(满足上面的粘性视图用例),那么就这样吧.

用于触发编程的代码.滚动,水平相同

@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);  
}  
Run Code Online (Sandbox Code Playgroud)

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

实际网格,它是一个包含在垂直滚动视图中的水平滚动视图,网格项在嵌套的linearlayout中垂直添加
>

  < 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>  
Run Code Online (Sandbox Code Playgroud)

水平粘滞视图

 < 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>
Run Code Online (Sandbox Code Playgroud)

垂直粘性视图

< 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>
Run Code Online (Sandbox Code Playgroud)

Ped*_*iro 6

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

简而言之:在scrollviews中使用scrollview是一件坏事,会打破许多优化.

现在,问你的问题.

我对你所描述的内容有类似的需求.我最终实现了一个自定义视图及其onDraw方法.这部分是因为我画的东西不是微不足道的,你可能不必这样做.

无论如何,我相信你最好的选择是:

  1. 实现扩展相对布局的自定义视图
  2. 使用将成为可滚动组件的top,left和"main"视图创建此视图的布局
  3. OnGestureListener添加到此视图,并将活动中的触摸事件传递到自定义视图中
  4. 当您的手势监听器检测到scrollBy拖动或滚动时,在每个滚动视图中调用.执行此操作时,如果希望顶视图仅水平滚动,请将0作为垂直滚动距离.
  5. 为了实现平滑的移动动作,您需要创建一个滚动条(在自定义视图中).当手势监听器检测到fling事件时,请将卷轴设置为向上.然后,覆盖自定义视图的computeScroll()方法并更新每个子视图中的滚动.查看此示例以了解如何实现它.我道歉,我会尽可能发布一个更好的例子. 检查下面的代码...它更简单:)

更新:示例代码

@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;
        }

    }
Run Code Online (Sandbox Code Playgroud)