Android踩坑日記:點擊變暗效果的ImageView實現原理

來源:互聯網
上載者:User

很多時候我們使用ImagView顯示圖片,無論是Gilde,Fresco等圖片顯示架構,比如設定中心更換頭像,網格相簿點擊預覽,選擇等情況,會遇到點擊變暗的互動需求。 源碼分析
    我們想的辦法是自訂一個ImageView,當點擊圖片時,是不是有回調方法來同時改變圖片的濾鏡或者蒙版等。
    特意去看了View.java的源碼(ImageView繼承View),想看看View被點擊之後是是否有回呼函數可用。

View的onTouchEvent()方法case MotionEvent.ACTION_DOWN:              mHasPerformedLongPress = false;             if (performButtonActionOnTouchDown(event)) {                          break;                }            // Walk up the hierarchy to determine if we're inside a scrolling container.            boolean isInScrollingContainer = isInScrollingContainer();            // For views inside a scrolling container, delay the pressed feedback for            // a short period in case this is a scroll.             if (isInScrollingContainer) {                   mPrivateFlags |= PFLAG_PREPRESSED;                   if (mPendingCheckForTap == null) {                              mPendingCheckForTap = new CheckForTap();                     }                       postDelayed(mPendingCheckForTap, ViewConfiguration.getTapTimeout());                     } else {                          // Not inside a scrolling container, so show the feedback right away                          setPressed(true);                          checkForLongClick(0);                      }                      break;  

意思就是case: MotionEvent.ACTION_DOWN,按下去的時候事件發生時,檢測View是否被點擊了,如果點擊了就setPressed(true);把狀態標記為已點擊
對應的case: MotionEvent.ACTION_UP,鬆開手的時候會檢測是否是unpressed,如果是就setPressed(false);把狀態標記為未點擊。

setPress(boolean pressed)這個方法,定義如下

  /**     * Sets the pressed state for this view.     *     * @see #isClickable()     * @see #setClickable(boolean)     *     * @param pressed Pass true to set the View's internal state to "pressed", or false to reverts     *        the View's internal state from a previously set "pressed" state.     */    public void setPressed(boolean pressed) {        final boolean needsRefresh = pressed != ((mPrivateFlags & PFLAG_PRESSED) == PFLAG_PRESSED);        if (pressed) {            mPrivateFlags |= PFLAG_PRESSED;        } else {            mPrivateFlags &= ~PFLAG_PRESSED;        }        if (needsRefresh) {            refreshDrawableState();        }        dispatchSetPressed(pressed);    }

就是說View按下時會調用這個方法改變view的狀態,那麼我們就可以在這個方法中做文章,重寫這個方法。當參數是true時,使用顏色矩陣ColorMetrix來改變drawable的濾鏡,當參數是false時,還原映像

/*點擊變暗效果的ImageView*/public class MaskImageView extends ImageView {    private boolean touchEffect = true;    public final float[] BG_PRESSED = new float[] { 1, 0, 0, 0, -50, 0, 1, 0, 0, -50, 0, 0, 1, 0, -50, 0, 0, 0, 1, 0 };    public final float[] BG_NOT_PRESSED = new float[] { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0 };    public MaskImageView(Context context) {        super(context);    }    public MaskImageView(Context context, AttributeSet attrs) {        super(context, attrs);    }    public MaskImageView(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);    }    public MaskImageView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {        super(context, attrs, defStyleAttr, defStyleRes);    }    @Override    public void setPressed(boolean pressed) {        updateView(pressed);        super.setPressed(pressed);    }    /**     * 根據是否按下去來重新整理bg和src     *     * @param pressed     */    private void updateView(boolean pressed){        //如果沒有點擊效果        if( !touchEffect ){            return;        }        if( pressed ){            /**             * 通過設定濾鏡來改變圖片亮度             */            this.setDrawingCacheEnabled(true);            this.setColorFilter( new ColorMatrixColorFilter(BG_PRESSED) ) ;            //此為src,背景用getBackground()            this.getDrawable().setColorFilter( new ColorMatrixColorFilter(BG_PRESSED) );        }else{            this.setColorFilter( new ColorMatrixColorFilter(BG_NOT_PRESSED) ) ;            this.getDrawable().setColorFilter( new ColorMatrixColorFilter(BG_NOT_PRESSED) );        }    }}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.