ImageButton에 Ontouch와 Onclick을 모두 사용하는 방법은 무엇입니까?
내 앱에서 두 가지 일이 일어나기를 원합니다.
ImageButton을 터치하고 드래그하면 손가락과 함께 움직여야합니다.
나는
OnTouchListener()이것을 위해 사용 했고 잘 작동합니다.ImageButton을 클릭하면 활동이 닫힙니다.
나는
OnClickListener()이것을 위해 사용 했고 또한 잘 작동합니다.
그래서 여기 내 문제가 있습니다. i가 이동 될 때마다 ImageButton OnTouchListenertirggered하고 ImageButton이동은은 OnClickListener내가 이동 버튼을 해제하고 때에도 끝에 트리거된다.
서로 간섭하지 않고 동일한 버튼에서 ontouch 및 onclick 리스너를 사용하는 방법은 무엇입니까?
이것을 시도하면 도움이 될 수 있습니다
onClick()방법 을 설정하지 않아도 onTouch()두 경우 모두 처리됩니다.
package com.example.demo;
import android.app.Activity;
import android.os.Bundle;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageButton;
public class MainActivity extends Activity {
private GestureDetector gestureDetector;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gestureDetector = new GestureDetector(this, new SingleTapConfirm());
ImageButton imageButton = (ImageButton) findViewById(R.id.img);
imageButton.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View arg0, MotionEvent arg1) {
if (gestureDetector.onTouchEvent(arg1)) {
// single tap
return true;
} else {
// your code for move and drag
}
return false;
}
});
}
private class SingleTapConfirm extends SimpleOnGestureListener {
@Override
public boolean onSingleTapUp(MotionEvent event) {
return true;
}
}
}
이려면 Click Listener, DoubleClick Listener, OnLongPress Listener, Swipe Left, Swipe Right, Swipe Up, Swipe Down싱글에 View다음을 수행해야합니다 setOnTouchListener. 즉,
view.setOnTouchListener(new OnSwipeTouchListener(MainActivity.this) {
@Override
public void onClick() {
super.onClick();
// your on click here
}
@Override
public void onDoubleClick() {
super.onDoubleClick();
// your on onDoubleClick here
}
@Override
public void onLongClick() {
super.onLongClick();
// your on onLongClick here
}
@Override
public void onSwipeUp() {
super.onSwipeUp();
// your swipe up here
}
@Override
public void onSwipeDown() {
super.onSwipeDown();
// your swipe down here.
}
@Override
public void onSwipeLeft() {
super.onSwipeLeft();
// your swipe left here.
}
@Override
public void onSwipeRight() {
super.onSwipeRight();
// your swipe right here.
}
});
}
이를 위해이 필요 OnSwipeTouchListener구현 클래스를 OnTouchListener.
public class OnSwipeTouchListener implements View.OnTouchListener {
private GestureDetector gestureDetector;
public OnSwipeTouchListener(Context c) {
gestureDetector = new GestureDetector(c, new GestureListener());
}
public boolean onTouch(final View view, final MotionEvent motionEvent) {
return gestureDetector.onTouchEvent(motionEvent);
}
private final class GestureListener extends GestureDetector.SimpleOnGestureListener {
private static final int SWIPE_THRESHOLD = 100;
private static final int SWIPE_VELOCITY_THRESHOLD = 100;
@Override
public boolean onDown(MotionEvent e) {
return true;
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
onClick();
return super.onSingleTapUp(e);
}
@Override
public boolean onDoubleTap(MotionEvent e) {
onDoubleClick();
return super.onDoubleTap(e);
}
@Override
public void onLongPress(MotionEvent e) {
onLongClick();
super.onLongPress(e);
}
// Determines the fling velocity and then fires the appropriate swipe event accordingly
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
boolean result = false;
try {
float diffY = e2.getY() - e1.getY();
float diffX = e2.getX() - e1.getX();
if (Math.abs(diffX) > Math.abs(diffY)) {
if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
if (diffX > 0) {
onSwipeRight();
} else {
onSwipeLeft();
}
}
} else {
if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
if (diffY > 0) {
onSwipeDown();
} else {
onSwipeUp();
}
}
}
} catch (Exception exception) {
exception.printStackTrace();
}
return result;
}
}
public void onSwipeRight() {
}
public void onSwipeLeft() {
}
public void onSwipeUp() {
}
public void onSwipeDown() {
}
public void onClick() {
}
public void onDoubleClick() {
}
public void onLongClick() {
}
}
onClick 및 OnTouch 이벤트의 문제점은 클릭하는 순간 (클릭 할 의도로) 이벤트가 OnTouch라고 가정하므로 OnClick이 해석되지 않는다는 것입니다. 해결 방법
isMove = false;
case MotionEvent.ACTION_DOWN:
//Your stuff
isMove = false;
case MotionEvent.ACTION_UP:
if (!isMove || (Xdiff < 10 && Ydiff < 10 ) {
view.performClick; //The check for Xdiff <10 && YDiff< 10 because sometime elements moves a little
even when you just click it
}
case MotionEvent.ACTION_MOVE:
isMove = true;
내 프로젝트에 @Biraj 솔루션을 적용하려고 시도했지만 작동하지 않았습니다.의 확장이 메서드를 SimpleOnGestureListener재정의 할뿐만 아니라 onSingleTapConfirmed메서드도 재정의해야한다는 것을 알았 onDown습니다. 문서 로 인해 :
기본적으로 GestureDetector.SimpleOnGestureListener가 수행하는 것처럼 onDown ()에서 false를 반환하면 시스템은 나머지 동작을 무시하고 GestureDetector.OnGestureListener의 다른 메서드가 호출되지 않는다고 가정합니다.
다음은 복잡한 솔루션입니다.
public class MainActivity extends Activity {
private GestureDetector gestureDetector;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gestureDetector = new GestureDetectorCompat(this, new SingleTapConfirm());
ImageButton imageButton = (ImageButton) findViewById(R.id.img);
imageButton.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View arg0, MotionEvent arg1) {
if (gestureDetector.onTouchEvent(arg1)) {
// single tap
return true;
} else {
// your code for move and drag
}
return false;
}
});
}
private class SingleTapConfirm extends SimpleOnGestureListener {
@Override
public boolean onDown(MotionEvent e) {
/*it needs to return true if we don't want
to ignore rest of the gestures*/
return true;
}
@Override
public boolean onSingleTapConfirmed(MotionEvent event) {
return true;
}
}
}
이 동작은 GestureDetectorCompat의 차이로 인해 발생할 수 있다고 생각하지만 설명서를 따르고 두 번째를 사용하겠습니다.
Android 1.6 이상을 실행하는 기기와의 호환성을 제공하려면 가능한 경우 지원 라이브러리 클래스를 사용해야합니다.
에서 MainActivity코드이.
public class OnSwipeTouchListener_imp extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_on_swipe_touch_listener);
ImageView view = (ImageView)findViewById(R.id.view);
view.setOnTouchListener(new OnSwipeTouchListener(OnSwipeTouchListener_imp.this)
{
@Override
public void onClick()
{
super.onClick(); // your on click here
Toast.makeText(getApplicationContext(),"onClick",Toast.LENGTH_SHORT).show();
}
@Override
public void onDoubleClick()
{
super.onDoubleClick(); // your on onDoubleClick here
}
@Override
public void onLongClick()
{
super.onLongClick(); // your on onLongClick here
}
@Override
public void onSwipeUp() {
super.onSwipeUp(); // your swipe up here
}
@Override
public void onSwipeDown() {
super.onSwipeDown(); // your swipe down here.
}
@Override
public void onSwipeLeft() {
super.onSwipeLeft(); // your swipe left here.
Toast.makeText(getApplicationContext(),"onSwipeLeft",Toast.LENGTH_SHORT).show();
}
@Override
public void onSwipeRight() {
super.onSwipeRight(); // your swipe right here.
Toast.makeText(getApplicationContext(),"onSwipeRight",Toast.LENGTH_SHORT).show();
}
});
}
}
그런 다음 OnSwipeTouchListenerJava 클래스를 만듭니다 .
public class OnSwipeTouchListener implements View.OnTouchListener {
private GestureDetector gestureDetector;
public OnSwipeTouchListener(Context c) {
gestureDetector = new GestureDetector(c, new GestureListener());
}
public boolean onTouch(final View view, final MotionEvent motionEvent) {
return gestureDetector.onTouchEvent(motionEvent);
}
private final class GestureListener extends GestureDetector.SimpleOnGestureListener {
private static final int SWIPE_THRESHOLD = 100;
private static final int SWIPE_VELOCITY_THRESHOLD = 100;
@Override
public boolean onDown(MotionEvent e) {
return true;
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
onClick();
return super.onSingleTapUp(e);
}
@Override
public boolean onDoubleTap(MotionEvent e) {
onDoubleClick();
return super.onDoubleTap(e);
}
@Override
public void onLongPress(MotionEvent e) {
onLongClick();
super.onLongPress(e);
}
// Determines the fling velocity and then fires the appropriate swipe event accordingly
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
boolean result = false;
try {
float diffY = e2.getY() - e1.getY();
float diffX = e2.getX() - e1.getX();
if (Math.abs(diffX) > Math.abs(diffY)) {
if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD)
{
if (diffX > 0)
{
onSwipeRight(); // Right swipe
} else {
onSwipeLeft(); // Left swipe
}
}
} else {
if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
if (diffY > 0) {
onSwipeDown(); // Down swipe
} else {
onSwipeUp(); // Up swipe
}
}
}
} catch (Exception exception) {
exception.printStackTrace();
}
return result;
}
}
public void onSwipeRight() {
}
public void onSwipeLeft() {
}
public void onSwipeUp() {
}
public void onSwipeDown() {
}
public void onClick() {
}
public void onDoubleClick() {
}
public void onLongClick() {
}
}
희망이 조명 u :)
부울로 작업 할 수 있습니다.
Boolean isMoving = false;
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_MOVE:
isMoving = true;
// implement your move codes
break;
case MotionEvent.ACTION_UP:
isMoving = false;
break;
default:
break;
}
그런 다음 onclick 메소드에서 부울을 확인하십시오. 거짓이면 클릭 동작을 수행하고 참이면 클릭 동작을 수행합니다.
public void onClick(View arg0) {
switch (arg0.getId()) {
case R.id.imagebutton:
if(!isMoving) {
//code for on click here
}
default:
break;
}
}
Clieck 리스너 이벤트; onclicklistener를 호출하는 것보다 구성 요소 경계에서 actiondown 및 action up이 발생하면 따라서 onclick 이벤트는 터치 감지로 활성화됩니다. onTouchListener를 설정하고 구성 요소가 시작 위치에서 작업이 시작되고 작업이 중지 된 경우에만 클릭 이벤트를받을 수 있습니다.
다음과 같은 개인 변수를 선언하십시오. boolean hasMoved = false;
이미지 버튼이 움직이기 시작하면 hasMoved = true
귀하의에서 OnClickListener실행 코드 만 if(!hasMoved)- 의미는 버튼을 이동하지 않은 경우에만 클릭 기능을 수행합니다. hasMoved = false;나중에 설정
Simply use a boolean field and set it to true value when your OnTouchListener is triggered. after that when the OnClickListener wants to trigger you will check the boolean field and if true don't act anything in your onClickListener.
private blnTouch = false;
private OnTouchListener btnOnTouchListener = new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
if (event.getAction()==MotionEvent.ACTION_DOWN){
blnOnTouch = true;
}
if (event.getAction()==MotionEvent.ACTION_UP){
blnOnTouch = false;
}
}
};
private OnClickListener btnOnClickListener = new OnClickListener() {
@Override
public void onClick(View arg0) {
if (blnOnTouch){
// Do Your OnClickJob Here without touch and move
}
}
};
Hope I'm not too late but you can achieve this by time counter. A click takes less than a second so with that in mind....
long prev=0;
long current = 0;
long dif =0;
public boolean onTouch(View view, MotionEvent event) {
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
prev = System.currentTimeMillis() / 1000;
break;
case MotionEvent.ACTION_UP:
current = System.currentTimeMillis() / 1000;
dif = current - prev;
if (dif == 0) {
//Perform Your Click Action
}
break;
}
}
Hope it helps out someone
You can differentiate between touch, click and swipe by getting the difference in the x,y values like:
var prevY = 0
var prevX = 0
controls.setOnTouchListener { v, event ->
when (event?.actionMasked) {
MotionEvent.ACTION_DOWN -> {
prevY = event.rawY.toInt()
prevX = event.rawX.toInt()
}
MotionEvent.ACTION_UP->{
Log.d("Controls","Action up")
var y = event.rawY.toInt()
var x = event.rawX.toInt()
val diffY = Math.abs(prevY - y)
val diffX = Math.abs(prevX - x)
if(diffX in 0..10 && diffY in 0..10){
// its a touch
}
//check diffY if negative, is a swipe down, else swipe up
//check diffX if negative, its a swipe right, else swipe left
}
}
true
}
ReferenceURL : https://stackoverflow.com/questions/19538747/how-to-use-both-ontouch-and-onclick-for-an-imagebutton
'Program Club' 카테고리의 다른 글
| 인용 부호 안에 인용 부호 사용 (0) | 2021.01.09 |
|---|---|
| Salesforce 인증 실패 (0) | 2021.01.09 |
| 부트 스트랩의 폼 컨트롤 팝 오버에서 필수 필드의 기본 메시지를 변경하는 방법은 무엇입니까? (0) | 2021.01.09 |
| Xcode 6.0.1이 메모리 사용량을 표시하지 않음 (0) | 2021.01.09 |
| React js의 서비스 워커 란? (0) | 2021.01.08 |