제스처 인식 - GestureDetector

11063 단어 배우다

손짓


구현 방법: 첫 번째: GestureDetector 두 번째: GestureOverlayView

GestureDetector


의 원리


1. 화면을 손으로 만지는 순간 Motion Event 이벤트를 터치합니다.2. OnTouchListener의 감청을 받아 onTouch에서 Motion Event 대상을 획득한다.GestureDetector가 MotionEvent 대상을 onGestureListener 4.onGestureListener는 이 대상을 가져와 이 대상이 봉인된 정보에 따라 적당한 피드백을 합니다.
GestureDetector에 두 개의 감청기 인터페이스가 있습니다.1. ONGestureListener: 클릭 클래스 이벤트 처리 2.OnDoubleTapListener: 더블 클릭 클래스에 대한 메시지를 처리합니다.이 안에는 많은 방법이 있다. 우리는 일반적으로 이 두 인터페이스를 단독으로 이용하지 않고 두 개의 인터페이스를 포함하는 유형을 계승한다. 그것이 바로 Simple On Gesture Listener이다.이 종류를 계승하고 그 중의 어떤 방법을 다시 써서 제스처를 식별한다.예를 들어 onDoubleTap () 는 두 번 클릭 이벤트이고, onFling () 은 슬라이딩 이벤트 (즉 View가 바로 손을 따라 이동하는 것이 아니다) 는 onScroll 은 스크롤 이벤트입니다.
코드는 다음과 같습니다.
public class MainActivity extends Activity {
  private ImageView imageView;
    private GestureDetector gestureDetector;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        imageView = (ImageView) findViewById(R.id.myimg);
        gestureDetector = new GestureDetector(new GestureDetector.SimpleOnGestureListener(){
            @Override
            public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
                if(e1.getX()-e2.getX()>50){
                    Toast.makeText(MainActivity.this, " ", Toast.LENGTH_SHORT).show();
                }else if(e2.getX()-e1.getX()>50){
                    Toast.makeText(MainActivity.this, " ", Toast.LENGTH_SHORT).show();
                }
                return super.onFling(e1, e2, velocityX, velocityY);
            }

            @Override
            public boolean onDoubleTap(MotionEvent e) {
                Toast.makeText(MainActivity.this, " ", Toast.LENGTH_SHORT).show();
                return super.onDoubleTap(e);
            }

        });
        imageView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                gestureDetector.onTouchEvent(motionEvent);
                return true;
            }
        });


    }


}

주의


모든 뷰는 클릭이나 터치 이벤트를 설정할 수 있습니다. 이 뷰의 OnTouchListener를 설정하면 onTouch에서 motion Event 이벤트를 얻을 수 있습니다.더 나아가 이view를 클릭하거나 미끄러질 때 해당하는 이벤트를 실행하도록 설정합니다.

사용자 정의 컨트롤의 제스처


코드는 다음과 같습니다.
public class MyButton extends Button {
    private GestureDetector mGestureDetector;

    interface OnDoubleClict{
        public void onOnDoubleClict(View view);
    }
    private  OnDoubleClict onDoubleClictListear;

    public void setOnDoubleClict(OnDoubleClict onDoubleClict) {
        this.onDoubleClictListear = onDoubleClict;
    }

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

    public MyButton(Context context, AttributeSet attrs) {
        super(context, attrs);
        mGestureDetector = new GestureDetector(context,new GestureDetector.SimpleOnGestureListener(){
            @Override
            public boolean onDoubleTap(MotionEvent e) {
                if(onDoubleClictListear!=null){
                    onDoubleClictListear.onOnDoubleClict(MyButton.this);
                }
                return true;
            }

            @Override
            public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
                if(Math.abs(e2.getX()-e1.getX())>30){

                    ObjectAnimator.ofFloat(MyButton.this,"translationX",getTranslationX(),getTranslationX()+e2.getX()-e1.getX()).setDuration(500).start();
                    return true;
                }
                return super.onFling(e1, e2, velocityX, velocityY);
            }

            @Override
            public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
                //TranslationX() x 。getTranslationX() View x 。
                setTranslationX(getTranslationX()+e2.getX()-e1.getX());
                setTranslationY(getTranslationY()+e2.getY()-e1.getY());
                Log.d("aaaaaaaa",""+getTranslationX());
                return true;
            }
        });
    }

    public MyButton(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        mGestureDetector.onTouchEvent(event);
        return super.onTouchEvent(event);

    }
}

onScroll에서 View 스크롤을 설정할 때 TranslationX()를 설정합니다.괄호 안에 있는 값은 뷰가 이동할 거리의 시작 뷰 위치에 대한 값 거리입니다. 마지막 값이 아닙니다.여기 button입니다. 자동으로 클릭 이벤트가 있습니다.다른 컨트롤러라면 터치할 때 반응이 없을 수도 있습니다.다음과 같이 하십시오.
1. TextView에서 선언
"@+id/my_recent_voice_edit"
                android:layout_width="148.3dp"
                android:layout_height="wrap_content"
                *android:duplicateParentState="true"*
                android:gravity="center"
                android:text="@string/voice_recent_btn_text"
                android:textColor="@color/update_voice_recent"
                android:color="#666666"
                android:layout_marginBottom="1dp"
                *android:clickable="true"*
                android:textSize="12sp" />

부모 Layout에서 clickable을 true로 선언합니다.
2. Layout의 하위 요소를 차단하여 포커스를 가져옵니다.이런 방법
"@+id/voice_recent_edit_layout"
            android:layout_width="193.3dp"
            android:layout_height="wrap_content"
            android:layout_marginLeft="33dp"
            android:layout_marginRight="33dp"
            android:background="@drawable/recent_voice_bg"
            *android:clickable="true"*
            android:descendantFocusability="blocksDescendants"
            android:gravity="center_vertical"
            android:visibility="gone" >

이 두 가지 방법은 모두 같은 효과에 도달할 수 있지만, 그들은 여전히 차이가 있다.그 중에서 가장 중요한 것은 다음 방법에서TextView에 selector를 지정할 수 없다는 것이다.또 하나의 이상한 차이점은 첫 번째 방법으로 사건을 길게 판단하면 효력을 잃을 수도 있고 두 번째 방법으로 사건을 길게 판단하면 효과가 좋다는 것이다.
Activity에 OnTouchListener를 설치했다면 이러지 않아도 됩니다. 시스템이 설치해 줍니다.

좋은 웹페이지 즐겨찾기