2020public class AlmightyShapeImageView extends AppCompatImageView {
2121 private Drawable mShapeResource ;
2222 private final Paint mShapePaint ;
23+ private ShapeScaleType mShapeScaleType ;
24+ private boolean isDrawShapeClear ;
2325
2426 public AlmightyShapeImageView (@ NonNull Context context ) {
2527 this (context , null );
@@ -34,26 +36,109 @@ public AlmightyShapeImageView(@NonNull Context context, @Nullable AttributeSet a
3436
3537 TypedArray a = context .obtainStyledAttributes (attrs , R .styleable .AlmightyShapeImageView );
3638 mShapeResource = a .getDrawable (R .styleable .AlmightyShapeImageView_almighty_shape_resource );
39+ mShapeScaleType = ShapeScaleType .getType (a .getInt (R .styleable .AlmightyShapeImageView_almighty_shape_scaleType , 0 ));
3740 a .recycle ();
3841 mShapePaint = new Paint ();
3942 mShapePaint .setColor (Color .WHITE );
4043 mShapePaint .setAntiAlias (true );
4144 mShapePaint .setStyle (Paint .Style .FILL );
42- mShapePaint .setXfermode (new PorterDuffXfermode (PorterDuff .Mode .SRC_IN ));
4345 }
4446
4547 @ Override
4648 protected void onDraw (Canvas canvas ) {
4749 if (mShapeResource != null ) {
50+ drawShapeClear (canvas );
51+
4852 drawShape (canvas );
4953 super .onDraw (canvas );
5054 canvas .restore ();
55+
56+
5157 } else {
5258 super .onDraw (canvas );
5359 }
5460
5561 }
5662
63+ private void drawShapeClear (Canvas canvas ) {
64+ if (mShapeScaleType != ShapeScaleType .ALWAYS_FIX_XY ){
65+ return ;
66+ }
67+ int height = getHeight ();
68+ int width = getWidth ();
69+ int paddingLeft = ViewUtils .getViewPaddingLeft (this );
70+ int paddingRight = ViewUtils .getViewPaddingRight (this );
71+ int paddingTop = getPaddingTop ();
72+ int paddingBottom = getPaddingBottom ();
73+ Drawable drawable = getDrawable ();
74+ Matrix matrix = getImageMatrix ();
75+ if (drawable == null || matrix == null ) {
76+ return ;
77+ }
78+
79+ float [] matrixValues = new float [9 ];
80+ matrix .getValues (matrixValues );
81+ int drawableWidth = drawable .getIntrinsicWidth ();
82+ int drawableHeight = drawable .getIntrinsicHeight ();
83+
84+
85+ float pictureWidth ;
86+ float pictureHeight ;
87+
88+
89+ float transX ;
90+ float transY ;
91+
92+ ScaleType scaleType = getScaleType ();
93+ if (scaleType == ScaleType .FIT_XY || scaleType == ScaleType .CENTER_CROP ) {
94+ transX = paddingLeft ;
95+ transY = paddingTop ;
96+ pictureWidth = width - paddingLeft - paddingRight ;
97+ pictureHeight = height - paddingTop - paddingBottom ;
98+ } else if (scaleType == ScaleType .CENTER ) {
99+ if (drawableWidth < width || drawableHeight < height ) {
100+ if (drawableWidth < width ) {
101+ pictureWidth = drawableWidth ;
102+ } else {
103+ pictureWidth = width ;
104+ }
105+ if (drawableHeight < height ) {
106+ pictureHeight = drawableHeight ;
107+ } else {
108+ pictureHeight = height ;
109+ }
110+ transX = (width - pictureWidth ) / 2 ;
111+ transY = (height - pictureHeight ) / 2 ;
112+ } else {
113+ transX = paddingLeft ;
114+ transY = paddingTop ;
115+ pictureWidth = width - paddingLeft - paddingRight ;
116+ pictureHeight = height - paddingTop - paddingBottom ;
117+ }
118+ } else {
119+ transX = (int ) matrixValues [2 ] + paddingLeft ;
120+ transY = (int ) matrixValues [5 ] + paddingTop ;
121+
122+ pictureWidth = drawableWidth * matrixValues [0 ];
123+ pictureHeight = drawableHeight * matrixValues [4 ];
124+ }
125+ int left = (int ) (transX );
126+ int top = (int ) (transY );
127+ int right = ((int ) (pictureWidth + transX ));
128+ int bottom = ((int ) (pictureHeight + transY ));
129+
130+ mShapePaint .setXfermode (null );
131+ canvas .saveLayer (new RectF (0 , 0 , canvas .getWidth (), canvas .getHeight ()), mShapePaint , Canvas .ALL_SAVE_FLAG );
132+ canvas .drawRect (left ,top ,right ,bottom ,mShapePaint );
133+
134+ mShapePaint .setXfermode (new PorterDuffXfermode (PorterDuff .Mode .SRC_IN ));
135+ canvas .saveLayer (new RectF (0 , 0 , canvas .getWidth (), canvas .getHeight ()), mShapePaint , Canvas .ALL_SAVE_FLAG );
136+ mShapeResource .setBounds (paddingLeft , paddingTop , width - paddingRight , height - paddingBottom );
137+ mShapeResource .draw (canvas );
138+
139+ isDrawShapeClear = true ;
140+ }
141+
57142 private void drawShape (Canvas canvas ) {
58143 int height = getHeight ();
59144 int width = getWidth ();
@@ -71,7 +156,7 @@ private void drawShape(Canvas canvas) {
71156 int top ;
72157 int right ;
73158 int bottom ;
74- if (matrix == null ) {
159+ if (matrix == null || mShapeScaleType == ShapeScaleType . ALWAYS_FIX_XY ) {
75160 left = paddingLeft ;
76161 top = paddingTop ;
77162 right = width - paddingRight ;
@@ -100,14 +185,7 @@ private void drawShape(Canvas canvas) {
100185 float transY ;
101186
102187 ScaleType scaleType = getScaleType ();
103- if (scaleType == ScaleType .FIT_XY ) {
104- transX = paddingLeft ;
105- transY = paddingTop ;
106- pictureWidth = width - paddingLeft - paddingRight ;
107- pictureHeight = height - paddingTop - paddingBottom ;
108- shapeWidth = pictureWidth ;
109- shapeHeight = pictureHeight ;
110- } else if (scaleType == ScaleType .CENTER_CROP ) {
188+ if (scaleType == ScaleType .FIT_XY || scaleType == ScaleType .CENTER_CROP ) {
111189 transX = paddingLeft ;
112190 transY = paddingTop ;
113191 pictureWidth = width - paddingLeft - paddingRight ;
@@ -168,19 +246,26 @@ private void drawShape(Canvas canvas) {
168246 shapeWidth = shapeHeight / shapeHWScale ;
169247 }
170248 }
171-
249+ if (mShapeScaleType == ShapeScaleType .FOLLOW_IMAGEVIEW_FULL_IMAGE ){
250+ shapeWidth = pictureWidth ;
251+ shapeHeight = pictureHeight ;
252+ }
172253 left = ((int ) (transX + (pictureWidth - shapeWidth ) / 2 ));
173254 top = ((int ) (transY + (pictureHeight - shapeHeight ) / 2 ));
174255 right = ((int ) (shapeWidth + transX + (pictureWidth - shapeWidth ) / 2 ));
175256 bottom = ((int ) (shapeHeight + transY + (pictureHeight - shapeHeight ) / 2 ));
176257 }
177258
178- mShapePaint .setXfermode (null );
179- canvas .saveLayer (new RectF (0 , 0 , canvas .getWidth (), canvas .getHeight ()), mShapePaint , Canvas .ALL_SAVE_FLAG );
180- mShapeResource .setBounds (left , top , right , bottom );
181- mShapeResource .draw (canvas );
259+ if (!isDrawShapeClear ){
260+ mShapePaint .setXfermode (null );
261+ canvas .saveLayer (new RectF (0 , 0 , canvas .getWidth (), canvas .getHeight ()), mShapePaint , Canvas .ALL_SAVE_FLAG );
262+ mShapeResource .setBounds (left , top , right , bottom );
263+ mShapeResource .draw (canvas );
264+ }
182265 mShapePaint .setXfermode (new PorterDuffXfermode (PorterDuff .Mode .SRC_IN ));
183266 canvas .saveLayer (new RectF (0 , 0 , canvas .getWidth (), canvas .getHeight ()), mShapePaint , Canvas .ALL_SAVE_FLAG );
267+
268+ isDrawShapeClear = false ;
184269 }
185270
186271 public Drawable getShapeDrawable () {
@@ -196,5 +281,27 @@ public void setShapeResource(@DrawableRes int shapeResourceRes) {
196281 setShapeResource (getResources ().getDrawable (shapeResourceRes ));
197282 }
198283
284+ public enum ShapeScaleType {
285+ FOLLOW_IMAGEVIEW_KEEP_RESOURCE_SCALE (0 ),FOLLOW_IMAGEVIEW_FULL_IMAGE (1 ), ALWAYS_FIX_XY (2 );
199286
287+ ShapeScaleType (int type ) {
288+ this .type = type ;
289+ }
290+
291+ final int type ;
292+
293+ public int getType () {
294+ return type ;
295+ }
296+
297+ public static ShapeScaleType getType (int type ) {
298+ if (type == 2 ) {
299+ return ALWAYS_FIX_XY ;
300+ } else if (type == 1 ) {
301+ return FOLLOW_IMAGEVIEW_FULL_IMAGE ;
302+ } else {
303+ return FOLLOW_IMAGEVIEW_KEEP_RESOURCE_SCALE ;
304+ }
305+ }
306+ }
200307}
0 commit comments