android viewpager嵌套使用photoview異常問題


最近,做項目時,遇到一個需求,需要像淘寶評論那樣,一組圖點開,然后可以雙指滑動放大,並左右切換換圖的功能。自然就想到了使用viewpager+photoview來實現這一功能,但是在實現后,卻發現一個bug,就是在使用雙手放大圖片時,會拋異常,拋的異常是如下: 

E/AndroidRuntime(22447): java.lang.IllegalArgumentException: pointerIndex out of range  
E/AndroidRuntime(22447):      at android.view.MotionEvent.nativeGetAxisValue(Native Method)  

我查了很多的資料,發現問題所在是,photoview和viewpager組合使用時,可能會出現這一錯誤,這一錯誤的原因是我們可以分析出即:手指觸控點越界了,這應該是和photoview放大圖片的原因,那么解決方法很簡單,我們只需要判斷當前是幾個手指,如果超過一個手指,viewpager事件不處理即可。

其具體解決辦法就是重寫viewpager,具體見下:

import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;

/**
 * Author: ai chengming
 * Date: 2018/1/20 
 */
public class MTouchViewPager extends ViewPager {

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

    public MTouchViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    private boolean mIsDisallowIntercept = false;
    @Override
    public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
        // keep the info about if the innerViews do
        // requestDisallowInterceptTouchEvent
        mIsDisallowIntercept = disallowIntercept;
        super.requestDisallowInterceptTouchEvent(disallowIntercept);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        // the incorrect array size will only happen in the multi-touch
        // scenario.
        if (ev.getPointerCount() > 1 && mIsDisallowIntercept) {
            requestDisallowInterceptTouchEvent(false);
            boolean handled = super.dispatchTouchEvent(ev);
            requestDisallowInterceptTouchEvent(true);
            return handled;
        } else {
            return super.dispatchTouchEvent(ev);
        }
    }

}

進行重寫后,在布局中使用重寫的viewpager,發現就可以使用了,能夠正常的運行。

除了這種方法,也對應的在網上找到了其他許多方法,有以下兩種方法:

第一種方法是:

修改frameworks\base\core\jni\android_view_MotionEvent.cppandroid_view_MotionEvent_nativeGetAxisValue方法

注釋掉

if (!validatePointerIndex(env, pointerIndex, pointerCount)) {return 0;}

改完后需重新編譯整個系統,然后替換lib庫,重新編譯整個系統一般需要半個多小時,這個方法就比較麻煩了

第二種是:

捕獲IllegalArgumentException(非法參數異常)異常,即如:

private float spacing(MotionEvent event) { 
        try { 
        x = event.getX(0) - event.getX(1); 
        y = event.getY(0) - event.getY(1); 
    } catch (IllegalArgumentException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
    } 

但是,由於造成這一異常的方法是在photoview使用時造成的,我們無法捕獲,除非找到對應的使用地方,因此這一方法相對重寫viewpager較為麻煩,所以沒有采用。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM