【问题标题】:how to implement double click in android [duplicate]如何在android中实现双击[重复]
【发布时间】:2012-04-02 05:19:14
【问题描述】:

我正在做一个项目,我想在单点触摸时显示一条特定消息,并使用 android 在双点触摸时显示另一条消息。我该如何实现它。

我的示例代码如下

if(firstTap){
            thisTime = SystemClock.timeMillis();
            firstTap = false;
        }else{
            prevTime = thisTime;
            thisTime = SystemClock.uptimeMillis();

            //Check that thisTime is greater than prevTime
            //just incase system clock reset to zero
            if(thisTime > prevTime){

                //Check if times are within our max delay
                if((thisTime - prevTime) <= DOUBLE_CLICK_MAX_DELAY){

                    //We have detected a double tap!
                    Toast.makeText(AddLocation.this, "DOUBLE TAP DETECTED!!!", Toast.LENGTH_LONG).show();
                    //PUT YOUR LOGIC HERE!!!!

                }else{
                    //Otherwise Reset firstTap
                    firstTap = true;
                }
            }else{
                firstTap = true;
            }
        }
        return false;

【问题讨论】:

标签: android


【解决方案1】:

尝试使用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) {
    //Single Tap
    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;
    }

}

【讨论】:

    【解决方案2】:

    您为什么不在推荐的 UI 中使用长按事件。 Read Answer Here,强烈推荐使用。

    或者如果你想实现它,你有两个选择,一个是this using boolean 第二个是使用Gesture Listener

    【讨论】:

    • 我觉得这个答案现在可能已经过时了。双击是桌面布局上的常见交互,虽然 Android 不是桌面操作系统,但 ChromeOS 是并且现在支持 Android 应用程序,因此我们是否应该使用双击可能因情况而异。用鼠标长按是不好的用户体验。
    • 同意@JediBurrell 的另一个原因是为了给定应用程序的一致性。我们只是将我们的 Win/iOS/OSX 应用程序移植到 Android。我们的用户习惯于双击来采取某种行动,如果让 Android 成为他们必须长按的唯一平台,那就太奇怪了。
    【解决方案3】:

    它是持有,但是,对于新读者,我做了一个小图书馆来简化这种东西,请查看这篇文章:Double click listener on android

    图书馆很小,这里是GitHub Repository Link

    你会像这样使用它:

    Button btn = new Button(this);
    
    btn.setOnClickListener( new DoubleClick(new DoubleClickListener() {
            @Override
            public void onSingleClick(View view) {
    
                // Single tap here.
            }
    
            @Override
            public void onDoubleClick(View view) {
    
                // Double tap here.
            }
        });
    

    【讨论】:

    • 它 100% 有效,谢谢
    【解决方案4】:

    您可以在长按时使用,而不是通过覆盖此方法使用双击

     abstract boolean onLongClick(View v)
    

    在单击并按住视图时调用。

    【讨论】:

      【解决方案5】:

      你可以使用RxAndroid,在这种情况下,在 Kotlin 中应该是这样的:

      yourView.clicks().buffer(500, TimeUnit.MILLISECONDS, 2).filter {
          it.size >= 2
      }.subscribe {
          // Handle double click
      }
      
      1. 我们在给定的视图上应用clicks() 扩展函数,它创建了一个 RX 可观察序列。
      2. 我们告诉 RX 在 500 毫秒或 500 毫秒内发生 2 次连续点击后发出事件。
      3. 我们告诉 RX 只接受 2 次连续点击的事件
      4. 最后但同样重要的是,我们订阅了作为我们的 DoubleClick 处理程序的事件序列

      【讨论】:

        【解决方案6】:

        我已经实现了单击屏幕两次(双击)时背景颜色和文本颜色发生变化的代码这里是代码...

                int i = 0;
                reader.setOnClickListener(new View.OnClickListener() {
                    int i = 0;
                    @Override
                    public void onClick(View v) {
                        // TODO Auto-generated method stub
                        i++;
                        Handler handler = new Handler();
                        Runnable r = new Runnable() {
        
                            @Override
                            public void run() {
                                i = 0;
                            }
                        };
        
                        if (i == 1) {
                            //Single click
                            handler.postDelayed(r, 250);
                        } else if (i == 2) {
        
                            if(color==1) {
        
                                reader.setTextColor(0xFF000000);
                                reader.setBackgroundColor(0xFFFFFFFF);
                                color = 2;
                            }else if(color==2)
                            {
                                reader.setTextColor(0xFFFFFFFF);
                                reader.setBackgroundColor(0xFF000000);
                                color=1;
                            }
                            i = 0;
        
                        }
        
        
                    }
                });
        

        【讨论】:

          【解决方案7】:

          试试下面的修改代码::

          //Check that thisTime is greater than prevTime
          //just incase system clock reset to zero
          static prevTime = 0;
          thisTime = Calendar.getInstance().getTimeInMillis();
          if(prevTime < thisTime) {
              //Check if times are within our max delay
              if((thisTime - prevTime) <= 1000) {  //1 SEC
                  //We have detected a double tap!
                  Toast.makeText(AddLocation.this, "DOUBLE TAP DETECTED!!!", Toast.LENGTH_LONG).show();
                  prevTime = thisTime;
                  //PUT YOUR LOGIC HERE!!!!
              } else {
                  //Otherwise Reset firstTap
                  firstTap = true;
              }
          } else {
              firstTap = true;
          }
          

          【讨论】:

            【解决方案8】:

            我做了一个这样的简单解决方案 -

            buttonTab.setOnClickListener(new View.OnClickListener() {
                        int count = 0;
                        Handler handler = new Handler();
                        Runnable runnable = () -> count = 0;
            
                        @Override
                        public void onClick(View v) {
                            if (!handler.hasCallbacks(runnable))
                                handler.postDelayed(runnable, 500);
                            if(count==2){
                                /*View is double clicked.Now code here.*/
                            }
                        }
                    });
            

            【讨论】:

            • 仅适用于 API 29+
            【解决方案9】:

            这里是 kotlin 中的完整示例双击监听器

            
            class MainActivity : AppCompatActivity() {
            
                private lateinit var gDetector : GestureDetectorCompat
                private lateinit var touchListener : View.OnTouchListener
            
                @SuppressLint("ClickableViewAccessibility")
                override fun onCreate(savedInstanceState: Bundle?) {
                    super.onCreate(savedInstanceState)
            
                    // instantiate GestureDetectorCompat
                    gDetector = GestureDetectorCompat(
                                  this,
                                  GestureDetector.SimpleOnGestureListener()
                                )
            
                    // Create anonymous class extend OnTouchListener and SimpleOnGestureListener
                    touchListener = object : View.OnTouchListener, GestureDetector.SimpleOnGestureListener() {
                        override fun onTouch(view: View?, event: MotionEvent?): Boolean {
            
                            gDetector.onTouchEvent(event)
                            gDetector.setOnDoubleTapListener(this)
            
                            return true
                        }
            
                        override fun onDoubleTap(e: MotionEvent?): Boolean {
                            Log.i("debug", "onDoubleTap")
                            return true
                        }
                    }
            
                    anyView.setOnTouchListener(touchListener)
            
               }
            }
            

            【讨论】:

              【解决方案10】:

              子类 View.OnClickListener

              我使用接口和线程创建了一个 DoubleClickListener。它可以与任何 View 一起使用,就像经典的 ClickListener 一样。这就是您可以为双击事件添加我的侦听器的方法。

              示例,

              button.setOnClickListener(new DoubleTapListener(this));
              

              并且在任何Activity中,重写这个方法来执行任务

              @Override
              public void onDoubleClick(View v) {
                  // Do what you like
              }
              

              实施:

              让我们看看实现。我创建了一个简单的 DoubleTapListener 但使用这种方法可以创建复杂的触摸 listeners(Tripletouch Listener, single, double, Triple listener all in 一)。

              1) DoubleTapListener

              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;             
                    }
              
                    @Override
                    public void onClick(View v) {
              
                       if(isRunning)
                       {
                          if(counter==1) //<-- makes sure that the callback is triggered on double click
                          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) DoubleTapCallback

              public interface DoubleTapCallback {
              
                   public void onDoubleClick(View v);
              }
              

              3) 在活动中实现回调并覆盖方法

              public class MainActivity extends AppCompatActivity implements DoubleTapCallback{
              
                    private Button button;       
              
                    @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 listener
              
                    }
              
                    @Override
                    public void onDoubleClick(View v) {
                          // Toast to show double click        
                    }
               }
              

              相关链接:

              可以看到完整的代码实现HERE

              【讨论】:

                【解决方案11】:

                我们扩展了OnClickListener,因此它可以轻松应用于任何视图:

                /**
                 * Allows to set double click events on views.
                 *
                 * @param action The action to perform on click.
                 * @param interval The maximum interval between two clicks, in milliseconds.
                 */
                class DoubleClickListener(private val action: (view: View) -> Unit, private val interval: Long = 800) : View.OnClickListener {
                
                    companion object {
                
                        /** The view that was clicked previously. */
                        private var myPreviouslyClickedView: WeakReference<View>? = null
                
                        /**
                         * Check if the click was a second one or not.
                         * @param view The view to check for.
                         *
                         * @return True if the click was a second one.
                         */
                        private fun isSecondClick(view: View) =
                            myPreviouslyClickedView?.get() == view
                
                    }
                
                    /** Execute the click. */
                    override fun onClick(view: View?) {
                        if (view != null) {
                
                            // Make sure this click is the second one
                            if (isSecondClick(view)) {
                                myPreviouslyClickedView?.clear()
                                action(view)
                
                            } else {
                
                                // Set the previous view to this one but remove it after few moments
                                myPreviouslyClickedView = WeakReference(view)
                                view.postDelayed({ myPreviouslyClickedView?.clear() }, interval)
                            }
                        }
                    }
                
                }
                

                myPreviouslyClickedView 属性确保可以有多个视图使用监听器。

                第 2 部分

                此外,我们通过扩展 View 使分配侦听器变得更容易:

                /**
                 * Set a double click listener on a view.
                 *
                 * @param action The action to perform on a double click.
                 */
                fun View.setOnDoubleClickListener(action: (view: View) -> Unit) =
                    this.setOnClickListener(DoubleClickListener(action))
                

                或者,处理两次点击之间的自定义间隔:

                /**
                 * Set a double click listener on a view.
                 *
                 * @param interval The maximum interval between two clicks, in milliseconds.
                 * @param action The action to perform on a double click.
                 */
                fun View.setTimedOnDoubleClickListener(interval: Long, action: (view: View) -> Unit) =
                    this.setOnClickListener(DoubleClickListener(action, interval))
                
                

                【讨论】:

                  猜你喜欢
                  • 2012-09-07
                  • 2011-06-18
                  • 2016-05-22
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2014-01-15
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多