Antworten:
Es gibt eine Methode in ScrollView ...
protected void onScrollChanged(int x, int y, int oldx, int oldy)
Leider hätte Google nie gedacht, dass wir darauf zugreifen müssen, weshalb sie es geschützt haben und keinen "setOnScrollChangedListener" -Hook hinzugefügt haben. Also müssen wir das für uns selbst tun.
Zuerst brauchen wir eine Schnittstelle.
package com.test;
public interface ScrollViewListener {
void onScrollChanged(ObservableScrollView scrollView, int x, int y, int oldx, int oldy);
}
Dann müssen wir die ScrollView-Klasse überschreiben, um den ScrollViewListener-Hook bereitzustellen.
package com.test;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.ScrollView;
public class ObservableScrollView extends ScrollView {
private ScrollViewListener scrollViewListener = null;
public ObservableScrollView(Context context) {
super(context);
}
public ObservableScrollView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public ObservableScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void setScrollViewListener(ScrollViewListener scrollViewListener) {
this.scrollViewListener = scrollViewListener;
}
@Override
protected void onScrollChanged(int x, int y, int oldx, int oldy) {
super.onScrollChanged(x, y, oldx, oldy);
if(scrollViewListener != null) {
scrollViewListener.onScrollChanged(this, x, y, oldx, oldy);
}
}
}
Und wir sollten diese neue ObservableScrollView-Klasse im Layout anstelle der vorhandenen ScrollView-Tags angeben.
<com.test.ObservableScrollView
android:id="@+id/scrollview1"
... >
...
</com.test.ObservableScrollView>
Schließlich haben wir alles in der Layout-Klasse zusammengefasst.
package com.test;
import android.app.Activity;
import android.os.Bundle;
public class Q3948934 extends Activity implements ScrollViewListener {
private ObservableScrollView scrollView1 = null;
private ObservableScrollView scrollView2 = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.q3948934);
scrollView1 = (ObservableScrollView) findViewById(R.id.scrollview1);
scrollView1.setScrollViewListener(this);
scrollView2 = (ObservableScrollView) findViewById(R.id.scrollview2);
scrollView2.setScrollViewListener(this);
}
public void onScrollChanged(ObservableScrollView scrollView, int x, int y, int oldx, int oldy) {
if(scrollView == scrollView1) {
scrollView2.scrollTo(x, y);
} else if(scrollView == scrollView2) {
scrollView1.scrollTo(x, y);
}
}
}
Der scrollTo () - Code kümmert sich um alle Schleifenbedingungen für uns, sodass wir uns darüber keine Sorgen machen müssen. Die einzige Einschränkung ist, dass diese Lösung in zukünftigen Android-Versionen nicht garantiert funktioniert, da wir eine geschützte Methode überschreiben.
Eine Verbesserung von Andys Lösung: In seinem Code verwendet er scrollTo. Das Problem ist, wenn Sie eine Bildlaufansicht in eine Richtung und dann eine andere in eine andere Richtung werfen, werden Sie feststellen, dass die erste seine vorherige Bewegung nicht aufhält Bewegung.
Dies liegt an der Tatsache, dass scrollView computeScroll () verwendet, um seine schleudernden Gesten auszuführen, und dass es in Konflikt mit scrollTo gerät.
Um dies zu verhindern, programmieren Sie den onScrollChanged einfach folgendermaßen:
public void onScrollChanged(ObservableScrollView scrollView, int x, int y, int oldx, int oldy) {
if(interceptScroll){
interceptScroll=false;
if(scrollView == scrollView1) {
scrollView2.onOverScrolled(x,y,true,true);
} else if(scrollView == scrollView2) {
scrollView1.onOverScrolled(x,y,true,true);
}
interceptScroll=true;
}
}
Mit interceptScroll wird ein statischer Boolescher Wert auf true initialisiert. (Dies hilft, Endlosschleifen bei ScrollChanged zu vermeiden.)
onOverScrolled ist die einzige Funktion, die ich gefunden habe, um das Scrollen der scrollView zu verhindern (aber es gibt möglicherweise andere, die ich verpasst habe!).
Um auf diese Funktion (die geschützt ist) zuzugreifen, müssen Sie diese Ihrem ObservableScrollViewer hinzufügen
public void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY) {
super.onOverScrolled(scrollX, scrollY, clampedX, clampedY);
}
Warum nicht einfach OnTouchListener
in Ihre Aktivität implementieren . Überschreiben Sie dann die onTouch-Methode, rufen Sie die Bildlaufposition der ersten ab ScrollViewOne.getScrollY()
und aktualisieren Sie sieScrollViewTwo.scrollTo(0, ScrollViewOne.getScrollY());
Nur eine andere Idee ... :)
Im Android Support-v4-Paket bietet Android eine neue Klasse mit dem Namen NestedScrollView
.
Wir können den <ScrollView>
Knoten durch <android.support.v4.widget.NestedScrollView>
in Layout-XML ersetzen und ihn NestedScrollView.OnScrollChangeListener
in Java implementieren , um das Scrollen zu handhaben.
Das macht die Sache einfacher.