将 Java 类和方法移植到 Android。 (文本布局、字体、Graphics2D 等)
我一直在 Android 中尝试并尝试通过 Java 应用程序进行移植。以下是我遇到的一些问题,希望得到一些指导。
这是一个相当大的问题(而是多个问题)。然而,我并不是盲目地询问他们,因为我已经对他们进行了研究,并试图运用我的理解。我花时间提出这些问题,希望他们对我想要实现的目标有一半的了解。
我将提供一半的代表作为赏金,因为我希望得到彻底的答案和帮助,希望这足以吸引一些人提供帮助。
预先感谢您的时间和帮助! (期待阅读回复)。
TextLayout &&字体&& Graphics2D
有问题的是以下类和方法:
TextLayout
TextLayout.getAdvance()
TextLayout.getAscent()
TextLayout .draw()
Graphics2D.getFontRenderContext()
我不太确定 Android 中的 TextLayout
相当于什么。我读到有些人制作了一个 TextView 并使用它,但我不确定这是否
适用于以下内容。我将提供一些我想做的事情的来源,也许有人可以帮助我。
Java 来源:
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 复制尝试:
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);
我一直在确定如何创建 TextLayout 以及如何使用 getAdvance()
方法。我注意到在 Paint.FontMetrics()
中有
一些可能的替代方案,但我不知道是否有任何比较。
我也不确定如何处理以下 Java 代码:
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);
上述问题回顾/摘要:
- What is an Android replacement for
TextLayout
? - 什么相当于
TextLayout.getAdvance()
? (我可以使用fontMetrics
来实现它吗?) - 是否有与
Graphics2D.getFontRenderContext()
等效的 Android 功能? - 您能提供 Android 的示例源吗?
这是目前我将 Java 移植到 Android 的最大问题之一。如果您能提供任何帮助、建议、示例等,我将不胜感激。
Font
下面是我想要复制的处理 font
、textlayout
和graphics2d
。第一个来源是 Java 方法,
下面是我复制它的尝试。
有问题的是以下类和方法:
Font.deriveFont(float size)
通过复制当前字体对象并向其应用新样式来创建新的字体对象TextLayout.getAdvance()< /code> 前进是从原点到沿行方向测量的最右边(最底部)字符的前进的距离
Graphics2D.setRenderingHint(RenderingHints, RenderingHints)
Graphics2D.getFontRenderContext()
封装应用程序提示,例如抗锯齿和分数度量
Java 来源:
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 尝试:
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;
}
关于上述方法的最终问题:
- 什么我有
TextLayout.getAdvance()
的替代方案吗? (忽略是否由于有关 TextLayout 的问题而得到回答) - 对于
Graphics2D.getFontRenderContext()
我有什么替代方案? - 我的 Android 源代码是否复制了 Java 源代码?如果不是,需要改变什么?
- 有更好的方法吗?如果是这样,怎么办?
Elipse2D.Double(double x, double y, double w, double h)
有没有办法创建 oval 的子类来创建与 Java Ellipse2D.Double 相同的东西?如果是这样,人们会怎样做呢?
ComponentAdapter && ComponentEvent
我在 java 中有这些,因为我的组件可以调整大小,在 Android 中,这些视图的等价物是什么? (如果有的话)
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:
- What is an Android alternative for
TextLayout
? - What is equivalent to
TextLayout.getAdvance()
? (Am I able to usefontMetrics
to achieve it?) - Are there Android equivalents to
Graphics2D.getFontRenderContext()
? - Can you provide example source for Android?
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 metrics
Java 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:
- What alternative do I have for
TextLayout.getAdvance()
? (Ignore if it has been answered due to the question regarding TextLayout) - What alternative do I have for
Graphics2D.getFontRenderContext()
? - Does my Android source replicate the Java source? If not, what needs to be changed?
- Are there better ways of doing this? If so, how?
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)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
TextLayout
、Font
和Graphics2D
问题可以在 Android 中通过使用TextView
简单地实现,其中的一些布局属性布局 xml 文件,并可能使用一些代码对其进行扩充。为了举例说明,TextView
可以在布局 xml 中声明如下:大多数属性都是不言自明的,但
layout_width
尚未设置为我们将使用 Font 来增强TextView
,这会影响它所占用的宽度。setTypeface()
方法重载了一个额外的样式参数,该参数还可以提供粗体和/或斜体效果。该文本在屏幕上绘制的具体位置将取决于您选择的布局或布局组合,例如
RelativeLayout
、AbsoluteLayout
等 - 有很多资源可以使用可以教你如何使用这些来达到良好的效果。如果这太有限,那么你可以直接在Canvas上绘图。在这里,您可以指定 Paint 或 TextPaint 对象,您可以在其中设置抗锯齿和其他几种绘画效果。
您可以使用
Canvas.drawOval(RectF oval, Paint Paint)
代替 Ellipse2D.Double,其中RectF
对象指定椭圆形。要使视图(组件)能够自动调整大小,您应该尽可能使用灵活的布局属性,例如
wrap_content
、match_parent
或fill_parent
,而不是特定的“倾角”尺寸。图形应转换为 9 块格式,以便它们可以拉伸以适应尺寸变化。如果你确实需要计算文本的长度,或者指定文本大小以适应特定的物理空间,那么你可以参考这个答案。
The
TextLayout
,Font
andGraphics2D
question can be achieved simply in Android by using aTextView
, some layout attributes in the layout xml file and possibly augmenting it with some code. To illustrate with an example, theTextView
could be declared in the layout xml as follows:Most of the attributes are self-explanatory, but the
layout_width
hasn't been set as we'll augment theTextView
with a Font which will affect the width it takes up.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 useCanvas.drawOval(RectF oval, Paint paint)
where theRectF
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
orfill_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.
没有与 TextLayout 完全相同的东西,但您可以使用 FontMetrics(请参阅 Paint)类来获取前进和上升。要绘制文本,只需使用画布即可。没有 FontRenderContext 的等效项(Android 上不需要它。)
Graphics2D 的渲染提示等效项只是 Paint 类上的属性。
Font.deriveFont() 没有等效项,只需在 Paint 上设置适当的属性即可。
椭圆是使用 Canvas 绘制的,没有 Oval 类。不过,您可以使用 Path 实例来执行相同的操作。
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.
我想您可能正在寻找 android.text.layout
I think you might be looking for android.text.layout
这是对 John J Smith 答案的评论,但对于评论框来说太长了。
关于布局方面的 java 与 XML:Android 在这方面非常灵活,对于视图创建,它们具有相当多的功能。不过,我强烈建议您考虑至少在基本布局中使用 XML,因为在代码中执行相同的操作很容易出错并且很快就会变得冗长。您稍后可以随时获取对这些视图元素的引用,并在代码中调整它们。此外,在满足不同的外形尺寸时,Android 的一个很好的功能是您可以根据设备分辨率和像素密度指定独特的布局,并且这些布局和适当资源(例如图像)的选择是由系统。另一个好处是您将拥有类似 Spring(但更好)的布局编辑,这比将已编译的应用程序加载到设备或模拟器上进行小的更改要快得多。
This is a comment to John J Smith's answer, but it's too long for the comment box.
About java vs. XML for layouts: Android's very flexible in this regard, and for view creation they have pretty much feature parity. However, I would highly recommend you look into using XML for at least the basic layouts, as doing the same in code is error prone and gets verbose very quickly. You can always grab references to these view elements later, and adjust them in code. Also, when catering for different form-factors, a nice feature of android is that you can specify unique layouts according to the device resolution and pixel density, and the selection of these layouts and appropriate resources (such as images) is done automatically by the system. An additional benefit is you'll have Spring-like (but better) layout-editing, which is much faster for making small changes than loading a compiled application onto a device or emulator.