I need to draw some text on canvas, this text may single line or multi lines. I found StaticLayout can fill this require. But When I create an StaticLayout and after I want to draw it, I call getHeight(), I found it always return the line count. Shouldn't this function return the number of pixels?
This is my code:
m_staticLayout = new StaticLayout(m_message, textPaint, m_messageWidth,
Layout.Alignment.ALIGN_NORMAL, 1.0f, 0f, false);
Any help will be appreciated.
Firstly, StaticLayout is deprecated.
The reason it probably doesn't return pixels is because we haven't drawn anything yet, we're just initializing the StaticLayout. Hence, it returns the line count which we could probably use in the future. If you are trying to draw some text on Canvas, I wouldn't recommend using StaticLayout.
Instead, use the Paint class, Canvas, and Bitmap. Think of paint as the ink of the Canvas(which hosts all the draw calls). Canvas will draw into your Bitmap.
We will have to create the Paint, set up it's attributes, and then host the draw call drawText to the canvas. The Canvas will then draw the text using the Paint we created.
All of this will be in an Activity which extends View, which we will then pass as the View in setContentView for our MainActivity
This is how we can implement this:
MainActivity.java:
public class MainActivity extends AppCompatActivity {
OtherActivity otherActivity;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
otherActivity = new OtherActivity(this);
otherActivity.setBackgroundColor(Color.GRAY);
setContentView(otherActivity);
}
}
OtherActivity.java:
public class OtherActivity extends View {
public OtherActivity(Context context) {
super(context);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
paint.setColor(Color.BLACK);
paint.setTextSize(20);
canvas.drawText("Some Text", 10, 25, paint);
}
}
Related
I have a custom view extends form TextView,and write some code in onDraw():
#Override
protected void onDraw(Canvas canvas) {
if (mTextShader == null) {
createShader();
}
shaderMatrix.setTranslate(mProgressWidth,0);
mTextShader.setLocalMatrix(shaderMatrix);
Paint paint = new Paint();
paint.setShader(mBgShader);
canvas.drawRect(0,0,mProgressWidth,getBottom(),paint);
getPaint().setShader(mTextShader);
super.onDraw(canvas);
}
It looks like this:
enter image description here
Just set some shader,and draw a rect,it works fine if I don't use
android:gravity="center"
and
android:singleLine="true"
together,(just one of them is pretty good,)
if only use this property,these shaders and rect are gone!
why?
Before you draw in the canvas, translate the scrolled XY distance
canvas.translate(getScrollX(), getScrollY());
canvas.drawRect(0,0, getWidth(), getHeight(), borderPaint);
your super.onDraw(canvas); should be first line otherwise parent will paint on top of your drawing. also call this setWillNotDraw(false) in your constructor.
Actually my problem is I want to add text view to surface view at a particular position whether it may be corner or centre.In this I am getting surface view dynamically and I have to add text view to this surface view dynamically please help me
Another approach would be to write the text directly into the SurfaceView. To do this, you can create your custom implementation of SurfaceView by extending it. Then, rewrite the onDraw() method to draw your text on top of it.
Haven't tested to see if this works, but trye something like:
public class MySurfaceView extends SurfaceView {
Paint paint;
public MySurfaceView() {
Paint paint = new Paint();
paint.setColor(Color.BLACK);
paint.setTextSize(25);
setWillNotDraw(false);
}
public class onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawText("Your Text", 10, 10, paint);
}
}
I want to add text in a circle or half circle programmatically, in such a way that instead of having a circle with line edges, the edges are the words. See image for a better explanation.
How can I do this in Android, or what resources could I read in order to help me with this problem?
In order to do this, you will need to draw your text onto a Canvas. Any subclass of View is passed a Canvas in onDraw() that you can use to draw your custom text. The method drawTextOnPath() lets you put text on any Path object you choose. You can create a semi-circle path by creating a new instance and using addArc().
you can Use Below Code. and Make it as you Want your Textview.
Here if you want Something as Backgroung image then use setBackgroundResource(R.drawable.YOUR_IMAGE);
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new GraphicsView(this));}
static public class GraphicsView extends View {
private static final String QUOTE = "text in a half-circle";
private Path circle;
private Paint cPaint;
private Paint tPaint;
public GraphicsView(Context context) {
super(context);
int color = Color.argb(127, 255, 0, 255);
circle = new Path();
circle.addCircle(230, 350, 150, Direction.CW);
cPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
cPaint.setStyle(Paint.Style.STROKE);
cPaint.setColor(Color.LTGRAY);
cPaint.setStrokeWidth(3);
// For Background Image
setBackgroundResource(R.drawable.YOUR_IMAGE);
tPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
tPaint.setStyle(Paint.Style.FILL_AND_STROKE);
//TextColor you want to set
tPaint.setColor(Color.BLACK);
//TextSize you want to set
tPaint.setTextSize(50);}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawTextOnPath(QUOTE, circle, 485, 20, tPaint);}
}
}
try it out. hope it will help you.
I'm extending LinearLayout:
public class MyLinearLayout extends LinearLayout {
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
paint.setColor(0xFFFF0000);
canvas.drawLine(0, 0, getWidth(), getHeight(), paint);
}
}
If the layout has child elements, shouldn't the red line above be drawn on top of them? Considering a layout like:
<MyLinearLayout>
<ImageView />
</MyLinearLayout>
I'd expect to get the red line drawn above the child ImageView. But it gets drawn below it. I was assuming all child drawing would have been completed after the super.onDraw() line is finished.
Is there a way to get to the canvas and draw something on it after all child drawing has been completed?
Thanks
Layouts don't draw unless you call setWillNotDraw(false);. They do that for efficiency reasons.
EDIT:
onDraw() really is meant to just allow you to modify the Canvas before the drawing operation happens. It doesn't actually draw. What you want to do is override draw() like so:
#Override
protected void draw(Canvas canvas) {
super.draw(canvas);
Paint paint = new Paint();
paint.setColor(0xFFFF0000);
canvas.drawLine(0, 0, getWidth(), getHeight(), paint);
}
Calling the super will draw all the children in the view. Then it will draw all the lines. I do still believe you need setWillNotDraw(false) to be called though.
I'm rewriting my answer as I hadn't seen your line of code where you were drawing to the canvas.
The canvas like some other graphics environments is inverted. So calling getHeight() is actually drawing the line at the bottom. Instead call
canvas.drawLine( 0, 0, getWidth(), 0, paint);
This means draw the line at the top, across the width of the view.
Also, calling super first paints the children prior to any custom painting so your fine there.
If you have a LinearLayout and you need:
draw all of its children first, like buttons, image views
then, on top of those components, draw something directly on the canvas.
You can try this:
public class YourClass extends LinearLayout
{
#Override
protected void dispatchDraw(Canvas canvas)
{
super.dispatchDraw(canvas);
// do your custom drawings afterwards
canvas.drawCircle...
canvas.drawLine...
I want to create an ImageView and then draw text on top of the ImageView. I also need to be able to modify the text periodically. Currently I've created a custom view that extends ImageView. Then I overwrite onDraw() and use it to draw the text. Only problem then is that when I use my custom ImageView it doesn't draw the image, just the text.
public class BoardView extends ImageView
{
public BoardView(Context context)
{
super(context);
}
protected void onDraw(Canvas canvas)
{
Paint paint = new Paint();
setImageResource(R.drawable.board);
paint.setColor(Color.BLUE);
canvas.drawText(x.getName(), x.getX(), x.getY(), paint);
}
}
You should call the super.onDraw in your onDraw method before your draw code.