猿问

同步滚动视图滚动位置-Android

同步滚动视图滚动位置-Android

我有两个ScrollView在我的Android布局。如何同步他们的滚动位置?



人到中年有点甜
浏览 413回答 3
3回答

元芳怎么了

在ScrollView中有一种方法.。protected&nbsp;void&nbsp;onScrollChanged(int&nbsp;x,&nbsp;int&nbsp;y,&nbsp;int&nbsp;oldx,&nbsp;int&nbsp;oldy)不幸的是,Google从未想过我们需要访问它,这就是为什么他们让它受到保护,并且没有添加一个“setOnScrollChangedListener”钩子。所以我们必须为自己做这件事。首先我们需要一个接口。package&nbsp;com.test;public&nbsp;interface&nbsp;ScrollViewListener&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;void&nbsp;onScrollChanged(ObservableScrollView&nbsp;scrollView,&nbsp;int&nbsp;x,&nbsp;int&nbsp;y,&nbsp;int&nbsp;oldx,&nbsp;int&nbsp;oldy);}然后,我们需要重写ScrollView类,以提供ScrollViewListener钩子。package&nbsp;com.test;import&nbsp;android.content.Context;import&nbsp;android.util.AttributeSet;import&nbsp;android.widget.ScrollView;public&nbsp;class&nbsp;ObservableScrollView&nbsp;extends&nbsp;ScrollView&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;ScrollViewListener&nbsp;scrollViewListener&nbsp;=&nbsp;null; &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;ObservableScrollView(Context&nbsp;context)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;super(context); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;ObservableScrollView(Context&nbsp;context,&nbsp;AttributeSet&nbsp;attrs,&nbsp;int&nbsp;defStyle)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;super(context,&nbsp;attrs,&nbsp;defStyle); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;ObservableScrollView(Context&nbsp;context,&nbsp;AttributeSet&nbsp;attrs)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;super(context,&nbsp;attrs); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;setScrollViewListener(ScrollViewListener&nbsp;scrollViewListener)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.scrollViewListener&nbsp;=&nbsp;scrollViewListener; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;@Override &nbsp;&nbsp;&nbsp;&nbsp;protected&nbsp;void&nbsp;onScrollChanged(int&nbsp;x,&nbsp;int&nbsp;y,&nbsp;int&nbsp;oldx,&nbsp;int&nbsp;oldy)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;super.onScrollChanged(x,&nbsp;y,&nbsp;oldx,&nbsp;oldy); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(scrollViewListener&nbsp;!=&nbsp;null)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;scrollViewListener.onScrollChanged(this,&nbsp;x,&nbsp;y,&nbsp;oldx,&nbsp;oldy); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;}}我们应该在布局中指定这个新的观察者ScrollView类,而不是现有的ScrollView标记。<com.test.ObservableScrollView &nbsp;&nbsp;&nbsp;&nbsp;android:id="@+id/scrollview1" &nbsp;&nbsp;&nbsp;&nbsp;...&nbsp;> &nbsp;&nbsp;&nbsp;&nbsp;...</com.test.ObservableScrollView>最后,我们将其放在布局类中。package&nbsp;com.test;import&nbsp;android.app.Activity;import&nbsp;android.os.Bundle;public&nbsp;class&nbsp;Q3948934&nbsp;extends&nbsp;Activity&nbsp;implements&nbsp;ScrollViewListener&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;ObservableScrollView&nbsp;scrollView1&nbsp;=&nbsp;null; &nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;ObservableScrollView&nbsp;scrollView2&nbsp;=&nbsp;null; &nbsp;&nbsp;&nbsp;&nbsp;@Override &nbsp;&nbsp;&nbsp;&nbsp;protected&nbsp;void&nbsp;onCreate(Bundle&nbsp;savedInstanceState)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;super.onCreate(savedInstanceState); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setContentView(R.layout.q3948934); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;scrollView1&nbsp;=&nbsp;(ObservableScrollView)&nbsp;findViewById(R.id.scrollview1); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;scrollView1.setScrollViewListener(this); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;scrollView2&nbsp;=&nbsp;(ObservableScrollView)&nbsp;findViewById(R.id.scrollview2); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;scrollView2.setScrollViewListener(this); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;onScrollChanged(ObservableScrollView&nbsp;scrollView,&nbsp;int&nbsp;x,&nbsp;int&nbsp;y,&nbsp;int&nbsp;oldx,&nbsp;int&nbsp;oldy)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(scrollView&nbsp;==&nbsp;scrollView1)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;scrollView2.scrollTo(x,&nbsp;y); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;else&nbsp;if(scrollView&nbsp;==&nbsp;scrollView2)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;scrollView1.scrollTo(x,&nbsp;y); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;}}SCROLLTO()代码为我们处理任何循环条件,因此我们不需要担心这个问题。唯一的警告是,这个解决方案不能保证在Android的未来版本中工作,因为我们正在覆盖一个受保护的方法。

慕哥6287543

Andy的解决方案的一个改进:在他的代码中,他使用了滚动到,问题是,如果你把一个滚动视图扔向一个方向,然后把另一个滚动视图扔向另一个方向,你会注意到第一个滚动视图并没有停止他以前的快速移动。这是因为SCROLLView使用ComputeScroll()来执行抛出的手势,并且它与滚动到冲突。为了防止这种情况,只需按以下方式对onScrollChanged进行编程:&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;onScrollChanged(ObservableScrollView&nbsp;scrollView,&nbsp;int&nbsp;x,&nbsp;int&nbsp;y,&nbsp;int&nbsp;oldx,&nbsp;int&nbsp;oldy)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;if(interceptScroll){ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;interceptScroll=false; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(scrollView&nbsp;==&nbsp;scrollView1)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;scrollView2.onOverScrolled(x,y,true,true); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;else&nbsp;if(scrollView&nbsp;==&nbsp;scrollView2)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;scrollView1.onOverScrolled(x,y,true,true); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;interceptScroll=true; &nbsp;&nbsp;&nbsp;&nbsp;}}使用intereptScroll,初始化为true的静态布尔值。(这有助于避免ScrollChanged上的无限循环)OnOverScrolled是我发现的唯一可以用来阻止滚动视图抛出的函数(但可能还有其他函数我错过了!)为了访问这个函数(它是受保护的),您必须将它添加到您的观测者ScrollViewer中。public&nbsp;void&nbsp;onOverScrolled(int&nbsp;scrollX,&nbsp;int&nbsp;scrollY,&nbsp;boolean&nbsp;clampedX,&nbsp;boolean&nbsp;clampedY)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;super.onOverScrolled(scrollX,&nbsp;scrollY,&nbsp;clampedX,&nbsp;clampedY);}

忽然笑

为什么不直接实现OnTouchListener在你的活动中。然后重写OnTouch方法,然后获得第一个滚动位置ScrollViewOne.getScrollY()和更新ScrollViewTwo.scrollTo(0, ScrollViewOne.getScrollY());只是另一个想法.。*)
随时随地看视频慕课网APP

相关分类

Android
我要回答