ellipsize for the canvas text in android - android

What i am trying to do: I am trying to set ... after 7 characters in canavs for text
How to achieve this ?
private void drawText(Canvas canvas, float tmpAngle, float sweepAngle, String mStr) {
float cx = (mRadius) / 2 + mPadding;
float cy = (mRadius) / 2 + mPadding;
float radius = mRadius / 2 + mPadding;
float x = cx - radius + (mPadding * 2);
float y = cy;
float textWidth = radius - (mPadding * 10);
TextPaint textPaint = new TextPaint();
textPaint.set(this.mTextPaint);
textPaint.setColor(Color.WHITE);
Typeface plain = Typeface.createFromAsset(getContext().getAssets(), "fonts/AvenirLTStd-Heavy.otf");
Typeface bold = Typeface.create(plain, Typeface.BOLD);
textPaint.setTypeface(bold);
float angle = tmpAngle + sweepAngle / 2;
canvas.save();
canvas.rotate(180+(angle), cx, cy); // +180 for start from right
canvas.drawText(mStr, x, y, textPaint);
canvas.restore();
}

You can do something like this,
TextPaint textPaint = new TextPaint();
// textPaint attributes
CharSequence ellipsizedText = TextUtils.ellipsize("Your text", textPaint, width,
TextUtils.TruncateAt.END);
canvas.drawText(ellipsizedText, 0, ellipsizedText.length(), x0, y0, textPaint);
But in your case you need it after 7 characters, better just check the text length and append ... after the text.

Related

How to get text BaseLine from Paint

I am trying to draw a text at the centre of canvas, Since canvas starts drawing text at BaseLine, I am not able to Place it at centre. If i can get the baseLine, then i can calculate the centre.
I have tried with paint.getFontMetrics() this gives ascent and descent but not baseLine.
Did you try this code
private void drawCenter(Canvas canvas, Paint paint, String text) {
canvas.getClipBounds(r);
int cHeight = r.height();
int cWidth = r.width();
paint.setTextAlign(Paint.Align.LEFT);
paint.getTextBounds(text, 0, text.length(), r);
float x = cWidth / 2f - r.width() / 2f - r.left;
float y = cHeight / 2f + r.height() / 2f - r.bottom;
canvas.drawText(text, x, y, paint);
}
All the calculations of paint.getFontMetrics() will happen with respect to baseLine. So if i just subtract (getMeasuredHeight() / 2f) - (fontMetrics.ascent / 2f) it will draw from center

How do I draw a resizable pentagon shape with user touch events?

I am trying to create a pentagon shaped polygon which can be resized by dragging one of its vertices. I tried some code from this question on SO but later realised that the code is specifically written for a rectangle shape. I tried modifying the code in the onDraw() method but later refactored it to the way it was earlier after realising that it is of no use.
Any help?
So here's a code I just wrote to draw a pentagon in the canvas. You pretty much have the vertices which you can edit on the onTouchEvent.
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int width = getWidth();
int heigth = getHeight();
// not required, but just to move it to the middle
float centerX = width / 2.f;
float centerY = heigth / 2.f;
// vertices
float p1x = 100.f + centerX;
float p1y = 0.f + centerY;
float p2x = 0.f + centerX;
float p2y = -80.f + centerY;
float p3x = -100.f + centerX;
float p3y = 0.f + centerY;
float p4x = -80.f + centerX;
float p4y = 80f + centerY;
float p5x = 80.f + centerX;
float p5y = 80.f + centerY;
Path path = new Path();
path.moveTo(p1x, p1y);
path.lineTo(p2x, p2y);
path.lineTo(p3x, p3y);
path.lineTo(p4x, p4y);
path.lineTo(p5x, p5y);
path.lineTo(p1x, p1y);
Paint paint = new Paint();
paint.setColor(Color.BLUE);
canvas.drawPath(path, paint);
}

How to draw a curved line between 2 points on canvas?

I have tried a lot of different approaches from examples around the web, but I can't seem to get this to work. I am trying to make a method that draws a curved line between 2 points on a canvas. The curve should be defined by a radius parameter.
Below is my current code.
public OverlayBuilder drawCurvedArrow(int startX, int startY, int endX, int endY, int curveRadius, int padding, int color) {
PointF mPoint1 = new PointF(startX, startY);
PointF mPoint2 = new PointF(endX, endY);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(12);
paint.setColor(color);
Path myPath = new Path();
myPath.moveTo(startX, startY);
myPath.quadTo(mPoint1.x, mPoint1.y, mPoint2.x, mPoint2.y);
canvas.drawPath(myPath, paint);
return this;
}
Edit
The problem is that I can't figure out how to curve the line that is drawn on the canvas.
I found a solution to my problem myself. Even though there were some great answers, they weren't an exact solution to my particular problem.
Here is what I did:
Found the point in between the 2 given points
Calculated the angle 90 degrees between the 2 points
Calculated the point X pixels from the middle point using the calculated degree from before.
Used "path.cubicTo" with these 3 points (Takes both negative and positive values to determine which way the line should curve).
Here is my code if anyone else should run into the same problem:
public OverlayBuilder drawCurvedArrow(int x1, int y1, int x2, int y2, int curveRadius, int color, int lineWidth) {
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(lineWidth);
paint.setColor(ContextCompat.getColor(context, color));
final Path path = new Path();
int midX = x1 + ((x2 - x1) / 2);
int midY = y1 + ((y2 - y1) / 2);
float xDiff = midX - x1;
float yDiff = midY - y1;
double angle = (Math.atan2(yDiff, xDiff) * (180 / Math.PI)) - 90;
double angleRadians = Math.toRadians(angle);
float pointX = (float) (midX + curveRadius * Math.cos(angleRadians));
float pointY = (float) (midY + curveRadius * Math.sin(angleRadians));
path.moveTo(x1, y1);
path.cubicTo(x1,y1,pointX, pointY, x2, y2);
canvas.drawPath(path, paint);
return this;
}
And here is an example of how the implementation looks like:
I think you are using wrong method for this purpose, one of the solutions that I can suggest is below
float radius = 20;
final RectF oval = new RectF();
oval.set(point1.x - radius, point1.y - radius, point1.x + radius, point1.y+ radius);
Path myPath = new Path();
myPath.arcTo(oval, startAngle, -(float) sweepAngle, true);
and for calculation of startAngle you will need
int startAngle = (int) (180 / Math.PI * Math.atan2(point.y - point1.y, point.x - point1.x));
for sweepAngle you can find detailed description here.
Suppose you have two points mPoint1 and mPoint2
int w=canvas.getWidth();
int h=canvas.getHeight();
int w_2= (w / 2);
int h_2= (h / 2);
PointF mPoint1 = new PointF(0, 0); //starts at canvas left top
PointF mPoint2 = new PointF(w_2, h_2);//mid of the canvas
Path drawPath1 =drawCurve(mPoint1, mPoint2);
canvas.drawPath(drawPath1, paint);
Method to draw the line
private Path drawCurve(PointF mPointa, PointF mPointb) {
Path myPath = new Path();
myPath.moveTo(mPointa.x, mPointa.y);
final float x2 = (mPointb.x + mPointa.x) / 3;
final float y2 = (mPointb.y + mPointa.y) / 3;
myPath.quadTo(x2, y2, mPointb.x, mPointb.y);
return myPath;
}

Android Wear(Long Textview)

Hi Guys am drawing an text using canvas, and i need to change the textview everyhour,
if the textview extends the width it should be displayed in the next line
For example , i have a text like "Good Morning" and "Good Morning rachel ! welcome you"
The first textview Good morning will be correctly displayed in Single line but the second textview i need to print by two line
how can i draw it
String mytext = "hi how are you how was the day "
canvas.drawText(mytext , x, centerX, mTextPaint);
scale = resources.getDisplayMetrics().density;
TextPaint TextPaint=new TextPaint();
TextPaint.setARGB(255, 255, 255, 255);
TextPaint.setTextSize(28f);
TextPaint.setTypeface(myfonttime);
StaticLayout mTextLayout;
mTextLayout = new StaticLayout(myText, TextPaint, canvas.getWidth(), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
int textHeight = mTextLayout.getHeight()- (int) (16 * scale +5.0);
int textWidth = canvas.getWidth() - (int) (16 * scale);
float x = cWidth / 2f - textWidth/2f - bounds.left;
float y = cHeight / 2f - textHeight/2f;
canvas.save();
canvas.translate(x, y);
mTextLayout.draw(canvas);
canvas.restore();
for example you have String like this
String text = "This is\nmulti-line\ntext";
Then draw in textview like this
canvas.drawText("This is", 100, 100, mTextPaint);
canvas.drawText("multi-line", 100, 150, mTextPaint);
canvas.drawText("text", 100, 200, mTextPaint);
Second way.
TextPaint mTextPaint=new TextPaint();
StaticLayout mTextLayout = new StaticLayout(mText, mTextPaint, canvas.getWidth(), Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
canvas.save();
// calculate x and y position where your text will be placed
textX = ...
textY = ...
canvas.translate(textX, textY);
mTextLayout.draw(canvas);
canvas.restore();
for more refer this link

draw with dp dimension

I have a loop af paint that create a circle, all work but on different device I get different paint dimension, I think that is a problem of density, how can I solve the problem?
this is my code:
for(int i=0; i<360; i = i + 12){
x = (float) (view.getWidth()/2 + raggio_in * Math.cos(Math.toRadians(i)));
y = (float) (view.getHeight()/2 + raggio_in * Math.sin(Math.toRadians(i)));
Paint paint = new Paint();
paint.setFlags(Paint.ANTI_ALIAS_FLAG);
paint.setColor(getResources().getColor(R.color.tutorial_text));
if(i < progress){
paint.setColor(Color.WHITE);
}
canvas.save(Canvas.MATRIX_SAVE_FLAG);
canvas.rotate(i, x, y);
canvas.drawRoundRect(new RectF((float) x-deltaX, (float) y-deltaY, (float) x+deltaX, (float) y+deltaY), raggio_elemento, raggio_elemento, paint);
canvas.restore();
x = (float) (view.getWidth()/2 + raggio_out * Math.cos(Math.toRadians(i)));
y = (float) (view.getHeight()/2 + raggio_out * Math.sin(Math.toRadians(i)));
paint = new Paint();
paint.setColor(getResources().getColor(R.color.tutorial_text));
if(i < progress){
paint.setColor(Color.WHITE);
}
canvas.save(Canvas.MATRIX_SAVE_FLAG);
canvas.rotate(i, x, y);
canvas.drawRoundRect(new RectF((float) x-deltaX, (float) y-deltaY, (float) x+deltaX, (float) y+deltaY), raggio_elemento, raggio_elemento, paint);
canvas.restore();
}
You can calculate the dimension in dp this way:
pixels * density + 0.5f
density can be access calling context.getResources().getDisplayMetrics().density
0.5f is used for rounding

Categories

Resources