スクロールビュー内のテキストビューに固定コンテンツがあります。ユーザーが特定の位置にスクロールしたら、アクティビティを開始するか、Toast
をトリガーしたいと思います。
<ScrollView xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="fill_parent" Android:layout_height="fill_parent"
Android:id="@+id/scroller">
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:orientation="vertical" Android:layout_width="fill_parent"
Android:layout_height="fill_parent">
<TextView Android:layout_width="fill_parent" Android:id="@+id/story"
Android:layout_height="wrap_content" Android:text="@string/lorem"
Android:gravity="fill" />
</LinearLayout>
</ScrollView>
私の問題は、保護されたメソッドonScrollChanged
を実装して、スクロールビューの位置を見つけることです。
私は this の答えを見つけました。投稿したリンクに見られるように、インターフェースを宣言したり、スクロールビューに乗ったりするよりも、これに対する簡単な解決策はありますか?
番号。
ScrollViewは、スクロールイベントのリスナーや、ユーザーがスクロールした距離を確認する方法さえ提供しないため、リンクで提案されていることを行う必要があります。
ScrollView
をサブクラス化するよりもはるかに簡単な方法があります。 ViewTreeObserver
のScrollView
オブジェクトを使用して、スクロールをリッスンできます。
ViewTreeObserver
オブジェクトはScrollView
の有効期間中に変更される可能性があるため、OnTouchListener
を取得するにはScrollView
にViewTreeObserver
を登録する必要があります_スクロール時。
final ViewTreeObserver.OnScrollChangedListener onScrollChangedListener = new
ViewTreeObserver.OnScrollChangedListener() {
@Override
public void onScrollChanged() {
//do stuff here
}
};
final ScrollView scrollView = (ScrollView) findViewById(R.id.scroller);
scrollView.setOnTouchListener(new View.OnTouchListener() {
private ViewTreeObserver observer;
@Override
public boolean onTouch(View v, MotionEvent event) {
if (observer == null) {
observer = scrollView.getViewTreeObserver();
observer.addOnScrollChangedListener(onScrollChangedListener);
}
else if (!observer.isAlive()) {
observer.removeOnScrollChangedListener(onScrollChangedListener);
observer = scrollView.getViewTreeObserver();
observer.addOnScrollChangedListener(onScrollChangedListener);
}
return false;
}
});
この質問はかなり古いですが、誰かが立ち寄った場合(私のように):
API 23以降、AndroidのView
にはOnScrollChangeListener
と matching setter があります。
サポートライブラリの NestedScrollView は、そのAPIレベルの前でもスクロールリスナーの設定もサポートしています。私の知る限り、NestedScrollView
は問題なく通常のScrollView
の代わりとして使用できます。
実際、ユーザーがどれだけスクロールしたかを知る方法があります。 ScrollViewのgetScrollY()メソッドはそれを示しています。
ScrollViewを拡張しました。 このリンク が役立つ場合があります。
class MyScroll extends ScrollView {
boolean onTop=true;
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
//Log.d(TAG, "scroll changed: " + this.getTop() + " "+t);
if(t <= 0){
onTop = true;
//Log.d(TAG, "scroll top: " + t);
super.onScrollChanged(l, t, oldl, oldt);
return;
// reaches the top end
}
onTop = false;
View view = (View) getChildAt(getChildCount()-1);
int diff = (view.getBottom()-(getHeight()+getScrollY()+view.getTop()));// Calculate the scrolldiff
if( diff <= 0 ){
// if diff is zero, then the bottom has been reached
}
super.onScrollChanged(l, t, oldl, oldt);
}
}
NestedScrollViewはAndroid.widget.ScrollViewと同様ですが、Androidの新旧両方のバージョンでネストされたスクロールの親と子の両方として機能することをサポートします。
1番目-ScrollViewの代わりにNestedScrollViewバインディングを使用します
2nd-Scrollリスナーをこのように設定して、headerViewの軸Yの動きを例で検出します
nestedScrollView.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
@Override
public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
Log.d(TAG, "onScrollChangeForY - scrollY: " + scrollY + " oldScrollY: " + oldScrollY);
int MOVE = -1, SCROLL_UP = 0, SCROLL_DOWN = 1;
float initialPositionY = headerView.getY();
MOVE = scrollY > oldScrollY ? SCROLL_UP : SCROLL_DOWN;
if (MOVE == SCROLL_UP) {
int incrementY = scrollY - oldScrollY;
headerView.setY(initialPositionY - incrementY);
} else {
int incrementY = oldScrollY - scrollY;
headerView.setY(initialPositionY + incrementY);
}
}
});
このトリガーを使用して、ToastまたはStart Activityを表示できます
scrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
@Override
public void onScrollChanged() {
// do something when Scroll
}
});
NestedScroll
とNestedScroll.setOnScrollChangeListener()
を使用するだけです。
ready for use component があり、Androidの任意のビューのスクロールイベントをリッスンするのに役立ちます。内部的にこのコンポーネントは、古いAndroid API(Shubhadeep Chaudhuriの回答で提案されたものと同様)のデバイスにViewTreeObserverスクロールイベントリスナーを追加し、新しいAndroid = API(APIレベル23+)。
API 23以降Android M、OnScrollChangeListenerを使用できます。
scrollView.setOnScrollChangeListener(new View.OnScrollChangeListener() {
@Override
public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
//work with parameters
}
});
このコードを使用して、上下スクロールを検出できます
scrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
int lastScroll=0;
@Override
public void onScrollChanged() {
int scrollY = scrollView.getScrollY(); // For ScrollView herzontial use getScrollX()
if (scrollY > lastScroll ) {
Log.e("scroll","down scroll"+scrollY);
} else if (scrollY < lastScroll ) {
Log.e("scroll","up scroll"+scrollY);
}
lastScroll=scrollY;
}
});