Android Button Has Setontouchlistener Called on It But Does Not Override Performclick

Android button has setOnTouchListener called on it but does not override performClick

This warning comes up because Android wants to remind you to think about the blind or visually impaired people who may be using your app. I suggest you watch this video for a quick overview about what that is like.

The standard UI views (like Button, TextView, etc.) are all set up to provide blind users with appropriate feedback through Accessibility services. When you try to handle touch events yourself, you are in danger of forgetting to provide that feedback. This is what the warning is for.

Option 1: Create a custom view

Handling touch events is normally something that is done in a custom view. Don't dismiss this option too quickly. It's not really that difficult. Here is a full example of a TextView that is overridden to handle touch events:

public class CustomTextView extends AppCompatTextView {

public CustomTextView(Context context) {
super(context);
}

public CustomTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);

switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
return true;

case MotionEvent.ACTION_UP:
performClick();
return true;
}
return false;
}

// Because we call this from onTouchEvent, this code will be executed for both
// normal touch events and for when the system calls this using Accessibility
@Override
public boolean performClick() {
super.performClick();
doSomething();
return true;
}

private void doSomething() {
Toast.makeText(getContext(), "did something", Toast.LENGTH_SHORT).show();
}
}

Then you would just use it like this:

<com.example.myapp.CustomTextView
android:id="@+id/textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="20dp"
android:text="Click me to do something"/>

See my other answer for more details about making a custom view.

Option 2: Silencing the warning

Other times it might be better to just silence the warning. For example, I'm not sure what it is you want to do with a Button that you need touch events for. If you were to make a custom button and called performClick() in onTouchEvent like I did above for the custom TextView, then it would get called twice every time because Button already calls performClick().

Here are a couple reasons you might want to just silence the warning:

  • The work you are performing with your touch event is only visual. It doesn't affect the actual working of your app.
  • You are cold-hearted and don't care about making the world a better place for blind people.
  • You are too lazy to copy and paste the code I gave you in Option 1 above.

Add the following line to the beginning of the method to suppress the warning:

@SuppressLint("ClickableViewAccessibility")

For example:

@SuppressLint("ClickableViewAccessibility")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

Button myButton = findViewById(R.id.my_button);
myButton.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
return false;
}
});
}

Custom view has setOnTouchListener called on it but does not override performClick (class extends Activity NOT View)

onTouch() method gets every touch event from underlying view that hasn't been marked as "processed". If your Version2CameraView doesn't handle touch events, they are processed in Activity and your Version2CameraView is passed as View v parameter.

Unfortunately, your JavaCameraView doesn't override performClick(), but you're trying call it on this view. Solution? Add this method to your Version2CameraView class:

@Override
public boolean performClick() {
// do what you want
return true;
}

Custom view 'CustomAutoCompleteTextView' has setOnTouchListener called on but does not override performClick

AutocompleteTextView. But onTouch() method shows warning: If a View that overrides onTouchEvent or uses an OnTouchListener does not also implement performClick

FROM DOCS

Handling custom touch events

Custom view controls may require non-standard touch event behavior. For example, a custom control may use the onTouchEvent(MotionEvent) listener method to detect the ACTION_DOWN and ACTION_UP events and trigger a special click event. In order to maintain compatibility with accessibility services, the code that handles this custom click event must do the following:

  1. Generate an appropriate AccessibilityEvent for the interpreted click action.

  2. Enable accessibility services to perform the custom click action for users who are not able to use a touch screen.

To handle these requirements in an efficient way, your code should override the performClick() method, which must call the super implementation of this method and then execute whatever actions are required by the click event. When the custom click action is detected, that code should then call your performClick() method. The following code example demonstrates this pattern.

SOLUTIONS

  1. Use @SuppressLint("ClickableViewAccessibility") to ignore this warning
  2. Second solution Your custom view should override the performClick() method,

SAMPLE code to override the performClick() method from docs

class CustomTouchView extends View {

public CustomTouchView(Context context) {
super(context);
}

boolean mDownTouch = false;

@Override
public boolean onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);

// Listening for the down and up touch events
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mDownTouch = true;
return true;

case MotionEvent.ACTION_UP:
if (mDownTouch) {
mDownTouch = false;
performClick(); // Call this method to handle the response, and
// thereby enable accessibility services to
// perform this action for a user who cannot
// click the touchscreen.
return true;
}
}
return false; // Return false for other touch events
}

@Override
public boolean performClick() {
// Calls the super implementation, which generates an AccessibilityEvent
// and calls the onClick() listener on the view, if any
super.performClick();

// Handle the action for the custom click here

return true;
}
}

Custom view RatingBar has setOnTouchListener called on it but does not override performClick

Lint seems to wrongly think that any view not implementing the performClick() method is a custom view. Knowing this, we can guess that the views affected by this warning are, in fact, missing that implementation.

Now to answer your question, you may need to extend the View you want to set a onTouchListener if you want the warning to disappear:

class TouchableRatingBar extends android.support.v7.widget.AppCompatRatingBar{

public TouchableRatingBar(Context context) {
super(context);
}
@Override
public boolean performClick() {
return true;
}
}

Override the performClick() method and you should be good to go.

Note that i used the AppCompatRatingBar as Lint seems to dislike doing otherwise.

You also may need to either double cast the Rating Bar or change it's type in the layout.

Double Cast:

TouchableRatingBar ratingBar = (TouchableRatingBar)(RatingBar)findViewById(R.id.ratingBar);

I wouldn't use the double cast personally, but if you need to have an alternative to simply changing the type in the layout it might do the job.

Type Change:

<yourcompany.yourproject.TouchableRatingBar
android:id="@+id/ratingBar"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_below="@id/textViewReleaseDate"
android:layout_marginLeft="16dp"
android:layout_marginTop="16dp"
android:layout_toRightOf="@id/imageViewPoster"
android:numStars="1"
android:stepSize="1.0" />

Kotlin OnTouchListener called but it does not override performClick

Okay, I solved my own problem by overriding the OnTouch listener.

override fun onTouch(view: View, motionEvent: MotionEvent): Boolean {
when (view) {
next -> {
Log.d("next", "yeyy")
when (motionEvent.action){
MotionEvent.ACTION_DOWN -> {
val icon: Drawable = ContextCompat.getDrawable(activity.applicationContext, R.drawable.layer_bt_next)
icon.setColorFilter(Color.GRAY, PorterDuff.Mode.MULTIPLY)
next.setImageDrawable(icon)
}
MotionEvent.ACTION_UP -> {
view.performClick()
next.setImageResource(R.drawable.layer_bt_next)
}
}
}
previous -> {
//ingredients here XD
}
}
return true
}

And in that way, I can call single onTouch and implement it to many button and also can use the onClick by :

view.performClick()

Don't forget to implement :

View.OnTouchListener

And set the listener :

next.setOnTouchListener(this)
previous.setOnTouchListener(this)


Related Topics



Leave a reply



Submit