2016-06-15 5 views
1

複数のポインタが異なるビュー上にある場合、どのようにして画面上のポインタの総数を取得できますか?私は画面上で複数のビューを持っており、ポインタがビューの関連領域にない場合、ビューはのの場合にfalseを返します。ポインタが複数のビューにあるときのポインタの合計数を取得する方法は?

最初の指がビュー上にあり、2番目の指が別のビューに接触すると、両方のビューはgetPointerCountメソッドで「1」を返します。ポインタのタッチをどのビューが処理するかにかかわらず、画面全体で合計ポインタ数を得る方法はありますか?

編集:ViewsonInterceptTouchが総ポインタ数を返しません理由で同じ親ViewGroup、ではありません。私はonInterceptTouchを非常にルートViewGroupに置くことができますが、私はAndroidがこのようないくつかの汚い回避策なしでポインタの総数を与えることを望んでいました。

+0

すべてのビューは、ViewGroup内にルートビューとして存在します。 ViewGroupクラスにはメソッド['onInterceptTouch()'](https://developer.android.com/reference/android/view/ViewGroup.html#onInterceptTouchEvent(android.view.MotionEvent))があります。あなたがそれから虚偽を返す限り、イベントはそれを通過し、次に子ビューに渡されます。したがって、理論的には、Viewsの親ViewGroupはすべてのポインタを監視できます。テストする必要があるのは確かです。 –

答えて

1

Activityではなく@ S.Dと呼ばれるメソッドを使用して直接行う方法はありません。指摘し、あなたがそれを行うにはViewGrouponInterceptTouchEventを使用することができます。

MyLinearLayout.java

public class MyLinearLayout extends LinearLayout { 
    public MyLinearLayout(Context context) { 
     super(context); 
    } 

    public MyLinearLayout(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 


    public MyLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) { 
     super(context, attrs, defStyleAttr); 
    } 

    @TargetApi(21) 
    public MyLinearLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 
     super(context, attrs, defStyleAttr, defStyleRes); 
    } 

    @Override 
    public boolean onInterceptTouchEvent(final MotionEvent ev) { 
     Log.e("TOUCHES", "num: " + ev.getPointerCount()); 

     return super.onInterceptTouchEvent(ev); 
    } 
} 

mylayout.xml

<mypackage.MyLinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical"> 

    <TextView 
     android:id="@+id/t1" 
     android:layout_width="match_parent" 
     android:layout_height="0dp" 
     android:layout_weight="0.5" 
     android:clickable="true" 
     android:gravity="center" 
     android:text="0"/> 

    <TextView 
     android:id="@+id/t2" 
     android:layout_width="match_parent" 
     android:layout_height="0dp" 
     android:layout_weight="0.5" 
     android:clickable="true" 
     android:gravity="center" 
     android:text="0"/> 

</mypackage.MyLinearLayout> 

MyActivity.java

public class MapsActivity extends FragmentActivity { 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.mylayout); 

     final TextView t1 = (TextView) findViewById(R.id.t1); 
     final TextView t2 = (TextView) findViewById(R.id.t2); 

     t1.setOnTouchListener(new View.OnTouchListener() { 
      @Override 
      public boolean onTouch(final View view, final MotionEvent motionEvent) { 
       t1.setText(""+motionEvent.getPointerCount()); 
       return true; 
      } 
     }); 

     t2.setOnTouchListener(new View.OnTouchListener() { 
      @Override 
      public boolean onTouch(final View view, final MotionEvent motionEvent) { 
       t2.setText(""+motionEvent.getPointerCount()); 
       return true; 
      } 
     }); 
    } 
} 

この例では、各TextViewによって受信MotionEventgetPointerCount()とt1とt2 TextView Sのテキストを設定し、あなたが必要MyLinearLayout

1

によって受信MotionEventgetPointerCount()の合計値を記録しますすべてのタッチイベントが傍受されるカスタムViewGroup。

あなたは、Androidでこの作品を理解する必要があります。

  • ViewGroup.onInterceptTouchEvent(MotionEvent)は、彼らが子供たちに到達する前のViewGroupがタッチイベントをインターセプトすることができます。 trueをここに返すとonTouchEvent()に次のタッチイベントが届き、現在のイベントが終了するまで(ポインターが削除されるまで)子どもはもうタッチイベントを受信しません。
  • 子供の見解では、迎え入れを拒否する親にViewGroup.requestDisallowInterceptTouchEvent(boolean)彼らは進行中のタッチイベントを認識し、彼らがそれを中断することを望んでいません。 ViewGroupがこの要求を受信した場合には、親に渡して、それを尊重しなければならない(=ここでは上からイベントをインターセプトしません)
  • 内部ViewGrouprequestDisallowInterceptTouchEvent(true)onInterceptTouchEventを呼び出すことはありませんあなたがする必要がある場合は

を受信しますすべてのタッチイベントを聴いてください。たとえ子供が傍受を許可しなくても、ViewGroupはそれが許可されていないと思って騙す必要がありますが、依然として拒否を尊重する必要があります(タッチイベントを傍受しないでください)。

これは私がまさにその私のプロジェクトの1のために書いたクラスです:あなただけで、あなたのリスナーを設定し

public class InterceptTouchFrameLayout extends FrameLayout { 
    private boolean mDisallowIntercept; 

    public interface OnInterceptTouchEventListener { 
     /** 
     * If disallowIntercept is true the touch event can't be stealed and the return value is ignored. 
     * @see android.view.ViewGroup#onInterceptTouchEvent(android.view.MotionEvent) 
     */ 
     boolean onInterceptTouchEvent(InterceptTouchFrameLayout view, MotionEvent ev, boolean disallowIntercept); 

     /** 
     * @see android.view.View#onTouchEvent(android.view.MotionEvent) 
     */ 
     public boolean onTouchEvent(InterceptTouchFrameLayout view, MotionEvent event); 
    } 

    private static final class DummyInterceptTouchEventListener implements OnInterceptTouchEventListener { 
     @Override 
     public boolean onInterceptTouchEvent(InterceptTouchFrameLayout view, MotionEvent ev, boolean disallowIntercept) { 
      return false; 
     } 
     @Override 
     public boolean onTouchEvent(InterceptTouchFrameLayout view, MotionEvent event) { 
      return false; 
     } 
    } 

    private static final OnInterceptTouchEventListener DUMMY_LISTENER = new DummyInterceptTouchEventListener(); 

    private OnInterceptTouchEventListener mInterceptTouchEventListener = DUMMY_LISTENER; 

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

    public InterceptTouchFrameLayout(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 

    public InterceptTouchFrameLayout(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
    } 

    @Override 
    public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) { 
     getParent().requestDisallowInterceptTouchEvent(disallowIntercept); 
     mDisallowIntercept = disallowIntercept; 
    } 

    public void setOnInterceptTouchEventListener(OnInterceptTouchEventListener interceptTouchEventListener) { 
     mInterceptTouchEventListener = interceptTouchEventListener != null ? interceptTouchEventListener : DUMMY_LISTENER; 
    } 

    @Override 
    public boolean onInterceptTouchEvent(MotionEvent ev) { 
     boolean stealTouchEvent = mInterceptTouchEventListener.onInterceptTouchEvent(this, ev, mDisallowIntercept); 
     return stealTouchEvent && !mDisallowIntercept || super.onInterceptTouchEvent(ev); 
    } 

    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
     boolean handled = mInterceptTouchEventListener.onTouchEvent(this, event); 
     return handled || super.onTouchEvent(event); 
    } 
} 

:そのリスナーの中にview.setOnInterceptTouchEventListener()

あなたはダウンポインタのカウントを保持することができます(onIntercetTouchEvent()メソッド内)。 そのレイアウトをレイアウトのルート(全画面)として配置するだけです。

あなたがすべてのタッチイベントを受け取ることが許可されていないため、不正行為を行わずに同じことをしようとすると、間違った情報に終わる可能性があります。

関連する問題