2016-05-31 47 views
1

我有類爲回收者視圖啓用項目點擊。 他們都很好。現在我已經將它們複製到一個新項目中,並且出現問題:無法從最終的GestureDetectorCompat繼承

cannot inherit from final 'android.support.v4.GestureDetectorCompat' 

現在我的班級有什麼問題?

enter image description here

ClickItemTouchListener.java

package com.stack.overflow.helperClasses; 

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 >= 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() & 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; 
      } 
     } 
    } 
} 

ItemClickSupport.java

package com.stack.overflow.helperClasses; 

import android.support.v7.widget.RecyclerView; 
import android.view.HapticFeedbackConstants; 
import android.view.SoundEffectConstants; 
import android.view.View; 

import com.mego.smscloud.R; 

public class ItemClickSupport { 
    /** 
    * Interface definition for a callback to be invoked when an item in the 
    * RecyclerView has been clicked. 
    */ 
    public interface OnItemClickListener { 
     /** 
     * Callback method to be invoked when an item in the RecyclerView 
     * has been clicked. 
     * 
     * @param parent The RecyclerView where the click happened. 
     * @param view The view within the RecyclerView that was clicked 
     * @param position The position of the view in the adapter. 
     * @param id The row id of the item that was clicked. 
     */ 
     void onItemClick(RecyclerView parent, View view, int position, long id); 
    } 

    /** 
    * Interface definition for a callback to be invoked when an item in the 
    * RecyclerView has been clicked and held. 
    */ 
    public interface OnItemLongClickListener { 
     /** 
     * Callback method to be invoked when an item in the RecyclerView 
     * has been clicked and held. 
     * 
     * @param parent The RecyclerView where the click happened 
     * @param view The view within the RecyclerView that was clicked 
     * @param position The position of the view in the list 
     * @param id The row id of the item that was clicked 
     * 
     * @return true if the callback consumed the long click, false otherwise 
     */ 
     boolean onItemLongClick(RecyclerView parent, View view, int position, long id); 
    } 

    private final RecyclerView mRecyclerView; 
    private final TouchListener mTouchListener; 

    private OnItemClickListener mItemClickListener; 
    private OnItemLongClickListener mItemLongClickListener; 

    private ItemClickSupport(RecyclerView recyclerView) { 
     mRecyclerView = recyclerView; 

     mTouchListener = new TouchListener(recyclerView); 
     recyclerView.addOnItemTouchListener(mTouchListener); 
    } 

    /** 
    * Register a callback to be invoked when an item in the 
    * RecyclerView has been clicked. 
    * 
    * @param listener The callback that will be invoked. 
    */ 
    public void setOnItemClickListener(OnItemClickListener listener) { 
     mItemClickListener = listener; 
    } 

    /** 
    * Register a callback to be invoked when an item in the 
    * RecyclerView has been clicked and held. 
    * 
    * @param listener The callback that will be invoked. 
    */ 
    public void setOnItemLongClickListener(OnItemLongClickListener listener) { 
     if (!mRecyclerView.isLongClickable()) { 
      mRecyclerView.setLongClickable(true); 
     } 

     mItemLongClickListener = listener; 
    } 

    public static ItemClickSupport addTo(RecyclerView recyclerView) { 
     ItemClickSupport itemClickSupport = from(recyclerView); 
     if (itemClickSupport == null) { 
      itemClickSupport = new ItemClickSupport(recyclerView); 
      recyclerView.setTag(R.id.recyclerview_item_click_support, itemClickSupport); 
     } else { 
      // TODO: Log warning 
     } 

     return itemClickSupport; 
    } 

    public static void removeFrom(RecyclerView recyclerView) { 
     final ItemClickSupport itemClickSupport = from(recyclerView); 
     if (itemClickSupport == null) { 
      // TODO: Log warning 
      return; 
     } 

     recyclerView.removeOnItemTouchListener(itemClickSupport.mTouchListener); 
     recyclerView.setTag(R.id.recyclerview_item_click_support, null); 
    } 

    public static ItemClickSupport from(RecyclerView recyclerView) { 
     if (recyclerView == null) { 
      return null; 
     } 

     return (ItemClickSupport) recyclerView.getTag(R.id.recyclerview_item_click_support); 
    } 

    private class TouchListener extends ClickItemTouchListener { 
     TouchListener(RecyclerView recyclerView) { 
      super(recyclerView); 
     } 

     @Override 
     boolean performItemClick(RecyclerView parent, View view, int position, long id) { 
      if (mItemClickListener != null) { 
       view.playSoundEffect(SoundEffectConstants.CLICK); 
       mItemClickListener.onItemClick(parent, view, position, id); 
       return true; 
      } 

      return false; 
     } 

     @Override 
     boolean performItemLongClick(RecyclerView parent, View view, int position, long id) { 
      if (mItemLongClickListener != null) { 
       view.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); 
       return mItemLongClickListener.onItemLongClick(parent, view, position, id); 
      } 

      return false; 
     } 


     @Override 
     public void onRequestDisallowInterceptTouchEvent(boolean b) { 

     } 
    } 
} 

ids.xml

<?xml version="1.0" encoding="utf-8"?> 
<resources> 

    <item name="recyclerview_item_click_support" type="id"/> 
    <item name="recyclerview_item_selection_support" type="id"/> 

</resources> 

回答

1

我得到這個整理出來了一種解決方法:

你應該檢查你的加載RecyclerView的地方,並稍微調整它的版本更新。可能你有24.0.0

對我來說,這是我build.gradleapp)在那裏我有:

dependecies.compile 'com.android.support:recyclerview-v7:23.1.1' 

的問題在23.2版本的產生是因爲一個update的。

希望這會有所幫助。

2

GestureDetectorCompat 

更改爲

GestureDetector 
+0

嗨。仔細闡述爲什麼不同的類名?你在哪裏找到它?有源連結嗎?謝謝 –

+0

GestureDetectorCompat來自支持庫,而GestureDetector不是:) –