GridView空白區(qū)域增加點(diǎn)擊事件

項(xiàng)目使用GridVIew展示縮略圖,gridView是設(shè)置了每行三張圖片的,當(dāng)圖片有四張的時(shí)候,難免會多出兩個(gè)空白區(qū)域。其中每張圖片可以放大展示原圖,其他區(qū)域需要有點(diǎn)擊后進(jìn)入詳情頁面。這時(shí),GridView空白的item無法點(diǎn)擊的問題就顯得格外需要處理了。

效果:

show.gif


增加空白處點(diǎn)擊事件,需要用到……對,就是……onTouchEvent(MotionEvent event);我發(fā)現(xiàn),onTouch真是救命稻草啊,每當(dāng)遇到困難的時(shí)候,它就像英雄一樣,手握寶劍,身披鎧甲,熠熠發(fā)光~

好了,臆想完畢。代碼君又來了!
首先我們需要定義一個(gè)接口和設(shè)置好外部回調(diào)方法不寫不行哦

 public interface OnTouchInvalidPositionListener {
        void onTouchInvalidPosition();
    }
 public void setOnTouchInvalidPositionListener(OnTouchInvalidPositionListener listener) {
        mTouchInvalidPosListener = listener;
    }

其次,也就是最重要的部分,重寫onTouch事件,英雄出場,所向披靡!

 @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (mTouchInvalidPosListener != null) {
            /*返回一個(gè)int值,判斷觸摸后坐標(biāo)能否映射到一個(gè)item上*/
            int motionPosition = pointToPosition((int) event.getX(), (int) event.getY());
            /*映射不到item上(即觸摸空白區(qū)域)并且是抬起動作,則執(zhí)行回調(diào)操作,并且自己消費(fèi),不往父布局傳遞*/
            if (motionPosition == INVALID_POSITION && event.getAction() == MotionEvent.ACTION_UP) {
                mTouchInvalidPosListener.onTouchInvalidPosition();
                return true;
            }
        }
        return super.onTouchEvent(event);
    }


最后,只需要調(diào)用接口就可以了~

 imageLayout.setOnTouchInvalidPositionListener(new MyGridView.OnTouchInvalidPositionListener() {
            @Override
            public void onTouchInvalidPosition() {
              //需要執(zhí)行的操作
        });

完畢~


想要在繼續(xù)研究的小伙伴,下面的內(nèi)容,可以讓你知道why to do this?
  在上述onTouchEvent()方法中,有一個(gè)相對新手來說陌生的方法,那就是pointToPosition(int x,int y);嗯~這個(gè)方法到底是干啥的,為什么它能判斷是不是空白區(qū)域呢?下面讓我們探索pointToPosition(int x,int y)吧~

進(jìn)入源碼的世界……

 /**
     * Rectangle used for hit testing children
     */
    private Rect mTouchFrame;
 /**
     * Maps a point to a position in the list.
     *
     * @param x X in local coordinate
     * @param y Y in local coordinate
     * @return The position of the item which contains the specified point, or
     *         {@link #INVALID_POSITION} if the point does not intersect an item.
     */
    public int pointToPosition(int x, int y) {
        Rect frame = mTouchFrame;
        if (frame == null) {
            mTouchFrame = new Rect();
            frame = mTouchFrame;
        }
    final int count = getChildCount();
        for (int i = count - 1; i >= 0; i--) {
            final View child = getChildAt(i);
            if (child.getVisibility() == View.VISIBLE) {
                child.getHitRect(frame);
                if (frame.contains(x, y)) {
                    return mFirstPosition + i;
                }
            }
        }
        return INVALID_POSITION;
    }

上述源碼可見,pointToPosition(int x, int y)返回一個(gè)int值,其中有個(gè)for循環(huán),需要引起我們的注意,循環(huán)的是這個(gè)view的子view,也就是GridView的item,使用if判斷是否item可見,如果可見,執(zhí)行child.getHitRect(frame);方法,那么這個(gè)方法是干啥的呢?繼續(xù)看源碼!

 /**
     * Hit rectangle in parent's coordinates
     *
     * @param outRect The hit rectangle of the view.
     */
    public void getHitRect(Rect outRect) {
        if (hasIdentityMatrix() || mAttachInfo == null) {
            outRect.set(mLeft, mTop, mRight, mBottom);
        } else {
            final RectF tmpRect = mAttachInfo.mTmpTransformRect;
            tmpRect.set(0, 0, getWidth(), getHeight());
            getMatrix().mapRect(tmpRect); // TODO: mRenderNode.mapRect(tmpRect)
            outRect.set((int) tmpRect.left + mLeft, (int) tmpRect.top + mTop,
                    (int) tmpRect.right + mLeft, (int) tmpRect.bottom + mTop);
        }
    }

這個(gè)方法也不用看太細(xì)致,大致意思就是給傳進(jìn)來的outRect矩形設(shè)置左上右下的值?;氐絧ointToPosition(int x, int y)方法中

 if (frame.contains(x, y)) {
      return mFirstPosition + i;
  }

這是判斷我們的觸摸點(diǎn)是否包含在getHitRect(Rect outRect)所得到的frame中。如果不包含的話,就執(zhí)行最后一句 return INVALID_POSITION(無效的位置);到這里,就和我們在onTouchEvent(MotionEvent event)中判斷的motionPosition == INVALID_POSITION對上了。也就得到了觸摸點(diǎn)是在空白區(qū)域的。

探索完畢有沒有漲姿勢呢哈哈撒花

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容