2011-05-31 2 views
15

単純な概要から、ユーザーがドラッグしてサイズを変更できるビットマップを含むカスタムビューがあります。onTouchEventをScrollViewと競合させてオーバーライドする

私はScrollViewでこれのCustomViewを配置したいときに私の問題が来るI私のCustomViewでonTouchEvent無効にして、ユーザが画像の中にタッチしているかどうかを確認、など

のように私はこれを行う方法は、かなり標準的です。これはうまくいきますが、ScrollViewとCustomViewはMotionEventsを競合しているようです。つまり、画像をドラッグしようとすると、動きが遅くなったりビューがスクロールしたりします。

私は、私はonInterceptTouchEventをオーバーライドすることができますし、ユーザーが画像の範囲内にしようとしないスクロールすることを知らせるために、私はScrollViewを拡張する必要があります考えています。しかし、ScrollViewが上位階層にあるため、CustomViewの現在の状態にどのようにアクセスできますか?

良い方法がありますか?

+1

私はそれがないことを決定した場合、イベントをオフに応じて、次に手をタッチイベントを処理する場合は、カスタムビューを決定するためにscrollviewをonInterceptTouchEventを実装してはならないと思います。ここでは

はいくつかのコードですそれを処理する。 – Nadewad

答えて

38

通常、Androidはアイテムをドラッグしてアイテムのコンテナをスクロールするときに曖昧さを解消するために、このような場合に長いドラッグを使用してドラッグを開始します。しかし、ユーザーがアイテムのドラッグを開始したときに明確な信号がある場合は、ユーザーがドラッグを開始していることを知っているときに、カスタムビューからgetParent().requestDisallowInterceptTouchEvent(true)を試してください。 (このメソッドのドキュメントhere。)これにより、ScrollViewが現在のジェスチャーの終了までタッチイベントをインターセプトできなくなります。見つかったソリューションの

+2

ありがとう、それは働いた!だからここにいくつかの偉大なAPIの知識があります:) – brk3

+1

あなたの質問に答えてプラットフォーム自体でこれらのものを維持する人々を持っているときに役立ちます。 ;) – adamp

+0

ありがとうございます:) –

8

どれも私のカスタムビューがビュー、ないのViewGroupを拡張し、おそらくので、私にとっては「箱から出して」働いていないので、私はonInterceptTouchEventを実装することはできません。

getParent().requestDisallowInterceptTouchEvent(true)とも呼ばれ、NPEを投げたり、何もしなかったりしていました。あなたのビューは、イベントの世話をするときにカスタムonTouchEventコールrequestDisallow...内部

は、最後にこれは私がこの問題を解決する方法です。例:

@Override 
public boolean onTouchEvent(MotionEvent event) { 
    Point pt = new Point((int)event.getX(), (int)event.getY()); 
    if (event.getAction() == MotionEvent.ACTION_DOWN) { 
     if (/*this is an interesting event my View will handle*/) { 
      // here is the fix! now without NPE 
      if (getParent() != null) { 
       getParent().requestDisallowInterceptTouchEvent(true); 
      } 

      clicked_on_image = true; 
     } 
    } else if (event.getAction() == MotionEvent.ACTION_MOVE) { 
     if (clicked_on_image) { 
      //do stuff, drag the image or whatever 
     } 
    } else if (event.getAction() == MotionEvent.ACTION_UP) { 
     clicked_on_image = false; 
    } 
    return true; 
} 

私のカスタムビューはうまく動作し、いくつかのイベントを処理して、scrollViewが気にしないものをキャッチするようになりました。ここに解決策が見つかりました:http://android-devblog.blogspot.com.es/2011/01/scrolling-inside-scrollview.html

希望します。

+0

それは助けた素晴らしい答え! :) しかし、私はNullPointerチェックを変更することをお勧めします: ViewParent parent = getParent(); if(parent!= null){ parent.requestDisallowInterceptTouchEvent(true); } – netzpurist

+0

これは完璧に動作しました – Ryan

0

MotionEvent.ACTION_CANCEL(値= 3)というAndroidイベントがあります。私が行うのは、私のカスタムコントロールのonTouchEventメソッドをオーバーライドしてこの値を取得することだけです。私がこの状態を検出すると、それに応じて対応します。

@Override 
public boolean onTouchEvent(MotionEvent event) { 
    if(isTouchable) { 
     int maskedAction = event.getActionMasked();   
     if (maskedAction == MotionEvent.ACTION_DOWN) { 
      this.setTextColor(resources.getColor(R.color.octane_orange)); 
      initialClick = event.getX(); 
     } else if (maskedAction == MotionEvent.ACTION_UP) { 
      this.setTextColor(defaultTextColor); 
      endingClick = event.getX(); 
      checkIfSwipeOrClick(initialClick, endingClick, range); 
     } else if(maskedAction == MotionEvent.ACTION_CANCEL) 
      this.setTextColor(defaultTextColor); 
    } 
    return true; 
} 
関連する問題