質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Kotlin

Kotlinは、ジェットブレインズ社のアンドリー・ブレスラフ、ドミトリー・ジェメロフが開発した、 静的型付けのオブジェクト指向プログラミング言語です。

Q&A

解決済

2回答

3061閲覧

Android ScrollViewでスクロールが止まった時に処理を行いたい

takepon0209

総合スコア34

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Kotlin

Kotlinは、ジェットブレインズ社のアンドリー・ブレスラフ、ドミトリー・ジェメロフが開発した、 静的型付けのオブジェクト指向プログラミング言語です。

0グッド

0クリップ

投稿2019/10/19 04:06

kotlinのScrollViewクラスで、スクロールが止まった時に処理が動くように実装することは可能でしょうか?
公式ドキュメントを調べても使えそうな関数は載っていませんでした。

https://developer.android.com/reference/kotlin/android/widget/ScrollView

やりたいことは、スクロールが止まった時の位置の取得です。

何か良い方法があれば教えていただきたいです。

よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jimbe

2019/10/19 04:13

ご存じと思いますが, 人の目には動き続けているように見えて, 機械的には「少し動く←→止まる」を繰り返しています. なにをもって「スクロールが止まった」と判断するのでしょうか.
takepon0209

2019/10/19 04:51

そうなんですね、知りませんでした。 人の目から見て止まった時に処理を行いたいのですが、 それは難しいということでしょうか?
jimbe

2019/10/19 14:38

難しいかどうかは仕様次第ですが, > 人の目から見て止まった時 という言われ方では, まだ抽象的です. 例えば...移動する場合に 10 秒おきに 1 mm 進む生物が居たとします. どのような場合に「この生物は止まった(=移動していない)」と言えるでしょうか.
takepon0209

2019/10/21 07:29

なるほど、そうですね。 止まってから1秒動きがなかったらなど、止まってからの経過秒数で判定したいです。
guest

回答2

0

jimbeさんの回答だとOnScrollChangeListenerを使用していてAndroid M(APIレベル23)以降でしか動かないので、それ以前のバージョンでも動作させたい場合は以下のようにScrollViewを拡張したクラスを実装して代わりに利用する方法があります。

kotlin

1class StopAwareScrollView(...) : ScrollView(...) { 2 private var debounceTask: Runnable? = null 3 4 var onStopListener: (Int, Int) -> Unit = { _, _ -> } 5 6 override fun onScrollChanged(l: Int, t: Int, oldl: Int, oldt: Int) { 7 super.onScrollChanged(l, t, oldl, oldt) 8 9 removeCallbacks(debounceTask) 10 debounceTask = Runnable { onStopListener(l, t) } 11 postDelayed(debounceTask, 1000L) 12 } 13 14 override fun onDetachedFromWindow() { 15 super.onDetachedFromWindow() 16 removeCallbacks(debounceTask) 17 } 18}
  • イベントを受け取る側

kotlin

1scrollView.onStopListener = { x, y -> 2 // do something... 3}

なお、こちらの実装ではThreadではなくHandlerを利用しているので、リスナーはメインスレッド上で呼ばれます。

投稿2019/10/21 23:15

編集2019/10/21 23:16
kakajika

総合スコア3131

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

takepon0209

2019/10/22 06:57

ありがとうございました!
jimbe

2019/10/22 09:34

私にも kotlin の勉強になりました. ありがとうございます.
guest

0

ベストアンサー

時間の監視でよろしければ, スクロールしたらリセットするタイマーを作り, そのタイマーが1秒経過したら「停止中」と判断しては如何でしょうか.

kotlin が使えないため java で失礼します.
非常にざっくりです.

activity_main.xml

xml

1<?xml version="1.0" encoding="utf-8"?> 2<androidx.constraintlayout.widget.ConstraintLayout 3 xmlns:android="http://schemas.android.com/apk/res/android" 4 xmlns:tools="http://schemas.android.com/tools" 5 android:layout_width="match_parent" 6 android:layout_height="match_parent" 7 tools:context="com.teratail.q218060.MainActivity"> 8 9 <ScrollView 10 android:layout_width="match_parent" 11 android:layout_height="match_parent" 12 android:id="@+id/scrollView"> 13 14 <TextView 15 android:layout_width="match_parent" 16 android:layout_height="wrap_content" 17 android:id="@+id/textView"/> 18 </ScrollView> 19</androidx.constraintlayout.widget.ConstraintLayout>

MainActivity.java

java

1package com.teratail.q218060; 2 3import androidx.appcompat.app.AppCompatActivity; 4 5import android.os.Bundle; 6import android.util.Log; 7import android.view.View; 8import android.widget.ScrollView; 9import android.widget.TextView; 10 11public class MainActivity extends AppCompatActivity { 12 private ScrollStopDetector scrollStopDetector; 13 @Override 14 protected void onCreate(Bundle savedInstanceState) { 15 super.onCreate(savedInstanceState); 16 setContentView(R.layout.activity_main); 17 18 TextView textView = findViewById(R.id.textView); 19 for(int i=1; i<=50; i++) textView.append(i+"\n"); 20 21 ScrollView scrollView = findViewById(R.id.scrollView); 22 scrollStopDetector = new ScrollStopDetector(scrollView, 1000, new ScrollStopDetector.Listener() { 23 @Override 24 public void stopped(View v) { 25 Log.d("MainActivity", "Scroll STOP"); 26 } 27 }); 28 scrollView.setOnScrollChangeListener(scrollStopDetector); 29 30 scrollStopDetector.start(); 31 } 32 @Override 33 protected void onDestroy() { 34 super.onDestroy(); 35 scrollStopDetector.finish(); 36 } 37}

ScrollStopDetector.java

java

1package com.teratail.q218060; 2 3import android.view.View; 4import android.widget.ScrollView; 5 6class ScrollStopDetector implements View.OnScrollChangeListener { 7 interface Listener { 8 void stopped(View v); 9 } 10 11 private class Sleeper implements Runnable { 12 @Override 13 public void run() { 14 while(!finish) { 15 try { 16 Thread.sleep(millis); //[ms] 17 listener.stopped(view); 18 } catch(InterruptedException ignore) { 19 } 20 } 21 } 22 } 23 24 private ScrollView view; 25 private long millis; 26 private Listener listener; 27 private Thread thread; 28 private boolean finish; 29 30 ScrollStopDetector(ScrollView view, long millis, Listener listener) { 31 this.view = view; 32 this.millis = millis; 33 this.listener = listener; 34 } 35 void start() { 36 thread = new Thread(new Sleeper()); 37 thread.start(); 38 } 39 void finish() { 40 finish = true; 41 } 42 43 @Override 44 public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) { 45 if(thread != null) thread.interrupt(); 46 } 47}

投稿2019/10/21 15:35

編集2019/10/22 09:32
jimbe

総合スコア12612

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

takepon0209

2019/10/22 06:57

ありがとうございます! 無事解決しました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問