安卓:两种不同的角度同步滚动 [英] Android: Synchronized scrolling of two different views

查看:163
本文介绍了安卓:两种不同的角度同步滚动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个棘手的问题涉及到两个同步滚动 不同的看法。 我做了我自己的自定义网格视图小部件,它具有粘性意见 左侧和顶部,仅在一个方向上与电网。想想一个 日历,你有时间在上面,红枣在左边,而当 你水平滚动,通过时间,日期视图应该原地不动, 当您完成日期垂直滚动,时间视图应 留在原地。

网格本身使用在嵌套水平滚动视图实现的 垂直滚动视图。网格是伟大的工作,所以没问题的。 由于粘的观点是不实际的网格,我已重写 onScrollChanged网格scrollviews和编程调用 scrollTo上,当用户滚动栅格粘意见。

这是正常工作,除了有轻微时间偏移 当两种不同的看法开始滚动和结束滚动。它 有道理当你考虑到滚动可能被执行 线性在UI线程我想..

所有的意见是滚动的意见,我已经启用平滑滚动 和二手smoothScrollTo等,而是要尽量改善这一点,但它的 同样的问题仍然。现在的问题是上尤其明显 更大的屏幕,如三星Galaxy Tab,而它几乎没有 引人注目的中小屏幕设备。

任何帮助是AP preciated!如果有一个简单的办法,great..if这意味着 新的设计(符合粘滞视图用例以上),那就这样吧。

code触发前卫。滚动,相同的水平。

  @覆盖
保护无效onScrollChanged(INT X,INT Y,INT oldx,诠释oldy){
   mListener.onScrollY(Y);
   super.onScrollChanged(X,Y,oldx,oldy);
}
//这导致,
//处理垂直滚动
公共无效onScrollY(最终诠释Y){
   mCurrentY = Y;
   mVerticalScroll.smoothScrollTo(0,y)基
}
 

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

的实际网格,它是一个水平滚动视图包裹在一个垂直滚动视图和网格项目被垂直于嵌套的LinearLayout
加入     >

 < COM ..... VerticalScrollView
    机器人:ID =@ + ID / gridscroll
    机器人:layout_width =FILL_PARENT
    机器人:layout_height =FILL_PARENT
    机器人:layout_below =@ ID / timescroll
    机器人:layout_toRightOf =@ ID / vertscroll
    机器人:layout_alignTop =@ ID / vertscroll
    机器人:layout_marginLeft =2DP机器人:滚动条=无
    机器人:fadingEdge =无>

    < COM .... HorizScrollView
    机器人:ID =@ + ID / horizscroll
    机器人:layout_width =FILL_PARENT
    机器人:layout_height =FILL_PARENT
    机器人:滚动条=无
    机器人:fadingEdge =无>

    <的LinearLayout机器人:ID =@ + ID /格
      机器人:layout_width =FILL_PARENT
      机器人:layout_height =FILL_PARENT
      机器人:方向=垂直>

      < /的LinearLayout>

      < /com.....HorizScrollView>

      < /com.....VerticalScrollView>
 

水平粘滞视图

  

 < COM ..... GridTimeScrollView
    机器人:ID =@ + ID / timescroller
    机器人:layout_width =FILL_PARENT
    机器人:layout_height =FILL_PARENT
    机器人:滚动条=无
    机器人:fadingEdge =无>

    <的LinearLayout机器人:ID =@ + ID / timelist
    机器人:layout_width =FILL_PARENT
    机器人:layout_height =FILL_PARENT
    机器人:方向=横向/>
    < /com.....GridTimeScrollView>
 

垂直粘滞视图

  

 < COM .... GridVertListScrollView
机器人:ID =@ + ID / vertscroller
机器人:layout_width =FILL_PARENT
机器人:layout_height =FILL_PARENT
机器人:滚动条=无
机器人:fadingEdge =无>

<的LinearLayout
机器人:ID =@ + ID / vertitemlist
机器人:layout_width =FILL_PARENT
机器人:layout_height =FILL_PARENT
机器人:方向=垂直/>
< /com.....GridVertListScrollView>
 

解决方案

首先,我想你应该知道这一点:的滚动型内滚动型

在短:内使用scrollviews scrollviews是一件坏事,打破许多优化

现在,到你的问题。

我也有类似的需要你所描述的。我最终实现一个自定义视图和的OnDraw 方法。这部分是因为我画的东西并不容易,而且你可能没有做到这一点。

总之,我认为,最好的选择是:

  1. 在实现一个可扩展相对布局的自定义视图
  2. 创建这个视图顶部的布局,左边和主的观点,这将是滚动部件
  3. 添加<一个href="http://developer.android.com/reference/android/view/GestureDetector.OnGestureListener.html">OnGestureListener这种观点和传递您的活动触摸事件到自定义视图
  4. 当你的姿态监听器检测到一扔或滚动,在每个滚动意见援引 scrollBy 。当你这样做,如果你想顶视图水平只有滚动,通过0作为垂直滚动的距离。
  5. 在为了实现平稳一扔的动作,你需要创建一个卷轴(在自定义视图)。当手势侦听器检测一扔事件,设置滚动条了。然后,覆盖您的自定义视图的 computeScroll()方法和更新在每个子视图滚动。 <击>勾选此<一个href="http://androidcore.com/android-programming-tutorials/608-android-two-dimensional-scrollview.html">example知道如何实现它。我很抱歉,我会尝试发布一个更好的例子,如果可能的话 检查我下面的code ......这是简单的:)

更新:样品code

  @覆盖
    公共无效computeScroll(){
        如果(scroller.computeScrollOffset()){
            如果(!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 =真;
        } 其他 {
            scrolledLastFrame = FALSE;
        }

    }
 

I have a tricky problem related to synchronized scrolling of two different views. I've made my own custom grid view widget, which has "sticky" views to the left and top that only in one direction with the grid. Think of a calendar where you have times at the top, dates at the left, and when you scroll horizontally through time, the date view should stay put, and when you scroll vertically through the dates, the time view should stay put.

The grid itself is implemented using a nested horizontal scrollview in a vertical scrollview. The grid is working great, so no problem there. Since the sticky views are not in the actual grid, I have overriden onScrollChanged in the grid scrollviews and programatically call scrollTo on the sticky views when the user scrolls the grid.

That works as expected, except that there is a slight time offset as to when the two different views start scrolling and ends scrolling. It makes sense when you consider that the scrolling likely is executed linearly on the UI thread I suppose..

All the views are scroll views, and I have enabled smooth scrolling and used smoothScrollTo, etc, instead to try to improve this, but it's the same problem nonetheless. The problem is especially noticeable on larger screens, such as the Samsung Galaxy Tab, whereas it's hardly noticeable on small-medium screen devices.

Any help is appreciated! If there is an easy fix, great..if it means new design (that meets the sticky view usecase above), then so be it.

Code to trigger prog. scroll, same for horizontal

@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 layouts below, if that's of any help

The actual grid, which is a horizontal scroll view wrapped in a vertical scroll view and the grid items are added vertically in the nested 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>  

The horizontal sticky 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>

The vertical sticky 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>

解决方案

First of all, I think you should be aware of this: ScrollView Inside ScrollView

In short: using scrollviews inside scrollviews is a bad thing that breaks many optimizations.

Now, onto your question.

I've had a similar need to what you described. I ended up implementing a custom view and its onDraw method. This was in part because I was drawing something not trivial and you may not have to do it.

Anyway, I believe that your best option is:

  1. Implement a custom view that extends relative layout
  2. create the layout of this view with the top, left and "main" views that will be the scrollable components
  3. add a OnGestureListener to this view and pass touch events in your activity into the custom view
  4. when your gesture listener detects a fling or a scroll, invoke scrollBy in each of the scrolling views. When you do this, if you want the top view to scroll horizontally only, pass 0 as the vertical scroll distance.
  5. In order to implement smooth fling movements, you need to create a scroller (in your custom view). When the gesture listener detects a fling event, set the scroller up. Then, override your custom view's computeScroll() method and update the scroll in each of child views. Check this example to know how to implement it. I apologize, I will try to post a better example when possible. Check my code below... it's simpler :)

Update: sample code

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

    }

这篇关于安卓:两种不同的角度同步滚动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆