I've been toying around in Android and attempting to port over a Java app. Below are some questions regarding to issues I've run into and would like some guidance on.
It is a rather large question (multiple questions rather). However, I'm not asking them blindly as I have researched what I could about them and attempted to put my understanding to use. I've put time into asking the questions in hopes that they are half-ways clear on what I'm wanting to achieve.
I'll be offering half of my rep as a bounty since I'm hoping for thorough answers and help, hopefully it will be enough to entice a few people to help.
In advance, thank you for your time and help! (looking forward to reading responses).
TextLayout && Font && Graphics2D
In question are the following classes and methods:
TextLayout
TextLayout.getAdvance()
TextLayout.getAscent()
TextLayout.draw()
Graphics2D.getFontRenderContext()
I'm not quite sure what is equivalent of TextLayout
in Android. I had read that some make a TextView
and use that, but am unsure if that will
work for the following. I'll provide some source of what I'm wanting to do and perhaps one can help me.
Java Source:
private Font myStringFont = new Font("Helvetica", Font.BOLD, 12);
private String myString = "My Test String";
private int midX = getWidth() / 2;
private int midY = getHeight() / 2;
Graphics2D g2 = new Graphics2d();
TextLayout layout = new TextLayout(myString, font, g2.getFontRenderContext());
g2.drawString(myString, midX - ((int)layout.getAdvance() /2), midY);
Android Replication Attempt:
Canvas canvas;
Paint paint;
private String myString = "My Test String";
private float midX = getWidth() / 2;
private float midY = getHeight() / 2;
//Unsure what to do about TextLayout <- this is where I need an alternative
canvas.drawText(myString, midX - /* whatever my alternative to layout.getAdvance() is */ /2), midY);
Im stuck at determining how to create a TextLayout and what to do for the method getAdvance()
. I noticed that in Paint.FontMetrics()
there are
some possible alternatives, but I don't know if any compare.
I'm also unsure how to deal with the following Java code:
Graphics2D g2 = new Graphics2d();
private int midX = getWidth() / 2;
private int midY = getHeight() / 2;
TextLayout layout = new TextLayout(myString, g2.getFont(), g2.getFontRenderContext());
layout.draw(g2, midX, MidY);
Review/Summary of Questions Above:
TextLayout
? TextLayout.getAdvance()
? (Am I able to use fontMetrics
to achieve it?)Graphics2D.getFontRenderContext()
?This is currently one of my biggest issues with porting Java over to Android. I would be greatful for any help, advice, examples, etc.
Font
Below are the methods I am wanting to replicate that deal with font
, textlayout
, and graphics2d
. The first source is the Java methods and
below it is my attempt to replicate it.
In question are the following classes and methods:
Font.deriveFont(float size)
Creates a new font objects by replicating the current font object and applying a new style to itTextLayout.getAdvance()
The advance is the distance from the origin to the advance of the rightmost (bottommost) character measuring in the line directionGraphics2D.setRenderingHint(RenderingHints, RenderingHints)
Graphics2D.getFontRenderContext()
Encapsulates application hints such as anti-aliasing and fractional metricsJava Source:
private String myString = "Print this test statement";
private int myStringFontSize = 15;
private Color myStringFontColor = Color.red;
private Font myStringFont = new Font("Helvetica", Font.BOLD, myStringFontSize);
private int midX = getWidth() / 2;
private int midY = getHeight() / 2;
public drawString(Graphics2D g2) {
g2.setFont(myStringFont.deriveFont(determineFontSize(g2, myString)));
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALISING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
TextLayout layout = new TextLayout(myString, g2.getFont(), g2.getFontRenderContext());
g2.setPaint(myStringFontColor);
g2.drawString(myString, midX - ((int) layout.getAdvance() / 2), midY);
}
protected float determinFontSize(Graphics2D g2, String myString) {
int space = getWidth();
float fontSize = 1.0f;
float finalFontSize = fontSize;
while(fontSize < 25) {
Font font myString.deriveFont(fontSize);
Textlayout layout = new TextLayout(waitingMessage, font, g2.getFontRenderContext());
if(layout.getAdvance() > space) {
finalFontSize = fontSize - 2;
break;
}
fontSize++;
}
finalFontSize = fontSize - 4;
return finalFontSize;
}
Android Attempt:
private String myString = "Print this test statement";
private int myStringFontSize = 15;
private int myStringFontColor = Color.RED; //Android uses int rather than Color
Typeface tf = new Typeface(); //Android uses Typeface rather than Font
private float midX = getWidth() / 2; //Changed to float because drawText requires float
private float midY = getHeight() / 2; //changed to float because drawText requires float
public drawString(Canvas canvas, Paint paint) {
tf.create("Helvetica", BOLD);
paint.setTypeface(tf);
paint.setTextSize((float) myStringFontSize);
paint.setTextSize(determineFontSize(canvas, myString, paint);
paint.setAntiAlias(true);
//NOT SURE WHAT TO DO WITH TextLayout YET
paint.setColor(myStringFontColor);
canvas.drawText(myString, midX - ((int)layout.getAdvance() / 2), midY, paint); //Not sure how to deal with layout.getAdvance() just yet
}
protected float determineFontSize(Canvas canvas, String myString, Paint paint) {
float fontSize = 1.0f;
float finalFontSize = fontSize;
int space = getWidth();
while(fontSize < 25) {
paint.setTextSize(fontSize);
//NOT SURE WHAT TO DO ABOUT TextLayout.getAdvance() YET or g2.getFontRenderContext()
if(layout.getAdvance() > space) {
finalFontSize = fontSize - 2;
break;
}
fontSize++;
}
finalFontSize = fontSize - 4;
return finalFontSize;
}
Final Questions About The Above Methods:
TextLayout.getAdvance()
? (Ignore if it has been answered due to the question regarding TextLayout)Graphics2D.getFontRenderContext()
?Elipse2D.Double(double x, double y, double w, double h)
Is there a way to make a subclass of oval to create something equal to Java Ellipse2D.Double? If so, how would one go about it?
ComponentAdapter && ComponentEvent
I have these in java because my component is able to be resized, in Android what are the equivalents of these for views? (if any)
The TextLayout
, Font
and Graphics2D
question can be achieved simply in Android by using a TextView
, some layout attributes in the layout xml file and possibly augmenting it with some code. To illustrate with an example, the TextView
could be declared in the layout xml as follows:
<TextView android:id="@+id/logo"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:paddingTop="5dip"
android:text="Fancy Logo"
android:textSize="24sp"
android:layout_weight="0.8"
android:textStyle="bold"
android:textColor="@color/black" />
Most of the attributes are self-explanatory, but the layout_width
hasn't been set as we'll augment the TextView
with a Font which will affect the width it takes up.
AssetManager assetManager = getContext().getAssets();
Typeface tf = Typeface.createFromAsset(assetManager,"GILB.TTF");
TextView logo = (TextView)findViewById(R.id.logo);
logo.setTypeface(tf);
The setTypeface()
method is overloaded with an additional style parameter which can also provide bold and/or italic effects.
The specific position this text is drawn on-screen will be dependent on the layout or combinations of layouts you choose e.g. RelativeLayout
, AbsoluteLayout
, etc - there are a lot of resources which can teach you how to use these to good effect.
If this is too limited, then you can draw on the Canvas directly. Here, you can specify a Paint, or TextPaint object, where you can set anti-aliasing and several other paint effects.
In place of Ellipse2D.Double
, you could use Canvas.drawOval(RectF oval, Paint paint)
where the RectF
object specifies the bounding box for the oval.
To enable views (components) to be resized automatically, you should use where possible, flexible layout attributes such as wrap_content
, match_parent
or fill_parent
rather than specific 'dip' sizes. Graphics should be converted to 9-patch formats so that they can stretch to accommodate size changes.
If you really need to calculate the length of text, or specify text size to fit a specific physical space, then you can refer to this answer on SO.
There is no exact equivalent to TextLayout but you can use FontMetrics (see the Paint) class to get the advance and ascent. To draw text, simply use a Canvas. There is no equivalent of FontRenderContext (it's not needed on Android.)
Graphics2D's rendering hints equivalents are simply properties on the Paint class. Font.deriveFont() has no equivalent, simply set the appropriate properties on Paint.
Ovals are drawn using a Canvas, there is no Oval class. You can use a Path instance to do the same thing though.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With