Glide4.0 centerCrop屬性和圓角 沖突


首先致謝:https://blog.csdn.net/flyinbed_/article/details/75506062

咱們不是代碼的生產者,只是代碼的搬運工。

  

最近有個工作中有個需求就是展示的圖片必須圓角、正方形,當時一想這太尼瑪簡單了,無非就是設置一個圖片參數的大小,然后在設置一個centerCrop的屬性,在自定義一個類去繼承BitmapTransformation重畫一下。

 

結果寫的時候發現,在glide4.0上面 centerCrop和圓角圖片有沖突只能顯示一個,結果就度娘問了一邊,大部分都是下面這行代碼,發現這個在glide4.0上面直接報錯  無法使用,最后沒辦法了只能自己擼一遍源碼看看了。

transform(new CenterCrop(getActivity()),new GlideRoundImage(getActivity()))  

  

點開centerCrop的源碼

/** 
 * Applies {@link CenterCrop} to all default types and 
 * throws an exception if asked to transform an unknown type. 
 * 
 * <p>this will override previous calls to {@link #dontTransform()} ()}. 
 * 
 * @see #transform(Class, Transformation) 
 * @see #optionalCenterCrop() 
 */  
public RequestOptions centerCrop() {  
  return transform(DownsampleStrategy.CENTER_OUTSIDE, new CenterCrop());  
}  

  

原來這犢子也是調用的 transform的方法,在點開 new Centercrop()這個方法看看里面的實現

/** 
 * Scale the image so that either the width of the image matches the given width and the height of 
 * the image is greater than the given height or vice versa, and then crop the larger dimension to 
 * match the given dimension. 
 * 
 * Does not maintain the image's aspect ratio 
 */  
public class CenterCrop extends BitmapTransformation {  
  private static final String ID = "com.bumptech.glide.load.resource.bitmap.CenterCrop";  
  private static final byte[] ID_BYTES = ID.getBytes(CHARSET);  
  
  public CenterCrop() {  
    // Intentionally empty.  
  }  
  
  @Deprecated  
  public CenterCrop(@SuppressWarnings("unused") Context context) {  
    this();  
  }  
  
  @Deprecated  
  public CenterCrop(@SuppressWarnings("unused") BitmapPool bitmapPool) {  
    this();  
  }  
  
  // Bitmap doesn't implement equals, so == and .equals are equivalent here.  
  @SuppressWarnings("PMD.CompareObjectsWithEquals")  
  @Override  
  protected Bitmap transform(  
      @NonNull BitmapPool pool, @NonNull Bitmap toTransform, int outWidth, int outHeight) {  
    return TransformationUtils.centerCrop(pool, toTransform, outWidth, outHeight);  
  }  
  
  @Override  
  public boolean equals(Object o) {  
    return o instanceof CenterCrop;  
  }  
  
  @Override  
  public int hashCode() {  
    return ID.hashCode();  
  }  
  
  @Override  
  public void updateDiskCacheKey(MessageDigest messageDigest) {  
    messageDigest.update(ID_BYTES);  
  }  
}  

  

不出所料 這里面也是繼承了BitmapTransformation這個類然后重畫了一邊,后面我們自己有調用了transform()這個方法等於把系統的Centercrop這個方法給覆蓋了,所以說這兩個屬性誰在后面就用哪種效果,但是現在的問題是我想兩個都要用咋整,那么問題來了,這下只能在自己自定義的BitmapTransformation將兩個效果一起畫出來了;

 

 

先是我的布局文件:很簡單就一個線性布局+3個ImageView

<?xml version="1.0" encoding="utf-8"?>  
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    xmlns:app="http://schemas.android.com/apk/res-auto"  
    xmlns:tools="http://schemas.android.com/tools"  
    android:layout_width="match_parent"  
    android:layout_height="match_parent"  
    android:orientation="vertical"  
    tools:context="com.flyinbed.myapplication.MainActivity">  
  
    <ImageView  
        android:id="@+id/icon1"  
        android:layout_width="150dp"  
        android:layout_height="150dp" />  
  
    <ImageView  
        android:id="@+id/icon2"  
        android:layout_marginTop="10dp"  
        android:layout_width="150dp"  
        android:layout_height="150dp"  />  
  
    <ImageView  
        android:id="@+id/icon3"  
        android:layout_marginTop="10dp"  
        android:layout_width="150dp"  
        android:layout_height="150dp"  />  
  
</LinearLayout>  

  

Activity代碼:3個Imageview加載3張本地圖片

public class MainActivity extends AppCompatActivity {  
    private ImageView icon1,icon2,icon3;  
  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  
        icon1 = (ImageView) findViewById(R.id.icon1);  
        icon2 = (ImageView) findViewById(R.id.icon2);  
        icon3 = (ImageView) findViewById(R.id.icon3);  
          
  
        Glide.with(this).load(R.drawable.item1).into(icon1);  
        Glide.with(this).load(R.drawable.image2).into(icon2);  
        Glide.with(this).load(R.drawable.image3).into(icon3);  
    }  
} 

  

效果:

 

先設置一下Centercrop的屬性:

題外話:glide4.0想設置圖片的屬性現在都是通過RequestOptions()這個類來實現的,然后在glide加載的時候通過

.apply()把那個類給塞進去就好了;

@Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  
        icon1 = (ImageView) findViewById(R.id.icon1);  
        icon2 = (ImageView) findViewById(R.id.icon2);  
        icon3 = (ImageView) findViewById(R.id.icon3);  
          
        RequestOptions myOptions = new RequestOptions()  
                .centerCrop();  
          
        Glide.with(this)  
                .load(R.drawable.item1)  
                .apply(myOptions)  
                .into(icon1);  
        Glide.with(this)  
                .load(R.drawable.image2)  
                .apply(myOptions)  
                .into(icon2);  
        Glide.with(this)  
                .load(R.drawable.image3)  
                .apply(myOptions)  
                .into(icon3);  
    }  

  

 

現在設置transform圓角屬性

protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  
        icon1 = (ImageView) findViewById(R.id.icon1);  
        icon2 = (ImageView) findViewById(R.id.icon2);  
        icon3 = (ImageView) findViewById(R.id.icon3);  
  
        RequestOptions myOptions = new RequestOptions()  
                .centerCrop()  
                .transform(new GlideRoundTransform(this,30));  
  
        Glide.with(this)  
                .load(R.drawable.item1)  
                .apply(myOptions)  
                .into(icon1);  
        Glide.with(this)  
                .load(R.drawable.image2)  
                .apply(myOptions)  
                .into(icon2);  
        Glide.with(this)  
                .load(R.drawable.image3)  
                .apply(myOptions)  
                .into(icon3);  
    }  

  

 

很明顯把Centercrop的屬性給覆蓋了;

下面是我自定義類GlideRoundTransform()的代碼:

public class GlideRoundTransform extends BitmapTransformation {  
  
    private static float radius = 0f;  
  
    public GlideRoundTransform(Context context) {  
        this(context, 4);  
    }  
  
    public GlideRoundTransform(Context context, int dp) {  
        super(context);  
        this.radius = Resources.getSystem().getDisplayMetrics().density * dp;  
    }  
  
    @Override  
    protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {  
        return roundCrop(pool, toTransform);  
    }  
  
    private static Bitmap roundCrop(BitmapPool pool, Bitmap source) {  
        if (source == null) return null;  
  
        Bitmap result = pool.get(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);  
        if (result == null) {  
            result = Bitmap.createBitmap(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);  
        }  
  
        Canvas canvas = new Canvas(result);  
        Paint paint = new Paint();  
        paint.setShader(new BitmapShader(source, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));  
        paint.setAntiAlias(true);  
        RectF rectF = new RectF(0f, 0f, source.getWidth(), source.getHeight());  
        canvas.drawRoundRect(rectF, radius, radius, paint);  
        return result;  
    }  
  
    public String getId() {  
        return getClass().getName() + Math.round(radius);  
    }  
  
    @Override  
    public void updateDiskCacheKey(MessageDigest messageDigest) {  
  
    }  
  
}  

  

接下來就開始解決這個問題了,在這個自定義類當中,我們要先獲取到Centercrop()這個屬性后得到到圖片,然后在根據這個圖片在進行圓角加工然后在返回。

 

其實屢清楚了思路很簡單 也就是一樣代碼的事,下面是我更改以后的代碼:

public class GlideRoundTransform extends BitmapTransformation {  
  
    private static float radius = 0f;  
  
    public GlideRoundTransform(Context context) {  
        this(context, 4);  
    }  
  
    public GlideRoundTransform(Context context, int dp) {  
        super(context);  
        this.radius = Resources.getSystem().getDisplayMetrics().density * dp;  
    }  
  
    @Override  
    protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {  
        Bitmap bitmap = TransformationUtils.centerCrop(pool, toTransform, outWidth, outHeight);  
        return roundCrop(pool, bitmap);  
    }  
  
    private static Bitmap roundCrop(BitmapPool pool, Bitmap source) {  
        if (source == null) return null;  
  
        Bitmap result = pool.get(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);  
        if (result == null) {  
            result = Bitmap.createBitmap(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);  
        }  
  
        Canvas canvas = new Canvas(result);  
        Paint paint = new Paint();  
        paint.setShader(new BitmapShader(source, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));  
        paint.setAntiAlias(true);  
        RectF rectF = new RectF(0f, 0f, source.getWidth(), source.getHeight());  
        canvas.drawRoundRect(rectF, radius, radius, paint);  
        return result;  
    }  
  
    public String getId() {  
        return getClass().getName() + Math.round(radius);  
    }  
  
    @Override  
    public void updateDiskCacheKey(MessageDigest messageDigest) {  
  
    }  
  
}  

  

在看看效果:

 

 

很完美,搞定收工,接下來是Activity的完整代碼:

public class MainActivity extends AppCompatActivity {  
    private ImageView icon1,icon2,icon3;  
  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  
        icon1 = (ImageView) findViewById(R.id.icon1);  
        icon2 = (ImageView) findViewById(R.id.icon2);  
        icon3 = (ImageView) findViewById(R.id.icon3);  
  
        //第一個是上下文,第二個是圓角的弧度  
        RequestOptions myOptions = new RequestOptions()  
                .transform(new GlideRoundTransform(this,30));  
  
        Glide.with(this)  
                .load(R.drawable.item1)  
                .apply(myOptions)  
                .into(icon1);  
        Glide.with(this)  
                .load(R.drawable.image2)  
                .apply(myOptions)  
                .into(icon2);  
        Glide.with(this)  
                .load(R.drawable.image3)  
                .apply(myOptions)  
                .into(icon3);  
    }  
}  

  

要是設置的效果沒用就清除下緩存,要是還不行就卸載重裝好了!!!!!

 

總結: 核心代碼

 1 public class GlideRoundTransform extends BitmapTransformation {  
 2   
 3     private static float radius = 0f;  
 4   
 5     public GlideRoundTransform(Context context) {  
 6         this(context, 4);  
 7     }  
 8   
 9     public GlideRoundTransform(Context context, int dp) {  
10         super(context);  
11         this.radius = Resources.getSystem().getDisplayMetrics().density * dp;  
12     }  
13   
14     @Override  
15     protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {  
16         Bitmap bitmap = TransformationUtils.centerCrop(pool, toTransform, outWidth, outHeight);  
17         return roundCrop(pool, bitmap);  
18     }  
19   
20     private static Bitmap roundCrop(BitmapPool pool, Bitmap source) {  
21         if (source == null) return null;  
22   
23         Bitmap result = pool.get(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);  
24         if (result == null) {  
25             result = Bitmap.createBitmap(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);  
26         }  
27   
28         Canvas canvas = new Canvas(result);  
29         Paint paint = new Paint();  
30         paint.setShader(new BitmapShader(source, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));  
31         paint.setAntiAlias(true);  
32         RectF rectF = new RectF(0f, 0f, source.getWidth(), source.getHeight());  
33         canvas.drawRoundRect(rectF, radius, radius, paint);  
34         return result;  
35     }  
36   
37     public String getId() {  
38         return getClass().getName() + Math.round(radius);  
39     }  
40   
41     @Override  
42     public void updateDiskCacheKey(MessageDigest messageDigest) {  
43   
44     }  
45   
46 }  
圓角轉換 GlideRoundTransform 核心代碼
1         //第一個是上下文,第二個是圓角的弧度  
2         RequestOptions myOptions = new RequestOptions()  
3                 .transform(new GlideRoundTransform(this,30));  
4   
5         Glide.with(this)  
6                 .load(path)  
7                 .apply(myOptions)  
8                 .into(img);  
使用方法 核心代碼

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM