onTouchEvent onClick onLongClick 调用

Posted

技术标签:

【中文标题】onTouchEvent onClick onLongClick 调用【英文标题】:onTouchEvent onClick onLongClick calls 【发布时间】:2011-11-12 02:43:29 【问题描述】:

在我们的应用程序中,我们处理按钮中的事件来记录数据。

所以最初当我将setOnLongClickListener()setOnClickListener() 与同一个按钮一起使用时,它对我们来说效果很好。

这意味着它将根据按钮的单击和 LongClick 调用此侦听器。现在,当我尝试将setOnTouchListener()setOnLongClickListener()setOnClickListener() 一起使用同一个按钮时,只有OnTouch 事件有效,rest onclick 和onLongclick 事件无效。

谁能告诉我为什么会发生这种情况,如果可能的话,用一个例子解释一下。

我使用的代码:

Button btnAdd=new Button(this)

btnAdd.setOnLongClickListener(this);

btnAdd.setOnClickListener(this);

btnAdd.setOnTouchClickListener(this);

public void onClick(View v)

    //Statements;


public void onLongClick(View v)

    //Statements;


public boolean onTouch(View v, MotionEvent e) 

    switch (e.getAction())
    
        case MotionEvent.ACTION_DOWN:
        
            //store the X value when the user's finger was pressed down
            m_downXValue = e.getX();
            break;
           
        
        case MotionEvent.ACTION_UP:
        
            //Get the X value when the user released his/her finger
            float currentX = e.getX();              
            //MotionEvent x=MotionEvent.obtain((long) m_downXValue,  SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, 1, 1, 1, 1,0, 0, 0, 0, 0);
 
            // going forwards: pushing stuff to the left
            if (m_downXValue > currentX && currentX < 0)
                               
                ViewFlipper vf = (ViewFlipper) findViewById(R.id.flipview);
                vf.setInAnimation(AnimationUtils.loadAnimation(this, R.anim.slide_left));
                
               
                vf.showNext();
                               
            
            
            // going backwards: pushing stuff to the right
            if (m_downXValue < currentX && currentX > 100)
                               
                ViewFlipper vf = (ViewFlipper) findViewById(R.id.flipview);                                     
                vf.setAnimation(AnimationUtils.loadAnimation(this, R.anim.slide_right));
                
                
                vf.showPrevious();
                                  
               
            
            if (m_downXValue == currentX)
                               
                onClick(v);
                
         
            break;
        
    
    return true;

【问题讨论】:

嘿卢卡斯你能帮我解决这个问题吗 调用onTouch时是否考虑MotionEvent? 我刚刚编辑了onTouch事件的代码..我找到了调用onClick事件的线索..但是如何调用onLongClick事件..请帮助我 嘿 dyonisos..你看过编辑过的代码吗 【参考方案1】:

根据文档Handling UI Events,

onLongClick() - 这会返回一个布尔值来指示您是否已经消费了该事件并且不应该进一步携带它。也就是说,返回 true 表示您已经处理了该事件,它应该在这里停止;如果您还没有处理它,则返回 false 和/或事件应该继续到任何其他点击监听器。

最重要的是关于 onTouch:

onTouch() - 这将返回一个布尔值来指示您的侦听器是否使用此事件。 重要的是这个事件可以有多个相互跟随的动作。因此,如果在接收到 down 操作事件时返回 false,则表明您尚未消费该事件,并且对该事件的后续操作也不感兴趣。因此,事件中的任何其他操作都不会调用您,例如手指手势或最终的向上操作事件。

确实,根据事件,您必须返回正确的值。

【讨论】:

你能给我举个例子吗..我用过 MotionEvent 但我可以调用 clickEvent 但如何调用 LongClick 事件不知道..你可以在上面看到我的代码,请告诉我应该做什么我愿意 当你在onTouch 中消费一个事件并且你不想调用onClick 或onLongClick 时,onTouch 返回true。当 onTouch 没有消费任何事件,你想调用 onClick 或 onLongClick 时,onTouch 返回 false。【参考方案2】:

您必须在 OnTouch(View v,MotionEvent event) 函数中返回 false 而不是 true,以便控件上的其他侦听器保持活动状态。

【讨论】:

【参考方案3】:

好像你有参考问题。尝试像这样设置点击、长按和触摸监听器:

btnAdd.setOnClickListener(new Button.OnClickListener()
    @Override
    public void onClick(View v) 
        // TODO Auto-generated method stub
    
);

btnAdd.setOnLongClickListener(new Button.OnLongClickListener()
    @Override
    public boolean onLongClick(View v) 
        // TODO Auto-generated method stub
        return false;
    
);

btnAdd.setOnTouchListener(new Button.OnTouchListener()
    @Override
    public boolean onTouch(View v, MotionEvent event) 
        // TODO Auto-generated method stub
        return false;
    
);

【讨论】:

确保你的类没有实现触摸监听器..你可以显示完整的类代码.. 我想你自己试过了..据我所知,我们必须使用运动事件来捕获每个事件..它适用于 Click 事件..但是锄头适用于 Longclick..i不知道..【参考方案4】:

当您需要在同一个视图上同时发生点击和触摸事件时,请使用GestureDetector。它也可以检测长按。

【讨论】:

【参考方案5】:

我不确定这是您想要实现的目标,因为您为按钮设置了 onTouchListener - 但是如果您想要实现的是可滑动的活动(例如滑动屏幕和屏幕内容的变化)您可以尝试让您的活动扩展下面发布的类,然后使用您想要的任何操作实现next()previous() 方法。

import android.app.Activity;
import android.os.Bundle;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.GestureDetector.SimpleOnGestureListener;

public abstract class SwipeActivity extends Activity 
    private static final int SWIPE_MIN_DISTANCE = 120;
    private static final int SWIPE_MAX_OFF_PATH = 250;
    private static final int SWIPE_THRESHOLD_VELOCITY = 200;
    private GestureDetector gestureDetector;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        gestureDetector = new GestureDetector( new SwipeDetector() );
    

    private class SwipeDetector extends SimpleOnGestureListener        
        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
                float velocityY) 

            // Check movement along the Y-axis. If it exceeds SWIPE_MAX_OFF_PATH, then dismiss the swipe.
            if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH)
                return false;

            // Swipe from right to left.
            // The swipe needs to exceed a certain distance (SWIPE_MIN_DISTANCE) and a certain velocity (SWIPE_THRESHOLD_VELOCITY).
            if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE
                    && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) 
                next();
                return true;
            

            // Swipe from left to right.
            // The swipe needs to exceed a certain distance (SWIPE_MIN_DISTANCE) and a certain velocity (SWIPE_THRESHOLD_VELOCITY).
            if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE
                    && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) 
                previous();
                return true;
            

            return false;
        
    

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) 
        //TouchEvent dispatcher.
        if (gestureDetector != null) 
            if (gestureDetector.onTouchEvent(ev))
                //If the gestureDetector handles the event, a swipe has been executed and no more needs to be done.
                return true;
        
        return super.dispatchTouchEvent(ev);
    

    @Override
    public boolean onTouchEvent(MotionEvent event) 
        return gestureDetector.onTouchEvent(event);
    

    protected abstract void previous();
    protected abstract void next();

【讨论】:

【参考方案6】:

这是我解决与 ontouch 和 onlongclick 同步的方法

希望每个人在看过这段代码后都能弄清楚。 发生的情况是,每当长按发生时,touchlistener 被设置为 none 侦听器,当再次触摸视图时,none 侦听器将 view 的 touchlistener 设置为其前一个侦听器

LinearLayout.LayoutParams longpressLP = new LinearLayout.LayoutParams(100,100);
    LinearLayout longpress = new LinearLayout(this);
    longpress.setBackgroundColor(Color.GREEN);
    //any layout you want to add your view in
    mainlayout.addView(longpress,longpressLP);



    final View.OnTouchListener buttontouch=new View.OnTouchListener() 

        public boolean onTouch(View v, MotionEvent event) 
                    if(event.getAction()==MotionEvent.ACTION_DOWN)
                Toast.makeText(getApplicationContext(), "Touched Down", Toast.LENGTH_SHORT).show();
            else
                Toast.makeText(getApplicationContext(), "Touched", Toast.LENGTH_SHORT).show();
            return false;//IMPORTANT
        
    ;
    final View.OnTouchListener buttontouchnone=new View.OnTouchListener() 

        public boolean onTouch(View v, MotionEvent event) 

            if(event.getAction()==MotionEvent.ACTION_DOWN)//IMPORTANT
            
                v.setOnTouchListener(buttontouch);//IMPORTANT
                v.dispatchTouchEvent(event);//IMPORTANT
                Toast.makeText(getApplicationContext(), "ChangedListener", Toast.LENGTH_SHORT).show();
            
            return false;//IMPORTANT
        
    ;
            //set listeners
    longpress.setOnTouchListener(buttontouch);
    longpress.setOnLongClickListener(new View.OnLongClickListener() 

        public boolean onLongClick(View v) 
            // TODO Auto-generated method stub
            Toast.makeText(getApplicationContext(), "LongClick", Toast.LENGTH_SHORT).show();
            v.setOnTouchListener(buttontouchnone);//IMPORTANT
            return true;//IMPORTANT
        
    );

【讨论】:

以上是关于onTouchEvent onClick onLongClick 调用的主要内容,如果未能解决你的问题,请参考以下文章

在Activity中同时重写onTouchEvent()和onClick()方法,该怎样获得被点击的

Android入门第38天-使用随鼠标移动的圆点来熟悉onTouchEvent

Android EditText单击触发onclick事件处理

js事件

进阶必备-Android Click事件是怎么触发的?

onTouchevent() 与 onTouch()