Custom option with ImageView

I already have an "ImageView" with these options:

android:layout_width="wrap_content" android:layout_height="wrap_content" 

and install custom Drawable :

 public class HexDrawable extends Drawable { private Path hexagonPath; private float mWidth, mHeight; private int mBackgroundColor; private int mStrokeColor; private int mStrokeWidth; public HexDrawable(){ init(); } public void setBackgroundColor(int color) { mBackgroundColor = color; } public void setStrokeWidth(int width) { mStrokeWidth = width; } public void setStrokeColor(int color) { mStrokeColor = color; } @Override public int getIntrinsicHeight() { return 60; } @Override public int getIntrinsicWidth() { return 60; } private void init() { hexagonPath = new Path(); mBackgroundColor = Color.BLUE; mStrokeColor = Color.GREEN; mStrokeWidth = 4; } private void calculatePath() { float p = mStrokeWidth / 2; float w = mWidth - 2 * p; float h = mHeight - 2 * p; float r = h / 2; float a = (float) (r / Math.sqrt(3)); PointF X = new PointF(p + a + r / 2, p); PointF Y = new PointF(p + a + r , p); PointF A = new PointF(p + a, p + 0f); PointF B = new PointF(p + 0f, p + r); PointF C = new PointF(p + a, p + 2 * r); PointF D = new PointF(p + w - a, p + 2 * r); PointF E = new PointF(p + w, p + r); PointF F = new PointF(p + w - a, p + 0); hexagonPath.moveTo(Yx, Yy); hexagonPath.lineTo(Ax, Ay); hexagonPath.lineTo(Bx, By); hexagonPath.lineTo(Cx, Cy); hexagonPath.lineTo(Dx, Dy); hexagonPath.lineTo(Ex, Ey); hexagonPath.lineTo(Fx, Fy); hexagonPath.lineTo(Xx, Xy); } @Override protected void onBoundsChange(Rect bounds) { mWidth = bounds.width(); mHeight = bounds.height(); calculatePath(); } @Override public void draw(Canvas canvas) { Paint paint = new Paint(); paint.setColor(mStrokeColor); // set the color paint.setStrokeWidth(mStrokeWidth); // set the size paint.setDither(true); // set the dither to true paint.setStyle(Paint.Style.STROKE); // set to STOKE paint.setStrokeJoin(Paint.Join.ROUND); // set the join to round you want paint.setStrokeCap(Paint.Cap.ROUND); // set the paint cap to round too paint.setPathEffect(new CornerPathEffect(mStrokeWidth)); // set the path effect when they join. paint.setAntiAlias(true); canvas.drawPath(hexagonPath, paint); canvas.clipPath(hexagonPath, Region.Op.INTERSECT); canvas.drawColor(mBackgroundColor); canvas.drawPath(hexagonPath, paint); canvas.save(); } @Override public void setAlpha(int alpha) { } @Override public void setColorFilter(ColorFilter colorFilter) { } @Override public int getOpacity() { return 0; } } 

ImageView seems to use full width in this case.

How to use Drawable to use it with ImageView ?

+5
source share
2 answers

The root of the problem was the clip mode.

It is better to use canvas.clipPath(hexagonPath, Region.Op.REPLACE);

Also, the sample question works well with ImageView, but after deep research, I found that in android 5.0 and above this drawable is used in drawableLeft in TextView . Also no need to override getIntrinsicHeight

+4
source

Your code is absolutely correct:

enter image description here

This is how I populate ImageView (in onCreate() activity):

 ((ImageView)findViewById(R.id.hexImageView)).setImageDrawable(new HexDrawable()); 

The layout of the Activity in the screenshot:

 <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="16dp"> <ImageView android:id="@+id/hexImageView" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </FrameLayout> 

If you replace wrap_content with a value, the hexagon is expected to resize.

Tested on Android 6.0 and 4.3.

Only one getIntrinsicHeight() advice - instead of hardcoded values ​​in getIntrinsicHeight() and getIntrinsicWidth() , it is better to use a dimens .

+1
source

Source: https://habr.com/ru/post/1238730/


All Articles