OnClickListener-x, y 이벤트 위치?


85

보기에서 파생 된 사용자 지정보기가 있습니다. 보기를 클릭 할 때 알림을 받고, 클릭이 발생한 위치의 x, y 위치를 알고 싶습니다. 긴 클릭도 마찬가지입니다.

이 작업을 수행하려는 것 같습니다 onTouchEvent(). 을 재정의해야합니다 . OnClickListener그래도 대신 이벤트의 x, y 위치를 가져올 방법이 없습니까?

그렇지 않은 경우 모션 이벤트가 '실제'클릭인지 긴 클릭인지 여부를 알 수있는 좋은 방법은 무엇입니까? 는 onTouchEvent연거푸 등 많은 이벤트를 생성합니다

답변:


91

감사합니다. 그것이 바로 제가 찾던 것입니다. 내 코드는 다음과 같습니다.

imageView.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if (event.getAction() == MotionEvent.ACTION_DOWN){
                textView.setText("Touch coordinates : " +
                        String.valueOf(event.getX()) + "x" + String.valueOf(event.getY()));
            }
            return true;
        }
    });

Mark가 요청한 것을 정확히 수행합니다.


4
이 좌표가 뷰에 국한됩니까?
Nigel

7
onTouch 핸들러가 반환 false되어 터치 이벤트를 차단하지 않아야합니까? (청취자가 다른 경우, 거짓을 소비 한 경우 View.OnTouchListener.onTouch는 true를 반환합니다.)
ehartwell

5
글쎄, "정확히"는 아니기 때문에 OnClickListener손가락을 뗄 때 발동되기 때문에 ACTION_UP제한이 있습니다. 피플링 (스 와이프) 제스처가 수행 된 경우 발동 OnClickListener되지는 않지만 ACTION_UP계속 처리됩니다.
Alex Semeniuk 2014

클릭 한 좌표에 텍스트를 쓰려고합니다. 좌표에 텍스트를 쓰려고 (event.getX(), event.getY()) 했지만 올바른 위치에 쓰지 않습니다.
왕자

여기 내 질문이 있습니다 : stackoverflow.com/questions/40199539/…
Prince

26

전체 예

다른 답변에는 일부 세부 정보가 없습니다. 다음은 전체 예입니다.

public class MainActivity extends AppCompatActivity {

    // class member variable to save the X,Y coordinates
    private float[] lastTouchDownXY = new float[2];

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // add both a touch listener and a click listener
        View myView = findViewById(R.id.my_view);
        myView.setOnTouchListener(touchListener);
        myView.setOnClickListener(clickListener);
    }

    // the purpose of the touch listener is just to store the touch X,Y coordinates
    View.OnTouchListener touchListener = new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {

            // save the X,Y coordinates
            if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
                lastTouchDownXY[0] = event.getX();
                lastTouchDownXY[1] = event.getY();
            }

            // let the touch event pass on to whoever needs it
            return false;
        }
    };

    View.OnClickListener clickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // retrieve the stored coordinates
            float x = lastTouchDownXY[0];
            float y = lastTouchDownXY[1];

            // use the coordinates for whatever
            Log.i("TAG", "onLongClick: x = " + x + ", y = " + y);
        }
    };
}

요약

  • 좌표를 저장할 클래스 변수 추가
  • 다음을 사용하여 X, Y 좌표를 저장합니다. OnTouchListener
  • X, Y 좌표에 액세스합니다. OnClickListener

1
2 개의 공백 float 배열 대신 Point ()를 사용할 수 있습니다.
ZooMagic

Point는 정수 유형의 X 및 Y를 갖습니다. 좌표는 부동 값입니다. Point 클래스를 사용하면 정밀도가 떨어질 것 같아요 .... 저는 Android가 처음이고 뭔가 놓친 것 같습니다.
mboada 19

@mboada, 당신이 맞아요. PointF 가 더 좋을 것입니다.
Suragch 19

onTouchListener를 피하고 onClickListener 만 사용하는 방법이 있어야합니다. 어쨌든 ContextMenu에는 필요하지 않습니다. 항목을 클릭하고보기가 앵커로 표시된 메뉴를 표시하면 터치 위치 근처에 항목을 놓을 위치를 알고 있습니다. 여기를 참조하십시오 : stackoverflow.com/q/57290574/878126 . 그것이 어떻게 가능한지 아십니까? 그렇다면 거기에서 대답 해보십시오.
안드로이드 개발자

3

onTouchEvent (MotionEvent ev) 재정의

그런 다음 다음을 수행 할 수 있습니다.

ev.getXLocation()

아니면 그런 것. 부치가 있습니다.


2
안녕하세요 Tom, 예, onTouchEvent를 사용할 수 있지만 클릭과 긴 클릭 사이의 식별을 직접 처리해야합니다. 그렇지 않습니까? 그들이 OnClickListener 등에서 클릭이나 긴 클릭이 발생한 위치를 아는 방법을 제공하지 않는다는 것은 말이되지 않습니까? 감사합니다
Mark

21
마지막 ACTION_UP 또는 ACTION_MOVE 이벤트의 x 및 y 위치를 기록하고 OnClickListener에서 이러한 값을 사용하기 만하면됩니다.
Romain Guy

@RomainGuy 그러나 클릭을 결정하려면 두 지점 사이의 거리도 계산해야합니다. (0,0)에서 ACTION_DOWN 이벤트를 수신 한 다음 (100,100)에서 ACTION_UP 이벤트를 받으면 확실히 클릭이 아닙니다.
TheRealChx101

@ chx101, RomainGuy가 의미하는 바는 터치 이벤트에서 마지막 action_up 좌표를 기록하면 onclick에서 사용할 수있는 좌표라는 것입니다. 그러나 실제로 뷰를 하위 클래스 화해야하거나 onclick이 호출되지 않는다고 생각합니다. 당신은 또한 같이 제스처 검출기로 탭을 감지 할 수 stackoverflow.com/questions/19538747/... 대답
라시 킨 누넨에게

0

Kotlin에서 다음과 같이 확장 함수를 만들 수 있습니다.

fun View.setOnClickListenerWithPoint(action: (Point) -> Unit) {
    val coordinates = Point()
    val screenPosition = IntArray(2)
    setOnTouchListener { v, event ->
        if (event.action == MotionEvent.ACTION_DOWN) {
            v.getLocationOnScreen(screenPosition)
            coordinates.set(event.x.toInt() + screenPosition[0], event.y.toInt() + screenPosition[1])
        }
        false
    }
    setOnClickListener {
        action.invoke(coordinates)
    }
}

긴 클릭이 필요한 경우-그냥 교체하십시오 setOnClickListener

getLocationOnScreen()RecyclerView의 ViewHolder에 대한 좌표가 필요 하기 때문에 사용합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.