2013-04-19 7 views
6

背景:私は、外部ソースから断続的なテキストストリームを受け取る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); 
} 

答えて

8

は、あなたがonTouchEventbooleanを使用してみましたのようなものを持っている

// if the output has changed, or the scroll hasn't reached the bottom yet 
// then keep scrolling down 
if (outputHasChanged || !scrollAtBottom() && !userIntercept) { 
    ScrollView sv = (ScrollView) findViewById (R.id.scrollView); 
    sv.fullScroll (View.FOCUS_DOWN); 
} 

あなたはちょうどあなたが返すことができる方法を決定する必要がありますuserInterceptfalseのいずれかがアプリケーションに最適です。

+4

ありがとう、それは動作する基本的な考えです。完全性のために、私が今やっていることは:ACTION_MOVEまたはACTION_DOWNは手動モードを開始し、「指を押し下げる」状態をオンにします。 ACTION_UPは「指を押し下げる」状態をオフにします。 onScrollChangedとACTION_UPは、finger stateとatBottomの両方がtrueの場合、自動スクロールを再びオンにします。 – idij

+1

スクロールする画面を「フリック」させることができ、スクロールが完了する前にACTION_UPを取得できるので、指の状態に基づいてonScrollChangedの手動モードを解除する必要があります。 – idij

関連する問題