android clipToPadding的一點理解

這個網上總結的很多,見android 關於 clipToPadding 和 clipChildren區別和作用

最近遇到的一處android ui問題最終使用clipToPadding得到了完美的解決,下面談下個人對clipToPadding的理解。

  1. 這個是ViewGroup的屬性,View是沒有的
  2. clipToPadding必須與paddingTop等屬性一起用,不然沒有任何意義
  3. 默認的值是true,即padding範圍內子控件不做任何layout和draw的動作,RecyclerView等邊界處的顯示效果也是在padding範圍外的。
  4. 如果設置爲false,那麼子控件layout任然是在padding外的(不然padding還有啥意義),draw當然也是在padding外的,這個是一般情況。如果子控件有任何位移動畫的話,這個值爲false的意義就有了,它在padding範圍內依然會顯示!!!
  5. 網上我搜索到的例子全部是和RecyclerView,listView或者是ViewPager有關的,這個是clipToPadding使用最廣泛的場景。即在列表組件頭部和尾部添加padding,如果是直接加padding的話,可以看到就是把RecyclerView頭部和尾部削掉,拖動的時候padding範圍內是沒有任何顯示的,拖動到底的動畫效果也是顯示在padding範圍外的。當設置clipToPadding爲false的時候哦,設置padding的效果其實就是相當於設置了headView和FooterView,滑動到底的時候纔有padding,其餘的顯示和拖動padding範圍內也是佔據的,這個是大多數期望的效果。

下面看下RecyclerView的源碼就很清楚了:

 @Override
    public void setClipToPadding(boolean clipToPadding) {
        if (clipToPadding != mClipToPadding) {
            invalidateGlows();
        }
        mClipToPadding = clipToPadding;
        super.setClipToPadding(clipToPadding);
        if (mFirstLayoutComplete) {
            requestLayout();
        }
    }

除了調用super的方法外,還用成員變量mClipToPadding保存了設置的值

void ensureTopGlow() {
        if (mTopGlow != null) {
            return;
        }
        mTopGlow = mEdgeEffectFactory.createEdgeEffect(this, EdgeEffectFactory.DIRECTION_TOP);
        if (mClipToPadding) {
            mTopGlow.setSize(getMeasuredWidth() - getPaddingLeft() - getPaddingRight(),
                    getMeasuredHeight() - getPaddingTop() - getPaddingBottom());
        } else {
            mTopGlow.setSize(getMeasuredWidth(), getMeasuredHeight());
        }

    }

top邊界效果,mClipToPadding值爲true的話size要考慮4個padding的限制,而爲false的話就不用考慮了

 public void draw(Canvas c) {
        super.draw(c);

        ...
        if (mTopGlow != null && !mTopGlow.isFinished()) {
            final int restore = c.save();
            if (mClipToPadding) {
                c.translate(getPaddingLeft(), getPaddingTop());
            }
            needsInvalidate |= mTopGlow != null && mTopGlow.draw(c);
            c.restoreToCount(restore);
        }
        ...
    }

draw的代碼,只關心mTopGlow的處理,mClipToPadding爲true的話要繪製的時候要依據padding做平移,而爲false的話則不用考慮,這樣邊界效果雖然設置了padding,顯示的時候卻不用考慮padding,這也就是mClipToPadding的意義啊。

同理在拖動的時候,內容依然是可以在padding範圍內顯示的,好像沒有padding一樣。clipToPadding就好像是針對列表組件特定的一樣,對於普通的ViewGroup並無多大意義。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章