How to paint with alpha? - android

I want to paint graphics onto a Canvas such that the colors are additive. For example, I want to produce this:
But instead, I get this:
Note that the half white, half black background is intentional, just to see how alpha interacts with both backgrounds. I will be happy to have this work with either background. Here is my code:
public class VennColorsActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
class VennView extends View {
public VennView(Context context) {
super(context);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int alpha = 60, val = 255;
int ar = Color.argb(alpha, val, 0, 0);
int ag = Color.argb(alpha, 0, val, 0);
int ab = Color.argb(alpha, 0, 0, val);
float w = canvas.getWidth();
float h = canvas.getHeight();
float cx = w / 2f;
float cy = h / 2;
float r = w / 5;
float tx = (float) (r * Math.cos(30 * Math.PI / 180));
float ty = (float) (r * Math.sin(30 * Math.PI / 180));
float expand = 1.5f;
Paint paint = new Paint();
paint.setColor(Color.WHITE);
canvas.drawRect(new Rect(0, 0, (int) w, (int) (h / 2)), paint);
PorterDuff.Mode mode = android.graphics.PorterDuff.Mode.ADD;
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColorFilter(new PorterDuffColorFilter(ar, mode));
paint.setColor(ar);
canvas.drawCircle(cx, cy - r, expand * r, paint);
paint.setColorFilter(new PorterDuffColorFilter(ag, mode));
paint.setColor(ag);
canvas.drawCircle(cx - tx, cy + ty, expand * r, paint);
paint.setColorFilter(new PorterDuffColorFilter(ab, mode));
paint.setColor(ab);
canvas.drawCircle(cx + tx, cy + ty, expand * r, paint);
}
}
this.setContentView(new VennView(this));
}
}
Can someone please help me understand how to paint with additive colors in Android graphics?

You are on the right track. There are 3 major issues in your code:
You need to set xfer mode iso color filter
Use temp bitmap for rendering your image
Alpha should be 0xFF in order to get results you are looking for
Here is what I've got by using xfer mode. What I'm doing - is drawing everything into temporary bitmap and then rendering entire bitmap to main canvas.
You ask why do you need temp bitmap? Good question! If you are drawing everything on a main canvas, your colors will be blended with main canvas background color, so all colors will get messed up. Transparent temp bitmap helps to keep your colors away of other parts of UI
Please make sure you are not allocating anything in onDraw() - you will run out memory very soon in this way.. Also make sure you have recycled your temp bitmap when you no longer need it.
package com.example.stack2;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.os.Bundle;
import android.view.View;
public class YouAreWelcome extends Activity {
Bitmap tempBmp = Bitmap.createBitmap(1, 1, Config.ARGB_8888);
Canvas c = new Canvas();
Paint paint = new Paint();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
class VennView extends View {
public VennView(Context context) {
super(context);
}
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if(tempBmp.isRecycled() || tempBmp.getWidth()!=canvas.getWidth() || tempBmp.getHeight()!=canvas.getHeight())
{
tempBmp.recycle();
tempBmp = Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(), Config.ARGB_8888);
c.setBitmap(tempBmp);
}
//clear previous drawings
c.drawColor(Color.TRANSPARENT, Mode.CLEAR);
int alpha = 255, val = 255;
int ar = Color.argb(alpha, val, 0, 0);
int ag = Color.argb(alpha, 0, val, 0);
int ab = Color.argb(alpha, 0, 0, val);
float w = canvas.getWidth();
float h = canvas.getHeight();
float cx = w / 2f;
float cy = h / 2;
float r = w / 5;
float tx = (float) (r * Math.cos(30 * Math.PI / 180));
float ty = (float) (r * Math.sin(30 * Math.PI / 180));
float expand = 1.5f;
paint.setAntiAlias(true);
paint.setXfermode(new PorterDuffXfermode(Mode.ADD));
paint.setColor(ar);
c.drawCircle(cx, cy - r, expand * r, paint);
paint.setColor(ag);
c.drawCircle(cx - tx, cy + ty, expand * r, paint);
paint.setColor(ab);
c.drawCircle(cx + tx, cy + ty, expand * r, paint);
canvas.drawBitmap(tempBmp, 0, 0, null);
}
}
this.setContentView(new VennView(this));
}
}

Thanks again Pavel. That would have been very difficult for me to have figured out on my own. I am answering my own question to better drill into details, but I've accepted yours as the best answer.
You are right that I prefer not to have to create and manage an off-screen Bitmap (and Canvas). That is essentially why I mentioned that a black or white background would be fine to make this work.
I'm never concerned with performance before I see something working but I share your caution after that point. Editing your version to fix that and remove those members gives the implementation below.
Is this robust? Note the two calls to Canvas.drawColor() which I suspect could also be combined into one.
package com.superliminal.android.test.venn;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.os.Bundle;
import android.view.View;
public class VennColorsActivity extends Activity {
private Paint paint = new Paint();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
class VennView extends View {
public VennView(Context context) {
super(context);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.BLACK);
canvas.drawColor(Color.TRANSPARENT, Mode.CLEAR);
int alpha = 255, val = 255;
int ar = Color.argb(alpha, val, 0, 0);
int ag = Color.argb(alpha, 0, val, 0);
int ab = Color.argb(alpha, 0, 0, val);
float w = canvas.getWidth();
float h = canvas.getHeight();
float cx = w / 2f;
float cy = h / 2;
float r = w / 5;
float tx = (float) (r * Math.cos(30 * Math.PI / 180));
float ty = (float) (r * Math.sin(30 * Math.PI / 180));
float expand = 1.5f;
paint.setAntiAlias(true);
paint.setXfermode(new PorterDuffXfermode(Mode.ADD));
paint.setColor(ar);
canvas.drawCircle(cx, cy - r, expand * r, paint);
paint.setColor(ag);
canvas.drawCircle(cx - tx, cy + ty, expand * r, paint);
paint.setColor(ab);
canvas.drawCircle(cx + tx, cy + ty, expand * r, paint);
}
}
setContentView(new VennView(this));
}
}

Related

diamond shape in android studio

I'm having trouble using a path to create a diamond shape on Android studio. It looks like I have a little more than half of the diamond, but I don't know what I am doing wrong and why the rest of it isn't printing out. I've been trying to change my code for hours and nothing is working. Could anyone please point out what I am doing wrong? Here is my code so far:
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.drawable.shapes.Shape;
public class Diamond extends Shape {
private int strokeWidth;
private final int fillColor;
private int strokeColor;
private Path path;
private Paint strokePaint;
private Paint fillPaint;
public Diamond(int strokeWidth, int fillColor, int strokeColor) {
this.strokeWidth = strokeWidth;
this.fillColor = fillColor;
this.strokeColor = strokeColor;
this.strokePaint = new Paint();
this.strokePaint.setStyle(Paint.Style.STROKE);
this.strokePaint.setStrokeWidth(strokeWidth);
this.fillPaint = new Paint();
this.fillPaint.setStyle(Paint.Style.FILL);
this.fillPaint.setColor(fillColor);
}
#Override
public void draw(Canvas canvas, Paint paint) {
canvas.drawPath(path, fillPaint);
canvas.drawPath(path, strokePaint);
}
#Override
protected void onResize(float width, float height) {
super.onResize(width, height);
path = new Path();
path.moveTo(width/2, 0);
path.lineTo(width, height);
path.lineTo(width/2, height*4);
path.lineTo(0, height);
path.close();
}
}
I think you should just need to change path.lineTo(width/2, height*4); to instead multiply the height by 2 as in path.lineTo(width/2, height*2);, using 4 makes the bottom half skewed longer than the top. There's also an example on this page drawing a rhombus which you can modify to draw a diamond by using the full width like:
public void drawRhombus(Canvas canvas, Paint paint, int x, int y, int width) {
int halfWidth = width / 2;
Path path = new Path();
path.moveTo(x, y + width); // Top
path.lineTo(x - halfWidth, y); // Left
path.lineTo(x, y - width); // Bottom
path.lineTo(x + halfWidth, y); // Right
path.lineTo(x, y + width); // Back to Top
path.close();
canvas.drawPath(path, paint);
}

How to create custom UI components like responsive seekbar?

I want to create custom sliders or seekbars in android (just as in the gif, slider on the bottom and right), could you provide me with any relevant process how to achieve this.
After searching for several days I have finally got enough resources to address the problem statement.
For staters go through the following resources:
1) https://guides.codepath.com/android/Basic-Painting-with-Views
2) https://guides.codepath.com/android/Progress-Bar-Custom-View
3) https://developer.android.com/guide/topics/ui/custom-components
Basics Steps -
Extend an existing View class or subclass with your own class.
Override some of the methods from the superclass. The superclass methods to override start with 'on', for example, onDraw(), onMeasure(), and onKeyDown(). This is similar to the on... events in Activity or ListActivity that you override for lifecycle and other functionality hooks.
Use your new extension class. Once completed, your new extension class can be used in place of the view upon which it was based.
Below is the code that demonstrate a working Clock in canvas -
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import java.util.Calendar;
/**
* Created by moonis
* on 23/06/18.
*/
public class CustomClock extends View {
private int height, width = 0;
private int padding = 0;
private int fontSize = 0;
int numeralSpacing = 0;
private int handTruncation, hourHandTruncation = 0;
private int radius = 0;
private Paint paint;
private boolean isInit;
private int[] numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
private Rect rect = new Rect();
public CustomClock(Context context, #Nullable AttributeSet attrs) {
super(context, attrs);
setFocusable(true);
setFocusableInTouchMode(true);
}
private void initClock() {
height = getHeight();
width = getWidth();
padding = numeralSpacing + 50;
fontSize = (int) DeviceDimensionHelper.convertDpToPixel(13, getContext());
int min = Math.min(height, width);
radius = min / 2 - padding;
handTruncation = min / 20;
hourHandTruncation = min / 7;
paint = new Paint();
isInit = false;
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (!isInit) {
initClock();
}
canvas.drawColor(Color.BLACK);
drawCircle(canvas);
drawCentre(canvas);
drawNumeral(canvas);
drawHands(canvas);
postInvalidateDelayed(500);
}
private void drawCircle(Canvas canvas) {
paint.reset();
paint.setColor(Color.WHITE);
paint.setAntiAlias(true);
paint.setStrokeWidth(5);
paint.setStyle(Paint.Style.STROKE);
canvas.drawCircle(width / 2, height / 2, radius + padding - 10, paint);
}
private void drawCentre(Canvas canvas) {
paint.setStyle(Paint.Style.FILL);
canvas.drawCircle(width / 2, height / 2, 12, paint);
}
private void drawNumeral(Canvas canvas) {
paint.setTextSize(fontSize);
for (int number : numbers) {
String tmp = String.valueOf(number);
paint.getTextBounds(tmp, 0, tmp.length(), rect);
double angle = Math.PI / 6 * (number - 3);
int x = (int) (width / 2 + Math.cos(angle) * radius - rect.width() / 2);
int y = (int) (height / 2 + Math.sin(angle) * radius - rect.height() / 2);
canvas.drawText(tmp, x, y, paint);
}
}
private void drawHands(Canvas canvas) {
Calendar c = Calendar.getInstance();
float hour = c.get(Calendar.HOUR_OF_DAY);
hour = hour > 12 ? hour - 12 : hour;
drawHand(canvas, (hour + c.get(Calendar.MINUTE) / 60) * 5f, true);
drawHand(canvas, c.get(Calendar.MINUTE), false);
drawHand(canvas, c.get(Calendar.SECOND), false);
}
private void drawHand(Canvas canvas, double loc, boolean isHour) {
double angle = Math.PI * loc / 30 - Math.PI / 2;
int handRadius = isHour ? radius - handTruncation - hourHandTruncation : radius - handTruncation;
canvas.drawLine(width / 2, height / 2, (float) (width / 2 + Math.cos(angle) * handRadius), (float) (height / 2 + Math.sin(angle) * handRadius), paint);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
float touchX = event.getX();
float touchY = event.getY();
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
//code to move clock hands on screen gestures
break;
case MotionEvent.ACTION_MOVE:
//code to move clock hands on screen gestures
break;
default:
return false;
}
//redraw view
postInvalidate();
return true;
}
}
Finally this library can be used to achieve the desired output -
https://github.com/moldedbits/android-dial-picker
have a look at this Wheelview Library to achieve the bottom wheel
and this for your vertical ruler
to scale your image horizontally and vertically, probably you might have to go with some sort of custom solution, Vector images would be a suitable fit.
Also refer this
Hope this helps you.

Android SweepGradient and Drawing Lines in a circular pattern

I am trying to achieve this circular progress bar with gradient intervals UI effect
Currently I have been able to achieve this.
The code for my current implementation is below.
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.SweepGradient;
import android.graphics.drawable.AnimationDrawable;
import android.support.annotation.IntRange;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
public class CBPDrawable extends AnimationDrawable {
Paint paint = new Paint();
RectF clip = new RectF();
LinearGradient shader;
Path path;
private static final int MAX = 360;
int dots = 75;
int dotRadius = 20;
RectF dotRect;
Context mContext;
public CBPDrawable(Context context){
mContext = context;
}
Shader gradient;
private int mTickOffset = 0;
private int mTickLength = 15;
private int mArcRadius = 10;
double slope, startTickX, startTickY, endTickX, endTickY, midTickX, midTickY, thetaInRadians;
double radiusOffset = mArcRadius + mTickOffset;
#Override
protected void onBoundsChange(Rect bounds) {
super.onBoundsChange(bounds);
path = new Path();
dotRect = new RectF(0, 0, dotRadius, dotRadius);
/*
for (int i = 0; i < dots; ++i) {
start();
path.addRoundRect(dotRect, dotRadius, dotRadius, Path.Direction.CCW);
stop();
}
*/
for (int i = 360; i >= 0; i -= 5) {
thetaInRadians = Math.toRadians(360 - i);
slope = Math.tan(thetaInRadians);
startTickX = (radiusOffset * Math.cos(thetaInRadians));
startTickY = slope * startTickX;
endTickX = startTickX + ((mTickLength) * Math.cos(thetaInRadians));
endTickY = slope * endTickX;
RectF r = new RectF();
r.set((float) startTickX, (float) startTickY, (float) endTickX, (float) endTickY);
path.addRoundRect(r, (int)radiusOffset, (int)radiusOffset, Path.Direction.CCW);
}
}
#Override
public void draw(#NonNull Canvas canvas) {
Rect b = getBounds();
final int width = canvas.getWidth();
final int height = canvas.getHeight();
final int squareSide = Math.min(width, height);
canvas.translate(width / 2f, height / 2f); // moving to the center of the View
canvas.rotate(270);
final float outerRadius = squareSide / 2f;
final float innerRadius = outerRadius - dotRadius;
final float angleFactor = 360f / 72;
int[] colors = new int[]{Color.BLUE, Color.RED};
float[] positions = new float[]{0,0.4f};
gradient = new SweepGradient(outerRadius / 2f, outerRadius / 2f,colors,null);
for (int i = 0; i < 72; ++i) {
canvas.save(); // creating a "checkpoint"
canvas.rotate(angleFactor * i);
canvas.translate(innerRadius, 0); //moving to the edge of the big circle
clip.set(b);
paint.setColor(Color.GRAY);
if(angleFactor * i <= 200){
paint.setShader(gradient);
}else{
paint.setShader(null);
}
//canvas.clipRect(clip, Region.Op.REPLACE);
canvas.drawPath(path, paint);
canvas.restore(); //restoring a "checkpoint"
//stop();
}
}
#Override
public void setAlpha(#IntRange(from = 0, to = 255) int i) {
}
#Override
public void setColorFilter(#Nullable ColorFilter colorFilter) {
}
#Override
public int getOpacity() {
return PixelFormat.OPAQUE;
}
}
As can be seen from the 2 images, I am unable to get the intervals correctly as a rectangle or line.
And, the gradient does not show, in spite of using a SweepGradient.
How should I go about achieving the desired effect?
Thanks.

Android How to draw a regular polygon via xml or programical

Is there any way to draw polygonal shapes on Android xml layouts?
or is any helper class as library to draw them?
I am using enhanced version of this Class
See working sample on GitHub (https://github.com/hiteshsahu/Benzene)
Drawable Class
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
/**
* Originally Created by AnderWeb (Gustavo Claramunt) on 7/10/14.
*/
public class PolygonalDrwable extends Drawable {
private int numberOfSides = 3;
private Path polygon = new Path();
private Path temporal = new Path();
private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
public PolygonalDrwable(int color, int sides) {
paint.setColor(color);
polygon.setFillType(Path.FillType.EVEN_ODD);
this.numberOfSides = sides;
}
#Override
public void draw(Canvas canvas) {
canvas.drawPath(polygon, paint);
}
#Override
public void setAlpha(int alpha) {
paint.setAlpha(alpha);
}
#Override
public void setColorFilter(ColorFilter cf) {
paint.setColorFilter(cf);
}
#Override
public int getOpacity() {
return paint.getAlpha();
}
#Override
protected void onBoundsChange(Rect bounds) {
super.onBoundsChange(bounds);
computeHex(bounds);
invalidateSelf();
}
public void computeHex(Rect bounds) {
final int width = bounds.width();
final int height = bounds.height();
final int size = Math.min(width, height);
final int centerX = bounds.left + (width / 2);
final int centerY = bounds.top + (height / 2);
polygon.reset();
polygon.addPath(createHexagon(size, centerX, centerY));
polygon.addPath(createHexagon((int) (size * .8f), centerX, centerY));
}
private Path createHexagon(int size, int centerX, int centerY) {
final float section = (float) (2.0 * Math.PI / numberOfSides);
int radius = size / 2;
Path polygonPath = temporal;
polygonPath.reset();
polygonPath.moveTo((centerX + radius * (float)Math.cos(0)), (centerY + radius
* (float)Math.sin(0)));
for (int i = 1; i < numberOfSides; i++) {
polygonPath.lineTo((centerX + radius * (float)Math.cos(section * i)),
(centerY + radius * (float)Math.sin(section * i)));
}
polygonPath.close();
return polygonPath;
}
}
Set drawable to any Imageview like this
//Triangle
((ImageView) findViewById(R.id.triangle))
.setBackgroundDrawable(new PolygonalDrwable(Color.GREEN, 3));
//Square
((ImageView) findViewById(R.id.square))
.setBackgroundDrawable(new PolygonalDrwable(Color.MAGENTA, 4));
//Pentagon
((ImageView) findViewById(R.id.pentagon))
.setBackgroundDrawable(new PolygonalDrwable(Color.LTGRAY, 5));
//Hexagon
((ImageView) findViewById(R.id.hex))
.setBackgroundDrawable(new PolygonalDrwable(Color.RED, 6));
//Heptagon
((ImageView) findViewById(R.id.hept))
.setBackgroundDrawable(new PolygonalDrwable(Color.MAGENTA, 7));
//Octagon
((ImageView) findViewById(R.id.oct))
.setBackgroundDrawable(new PolygonalDrwable(Color.YELLOW, 8));
You can create custom drawable and shapes as drawable resources.
Right click on the "drawable" folder in Android Studio and select New->Drawable Resource File.
Here is a decent tutorial for shapes and strokes to get started.
Here is some example shapes ready to use.
Here is documentation for some more complex things you can do with drawables.

Issue on TextView width when creating my own TextView

I created my own TextView by extending the TextView class in order to improve its display. I created various Paint and stuff to add a kind of margin. Then text has to be displayed right after the margin. If I set
android:layout_width="fill_parent"
the display is ok and my line is fully filled with a white background (as defined in my layout).
BUT if I set
android:layout_width="wrap_content"
the display goes wrong and the end of the text of my TextView is cropped. I guess this is due to the fact that I made a Translate in the onDraw method of my TextView but I don't know how to fix it.
Please note that I need the set wrap_content because I want to add another TextBox right after, and a LinearLayout around both, but for the moment the other TextBox erase a part of the content of the first one.
The code of my new TextBox is the following one :
package com.flo.ui;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.widget.TextView;
import com.flo.musicalnotes.R;
public class NoteItemTextView extends TextView {
// Properties
private Paint marginPaint;
private Paint linePaint;
private Paint circlePaint;
private int paperColor;
private float margin;
private float marginEnd;
private float textStart;
// Initialization
public NoteItemTextView(Context context) {
super(context);
this.Init(context);
}
public NoteItemTextView(Context context, AttributeSet attrs)
{
super(context, attrs);
this.Init(context);
}
private void Init(Context context)
{
// Resources retrieval
Resources myResources = getResources();
// Brush definition
this.marginPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
this.marginPaint.setColor(myResources.getColor(R.color.marginColor));
this.marginPaint.setStrokeWidth((float) 1.8);
this.linePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
this.linePaint.setColor(myResources.getColor(R.color.underlineColor));
this.circlePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
this.circlePaint.setColor(myResources.getColor(R.color.marginColor));
this.circlePaint.setStyle(Paint.Style.FILL_AND_STROKE);
// various resources
this.paperColor = myResources.getColor(R.color.bgColor);
this.margin = myResources.getDimension(R.dimen.marginSize);
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
int ot = getResources().getConfiguration().orientation;
switch(ot)
{
case Configuration.ORIENTATION_LANDSCAPE:
this.marginEnd = this.margin + metrics.widthPixels / 100;
this.textStart = this.marginEnd + metrics.widthPixels / 100;
case Configuration.ORIENTATION_PORTRAIT:
this.marginEnd = this.margin + metrics.heightPixels / 100;
this.textStart = this.marginEnd + metrics.heightPixels / 100;
default:
this.marginEnd = this.margin + 5;
this.textStart = this.marginEnd + 10;
}
}
//#Override
protected void onDraw(Canvas canvas) {
// paper color
canvas.drawColor(this.paperColor);
// lines drawing
canvas.drawLine(0, getMeasuredHeight(), getMeasuredWidth(), getMeasuredHeight(), this.linePaint);
// marge drawing
canvas.drawLine(this.margin, 0, this.margin, getMeasuredHeight(), this.marginPaint);
canvas.drawLine(this.marginEnd, 0, this.marginEnd, getMeasuredHeight(), this.marginPaint);
double x = (this.textStart + this.marginEnd) / 1.8;
float y1 = getMeasuredHeight() / 3;
float y2 = getMeasuredHeight() * 2 / 3;
float radius = (float) 2.5;
canvas.drawCircle((float) x, y1, radius, this.circlePaint);
canvas.drawCircle((float) x, y2, radius, this.circlePaint);
canvas.save();
canvas.translate(this.textStart, 0);
super.onDraw(canvas);
canvas.restore();
}
}
Thanks for your help !
Try to add this code to your custom textview class
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int height = getMeasuredHeight();
int width = getMeasuredWidth();
Log.e(getClass().getSimpleName() , String.format("height x %s ::: width x %s ",height , width));
float density = getResources().getDisplayMetrics().density;
//Extra space after last letter.
float px = 2 * density;
int adjustedWidth = (int) (width + textStart + px);
setMeasuredDimension(adjustedWidth, height);
}
add this to your textview
android:paddingRight="25dp"

Categories

Resources