背景:私は、外部ソースから断続的なテキストストリームを受け取るScrollView/TextViewペアを持っています。各更新プログラムの下に自動的にスクロールします。アンドロイドScrollViewのエンドユーザスクロールとプログラムスクロールを区別するにはどうすればよいですか?
私は手動でどこかにスクロールすることによって、その自動スクロールダウンモードから抜け出すことができるようにしたいと思いますが、自分でやっているプログラムスクロールと手動スクロールを区別する方法がわかりません。
私のUIの更新は再描画をバッファリングするためのタイマーで実行されます:
private Handler outputUpdater = new Handler();
private static String outputBuffer = "";
private static boolean outputHasChanged = false;
private static final Object lock = new Object();
private Runnable outputUpdaterTask = new Runnable() {
public void run() {
synchronized (lock) {
// if the output has changed, update the TextView
if (outputHasChanged) {
TextView tv = (TextView) findViewById (R.id.textView);
tv.setText (outputBuffer);
}
// if the output has changed, or the scroll hasn't reached the bottom yet
// then keep scrolling down
if (outputHasChanged || !scrollAtBottom()) {
ScrollView sv = (ScrollView) findViewById (R.id.scrollView);
sv.fullScroll (View.FOCUS_DOWN);
}
outputHasChanged = false;
}
outputUpdater.postDelayed (this, 100);
}
};
scrollAtBottom
それはonScrollChanged
ハンドラからの値です取得します。
これはすべて問題なく動作します。テキストの更新がなくても、fullScroll
への1回の呼び出しは、TextViewの更新が行われているか、仮想キーパッドの可視性が変更されているなど、常に下に行くとは限りません。
私はユーザーが手動でスクロールすると、私はfullScroll
の呼び出しを止める決定を下すことができます。
残念ながら、さまざまなUIの変更がスクロールビューをオフにするように見えるため、手動モードに切り替えるための手がかりとして、「下部、自動モード」から「下部にはない」への移行を扱うだけでは不十分だと思われます(例えば、仮想キーパッドが表示されている)。
質問: ユーザーが開始したスクロールをプログラムスクロールと区別するにはどうすればよいですか?あなたのoutputUpdaterTask
で、その後
boolean userIntercept = false;
@Override
public boolean onTouchEvent(MotionEvent me) {
int action = me.getAction();
if (action == MotionEvent.ACTION_MOVE) {
userIntercept = true;
}
return super.onTouchEvent(me);
}
:
ありがとう、それは動作する基本的な考えです。完全性のために、私が今やっていることは:ACTION_MOVEまたはACTION_DOWNは手動モードを開始し、「指を押し下げる」状態をオンにします。 ACTION_UPは「指を押し下げる」状態をオフにします。 onScrollChangedとACTION_UPは、finger stateとatBottomの両方がtrueの場合、自動スクロールを再びオンにします。 – idij
スクロールする画面を「フリック」させることができ、スクロールが完了する前にACTION_UPを取得できるので、指の状態に基づいてonScrollChangedの手動モードを解除する必要があります。 – idij