代码之家  ›  专栏  ›  技术社区  ›  Trzy Gracje

onTouchListener警告:当检测到单击时,onTouch应调用View#performClick

  •  163
  • Trzy Gracje  · 技术社区  · 10 年前

    我创建了一个 onTouchListener 。不幸的是,onTouch()方法 throws 我警告:

    com/calculator/activitys/Calculator$1#onTouch should call View#performClick when a click is detected
    

    这是什么意思?我没有找到有关此警告的任何信息。以下是完整代码:

    LinearLayout llCalculatorContent = (LinearLayout) fragmentView.findViewById(R.id.calculator_content);
    
    llCalculatorContent.setOnTouchListener(new View.OnTouchListener() {
                
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            Tools.hideKeyboard(getActivity(), getView());
            getView().clearFocus();
            return false;
        }   
    });
    
    8 回复  |  直到 4 年前
        1
  •  184
  •   Secko    10 年前

    干得好:

    public boolean onTouch(View v, MotionEvent event) {
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            //some code....
            break;
        case MotionEvent.ACTION_UP:
            v.performClick();
            break;
        default:
            break;
        }
        return true;
    }
    
        2
  •  9
  •   yoAlex5    2 年前

    警告:当检测到单击时,onTouch应调用View#performClick

    你可以压制林特

    @SuppressLint("ClickableViewAccessibility")
    

    你应该打电话 performClick() 在…内 onTouchEvent() .

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        //Logic 
        performClick();
        return super.onTouchEvent(event);
    }
    

    findViewById(R.id.view1).setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            v.performClick();
            return v.onTouchEvent(event);
        }
    });
    

    [OnTouch flow]

    阅读更多信息 here

        3
  •  5
  •   exploitr    6 年前

    如果您没有使用 Custom View 它显式重写 onPerformClick ,警告不会因为只听赛科的回答而消除。

    除了他的回答之外,他还在像 android.widget.Button Button 您需要创建一个扩展目标视图的简单自定义视图。

    例子:

    自定义视图类:

    public class UselessButton extends AppCompatButton {
        public UselessButton(Context context) {
            super(context);
        }
    
        public UselessButton(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public UselessButton(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
        }
    
        @Override
        public boolean performClick() {
            return super.performClick();
        }
    }
    

    XML格式 :

    <stackoverflow.onEarth.UselessButton
        android:id="@+id/left"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:layout_marginStart="16dp"
        android:layout_marginTop="16dp"
        android:layout_marginEnd="8dp"
        android:layout_marginBottom="8dp"
        android:background="@drawable/left"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.16"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBaseline_toBaselineOf="@+id/right"
        app:layout_constraintVertical_bias="0.5" />
    

    Java语言 :

        left.setOnTouchListener((v, event) -> {
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                enLeft = 1;
                enRight = 0;
                return true;
            } else if (event.getAction() == MotionEvent.ACTION_UP) {
                enLeft = 0;
                v.performClick();
                return false;
            } else {
                return false;
            }
        });
    

    当前问题:IDE解决了警告,但无法在真正的Android设备上看到这种实际执行的点击操作。

    编辑 :修复了获取点击事件:使用 View.setPressed(boolean)

    down.setOnTouchListener((v, event) -> {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            enFront = 0;
            enBack = 1;
            left.setPressed(true);
            return true;
        } else if (event.getAction() == MotionEvent.ACTION_UP) {
            enBack = 0;
            v.performClick();
            v.setPressed(false);
            return false;
        } else {
            return false;
        }
    
        4
  •  2
  •   Clairton Luz    5 年前

    只需调用performClick方法,如下所示:

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        v.performClick();
        Tools.hideKeyboard(getActivity(), getView());
        getView().clearFocus();
        return false;
    }   
    
        5
  •  2
  •   Kevin Perez    3 年前

    我使用Kotlin扩展解决了这个警告

    首先创建扩展(例如ViewExtensions.kt)

    fun Button.onTouch(touch: (view: View, motionEvent: MotionEvent) -> Unit) {
        setOnTouchListener { v, event ->
            touch(v,event)
            v.performClick()
            true
        }
    }
    

    第二,在片段或活动中创建一个函数

    private fun onTouchButton(v: View, event: MotionEvent) {
           /* My Amazing implementation */
    }
    

    最后,使用扩展名

    myButton.onTouch { v, event ->
     onTouchButton(v, event)
    }
    
        6
  •  0
  •   Osvel Alvarez Jacomino    5 年前

    我也有类似的问题 MultiTouchListener 并通过实施 GestureDetector 并倾听 SingleTap (这不会消除警告,但会开始触发 onClick 我的观点中的事件)

    class TouchListener(context: Context) : MultiTouchListener() {
    
        private var tochedView: View? = null
        private var mGestureDetector = CustomGestureDetector()
        private var gestureDetector: GestureDetector = GestureDetector(context, mGestureDetector)
    
        @SuppressLint("ClickableViewAccessibility")
        override fun onTouch(view: View?, event: MotionEvent?): Boolean {
            val aux = super.onTouch(view, event)
    
            tochedView = view
            gestureDetector.onTouchEvent(event)
    
            return aux
        }
    
        private inner class CustomGestureDetector: GestureDetector.SimpleOnGestureListener() {
    
            override fun onSingleTapUp(e: MotionEvent?): Boolean {
                // this will be called even when a double tap is
                tochedView?.performClick()
                return super.onSingleTapUp(e)
            }
    
            override fun onSingleTapConfirmed(e: MotionEvent?): Boolean {
                // this will only be called after the detector is confident that the
                // user's first tap is not followed by a second tap leading to a double-tap gesture.
                tochedView?.performClick()
                return super.onSingleTapConfirmed(e)
            }
    
        }
    
    }
    
        7
  •  0
  •   Fathi Omer    4 年前

    这是一个非常晚的答案,但我希望它会帮助一些人。我不久前遇到了这个警告,我的方法是 View.class 然后在该类中创建一个名为它的公共方法 closeKeyboard(View view){} 这是它的外观:

    public class MyTouchEvent extends View {
    
        public MyTouchEvent(Context context) {
            super(context);
        }
    
        public void closeKeyboard(View view) {
            view.setOnTouchListener((view1, motionEvent) -> {
                view1.performClick();
           // this is a library handels the closing of keyboard
                UIUtil.hideKeyboard((Activity) getContext());
                return false;
            });
        }
    
        @Override
        public boolean performClick() {
            super.performClick();
            return true;
        }
    }
    

    MainActivity 我打电话给 closeKeyboard(view) 并使用父布局作为如下参数:

    new MyTouchEvent(this).collapseKeyboard(parentLayout);
    

    用于关闭键盘的库

    implementation 'net.yslibrary.keyboardvisibilityevent:keyboardvisibilityevent:3.0.0-RC2'
    

    library source

        8
  •  0
  •   Dave Hubbard    4 年前

    我不得不忽略它。我有一个TouchListener来引起一个动画按钮按下(在我的情况下改变颜色)。但我也有一个点击监听器来完成按钮工作。因此,这导致我的点击监听器再次启动。我将其作为触摸事件(Action_Down、Up等)开关中的默认情况进行了尝试