MaterialDesign系列文章(九)CardView的使用及適配

今天改需求改的我頭疼帮毁,最可氣的是,測(cè)試悠哉游哉的跑過(guò)來(lái)豺撑,丟下一句"喲烈疚,又寫B(tài)UG呢?"聪轿,我一想我也不是慣孩子人耙巍?當(dāng)時(shí)我就回了一句陆错,"正寫著呢灯抛?要不晚上一起加班啊音瓷?請(qǐng)你吃好吃的"对嚼,這貨居然說(shuō)"行啊绳慎!"吃貨的世界真的不懂纵竖!但是真心說(shuō)一句漠烧,改需求能不能不這么從容,每次都是馬上上線了磨确,淡定的丟下一句沽甥,不行改改吧!我的心里是這樣的乏奥。摆舟。。

image

本來(lái)都準(zhǔn)備好下班打卡出去浪的邓了。只能坐在那里改恨诱、改、改骗炉≌毡Γ總說(shuō)我們程序員是單身汪,能不單身嗎句葵?然后每次改好了需求等測(cè)試反饋還是這樣的2蘧椤!乍丈!

image

好吧<敛辍!轻专!原諒我的放縱忆矛,被公司看見會(huì)不會(huì)被打死?请垛?催训?我要去看我的秘籍了。宗收。漫拭。

一位具有多年開發(fā)經(jīng)驗(yàn)的人推薦

好了不扯淡了!

本文知識(shí)點(diǎn)

  • CardView是什么?
  • CardView有哪些屬性可以設(shè)置混稽?
  • CardView的簡(jiǎn)單使用嫂侍?
  • CardView的適配問(wèn)題?

1.CardView是什么荚坞?

CardView是google在5.0中提供帶圓角和陰影的布局挑宠,繼承自FrameLayout。

2.CardView的一些屬性設(shè)置

  • android:cardBackgroundColor 設(shè)置背景
  • android:cardCornerRadius 設(shè)置圓角
  • app:cardElevation 設(shè)置陰影大小
  • app:cardMaxElevation 設(shè)置陰影的最大高度
  • app:contentPadding 內(nèi)容距離邊界的距離
  • app:contentPaddingXXX 設(shè)置局部的內(nèi)邊距颓影,替換Padding的各淀,在CardView中設(shè)置Padding是不起作用的。
  • app:cardUseCompatPadding 如果您需要將CardView與其他視圖對(duì)齊诡挂,可能在21以下碎浇,可以將此標(biāo)志設(shè)置為true临谱,CardView將在21之后的平臺(tái)上添加相同的填充值。
  • app:cardPreventCornerOverlap 是否裁剪邊界以防止重疊

能設(shè)置的屬性就這么多了奴璃,沒(méi)有什么好說(shuō)的悉默。但是最后兩個(gè)屬性會(huì)在后面的時(shí)候詳細(xì)講解,涉及到相應(yīng)的適配苟穆!

3. CardView的簡(jiǎn)單使用

其實(shí)在平時(shí)的開發(fā)中抄课,如果不考慮適配的話,CardView使用起來(lái)是很簡(jiǎn)單雳旅,但是說(shuō)起適配的話跟磨,感覺(jué)真心頭疼。我第一次用CardView的時(shí)候攒盈,弄適配弄了兩個(gè)多消失抵拘,當(dāng)時(shí)覺(jué)得天都是黑的!P突怼僵蛛!先看簡(jiǎn)單的效果吧。迎变。充尉。

    <android.support.v7.widget.CardView
        android:id="@+id/cv1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        app:cardBackgroundColor="#c4c6c8"
        app:cardCornerRadius="10dp"
        app:cardElevation="10dp"
        app:cardPreventCornerOverlap="true"
        app:layout_constraintTop_toTopOf="parent">

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@mipmap/heard_1" />
    </android.support.v7.widget.CardView>

效果是這個(gè)樣子的。氏豌。喉酌。

效果還是可以的

注意啊這個(gè)是5.0以上的手機(jī)拍的热凹,它默認(rèn)幫我們把圓角裁剪了(如果你設(shè)置了圓角的話)泵喘。按照上面的屬性進(jìn)行設(shè)置就可以了!

4.CardView的適配問(wèn)題

這個(gè)才是本片文章的重點(diǎn)問(wèn)題般妙!如果沒(méi)有做過(guò)適配的人纪铺,會(huì)覺(jué)得CardView很簡(jiǎn)單的。但是如果讓你適配的話碟渺,你就鲜锚。。苫拍。先來(lái)看一張照片芜繁!

image

重點(diǎn)的地方,我都標(biāo)記出來(lái)了绒极,如果你們產(chǎn)品和美工能容忍的話骏令。那只能說(shuō)你跟他們有一腿!

4.1 關(guān)于內(nèi)邊距的問(wèn)題垄提!

圖片上下左右的邊距比較好處理榔袋,因?yàn)樯厦嫣岬搅藘蓚€(gè)屬性

    app:cardUseCompatPadding="true"
    app:cardPreventCornerOverlap="false"
  • 屬性1: 這個(gè)屬性如果你設(shè)置成true的話周拐,那么就能保證所有版本的Padding都設(shè)置相同的Padding,默認(rèn)是false凰兑,就像上面這張圖一樣妥粟,會(huì)留出一定的邊距!
  • 屬性2: 是否裁剪邊角吏够,以保證邊角是圓形的勾给!在21以上的版本,默認(rèn)是幫你裁剪好圓角的稿饰,但是21之前的版本是不會(huì)幫你裁剪的锦秒,會(huì)出現(xiàn)下面這種!
image

內(nèi)邊距是不見了喉镰,但是圓角的處理就成了接下來(lái)的問(wèn)題了旅择。

4.2 關(guān)于圓角的處理

最開始我以為設(shè)置上面兩個(gè)屬性就能輕松的設(shè)置圓角了呢?太相信谷歌了侣姆。然后我的想法就是找一個(gè)處理圓角的控件生真,但是找了好久,基本上都是處理四個(gè)圓角的捺宗,沒(méi)有單個(gè)圓角的處理柱蟀,當(dāng)時(shí)產(chǎn)品的意思是只處理左邊的兩個(gè)圓角。好吧蚜厉,繼續(xù)找长已,最后中于找到了。當(dāng)時(shí)給大家發(fā)個(gè)福利了昼牛!哈哈术瓮,我真的不知道怎么上傳相應(yīng)的文件。原諒我的無(wú)知贰健!

public class SelectableRoundedImageView extends ImageView {

    public static final String TAG = "SelectableRoundedImageView";

    private int mResource = 0;

    private static final ScaleType[] sScaleTypeArray = {
        ScaleType.MATRIX,
        ScaleType.FIT_XY,
        ScaleType.FIT_START,
        ScaleType.FIT_CENTER,
        ScaleType.FIT_END,
        ScaleType.CENTER,
        ScaleType.CENTER_CROP,
        ScaleType.CENTER_INSIDE
    };

    // Set default scale type to FIT_CENTER, which is default scale type of
    // original ImageView.
    private ScaleType mScaleType = ScaleType.FIT_CENTER;

    private float mLeftTopCornerRadius = 0.0f;
    private float mRightTopCornerRadius = 0.0f;
    private float mLeftBottomCornerRadius = 0.0f;
    private float mRightBottomCornerRadius = 0.0f;

    private float mBorderWidth = 0.0f;
    private static final int DEFAULT_BORDER_COLOR = Color.BLACK;
    private ColorStateList mBorderColor = ColorStateList.valueOf(DEFAULT_BORDER_COLOR);

    private boolean isOval = false;

    private Drawable mDrawable;

    private float[] mRadii = new float[] { 0, 0, 0, 0, 0, 0, 0, 0 };

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

    public SelectableRoundedImageView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public SelectableRoundedImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        TypedArray a = context.obtainStyledAttributes(attrs,
                R.styleable.SelectableRoundedImageView, defStyle, 0);

        final int index = a.getInt(R.styleable.SelectableRoundedImageView_android_scaleType, -1);
        if (index >= 0) {
            setScaleType(sScaleTypeArray[index]);
        }

        mLeftTopCornerRadius = a.getDimensionPixelSize(
                R.styleable.SelectableRoundedImageView_sriv_left_top_corner_radius, 0);
        mRightTopCornerRadius = a.getDimensionPixelSize(
                R.styleable.SelectableRoundedImageView_sriv_right_top_corner_radius, 0);
        mLeftBottomCornerRadius = a.getDimensionPixelSize(
                R.styleable.SelectableRoundedImageView_sriv_left_bottom_corner_radius, 0);
        mRightBottomCornerRadius = a.getDimensionPixelSize(
                R.styleable.SelectableRoundedImageView_sriv_right_bottom_corner_radius, 0);
        
        if (mLeftTopCornerRadius < 0.0f || mRightTopCornerRadius < 0.0f
                || mLeftBottomCornerRadius < 0.0f || mRightBottomCornerRadius < 0.0f) {
            throw new IllegalArgumentException("radius values cannot be negative.");
        }
        
        mRadii = new float[] { 
                mLeftTopCornerRadius, mLeftTopCornerRadius,
                mRightTopCornerRadius, mRightTopCornerRadius, 
                mRightBottomCornerRadius, mRightBottomCornerRadius, 
                mLeftBottomCornerRadius, mLeftBottomCornerRadius };

        mBorderWidth = a.getDimensionPixelSize(
                R.styleable.SelectableRoundedImageView_sriv_border_width, 0);
        if (mBorderWidth < 0) {
            throw new IllegalArgumentException("border width cannot be negative.");
        }

        mBorderColor = a
                .getColorStateList(R.styleable.SelectableRoundedImageView_sriv_border_color);
        if (mBorderColor == null) {
            mBorderColor = ColorStateList.valueOf(DEFAULT_BORDER_COLOR);
        }

        isOval = a.getBoolean(R.styleable.SelectableRoundedImageView_sriv_oval, false);
        a.recycle();
        
        updateDrawable();
    }

    @Override
    protected void drawableStateChanged() {
        super.drawableStateChanged();
        invalidate();
    }

    @Override
    public ScaleType getScaleType() {
        return mScaleType;
    }

    @Override
    public void setScaleType(ScaleType scaleType) {
        super.setScaleType(scaleType);
        mScaleType = scaleType;
        updateDrawable();
    }

    @Override
    public void setImageDrawable(Drawable drawable) {
        mResource = 0;
        mDrawable = SelectableRoundedCornerDrawable.fromDrawable(drawable, getResources());
        super.setImageDrawable(mDrawable);
        updateDrawable();
    }

    @Override
    public void setImageBitmap(Bitmap bm) {
        mResource = 0;
        mDrawable = SelectableRoundedCornerDrawable.fromBitmap(bm, getResources());
        super.setImageDrawable(mDrawable);
        updateDrawable();
    }

    @Override
    public void setImageResource(int resId) {
        if (mResource != resId) {
            mResource = resId;
            mDrawable = resolveResource();
            super.setImageDrawable(mDrawable);
            updateDrawable();
        }
    }

    @Override
    public void setImageURI(Uri uri) {
        super.setImageURI(uri);
        setImageDrawable(getDrawable());
    }

    private Drawable resolveResource() {
        Resources rsrc = getResources();
        if (rsrc == null) {
            return null;
        }

        Drawable d = null;

        if (mResource != 0) {
            try {
                d = rsrc.getDrawable(mResource);
            } catch (NotFoundException e) {
                // Don't try again.
                mResource = 0;
            }
        }
        return SelectableRoundedCornerDrawable.fromDrawable(d, getResources());
    }

    private void updateDrawable() {
        if (mDrawable == null) {
            return;
        }

        ((SelectableRoundedCornerDrawable) mDrawable).setScaleType(mScaleType);
        ((SelectableRoundedCornerDrawable) mDrawable).setCornerRadii(mRadii);
        ((SelectableRoundedCornerDrawable) mDrawable).setBorderWidth(mBorderWidth);
        ((SelectableRoundedCornerDrawable) mDrawable).setBorderColor(mBorderColor);
        ((SelectableRoundedCornerDrawable) mDrawable).setOval(isOval);
    }

    public float getCornerRadius() {
        return mLeftTopCornerRadius;
    }

    /**
     * Set radii for each corner.
     * 
     * @param leftTop The desired radius for left-top corner in dip.
     * @param rightTop The desired desired radius for right-top corner in dip.
     * @param leftBottom The desired radius for left-bottom corner in dip.
     * @param rightBottom The desired radius for right-bottom corner in dip.
     * 
     */
    public void setCornerRadiiDP(float leftTop, float rightTop, float leftBottom, float rightBottom) {
        final float density = getResources().getDisplayMetrics().density;
        
        final float lt = leftTop * density;
        final float rt = rightTop * density;
        final float lb = leftBottom * density;
        final float rb = rightBottom * density;
        
        mRadii = new float[] { lt, lt, rt, rt, rb, rb, lb, lb };
        updateDrawable();
    }

    public float getBorderWidth() {
        return mBorderWidth;
    }

    /**
     * Set border width.
     * 
     * @param width
     *            The desired width in dip.
     */
    public void setBorderWidthDP(float width) {
        float scaledWidth = getResources().getDisplayMetrics().density * width; 
        if (mBorderWidth == scaledWidth) {
            return;
        }

        mBorderWidth = scaledWidth;
        updateDrawable();
        invalidate();
    }

    public int getBorderColor() {
        return mBorderColor.getDefaultColor();
    }

    public void setBorderColor(int color) {
        setBorderColor(ColorStateList.valueOf(color));
    }

    public ColorStateList getBorderColors() {
        return mBorderColor;
    }

    public void setBorderColor(ColorStateList colors) {
        if (mBorderColor.equals(colors)) {
            return;
        }

        mBorderColor = (colors != null) ? colors : ColorStateList
                .valueOf(DEFAULT_BORDER_COLOR);
        updateDrawable();
        if (mBorderWidth > 0) {
            invalidate();
        }
    }

    public boolean isOval() {
        return isOval;
    }

    public void setOval(boolean oval) {
        isOval = oval;
        updateDrawable();
        invalidate();
    }

    static class SelectableRoundedCornerDrawable extends Drawable {

        private static final String TAG = "SelectableRoundedCornerDrawable";
        private static final int DEFAULT_BORDER_COLOR = Color.BLACK;

        private RectF mBounds = new RectF();
        private RectF mBorderBounds = new RectF();

        private final RectF mBitmapRect = new RectF();
        private final int mBitmapWidth;
        private final int mBitmapHeight;

        private final Paint mBitmapPaint;
        private final Paint mBorderPaint;

        private BitmapShader mBitmapShader;

        private float[] mRadii = new float[] { 0, 0, 0, 0, 0, 0, 0, 0 };
        private float[] mBorderRadii = new float[] { 0, 0, 0, 0, 0, 0, 0, 0 };

        private boolean mOval = false;

        private float mBorderWidth = 0;
        private ColorStateList mBorderColor = ColorStateList.valueOf(DEFAULT_BORDER_COLOR);
        // Set default scale type to FIT_CENTER, which is default scale type of
        // original ImageView.
        private ScaleType mScaleType = ScaleType.FIT_CENTER;

        private Path mPath = new Path();
        private Bitmap mBitmap;
        private boolean mBoundsConfigured = false;

        public SelectableRoundedCornerDrawable(Bitmap bitmap, Resources r) {
            mBitmap = bitmap;
            mBitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);

            if (bitmap != null) {
                mBitmapWidth = bitmap.getScaledWidth(r.getDisplayMetrics());
                mBitmapHeight = bitmap.getScaledHeight(r.getDisplayMetrics());
            } else {
                mBitmapWidth = mBitmapHeight = -1;
            }

            mBitmapRect.set(0, 0, mBitmapWidth, mBitmapHeight);

            mBitmapPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            mBitmapPaint.setStyle(Paint.Style.FILL);
            mBitmapPaint.setShader(mBitmapShader);

            mBorderPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            mBorderPaint.setStyle(Paint.Style.STROKE);
            mBorderPaint.setColor(mBorderColor.getColorForState(getState(), DEFAULT_BORDER_COLOR));
            mBorderPaint.setStrokeWidth(mBorderWidth);
        }

        public static SelectableRoundedCornerDrawable fromBitmap(Bitmap bitmap, Resources r) {
            if (bitmap != null) {
                return new SelectableRoundedCornerDrawable(bitmap, r);
            } else {
                return null;
            }
        }

        public static Drawable fromDrawable(Drawable drawable, Resources r) {
            if (drawable != null) {
                if (drawable instanceof SelectableRoundedCornerDrawable) {
                    return drawable;
                } else if (drawable instanceof LayerDrawable) {
                    LayerDrawable ld = (LayerDrawable) drawable;
                    final int num = ld.getNumberOfLayers();
                    for (int i = 0; i < num; i++) {
                        Drawable d = ld.getDrawable(i);
                        ld.setDrawableByLayerId(ld.getId(i), fromDrawable(d, r));
                    }
                    return ld;
                }

                Bitmap bm = drawableToBitmap(drawable);
                if (bm != null) {
                    return new SelectableRoundedCornerDrawable(bm, r);
                } else {
                }
            }
            return drawable;
        }

        public static Bitmap drawableToBitmap(Drawable drawable) {
            if (drawable == null) {
                return null;
            }

            if (drawable instanceof BitmapDrawable) {
                return ((BitmapDrawable) drawable).getBitmap();
            }

            Bitmap bitmap;
            int width = Math.max(drawable.getIntrinsicWidth(), 2);
            int height = Math.max(drawable.getIntrinsicHeight(), 2);
            try {
                bitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);
                Canvas canvas = new Canvas(bitmap);
                drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
                drawable.draw(canvas);
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
                bitmap = null;
            }
            return bitmap;
        }

        @Override
        public boolean isStateful() {
            return mBorderColor.isStateful();
        }

        @Override
        protected boolean onStateChange(int[] state) {
            int newColor = mBorderColor.getColorForState(state, 0);
            if (mBorderPaint.getColor() != newColor) {
                mBorderPaint.setColor(newColor);
                return true;
            } else {
                return super.onStateChange(state);
            }
        }

        private void configureBounds(Canvas canvas) {
            // I have discovered a truly marvelous explanation of this,
            // which this comment space is too narrow to contain. :)
            // If you want to understand what's going on here,
            // See http://www.joooooooooonhokim.com/?p=289
            Rect clipBounds = canvas.getClipBounds();
            Matrix canvasMatrix = canvas.getMatrix();

            if (ScaleType.CENTER == mScaleType) {
                mBounds.set(clipBounds);
            } else if (ScaleType.CENTER_CROP == mScaleType) {
                applyScaleToRadii(canvasMatrix);
                mBounds.set(clipBounds);
            } else if (ScaleType.FIT_XY == mScaleType) {
                Matrix m = new Matrix();
                m.setRectToRect(mBitmapRect, new RectF(clipBounds), Matrix.ScaleToFit.FILL);
                mBitmapShader.setLocalMatrix(m);
                mBounds.set(clipBounds);
            } else if (ScaleType.FIT_START == mScaleType || ScaleType.FIT_END == mScaleType
                    || ScaleType.FIT_CENTER == mScaleType || ScaleType.CENTER_INSIDE == mScaleType) {
                applyScaleToRadii(canvasMatrix);
                mBounds.set(mBitmapRect);
            } else if (ScaleType.MATRIX == mScaleType) {
                applyScaleToRadii(canvasMatrix);
                mBounds.set(mBitmapRect);
            }
        }

        private void applyScaleToRadii(Matrix m) {
            float[] values = new float[9];
            m.getValues(values);
            for (int i = 0; i < mRadii.length; i++) {
                mRadii[i] = mRadii[i] / values[0];
            }
        }

        private void adjustCanvasForBorder(Canvas canvas) {
            Matrix canvasMatrix = canvas.getMatrix();
            final float[] values = new float[9];
            canvasMatrix.getValues(values);

            final float scaleFactorX = values[0];
            final float scaleFactorY = values[4];
            final float translateX = values[2];
            final float translateY = values[5];

            final float newScaleX = mBounds.width()
                    / (mBounds.width() + mBorderWidth + mBorderWidth);
            final float newScaleY = mBounds.height()
                    / (mBounds.height() + mBorderWidth + mBorderWidth);

            canvas.scale(newScaleX, newScaleY);
            if (ScaleType.FIT_START == mScaleType || ScaleType.FIT_END == mScaleType
                    || ScaleType.FIT_XY == mScaleType || ScaleType.FIT_CENTER == mScaleType
                    || ScaleType.CENTER_INSIDE == mScaleType || ScaleType.MATRIX == mScaleType) {
                canvas.translate(mBorderWidth, mBorderWidth);
            } else if (ScaleType.CENTER == mScaleType || ScaleType.CENTER_CROP == mScaleType) {
                // First, make translate values to 0
                canvas.translate(
                        -translateX / (newScaleX * scaleFactorX), 
                        -translateY / (newScaleY * scaleFactorY));
                // Then, set the final translate values.
                canvas.translate(-(mBounds.left - mBorderWidth), -(mBounds.top - mBorderWidth));
            } 
        }

        private void adjustBorderWidthAndBorderBounds(Canvas canvas) {
            Matrix canvasMatrix = canvas.getMatrix();
            final float[] values = new float[9];
            canvasMatrix.getValues(values);

            final float scaleFactor = values[0];

            float viewWidth = mBounds.width() * scaleFactor;
            mBorderWidth = (mBorderWidth * mBounds.width()) / (viewWidth - (2 * mBorderWidth));
            mBorderPaint.setStrokeWidth(mBorderWidth);

            mBorderBounds.set(mBounds);
            mBorderBounds.inset(- mBorderWidth / 2, - mBorderWidth / 2);
        }

        private void setBorderRadii() {
            for (int i = 0; i < mRadii.length; i++) {
                if (mRadii[i] > 0) {
                    mBorderRadii[i] = mRadii[i];
                    mRadii[i] = mRadii[i] - mBorderWidth;
                }
            }
        }

        @Override
        public void draw(Canvas canvas) {
            canvas.save();
            if (!mBoundsConfigured) {
                configureBounds(canvas);
                if (mBorderWidth > 0) {
                    adjustBorderWidthAndBorderBounds(canvas);
                    setBorderRadii();
                }
                mBoundsConfigured = true;
            }

            if (mOval) {
                if (mBorderWidth > 0) {
                    adjustCanvasForBorder(canvas);
                    mPath.addOval(mBounds, Path.Direction.CW);
                    canvas.drawPath(mPath, mBitmapPaint);
                    mPath.reset();
                    mPath.addOval(mBorderBounds, Path.Direction.CW);
                    canvas.drawPath(mPath, mBorderPaint);
                } else {
                    mPath.addOval(mBounds, Path.Direction.CW);
                    canvas.drawPath(mPath, mBitmapPaint);
                }
            } else {
                if (mBorderWidth > 0) {
                    adjustCanvasForBorder(canvas);
                    mPath.addRoundRect(mBounds, mRadii, Path.Direction.CW);
                    canvas.drawPath(mPath, mBitmapPaint);
                    mPath.reset();
                    mPath.addRoundRect(mBorderBounds, mBorderRadii, Path.Direction.CW);
                    canvas.drawPath(mPath, mBorderPaint);
                } else {
                    mPath.addRoundRect(mBounds, mRadii, Path.Direction.CW);
                    canvas.drawPath(mPath, mBitmapPaint);
                }
            }
            canvas.restore();
        }

        public void setCornerRadii(float[] radii) {
            if (radii == null)
                return;

            if (radii.length != 8) {
                throw new ArrayIndexOutOfBoundsException("radii[] needs 8 values");
            }

            for (int i = 0; i < radii.length; i++) {
                mRadii[i] = radii[i];
            }
        }

        @Override
        public int getOpacity() {
            return (mBitmap == null || mBitmap.hasAlpha() || mBitmapPaint.getAlpha() < 255) ? PixelFormat.TRANSLUCENT
                    : PixelFormat.OPAQUE;
        }

        @Override
        public void setAlpha(int alpha) {
            mBitmapPaint.setAlpha(alpha);
            invalidateSelf();
        }

        @Override
        public void setColorFilter(ColorFilter cf) {
            mBitmapPaint.setColorFilter(cf);
            invalidateSelf();
        }

        @Override
        public void setDither(boolean dither) {
            mBitmapPaint.setDither(dither);
            invalidateSelf();
        }

        @Override
        public void setFilterBitmap(boolean filter) {
            mBitmapPaint.setFilterBitmap(filter);
            invalidateSelf();
        }

        @Override
        public int getIntrinsicWidth() {
            return mBitmapWidth;
        }

        @Override
        public int getIntrinsicHeight() {
            return mBitmapHeight;
        }

        public float getBorderWidth() {
            return mBorderWidth;
        }

        public void setBorderWidth(float width) {
            mBorderWidth = width;
            mBorderPaint.setStrokeWidth(width);
        }

        public int getBorderColor() {
            return mBorderColor.getDefaultColor();
        }

        public void setBorderColor(int color) {
            setBorderColor(ColorStateList.valueOf(color));
        }

        public ColorStateList getBorderColors() {
            return mBorderColor;
        }

        /**
         * Controls border color of this ImageView.
         * 
         * @param colors
         *            The desired border color. If it's null, no border will be
         *            drawn.
         * 
         */
        public void setBorderColor(ColorStateList colors) {
            if (colors == null) {
                mBorderWidth = 0;
                mBorderColor = ColorStateList.valueOf(Color.TRANSPARENT);
                mBorderPaint.setColor(Color.TRANSPARENT);
            } else {
                mBorderColor = colors;
                mBorderPaint.setColor(mBorderColor.getColorForState(getState(),
                        DEFAULT_BORDER_COLOR));
            }
        }

        public boolean isOval() {
            return mOval;
        }

        public void setOval(boolean oval) {
            mOval = oval;
        }

        public ScaleType getScaleType() {
            return mScaleType;
        }

        public void setScaleType(ScaleType scaleType) {
            if (scaleType == null) {
                return;
            }
            mScaleType = scaleType;
        }
    }

}

自定義屬性

    <declare-styleable name="SelectableRoundedImageView">
        <attr name="sriv_left_top_corner_radius" format="dimension"/>
        <attr name="sriv_right_top_corner_radius" format="dimension"/>
        <attr name="sriv_left_bottom_corner_radius" format="dimension"/>
        <attr name="sriv_right_bottom_corner_radius" format="dimension"/>
        <attr name="sriv_border_width" format="dimension"/>
        <attr name="sriv_border_color" format="color"/>
        <attr name="sriv_oval" format="boolean"/>
        <attr name="android:scaleType"/>
    </declare-styleable>

也忘記是哪位大神些的了胞四,在這里謝謝作者的開源精神!使用的時(shí)候直接設(shè)置相應(yīng)的邊角就可以了伶椿!還是很方便的辜伟。。脊另。今天就到這里吧导狡,我可把我壓箱底的東西都拿出來(lái)了,希望對(duì)你有幫助偎痛!好了旱捧,今天就到這里了,See You!!!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末看彼,一起剝皮案震驚了整個(gè)濱河市廊佩,隨后出現(xiàn)的幾起案子囚聚,更是在濱河造成了極大的恐慌,老刑警劉巖标锄,帶你破解...
    沈念sama閱讀 218,122評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件顽铸,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡料皇,警方通過(guò)查閱死者的電腦和手機(jī)谓松,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)践剂,“玉大人鬼譬,你說(shuō)我怎么就攤上這事⊙犯” “怎么了优质?”我有些...
    開封第一講書人閱讀 164,491評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)军洼。 經(jīng)常有香客問(wèn)我巩螃,道長(zhǎng),這世上最難降的妖魔是什么匕争? 我笑而不...
    開封第一講書人閱讀 58,636評(píng)論 1 293
  • 正文 為了忘掉前任避乏,我火速辦了婚禮,結(jié)果婚禮上甘桑,老公的妹妹穿的比我還像新娘拍皮。我一直安慰自己,他們只是感情好跑杭,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,676評(píng)論 6 392
  • 文/花漫 我一把揭開白布铆帽。 她就那樣靜靜地躺著,像睡著了一般艘蹋。 火紅的嫁衣襯著肌膚如雪锄贼。 梳的紋絲不亂的頭發(fā)上票灰,一...
    開封第一講書人閱讀 51,541評(píng)論 1 305
  • 那天女阀,我揣著相機(jī)與錄音,去河邊找鬼屑迂。 笑死浸策,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的惹盼。 我是一名探鬼主播庸汗,決...
    沈念sama閱讀 40,292評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼手报!你這毒婦竟也來(lái)了蚯舱?” 一聲冷哼從身側(cè)響起改化,我...
    開封第一講書人閱讀 39,211評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎枉昏,沒(méi)想到半個(gè)月后陈肛,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,655評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡兄裂,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,846評(píng)論 3 336
  • 正文 我和宋清朗相戀三年句旱,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片晰奖。...
    茶點(diǎn)故事閱讀 39,965評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡谈撒,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出匾南,到底是詐尸還是另有隱情啃匿,我是刑警寧澤,帶...
    沈念sama閱讀 35,684評(píng)論 5 347
  • 正文 年R本政府宣布蛆楞,位于F島的核電站立宜,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏臊岸。R本人自食惡果不足惜橙数,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,295評(píng)論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望帅戒。 院中可真熱鬧灯帮,春花似錦、人聲如沸逻住。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)瞎访。三九已至腻贰,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間扒秸,已是汗流浹背播演。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留伴奥,地道東北人写烤。 一個(gè)月前我還...
    沈念sama閱讀 48,126評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像拾徙,于是被迫代替她去往敵國(guó)和親洲炊。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,914評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容