title: Android - cannot inherit from final GestureDetectorCompat
body: <p>I receive this error "cannot inherit from final GestureDetectorCompat" when I change the API version in gradle file.
  If I use api 22 it works fine but if I use api 23 I've got this error, why?</p>
  
  <p>Here is my code:
  file ClickItemTouchListener.java</p>
  
  <pre><code>package com.ddfilms.dado.RecyclerView.Utils;
  
  import android.content.Context;
  import android.os.Build;
  import android.support.v4.view.GestureDetectorCompat;
  import android.support.v4.view.MotionEventCompat;
  import android.support.v7.widget.RecyclerView;
  import android.support.v7.widget.RecyclerView.OnItemTouchListener;
  import android.view.GestureDetector.SimpleOnGestureListener;
  import android.view.MotionEvent;
  import android.view.View;
  
  abstract class ClickItemTouchListener implements OnItemTouchListener {
      private static final String LOGTAG = "ClickItemTouchListener";
  
      private final GestureDetectorCompat mGestureDetector;
  
      ClickItemTouchListener(RecyclerView hostView) {
          mGestureDetector = new ItemClickGestureDetector(hostView.getContext(),
                  new ItemClickGestureListener(hostView));
      }
  
      private boolean isAttachedToWindow(RecyclerView hostView) {
          if (Build.VERSION.SDK_INT &gt;= 19) {
              return hostView.isAttachedToWindow();
          } else {
              return (hostView.getHandler() != null);
          }
      }
  
      private boolean hasAdapter(RecyclerView hostView) {
          return (hostView.getAdapter() != null);
      }
  
      @Override
      public boolean onInterceptTouchEvent(RecyclerView recyclerView, MotionEvent event) {
          if (!isAttachedToWindow(recyclerView) || !hasAdapter(recyclerView)) {
              return false;
          }
  
          mGestureDetector.onTouchEvent(event);
          return false;
      }
  
      @Override
      public void onTouchEvent(RecyclerView recyclerView, MotionEvent event) {
          // We can silently track tap and and long presses by silently
          // intercepting touch events in the host RecyclerView.
      }
  
      abstract boolean performItemClick(RecyclerView parent, View view, int position, long id);
  
      abstract boolean performItemLongClick(RecyclerView parent, View view, int position, long id);
  
      private class ItemClickGestureDetector extends GestureDetectorCompat {
          private final ItemClickGestureListener mGestureListener;
  
          public ItemClickGestureDetector(Context context, ItemClickGestureListener listener) {
              super(context, listener);
              mGestureListener = listener;
          }
  
          @Override
          public boolean onTouchEvent(MotionEvent event) {
              final boolean handled = super.onTouchEvent(event);
  
              final int action = event.getAction() &amp; MotionEventCompat.ACTION_MASK;
              if (action == MotionEvent.ACTION_UP) {
                  mGestureListener.dispatchSingleTapUpIfNeeded(event);
              }
  
              return handled;
          }
      }
  
      private class ItemClickGestureListener extends SimpleOnGestureListener {
          private final RecyclerView mHostView;
          private View mTargetChild;
  
          public ItemClickGestureListener(RecyclerView hostView) {
              mHostView = hostView;
          }
  
          public void dispatchSingleTapUpIfNeeded(MotionEvent event) {
              // When the long press hook is called but the long press listener
              // returns false, the target child will be left around to be
              // handled later. In this case, we should still treat the gesture
              // as potential item click.
              if (mTargetChild != null) {
                  onSingleTapUp(event);
              }
          }
  
          @Override
          public boolean onDown(MotionEvent event) {
              final int x = (int) event.getX();
              final int y = (int) event.getY();
  
              mTargetChild = mHostView.findChildViewUnder(x, y);
              return (mTargetChild != null);
          }
  
          @Override
          public void onShowPress(MotionEvent event) {
              if (mTargetChild != null) {
                  mTargetChild.setPressed(true);
              }
          }
  
          @Override
          public boolean onSingleTapUp(MotionEvent event) {
              boolean handled = false;
  
              if (mTargetChild != null) {
                  mTargetChild.setPressed(false);
  
                  final int position = mHostView.getChildPosition(mTargetChild);
                  final long id = mHostView.getAdapter().getItemId(position);
                  handled = performItemClick(mHostView, mTargetChild, position, id);
  
                  mTargetChild = null;
              }
  
              return handled;
          }
  
          @Override
          public boolean onScroll(MotionEvent event, MotionEvent event2, float v, float v2) {
              if (mTargetChild != null) {
                  mTargetChild.setPressed(false);
                  mTargetChild = null;
  
                  return true;
              }
  
              return false;
          }
  
          @Override
          public void onLongPress(MotionEvent event) {
              if (mTargetChild == null) {
                  return;
              }
  
              final int position = mHostView.getChildPosition(mTargetChild);
              final long id = mHostView.getAdapter().getItemId(position);
              final boolean handled = performItemLongClick(mHostView, mTargetChild, position, id);
  
              if (handled) {
                  mTargetChild.setPressed(false);
                  mTargetChild = null;
              }
          }
      }
  }
  </code></pre>
  
  <p>and gradle file:</p>
  
  <pre><code>apply plugin: 'com.android.application'
  
  android {
      compileSdkVersion 22
      buildToolsVersion "22.0.1"
  
      defaultConfig {
          applicationId "com.ddfilms.dado"
          minSdkVersion 16
          targetSdkVersion 22
          versionCode 4
          versionName "2.0"
          multiDexEnabled true
      }
      buildTypes {
          release {
              minifyEnabled false
              proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
          }
      }
      dexOptions {
          preDexLibraries = false
      }
  }
  
  dependencies {
      compile 'com.android.support:appcompat-v7:22.1.0'
      compile 'com.android.support:cardview-v7:22.+'
      compile 'com.squareup.picasso:picasso:2.5.+'
      compile 'com.android.support:recyclerview-v7:22.1.0'
      compile 'com.github.manuelpeinado.fadingactionbar:fadingactionbar:3.1.2'
      compile 'com.readystatesoftware.systembartint:systembartint:1.0.3'
      compile files('libs/ksoap2-android-assembly-3.2.0-jar-with-dependencies.jar')
      compile files('libs/android-query-full.0.26.7.jar')
  }
  </code></pre>
  
  <p>With this code it work, but if i change in gradle with api 23 i've got the error</p>
  
  <pre><code>...
      compileSdkVersion 23
      buildToolsVersion "23.0.3"
  ...
          targetSdkVersion 23
  ...
      compile 'com.android.support:appcompat-v7:23.4.0'
      compile 'com.android.support:cardview-v7:23.+'
      compile 'com.squareup.picasso:picasso:2.5.+'
      compile 'com.android.support:recyclerview-v7:23.4.0'
  ...
  </code></pre>
  
  <p>Can anyone help me? Thanks</p>