(歡迎轉載,但轉載請注明出處:https://blog.csdn.net/actionwind/article/details/112651614,參考請注明章節,)
根據Android官方的API檔案,使用ScaleGestureDetector和它OnScaleGestureListener對View用手勢進行縮放的時候是這么做的:ScaleGestureDetector(Context context, ScaleGestureDetector.OnScaleGestureListener listener)……………………,詳細的方法網上已經有很多,在這里我就不多說了,但這幾天我在寫程式的時候發現如果要對RecyclerView進行縮放的話,用一般對付View的方法使用ScaleGestureDetector是不行的,它的監聽器無法獲取到手指縮放的動作,因為手勢的輸入都被RecyclerView給攔截了,RecyclerView它自己要對手勢進行處理,一般是滑動操作,但它自己又不支持手勢縮放動作的處理,所以ScaleGestureDetector對View的一般使用方法無法用在RecyclerView上,
然后在網上搜來搜去,看了幾個解決方案大致都是自己創建類和方法去監聽和處理縮放的手勢(佩服佩服,五體投地),實在是太麻煩了,總覺得Android官方不會給RecyclerView留一個這么大的缺陷交給Android app開發者去解決,于是結合網上各位大牛的解決方案再去多看了幾眼Android的API檔案,最終找到了簡單一些的解決方案,網上好像找不到這樣的方法,所以在這里做一下記錄吧,
(歡迎轉載,但轉載請注明出處:https://blog.csdn.net/actionwind/article/details/112651614,參考請注明章節,)
簡單地說,RecyclerView提供了一個內部類OnItemTouchListener,這個監聽器的作用是:當在RecyclerView上的點觸手勢操作被RecyclerView強制“搶走”之前,你可以對它們進行攔截,轉送給其他方法進行處理,有了這個監聽器我們就可以將縮放手勢操作抽離出來,交給ScaleGestureDetector的監聽器去處理了,具體做法如下:
//創建一個類同時實作RecyclerView的OnItemTouchListener介面和ScaleGestureDetector的OnScaleGestureListener介面
class PdfScale implements RecyclerView.OnItemTouchListener, ScaleGestureDetector.OnScaleGestureListener {
RecyclerView recView;
ScaleGestureDetector scaleDetector;
float scaleBase=1;
float scaleLevel=1;
float average=1;
float scaledRecord=0;
@Override
public boolean onInterceptTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) {//這個方法用于判斷點觸手勢要不要被攔截,要攔截的話就會把手勢送給下面的onTouchEvent去處理,
recView = rv;//獲取外面傳過來的要進行縮放的RecyclerView
scaleDetector = new ScaleGestureDetector(rv.getContext(), this);//初始化ScaleGestureDetector物件,讓它系結我們要進行縮放處理的rv,指定監聽器用本身這個OnScaleGestureListener
if (e.getPointerCount() > 1) {//縮放的手勢起碼要兩根手指來完成吧?所以檢測到RecyclerView上的觸點大于1的時候,return true就是把這類手勢轉送給onTouchEvent去處理,
return true;
} else {//其他操作則不攔截,仍由RecyclerView自身去處理,
return false;
}
}
@Override
public void onTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) {//這個是轉發手勢的介面,這次我們在這里要做的就簡單了,
scaleDetector.onTouchEvent(e);//直接把手勢交給ScaleGestureDetector去處理,
}
@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {//這個方法我們這次不需要用到,但是OnItemTouchListener要求必須實作它,留空即可,
}
//以下幾個方法都是OnScaleGestureListener介面要求必須實作的,尋尋覓覓找到這篇文章的同學,應該早就知道下面幾個的實作方法,我也就不說得太詳細了:
@Override
public boolean onScale(ScaleGestureDetector detector) {
average=(average+detector.getCurrentSpan())/2;//采用取平均值的方法來防抖動
scaleLevel=average/scaleBase;
if(scaledRecord!=0){
scaleLevel*=scaledRecord;//在上次的基礎上進行放大(否則會跳回1倍大小重新開始縮放);
}
recView.setScaleX(scaleLevel);
recView.setScaleY(scaleLevel);
recView.invalidate();
// recView.setVisibility(View.INVISIBLE);
// recView.setVisibility(View.VISIBLE);
return true;
}
@Override
public boolean onScaleBegin(ScaleGestureDetector detector) {
recView.setPivotX(detector.getFocusX());
recView.setPivotY(detector.getFocusY());
average=scaleBase=detector.getCurrentSpan();
return true;
}
@Override
public void onScaleEnd(ScaleGestureDetector detector) {
scaledRecord=scaleLevel;
}
}
然后在主程式中,你要使用RecyclerView之前,先添加一下這個監聽器:
recyclerView.addOnItemTouchListener(new PdfScale());
這樣你的RecyclerView就能正常的用手勢進行縮放了, 參考閱讀: 官方的API檔案 https://developer.android.com/reference/androidx/recyclerview/widget/RecyclerView.OnItemTouchListener 另外,同學們,閱讀API檔案很重要啊,學好英語很重要啊………………
(歡迎轉載,但轉載請注明出處:https://blog.csdn.net/actionwind/article/details/112651614,參考請注明章節,)
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/249502.html
標籤:其他
