Android : 두 번 탭을 감지하는 방법?
더블 탭을 구현하는 데 문제가 있습니다. 글쎄, 나는을 구현하고 onGestureListener
가지고 gestureDetector
있었지만 문제가 어디에 있는지 잘 모르겠습니다. 여기에 내 코드가 있습니다.
public class home extends TabActivity implements OnGestureListener {
/** Called when the activity is first created. */
private EditText queryText;
private ResultsAdapter m_adapter;
private ProgressDialog pd;
final Handler h = new Handler();
private TabHost mTabHost;
private ArrayList<SearchItem> sResultsArr = new ArrayList<SearchItem>();
private String queryStr;
private JSONObject searchResponse;
private GestureDetector gestureScanner;
final Runnable mUpdateResults = new Runnable() {
public void run() {
updateListUi();
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button search = (Button)findViewById(R.id.search);
Button testButt = (Button)findViewById(R.id.testbutt);
queryText = (EditText)findViewById(R.id.query);
ListView lvr = (ListView)findViewById(R.id.search_results);
//initialise the arrayAdapter
this.m_adapter = new ResultsAdapter(home.this, R.layout.listrow, sResultsArr);
lvr.setAdapter(this.m_adapter);
lvr.setOnItemClickListener(new OnItemClickListener(){
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
// TODO Auto-generated method stub
pd = ProgressDialog.show(home.this, null,"Loading products from server", true, false);
}
});
gestureScanner = new GestureDetector(this,this);
gestureScanner.setOnDoubleTapListener(new OnDoubleTapListener(){
public boolean onDoubleTap(MotionEvent e) {
//viewA.setText("-" + "onDoubleTap" + "-");
pd = ProgressDialog.show(home.this, null,"Loading products from server", true, false);
return false;
}
public boolean onDoubleTapEvent(MotionEvent e) {
// viewA.setText("-" + "onDoubleTapEvent" + "-");
return false;
}
public boolean onSingleTapConfirmed(MotionEvent e) {
//viewA.setText("-" + "onSingleTapConfirmed" + "-");
return false;
}
});
//initialise tab contents
mTabHost = getTabHost();
mTabHost.addTab(mTabHost.newTabSpec("tab1").setIndicator("Home").setContent(R.id.homepage));
mTabHost.addTab(mTabHost.newTabSpec("tab2").setIndicator("Search Results").setContent(R.id.tab2));
mTabHost.setCurrentTab(0);
//sets the respective listeners
testButt.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
if(mTabHost.getTabWidget().getVisibility()==View.GONE){
mTabHost.getTabWidget().setVisibility(View.VISIBLE);
}
else{
mTabHost.getTabWidget().setVisibility(View.GONE);
}
}
});
search.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
sResultsArr.clear();
queryStr = "http://rose.mosuma.com/mobile?query=" + queryText.getText().toString();
pd = ProgressDialog.show(home.this, null,"Loading products from server", true, false);
goSearch();
}
});
}
//updates the listUI whenever after receiving the response from the server
public void updateListUi(){
if(sResultsArr.size() > 0){
}
try{
String ptypename;
int count;
LinearLayout ptypebar = (LinearLayout)findViewById(R.id.productCat);
ptypebar.removeAllViews();
JSONArray ptypes = searchResponse.getJSONArray("ptypes");
for(int index =0;index < ptypes.length();index++){
JSONObject ptype = ptypes.getJSONObject(index);
count = ptype.getInt("count");
ptypename = ptype.getString("ptypename");
//add into tab 2's UI
//ImageView icon = new ImageView(this);
TextView t = new TextView(home.this);
t.setText(ptypename + " (" + count + ")");
ptypebar.addView(t);
}
}
catch(JSONException e){
}
//if(m_adapter.getItems() != sResultsArr){
ArrayList<SearchItem> a = m_adapter.getItems();
a = sResultsArr;
//}
m_adapter.notifyDataSetChanged();
pd.dismiss();
}
public void goSearch(){
mTabHost.setCurrentTab(1);
//separate thread for making http request and updating the arraylist
Thread t = new Thread() {
public void run() {
searchResponse = sendSearchQuery(queryStr);
try{
JSONArray results = searchResponse.getJSONArray("results");
//this is stupid. i probably have to see how to make a json adapter
for(int index =0;index < results.length();index++){
JSONObject product = results.getJSONObject(index);
//gets the searched products from the json object
URL imgUrl = new URL(product.getString("image"));
String productname = product.getString("productname");
String ptypename = product.getString("ptypename");
int pid = product.getInt("pid");
int positive = product.getInt("pos");
int negative = product.getInt("neg");
int neutral = product.getInt("neu");
SearchItem item = new SearchItem(imgUrl,productname,ptypename,neutral,positive,negative,pid);
sResultsArr.add(item);
}
}
catch(JSONException e){
}
catch(Exception e){
}
//returns back to UI therad
h.post(mUpdateResults);
}
};
t.start();
}
//sends a request with qry as URL
//and receives back a JSONobject as response
public JSONObject sendSearchQuery(String qry){
HttpRequest r = new HttpRequest();
JSONObject response = r.sendHttpRequest(qry);
return response;
}
@Override
public boolean onDown(MotionEvent arg0) {
return gestureScanner.onTouchEvent(arg0);
}
@Override
public boolean onFling(MotionEvent arg0, MotionEvent arg1, float arg2,
float arg3) {
// TODO Auto-generated method stub
return false;
}
@Override
public void onLongPress(MotionEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public boolean onScroll(MotionEvent arg0, MotionEvent arg1, float arg2,
float arg3) {
// TODO Auto-generated method stub
return false;
}
@Override
public void onShowPress(MotionEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public boolean onSingleTapUp(MotionEvent arg0) {
// TODO Auto-generated method stub
return false;
}
아, 또 다른 질문 ListView
이 있습니다. onItemClickListener
, Android가 한 번 탭하거나 두 번 탭하면 감지 할 수 있습니까?
롱 프레스를 사용하지 않는 이유는 무엇입니까? 아니면 이미 다른 용도로 사용하고 있습니까? 더블 터치에 비해 강화 누르기의 장점 :
- 상호 작용하는 것입니다.
- 사용자가 기대하는 것입니다. 사용자는 더블 터치 동작을 실패 할 수 없습니다.
- 이미 API에서 처리되었습니다 .
- 더블 터치를 구현하면 싱글 터치 처리에 영향을 미칠 수 있습니다. 처리하기 전에 모든 싱글 터치가 더블 터치로 바뀌는 지 확인하기 위해 기다려야하기 때문입니다.
GestureDetector를 사용할 수 있습니다. 다음 코드를 참조하십시오.
public class MyView extends View {
GestureDetector gestureDetector;
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
// creating new gesture detector
gestureDetector = new GestureDetector(context, new GestureListener());
}
// skipping measure calculation and drawing
// delegate the event to the gesture detector
@Override
public boolean onTouchEvent(MotionEvent e) {
return gestureDetector.onTouchEvent(e);
}
private class GestureListener extends GestureDetector.SimpleOnGestureListener {
@Override
public boolean onDown(MotionEvent e) {
return true;
}
// event when double tap occurs
@Override
public boolean onDoubleTap(MotionEvent e) {
float x = e.getX();
float y = e.getY();
Log.d("Double Tap", "Tapped at: (" + x + "," + y + ")");
return true;
}
}
}
단일 탭, 플링 등을 위해 리스너의 다른 메소드를 재정의 할 수 있습니다.
GestureDetector의 간단한 대안으로이 클래스를 사용할 수 있습니다.
public abstract class DoubleClickListener implements OnClickListener {
private static final long DOUBLE_CLICK_TIME_DELTA = 300;//milliseconds
long lastClickTime = 0;
@Override
public void onClick(View v) {
long clickTime = System.currentTimeMillis();
if (clickTime - lastClickTime < DOUBLE_CLICK_TIME_DELTA){
onDoubleClick(v);
} else {
onSingleClick(v);
}
lastClickTime = clickTime;
}
public abstract void onSingleClick(View v);
public abstract void onDoubleClick(View v);
}
예 :
view.setOnClickListener(new DoubleClickListener() {
@Override
public void onSingleClick(View v) {
}
@Override
public void onDoubleClick(View v) {
}
});
"Bughi" "DoubleClickListner"및 "Jayant Arora"Timer를 하나의 포함 된 클래스에 결합 :
public abstract class DoubleClickListener implements OnClickListener {
private Timer timer = null; //at class level;
private int DELAY = 400;
private static final long DOUBLE_CLICK_TIME_DELTA = 300;//milliseconds
long lastClickTime = 0;
@Override
public void onClick(View v) {
long clickTime = System.currentTimeMillis();
if (clickTime - lastClickTime < DOUBLE_CLICK_TIME_DELTA){
processDoubleClickEvent(v);
} else {
processSingleClickEvent(v);
}
lastClickTime = clickTime;
}
public void processSingleClickEvent(final View v){
final Handler handler=new Handler();
final Runnable mRunnable=new Runnable(){
public void run(){
onSingleClick(v); //Do what ever u want on single click
}
};
TimerTask timertask=new TimerTask(){
@Override
public void run(){
handler.post(mRunnable);
}
};
timer=new Timer();
timer.schedule(timertask,DELAY);
}
public void processDoubleClickEvent(View v){
if(timer!=null)
{
timer.cancel(); //Cancels Running Tasks or Waiting Tasks.
timer.purge(); //Frees Memory by erasing cancelled Tasks.
}
onDoubleClick(v);//Do what ever u want on Double Click
}
public abstract void onSingleClick(View v);
public abstract void onDoubleClick(View v);
}
다음과 같이 호출 할 수 있습니다.
view.setOnClickListener(new DoubleClickListener() {
@Override
public void onSingleClick(View v) {
}
@Override
public void onDoubleClick(View v) {
}
});
사용자 정의보기로 이동하지면 다음 접근 방식을 사용할 수 있습니다. 예 : ImageView
// class level
GestureDetector gestureDetector;
boolean tapped;
ImageView imageView;
// inside onCreate of Activity or Fragment
gestureDetector = new GestureDetector(context,new GestureListener());
// ------------------------------------------------ --------------------------------
public class GestureListener extends
GestureDetector.SimpleOnGestureListener {
@Override
public boolean onDown(MotionEvent e) {
return true;
}
// event when double tap occurs
@Override
public boolean onDoubleTap(MotionEvent e) {
tapped = !tapped;
if (tapped) {
} else {
}
return true;
}
}
// ------------------------------------------------ --------------------------------
ImageView 용
imageView.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
return gestureDetector.onTouchEvent(event);
}
});
이것은 내 솔루션 setOnItemClickListener()
입니다. 구현해야 할 작업이 있습니다. 곧 github에 예제와 사용자 정의 클래스를 게시 할 것입니다. 간단한 설명이 제공됩니다. 밀리 초 단위의 시간이 시스템 ( ViewConfiguration.getDoubleTapTimeout()
소스 참조 )이 단일 탭과 두 번 탭 사이를 결정하는지 여부 차이인지 확실하지 .
편집 : 여기를 참조하십시오 : https://github.com/NikolaDespotoski/DoubleTapListView 또는 https://github.com/NikolaDespotoski/DoubleTapListViewHandler
GuestureDetecter는 대부분의 장치에서 잘 작동합니다. 두 번 클릭 이벤트에서 두 번의 클릭 사이의 시간을 사용자 정의 할 수있는 방법을 알고 싶습니다. 그렇게 할 수 없었습니다. 위의 코드를 "Bughi" "DoubleClickListner"로 업데이트하고, 한 번의 클릭으로 특정 지연 후 코드를 실행하는 번을 사용하여 타이머를 추가하고, 그 지연 전에 두 번 클릭하면 타이머와 한 번의 클릭 작업 만 취소 및 실행됩니다. 작업을 두 번 클릭하십시오. 코드가 잘 작동합니다. 더블 클릭 목록 작성기로 사용 완벽합니다.
private Timer timer = null; //at class level;
private int DELAY = 500;
view.setOnClickListener(new DoubleClickListener() {
@Override
public void onSingleClick(View v) {
final Handler handler = new Handler();
final Runnable mRunnable = new Runnable() {
public void run() {
processSingleClickEvent(v); //Do what ever u want on single click
}
};
TimerTask timertask = new TimerTask() {
@Override
public void run() {
handler.post(mRunnable);
}
};
timer = new Timer();
timer.schedule(timertask, DELAY);
}
@Override
public void onDoubleClick(View v) {
if(timer!=null)
{
timer.cancel(); //Cancels Running Tasks or Waiting Tasks.
timer.purge(); //Frees Memory by erasing cancelled Tasks.
}
processDoubleClickEvent(v);//Do what ever u want on Double Click
}
});
boolean nonDoubleClick = true, singleClick = false;
private long firstClickTime = 0L;
private final int DOUBLE_CLICK_TIMEOUT = 200;
listview.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View v, int pos, long id) {
// TODO Auto-generated method stub
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
if (singleClick) {
Toast.makeText(getApplicationContext(), "Single Tap Detected", Toast.LENGTH_SHORT).show();
}
firstClickTime = 0L;
nonDoubleClick = true;
singleClick = false;
}
}, 200);
if (firstClickTime == 0) {
firstClickTime = SystemClock.elapsedRealtime();
nonDoubleClick = true;
singleClick = true;
} else {
long deltaTime = SystemClock.elapsedRealtime() - firstClickTime;
firstClickTime = 0;
if (deltaTime < DOUBLE_CLICK_TIMEOUT) {
nonDoubleClick = false;
singleClick = false;
Toast.makeText(getApplicationContext(), "Double Tap Detected", Toast.LENGTH_SHORT).show();
}
}
}
});
두 번 탭 및 한 번 탭
두 번 탭하기 만
SimpleOnGestureListener
( Hannes Niederhausen의 답변 에서 보여준 것처럼) 를 사용하여 뷰에서 탭을 감지하는 것은 매우 신뢰할 수있는 더블 수용 .
private class GestureListener extends GestureDetector.SimpleOnGestureListener {
@Override
public boolean onDown(MotionEvent e) {
return true;
}
@Override
public boolean onDoubleTap(MotionEvent e) {
return true;
}
}
이에 대한 논리를 다시 발명하는 것이 큰 이점을 볼 수 없습니다 (예 : bughi의 답변 ).
지연이있는 두 번 탭 및 한 번 탭
를 사용하여 SimpleOnGestureListener
단일 탭과 두 번 탭을 상호 배타적 인 이벤트로 구분할 수도 있습니다 . 그렇게하세요 onSingleTapConfirmed
. 이렇게하면 시스템에서 사용자가 두 번 탭하지 갑자기 혹시 확인할 때 단일 탭 코드 실행이 지연됩니다 (예 : 지연> ViewConfiguration.getDoubleTapTimeout()
). 이에 대한 모든 논리를 다시 발명 할 이유가 없습니다 ( this , this 및 기타 답변 에서 수행됨 ).
private class GestureListener extends GestureDetector.SimpleOnGestureListener {
@Override
public boolean onDown(MotionEvent e) {
return true;
}
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
return true;
}
@Override
public boolean onDoubleTap(MotionEvent e) {
return true;
}
}
지연없이 두 번 탭 및 한 번 탭
딱딱한 인 문제 onSingleTapConfirmed
는 지연입니다. 눈에 띄는 것은 지연이 허용되지 않습니다. 경우 당신은이 대체 할 수 있습니다 onSingleTapConfirmed
로 onSingleTapUp
.
private class GestureListener extends GestureDetector.SimpleOnGestureListener {
@Override
public boolean onDown(MotionEvent e) {
return true;
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
return true;
}
@Override
public boolean onDoubleTap(MotionEvent e) {
return true;
}
}
당신은,하지만, 실현하는 것이 필요 둘 onSingleTapUp
과 onDoubleTap
더블 탭이있는 경우 호출됩니다. (이것은 본질적으로 bughi 대답의 이하는 일과 일부 주석가가 불평 한을 구석으로입니다.) 지연을 사용하거나 두 메서드를 모두 호출해야합니다 . 지연없이 한 번의 탭으로 동시에 사용자가 다시 탭할지 여부를 알 수는 없습니다.
단일 탭 지연이 허용되지 않는 경우 다음 두 가지 옵션이 있습니다.
- 모두 받아 들일
onSingleTapUp
및onDoubleTap
더블 탭에 대한 호출됩니다. 문제가되지 않도록 논리를 이해하게 나누십시오. 이것은 본질적으로 사용자 정의 키보드에서 caps-lock을 위해 두 번 탭할 때 수행 한 작업입니다. 두 번 탭하지 대부분의 경우 처리 인 UI 작업이 아닙니다. Dave Webb이 제안하는 것이 바로 누르는 것이 좋습니다. 다음을 사용하여 구현할 수도 있습니다
SimpleOnGestureListener
.private class GestureListener extends GestureDetector.SimpleOnGestureListener { @Override public boolean onDown(MotionEvent e) { return true; } @Override public boolean onSingleTapUp(MotionEvent e) { return true; } @Override public void onLongPress(MotionEvent e) { } }
즉석 dhruvi 코드
public abstract class DoubleClickListener implements View.OnClickListener {
private static final long DOUBLE_CLICK_TIME_DELTA = 300;//milliseconds
long lastClickTime = 0;
boolean tap = true;
@Override
public void onClick(View v) {
long clickTime = System.currentTimeMillis();
if (clickTime - lastClickTime < DOUBLE_CLICK_TIME_DELTA){
onDoubleClick(v);
tap = false;
} else
tap = true;
v.postDelayed(new Runnable() {
@Override
public void run() {
if(tap)
onSingleClick();
}
},DOUBLE_CLICK_TIME_DELTA);
lastClickTime = clickTime;
}
public abstract void onDoubleClick(View v);
public abstract void onSingleClick();
}
내 솔루션이 도움이 될 수 있습니다.
long lastTouchUpTime = 0;
boolean isDoubleClick = false;
private void performDoubleClick() {
long currentTime = System.currentTimeMillis();
if(!isDoubleClick && currentTime - lastTouchUpTime < DOUBLE_CLICK_TIME_INTERVAL) {
isDoubleClick = true;
lastTouchUpTime = currentTime;
Toast.makeText(context, "double click", Toast.LENGTH_SHORT).show();
}
else {
lastTouchUpTime = currentTime;
isDoubleClick = false;
}
}
단일 및 더블 클릭 실현
public abstract class DoubleClickListener implements View.OnClickListener {
private static final long DOUBLE_CLICK_TIME_DELTA = 200;
private long lastClickTime = 0;
private View view;
private Handler handler = new Handler();
private Runnable runnable = new Runnable() {
@Override
public void run() {
onSingleClick(view);
}
};
private void runTimer(){
handler.removeCallbacks(runnable);
handler.postDelayed(runnable,DOUBLE_CLICK_TIME_DELTA);
}
@Override
public void onClick(View view) {
this.view = view;
long clickTime = System.currentTimeMillis();
if (clickTime - lastClickTime < DOUBLE_CLICK_TIME_DELTA){
handler.removeCallbacks(runnable);
lastClickTime = 0;
onDoubleClick(view);
} else {
runTimer();
lastClickTime = clickTime;
}
}
public abstract void onSingleClick(View v);
public abstract void onDoubleClick(View v);
}
public class MyView extends View {
GestureDetector gestureDetector;
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
// creating new gesture detector
gestureDetector = new GestureDetector(context, new GestureListener());
}
// skipping measure calculation and drawing
// delegate the event to the gesture detector
@Override
public boolean onTouchEvent(MotionEvent e) {
return gestureDetector.onTouchEvent(e);
}
private class GestureListener extends GestureDetector.SimpleOnGestureListener {
@Override
public boolean onDown(MotionEvent e) {
return true;
}
// event when double tap occurs
@Override
public boolean onDoubleTap(MotionEvent e) {
float x = e.getX();
float y = e.getY();
Log.d("Double Tap", "Tapped at: (" + x + "," + y + ")");
return true;
}
}
}
Kotlin을 사용하는 경우 다음과 같이 할 수 있습니다.
이 코드를 Kotlin으로 변환하는 데 많은 시간을 소비합니다. 누군가의 시간을 절약하기를 바랍니다.
동작 감지기를 만듭니다.
val gestureDetector = GestureDetector(this, object : GestureDetector.SimpleOnGestureListener() {
override fun onDoubleTap(e: MotionEvent): Boolean {
Toast.makeText(this@DemoActivity,"Double Tap",Toast.LENGTH_LONG).show()
//Show or hide Ip address on double tap
toggleIPaddressVisibility()
return true;
}
override fun onLongPress(e: MotionEvent) {
super.onLongPress(e);
//rotate frame on long press
toggleFrameRotation()
Toast.makeText(this@DemoActivity,"LongClick",Toast.LENGTH_LONG).show()
}
override fun onDoubleTapEvent(e: MotionEvent): Boolean {
return true
}
override fun onDown(e: MotionEvent): Boolean {
return true
}
})
보기에 할당 :
IPAddress.setOnTouchListener { v, event ->
return@setOnTouchListener gestureDetector.onTouchEvent(event)
}
copypast에 대한 bughi & Jayant Arora의 솔루션 :
public abstract class DoubleClickListener implements View.OnClickListener {
private int position;
private Timer timer;
private static final long DOUBLE_CLICK_TIME_DELTA = 300;//milliseconds
long lastClickTime = 0;
public DoubleClickListener (int position) {
this.position = position;
}
@Override
public void onClick(View v) {
long clickTime = System.currentTimeMillis();
if (clickTime - lastClickTime < DOUBLE_CLICK_TIME_DELTA){
if (timer != null) {
timer.cancel(); //Cancels Running Tasks or Waiting Tasks.
timer.purge(); //Frees Memory by erasing cancelled Tasks.
}
onDoubleClick(v, position);
} else {
final Handler handler = new Handler();
final Runnable mRunnable = () -> {
onSingleClick(v, position);
};
TimerTask timertask = new TimerTask() {
@Override
public void run() {
handler.post(mRunnable);
}
};
timer = new Timer();
timer.schedule(timertask, DOUBLE_CLICK_TIME_DELTA);
}
lastClickTime = clickTime;
}
public abstract void onSingleClick(View v, int position);
public abstract void onDoubleClick(View v, int position);}
동일한 기능을 구현하는 데 동등한 동등한 C # 코드이며 N 개의 탭을 허용하도록 사용자 수도 있습니다.
public interface IOnTouchInterface
{
void ViewTapped();
}
public class MultipleTouchGestureListener : Java.Lang.Object, View.IOnTouchListener
{
int clickCount = 0;
long startTime;
static long MAX_DURATION = 500;
public int NumberOfTaps { get; set; } = 7;
readonly IOnTouchInterface interfc;
public MultipleTouchGestureListener(IOnTouchInterface tch)
{
this.interfc = tch;
}
public bool OnTouch(View v, MotionEvent e)
{
switch (e.Action)
{
case MotionEventActions.Down:
clickCount++;
if(clickCount == 1)
startTime = Utility.CurrentTimeSince1970;
break;
case MotionEventActions.Up:
var currentTime = Utility.CurrentTimeSince1970;
long time = currentTime - startTime;
if(time <= MAX_DURATION * NumberOfTaps)
{
if (clickCount == NumberOfTaps)
{
this.interfc.ViewTapped();
clickCount = 0;
}
}
else
{
clickCount = 0;
}
break;
}
return true;
}
}
public static class Utility
{
public static long CurrentTimeSince1970
{
get
{
DateTime dt = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Local);
DateTime dtNow = DateTime.Now;
TimeSpan result = dtNow.Subtract(dt);
long seconds = (long)result.TotalMilliseconds;
return seconds;
}
}
}
현재 위의 코드는 View Tapped 이벤트를 발생시키기 전에 탭 수로 7을 허용합니다. 그러나 그것은 어떤 숫자 로든지 주문을 만들어 질 수 있습니다
kotlin 코 루틴을 사용하여 간단한 사용자 지정 메서드를 구현했습니다 (Java의 경우 사례를 통해 수행 할 수 있음).
var click = 0
view.setOnClickListener{
click++
clicksHandling()
}
fun clicksHandling() {
if (click == 1) {
launch {
delay(300) // custom delay duration between clicks
// if user didn't double tap then click counter still 1
if (click == 1) {
// single click handling
runOnUiThread {
// whatever you wanna do on UI thread
}
}
click = 0 //reset counter , this will run no matter single / double tap
}
//double click handling
if (click == 2) {
// whatever on double click
}
}
기능 + 인터페이스 = DoubleTapListener, AnyTap 리스너 등
이 예에서는 예시가있는 DoubleTap Listener를 구현했습니다. ClickListener와 모든 항목보기 개체에 내 리스너를 추가 할 수 있습니다. 이 접근 방식을 사용하면 모든 종류의 클릭 리스너를 쉽게 수 있습니다.
yourButton.setOnClickListener(new DoubleTapListener(this));
1) 내 Listrener 클래스
public class DoubleTapListener implements View.OnClickListener{
private boolean isRunning= false;
private int resetInTime =500;
private int counter=0;
private DoubleTapCallback listener;
public DoubleTapListener(Context context)
{
listener = (DoubleTapCallback)context;
Log.d("Double Tap","New");
}
@Override
public void onClick(View v) {
if(isRunning)
{
if(counter==1)
listener.onDoubleClick(v);
}
counter++;
if(!isRunning)
{
isRunning=true;
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(resetInTime);
isRunning = false;
counter=0;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}
}
2) 리스너 제공
public interface DoubleTapCallback {
public void onDoubleClick(View v);
}
3) 활동에서 구현
public class MainActivity extends AppCompatActivity implements DoubleTapCallback{
private Button button;
private int counter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (Button)findViewById(R.id.button);
button.setOnClickListener(new DoubleTapListener(this)); // Set mt listener
}
@Override
public void onDoubleClick(View v) {
counter++;
textView.setText(counter+"");
}
관련 링크 :
여기에서 전체 작동 코드를 볼 수 있습니다.
GestureDetectorCompat
클래스를 사용하여 두 번 탭을 구현할 수 있습니다 . 이 샘플에서는 textview를 두 번 탭하면 논리를 수행 할 수 있습니다.
public class MainActivity extends AppCompatActivity {
GestureDetectorCompat gestureDetectorCompat;
TextView textElement;
@Override
protected void onCreate(Bundle savedInstanceState) {
.....
textElement = findViewById(R.id.textElement);
gestureDetectorCompat = new GestureDetectorCompat(this, new MyGesture());
textElement.setOnTouchListener(onTouchListener);
}
View.OnTouchListener onTouchListener = new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
gestureDetectorCompat.onTouchEvent(event);
return true;
}
};
class MyGesture extends GestureDetector.SimpleOnGestureListener {
@Override
public boolean onDown(MotionEvent e) {
return true;
}
@Override
public boolean onDoubleTap(MotionEvent e) {
// whatever on double click
return true;
}
}
어떤 동작을 실행하기 전에 두 번째 클릭이 좋은 솔루션입니다.
int init = 0;
myView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (init == 0) {
init++;
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
if (init == 1) {
Log.d("hereGoes", "actionOne");
} else {
Log.d("hereGoes", "actionTwo");
}
init = 0;
}
}, 250);
} else {
init++;
}
}
});
참고 URL : https://stackoverflow.com/questions/2217670/android-how-to-detect-double-tap
'ProgramingTip' 카테고리의 다른 글
목록에없는 요소 찾기 (0) | 2020.12.02 |
---|---|
AngularJS 필터를 사용하여 선행 0을 갖도록 숫자를 형식화 지불해야합니까? (0) | 2020.12.02 |
Windows 7에서 명령 프롬프트의 기본 시작 디렉터리 변경 (0) | 2020.12.02 |
UISegmentedControl을 컨테이너보기에 프로그래밍 방식으로 추가하는 방법 (0) | 2020.12.02 |
차이를 반환하는 2 개의 배열 비교 (0) | 2020.12.02 |