2013-12-15 13 views
5

私はコンテナViewGroupを持っています。ScrollViewの中に入れます。このコンテナビューは、私が理解することはできません他のViews(例えばパン可能イメージ)さんは、ウィジェットそれらを呼びましょう、そのうちのいくつかは、MotionEventのtheirselvesをスクロールして使用してからScrollViewを防止することに興味がある子ビューのScrollView、スクロールを条件付きで行う方法

の数をホストします適切なイベントインターセプト戦略を使用します。 ScrollViewは、子の前に常にイベントを処理するか、子がイベントを処理しますが、scrollviewは無効です。

私は、このビューがイベントをキャプチャしたいが、そのonTouchEventが呼び出されない場合は、子ビューでgetParent().requestDisableInterceptTouchEvent()発行について読んScrollViewは、事前にイベントを巻き込んだたので、私は考えます。私は2レベルのレイヤー(コンテナ+ウィジェット)でこれが動作しないようにしていると思いますが、コンテナViewGroupはここで重要な部分を演奏しなければならないと思います。 ScrollView'sonInterceptTouchEventのレベルで、コンテナのどのウィジェットがタッチされているかどうかを判断するためにタッチされたかどうかを知ることができますか?

か...

どの層を「ウィジェット」ができViewGroupはので、私はgetParent().onRequestDisableInterceptTouch()を呼び出すことができますScrollView前にイベントを取得...またはそれはgetParent().getParent().onRequestDisableInterceptTouch()ありますか?事前

おかげで私は、まあ、私はこの作業を取得するために管理コカコーラ&デバッグの夜の後に、関連する質問を読んでますが運... Handle touch events in ScrollView Android

答えて

9

てきました。誰かに興味がある場合に備えて、私は解決策を共有します。なぜなら、それを実行するにはかなりの時間がかかりましたからです。

getParent().onRequestDisableInterceptTouch()で動作させることはできませんでしたが、私は親しかったですが、親ウィジェットでタッチを傍受したらスクロールに必要なMotionEventsを子ウィジェットが取得する方法を見つけることができませんでした外側のスクロールが正しく防止されていても、内側のウィジェットはスクロールしませんでした。

だから、解決策は、子供のinterceptTouchEventsONLYにあり、そして子供たちが(既知の特性)スクロール可能で、タッチがACTION_DOWNであれば、2つのレベルを超えるscrollviewを無効にします。タッチがACTION_UPの場合、スクロールビューが有効になります。

スクロールビューを有効/無効にするには、タッチイベントを傍受し、フラグを使用してイベントを傍受します。

私は3つの補助クラス、ScrollViewに1つ、コンテナの1、ウィジェットのひとつでした:、このクラスは、すべてのウィジェットをラップし、私はsetNeedsScroll(true)を呼び出す場合は、触れたが傍受されます

をそれがタッチされると、スクロールビューに自身を無効にするよう伝える(コンテナに伝える)。タッチが離されると、スクロールビューが再び有効になります。

class WidgetWrapperLayout extends FrameLayout { 

    private boolean mNeedsScroll=false; 

    public WidgetWrapperLayout(Context context) { 
     super(context); 
    } 

    /** Called anytime, ie, during construction, to indicate that this 
    * widget uses vertical scroll, so we need to disable its container scroll 
    */ 

    public void setNeedsScroll(boolean needsScroll) { 
     mNeedsScroll=needsScroll; 
    } 

    @Override 
    public boolean onInterceptTouchEvent(MotionEvent ev) { 
     if (mNeedsScroll) { 
      switch (ev.getAction()) { 
      case MotionEvent.ACTION_DOWN: 
       ((SlideLayout)getParent()).setEnableScroll(false); 
       break; 
      case MotionEvent.ACTION_UP: 
       ((SlideLayout)getParent()).setEnableScroll(true); 
       break; 
      } 
      return false; 
     } 
     return super.onInterceptTouchEvent(ev); 
    } 
} 

これはscrollviewの子のみのコンテナで、異なるウィジェットを保持します。

public class ContainerLayout extends FrameLayout { 

    public ContainerLayout(Context context) { 
     super(context); 
    } 

    public void setEnableScroll(boolean status) { 
     if (Conf.LOG_ON) Log.d(TAG, "Request enable scroll: "+status); 
     ((StoppableScrollView)getParent()).setScrollEnabled(status); 
    } 
} 

、最終的に停止することscrollview:彼らは無効/スクロールを有効にすることができますので、それはちょうど子供のための方法を提供します。これは、スクロール 'old-skool'、インターセプトおよびブロッキングイベントを無効にします。

public class StoppableScrollView extends ScrollView { 

    private String TAG="StoppableScrollView"; 

    private boolean mDisableScrolling=false; 

    public StoppableScrollView(Context context) { 
     super(context); 
    } 

    /** Enables or disables ScrollView scroll */ 
    public void setScrollEnabled (boolean status) { 
     if (Conf.LOG_ON) Log.d(TAG, "Scroll Enabled "+status); 
     mDisableScrolling=!status; 
    } 


    @Override 
    public boolean onInterceptTouchEvent(MotionEvent ev) { 
     if (mDisableScrolling) return false; 
     return super.onInterceptTouchEvent(ev); 
    } 
} 
0

あなたの活動にView.OnTouchListenerを実装し、ScrollViewにそのリスナーを追加します。その後、onTouchEvent(...)にtrueを返します。帰る前に、そのイベントを処理したい子のonTouchに電話してください。

関連する問題