Android düzenimde 2 ScrollView var. Kaydırma konumlarını nasıl senkronize edebilirim?
Yanıtlar:
ScrollView'da bir yöntem var ...
protected void onScrollChanged(int x, int y, int oldx, int oldy)
Ne yazık ki Google, ona erişmemiz gerekeceğini hiç düşünmedi, bu yüzden korumalı yaptılar ve bir "setOnScrollChangedListener" kancası eklemediler. Yani bunu kendimiz için yapmak zorunda kalacağız.
Önce bir arayüze ihtiyacımız var.
package com.test;
public interface ScrollViewListener {
void onScrollChanged(ObservableScrollView scrollView, int x, int y, int oldx, int oldy);
}
Sonra ScrollViewListener kancasını sağlamak için ScrollView sınıfını geçersiz kılmamız gerekir.
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);
}
}
}
Ve mevcut ScrollView etiketleri yerine bu yeni ObservableScrollView sınıfını mizanpajda belirtmeliyiz.
<com.test.ObservableScrollView
android:id="@+id/scrollview1"
... >
...
</com.test.ObservableScrollView>
Son olarak, hepsini Layout sınıfında bir araya getirdik.
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);
}
}
}
ScrollTo () kodu, bizim için herhangi bir döngü koşulunun üstesinden gelir, bu nedenle bunun için endişelenmemize gerek yoktur. Tek uyarı, bu çözümün Android'in gelecekteki sürümlerinde çalışacağının garanti edilmemesidir, çünkü korumalı bir yöntemi geçersiz kılıyoruz.
Andy'nin çözümünde bir gelişme: Kodunda, scrollTo kullanıyor, sorun şu ki, bir kaydırma görünümünü bir yöne çevirirseniz ve sonra başka bir yöne başka bir yöne fırlatırsanız, ilkinin önceki atışını durdurmadığını fark edeceksiniz hareket.
Bunun nedeni, scrollView'in hızlı hareketleri yapmak için computeScroll () kullanması ve scrollTo ile çakışmaya girmesidir.
Bunu önlemek için, onScrollChanged'yi şu şekilde programlayın:
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;
}
}
ile interceptScroll true olarak başlatılmış statik bir boolean. (bu, ScrollChanged'da sonsuz döngülerden kaçınmaya yardımcı olur)
onOverScrolled, scrollView'un fırlamasını durdurmak için kullanılabileceğini bulduğum tek işlevdir (ancak kaçırdığım başkaları da olabilir!)
Bu işleve (korumalı) erişmek için, bunu ObservableScrollViewer'a eklemeniz gerekir.
public void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY) {
super.onOverScrolled(scrollX, scrollY, clampedX, clampedY);
}
Neden OnTouchListener
faaliyetinizde sadece uygulamıyorsunuz ? Ardından onTouch yöntemini geçersiz kılın, ardından ilkinin kaydırma konumunu alın ScrollViewOne.getScrollY()
ve güncelleyinScrollViewTwo.scrollTo(0, ScrollViewOne.getScrollY());
Sadece başka bir fikir ... :)
Android destek-v4 paketinde Android NestedScrollView
,.
<ScrollView>
düğümü <android.support.v4.widget.NestedScrollView>
in layout xml ile
değiştirebiliriz NestedScrollView.OnScrollChangeListener
ve kaydırmayı işlemek için Java'da uygularız .
Bu işleri kolaylaştırır.