RoundedImageView源码解析(三)RoundedImageView解析

来源:互联网 发布:海尔美的工厂模式java 编辑:程序博客网 时间:2024/06/09 17:51

现在开始RoundedImageView的源码解析了,之前的RoundedDrawable就是为RoundedImageView的实现做铺垫。

RoundedDrawable的作用主要是把Drawable转化为圆角的Drawable. 如果不清楚RoundedDrawable的话,可以参考我的前一篇博客http://blog.csdn.net/wangdong20/article/details/50737333

现在RoundedImageView就要利用RoundedDrawable来实现圆角图片功能。


首先RoundedImageView继承于ImageView,这就说明ImageView该有的特性RoundedImageView都有。

RoundedImageView也有src和background属性,而且都支持src和background为圆角功能。


我们可以先看看关于ImageView的src属性的设置相关代码。

 @Override  public void setImageDrawable(Drawable drawable) {    mResource = 0;    mDrawable = RoundedDrawable.fromDrawable(drawable);    updateDrawableAttrs();    super.setImageDrawable(mDrawable);  }  @Override  public void setImageBitmap(Bitmap bm) {    mResource = 0;    mDrawable = RoundedDrawable.fromBitmap(bm);    updateDrawableAttrs();    super.setImageDrawable(mDrawable);  }  @Override  public void setImageResource(@DrawableRes int resId) {    if (mResource != resId) {      mResource = resId;      mDrawable = resolveResource();      updateDrawableAttrs();      super.setImageDrawable(mDrawable);    }  }

我们可以发现重写了ImageView的setImageDrawable,setImageBitmap和setImageResource方法,其中setImageDrawable和setImageBitmap方法,都使用了RoundedDrawable对Drawable或者Bitmap进行转换然后赋值给mDrawable,setImageResource里面也调用了resolveResource()方法。代码如下:


private Drawable resolveResource() {    Resources rsrc = getResources();    if (rsrc == null) { return null; }    Drawable d = null;    if (mResource != 0) {      try {        d = rsrc.getDrawable(mResource);      } catch (Exception e) {        Log.w(TAG, "Unable to find resource: " + mResource, e);        // Don't try again.        mResource = 0;      }    }    return RoundedDrawable.fromDrawable(d);  }

从代码中我们可以看出,resolveResource()方法也是根据mResource获取Drawable,然后将其转换为RoundedDrawable最后赋值给mDrawable。


setImageDrawable,setImageBitmap,setImageResource方法后面都调用了updateDrawableAttrs()方法,我们来看看这部分代码。


private void updateDrawableAttrs() {    updateAttrs(mDrawable);  }

这里就一行代码,updateAttrs(mDrawable); 我们继续跟踪下去。


private void updateAttrs(Drawable drawable) {    if (drawable == null) { return; }    if (drawable instanceof RoundedDrawable) {      ((RoundedDrawable) drawable)          .setScaleType(mScaleType)          .setBorderWidth(mBorderWidth)          .setBorderColor(mBorderColor)          .setOval(mIsOval)          .setTileModeX(mTileModeX)          .setTileModeY(mTileModeY);      if (mCornerRadii != null) {        ((RoundedDrawable) drawable).setCornerRadius(            mCornerRadii[Corner.TOP_LEFT],            mCornerRadii[Corner.TOP_RIGHT],            mCornerRadii[Corner.BOTTOM_RIGHT],            mCornerRadii[Corner.BOTTOM_LEFT]);      }      applyColorMod();    } else if (drawable instanceof LayerDrawable) {      // loop through layers to and set drawable attrs      LayerDrawable ld = ((LayerDrawable) drawable);      for (int i = 0, layers = ld.getNumberOfLayers(); i < layers; i++) {        updateAttrs(ld.getDrawable(i));      }    }  }

这部分代码就跟之前的RoundedDrawable的fromDrawable()方法类似,首先对传入的Drawable参数进行检查,如果是RoundedDrawable,那么我们就把RoundedDrawable相关的属性设置给Drawable,如果是LayerDrawable的话,就把LayerDrawable的每一个Drawable提取出来重新进入updateAttrs流程。


以上部分代码我们就可以观察到,基本上就可以实现RoundedImageView的src属性为圆角效果,但是我们的RoundedImageView还支持background属性呢!


@Override  public void setBackground(Drawable background) {    setBackgroundDrawable(background);  }@Override  @Deprecated  public void setBackgroundDrawable(Drawable background) {    mBackgroundDrawable = background;    updateBackgroundDrawableAttrs(true);    super.setBackgroundDrawable(mBackgroundDrawable);  }

观察以上代码发现调用了updateBackgroundDrawableAttrs(true),直接跟进去。


private void updateBackgroundDrawableAttrs(boolean convert) {    if (mMutateBackground) {      if (convert) {        mBackgroundDrawable = RoundedDrawable.fromDrawable(mBackgroundDrawable);      }      updateAttrs(mBackgroundDrawable);    }  }


这段代码可以看出这里面涉及到mMutateBackground属性,如果mMutateBackground为true,并且传入的参数也为true的话,会调用RoundedDrawable的方法把mBackgroundDrawable转化为圆角,最后通过之前讲的updateAttrs(Drawable)方法实现更新mBackgroundDrawable有关RoundedDrawable的属性。


上面提到了mMutateBackground属性,就是实现background是否也可以有圆角效果。

mMutateBackground = a.getBoolean(R.styleable.RoundedImageView_riv_mutate_background, false);

这里的mMutateBackground属性默认为false,所以如果希望background也有圆角效果,那么需要在xml里面或者代码里面将mMutateBackground设置为true。


<com.makeramen.roundedimageview.RoundedImageView        xmlns:app="http://schemas.android.com/apk/res-auto"        android:id="@+id/imageView1"        android:src="@drawable/photo1"        android:background="@drawable/background"        android:scaleType="fitCenter"        app:riv_corner_radius="30dip"        app:riv_border_width="2dip"        app:riv_border_color="#333333"        app:riv_mutate_background="true"        app:riv_tile_mode="repeat"        app:riv_oval="true" />

也就是在xml里面设置app:riv_mutate_background="true"或者再代码里面riv.mutateBackground(true)。


1 0