简体   繁体   English

单击和双击android中的按钮

[英]Single click and double click of a button in android

In my application i have a button.在我的应用程序中,我有一个按钮。 After single and double clicking of the button will perform separate operation.单击按钮和双击按钮后将执行单独的操作。 How can i do that?我怎样才能做到这一点? Thanks谢谢

You may need to create a delay variable which will differenciate between single click and double click.您可能需要创建一个延迟变量来区分单击和双击。

See this code,看到这个代码,

private static final long DOUBLE_PRESS_INTERVAL = 250; // in millis
private long lastPressTime;

private boolean mHasDoubleClicked = false;

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {    

        // Get current time in nano seconds.
        long pressTime = System.currentTimeMillis();


        // If double click...
        if (pressTime - lastPressTime <= DOUBLE_PRESS_INTERVAL) {
            Toast.makeText(getApplicationContext(), "Double Click Event", Toast.LENGTH_SHORT).show();
            mHasDoubleClicked = true;
        }
        else {     // If not double click....
            mHasDoubleClicked = false;
            Handler myHandler = new Handler() {
                 public void handleMessage(Message m) {
                      if (!mHasDoubleClicked) {
                            Toast.makeText(getApplicationContext(), "Single Click Event", Toast.LENGTH_SHORT).show();
                      }
                 }
            };
            Message m = new Message();
            myHandler.sendMessageDelayed(m,DOUBLE_PRESS_INTERVAL);
        }
        // record the last time the menu button was pressed.
        lastPressTime = pressTime;      
        return true;
    }

Well it is simple just override.那么它很简单只是覆盖。

onClick method of OnClickListener OnClickListener 的 onClick 方法

public abstract class DoubleClickListener implements View.OnClickListener {
private static final long DEFAULT_QUALIFICATION_SPAN = 200;
private boolean isSingleEvent;
private long doubleClickQualificationSpanInMillis;
private long timestampLastClick;
private Handler handler;
private Runnable runnable;

public DoubleClickListener() {
    doubleClickQualificationSpanInMillis = DEFAULT_QUALIFICATION_SPAN;
    timestampLastClick = 0;
    handler = new Handler();
    runnable = new Runnable() {
        @Override
        public void run() {
            if (isSingleEvent) {
                onSingleClick();
            }
        }
    };
}

@Override
public void onClick(View v) {
    if((SystemClock.elapsedRealtime() - timestampLastClick) < doubleClickQualificationSpanInMillis) {
        isSingleEvent = false;
        handler.removeCallbacks(runnable);
        onDoubleClick();
        return;
    }

    isSingleEvent = true;
    handler.postDelayed(runnable, DEFAULT_QUALIFICATION_SPAN);
    timestampLastClick = SystemClock.elapsedRealtime();
}

public abstract void onDoubleClick();
public abstract void onSingleClick();
}

Usage用法

 button.setOnClickListener(new DoubleClickListener() {
        @Override
        public void onDoubleClick() {
            Log.i("onClick", "double");
        }

        @Override
        public void onSingleClick() {
            Log.i("onClick", "single");
        }
    });

You may want to consider not using a DoubleTap.您可能需要考虑不使用 DoubleTap。 It is not a normal Android behavior.这不是正常的 Android 行为。

When I first started programming on the Android, I kept running into things that were really "hard" to do on the android.当我第一次开始在 Android 上编程时,我一直遇到在 android 上非常“困难”的事情。 Over time, I've found that many of them were difficult because they were a pretty bad idea.随着时间的推移,我发现其中的许多方法都很困难,因为它们是一个非常糟糕的主意。

If you are porting an iOS app, or emulating an iOS app's behavior, you may want to consider converting the UI over to Android style behaviors and use a longPress or other 'androidy' gestures.如果您要移植 iOS 应用程序,或模拟 iOS 应用程序的行为,您可能需要考虑将 UI 转换为 Android 风格的行为并使用 longPress 或其他“androidy”手势。

Here is a similar question and answer:这是一个类似的问答:

Android: How to detect double-tap? Android:如何检测双击?

You have to implement GestureDetector and put your code in single/double click .您必须实现GestureDetector并将您的代码放入single/double click

TestActivity.java测试活动.java

iv.setOnClickListener(new OnClickListener() {           
                @Override
                public void onClick(View v) {
                    //putyour first activity call.
                }
    }

iv.setOnTouchListener(new OnTouchListener() {
             GestureDetector gestureDetector = new GestureDetector(context, new MyGestureDetector(context));
         @Override
         public boolean onTouch(View v, MotionEvent event) {
                return gestureDetector.onTouchEvent(event);
         }
});

Now you have to create GestureDetector.java class.现在您必须创建GestureDetector.java类。

public class MyGestureDetector extends SimpleOnGestureListener {
    public Context context;
    public String phno;

    public MyGestureDetector(Context con) {
        this.context=con;       
    }

    @Override
    public boolean onDown(MotionEvent e) {
        return super.onDown(e);
    }

    @Override
    public boolean onDoubleTap(MotionEvent e) {
        System.out.println("in Double tap");

        return true;
    }

    @Override
    public boolean onSingleTapUp(MotionEvent e) {
        System.out.println("in single tap up");
            //put your second activity.
        return super.onSingleTapUp(e);
    }   
}

Thanks to @NikolaDespotoski .感谢@NikolaDespotoski

You can check DOUBLE-TAP example from following URL .您可以从以下URL检查DOUBLE-TAP示例 that is used in listView.在列表视图中使用。 i hope it is useful for you.我希望它对你有用。

https://nodeload.github.com/NikolaDespotoski/DoubleTapListView/zip/master https://nodeload.github.com/NikolaDespotoski/DoubleTapListView/zip/master

Though it's too late, but anyone can figure out if they see this.虽然为时已晚,但任何人都可以弄清楚他们是否看到了这一点。

int number_of_clicks = 0;
boolean thread_started = false;
final int DELAY_BETWEEN_CLICKS_IN_MILLISECONDS = 250;

button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        ++number_of_clicks;
        if(!thread_started){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    thread_started = true;
                    try {
                        Thread.sleep(DELAY_BETWEEN_CLICKS_IN_MILLISECONDS);
                        if(number_of_clicks == 1){
                            client.send(AppHelper.FORMAT_LEFT_CLICK);
                        } else if(number_of_clicks == 2){
                            client.send(AppHelper.FORMAT_DOUBLE_CLICK);
                        }
                        number_of_clicks = 0;
                        thread_started = false;
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        }
    }
});

Explanation:解释:


Before the button click, number_of_click is initialized to 0. thread_started is a flag detecting if the thread is started before or not. 在按钮点击之前,number_of_click 被初始化为 0。 thread_started 是一个标志,检测线程是否在之前启动。 Now, on button click, increase the number of button click by incremental operator. 现在,在单击按钮时,通过增量运算符增加按钮单击次数。 check if the thread is previously started or not, if not, then start the thread. 检查线程之前是否已启动,如果没有,则启动线程。 on thread, apply your logic by using the number_of_clicks. 在线程上,使用 number_of_clicks 应用您的逻辑。 and the thread will wait for next milliseconds and then will go through your logic. 线程将等待下一个毫秒,然后将通过您的逻辑。 So, now you can apply as many clicks as you want. 因此,现在您可以根据需要应用任意数量的点击。

Solving this by inherit from the View.OnClickListener and checking the click time to distinguish the single click or double click, this also solve the problem of fast clicking.通过继承View.OnClickListener解决这个问题,通过检查点击时间来区分单击还是双击,这样也解决了快速点击的问题。 This solution will bring minor code change, just replace View.OnClickLister.此解决方案将带来较小的代码更改,只需替换 View.OnClickLister。 You also can override the getGap() to redefine the time between two clicks.您还可以覆盖 getGap() 以重新定义两次单击之间的时间。

import android.os.SystemClock;
import android.view.View;

/*****
 * Implement to fix the double click problem.
 * Avoid the fast double click for button and images.
 */
public abstract class OnSingleClickListener implements View.OnClickListener {
    private long prevClickTime =0;

    @Override
    public void onClick(View v) {
        _onClick(v);
    }

    private synchronized void _onClick(View v){
        long current = SystemClock.elapsedRealtime();
        if(current-prevClickTime> getGap()){
            onSingleClick(v);
            prevClickTime = SystemClock.elapsedRealtime();
        }else {
            onDoubleClick(v);
            prevClickTime = 0;
        }
    }

    public abstract void onSingleClick(View v);
    public abstract void onDoubleClick(View v);

    /********
     *
     * @return The time in ms between two clicks.
     */
    public long getGap(){
        return 500L; //500ms
    }
}

This is @saksham's answer in Kotlin.这是@saksham 在 Kotlin 中的回答。

abstract class DoubleClickListener : View.OnClickListener {
    private val DEFAULT_QUALIFICATION_SPAN = 200L
    private var isSingleEvent = false
    private val doubleClickQualificationSpanInMillis =
        DEFAULT_QUALIFICATION_SPAN
    private var timestampLastClick = 0L
    private val handler = Handler(Looper.getMainLooper())
    private val runnable: () -> Unit = {
        if (isSingleEvent) {
            onSingleClick()
        }
    }
    override fun onClick(v: View) {
        if (SystemClock.elapsedRealtime() - timestampLastClick < doubleClickQualificationSpanInMillis) {
            isSingleEvent = false
            handler.removeCallbacks(runnable)
            onDoubleClick()
            return
        }
        isSingleEvent = true
        handler.postDelayed(runnable, DEFAULT_QUALIFICATION_SPAN)
        timestampLastClick = SystemClock.elapsedRealtime()
    }

    abstract fun onDoubleClick()
    abstract fun onSingleClick()
}

The up solution cannot work for multi click, i test it but failed. up 解决方案不适用于多次点击,我测试了它但失败了。

So i suggest to use RxBinding with ProgressDialog.所以我建议将 RxBinding 与 ProgressDialog 一起使用。

when click button, the progressDialog show setting it cannot be cancel, Fix it.单击按钮时,progressDialog 显示设置无法取消,请修复它。

I also got the same problem once我也遇到过同样的问题

setOnClickListener(new OnClickListener() {           
            @Override
            public void onClick(View v) {
                if(isFmOn()){
                   //stopFM
                }else{
                  //do other things
                }
            }
}

when I clicked the Button,FM stopped;but when I double clicked,FM did not stop.The problem was that single and double clicking of the button ,the value of isFmOn() was difference.当我单击按钮时,FM 停止;但是当我双击时,FM 没有停止。问题是单击按钮和双击按钮时,isFmOn() 的值不同。 I sloved the problem using this:我用这个解决了这个问题:

setOnClickListener(new OnClickListener() {           
            @Override
            public void onClick(View v) {
                Thread.sleep(500);//500ms was enough to finish stopFM before the second click
                if(isFmOn()){
                   //stopFM
                }else{
                  //do other things
                }
            }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM