将Java类和方法移植到Android。 (TextLayout,Font,Graphics2D,以及更多)

时间:2011-07-25 21:02:35

标签: java android text porting 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);

上述问题的回顾/总结:

  • 什么是TextLayout的Android替代品?
  • 相当于TextLayout.getAdvance()的是什么? (我可以使用fontMetrics来实现它吗?)
  • 是否有Graphics2D.getFontRenderContext()的Android等价物?
  • 您能为Android提供示例来源吗?

目前,这是将Java移植到Android的最大问题之一。我会非常感谢任何帮助,建议,例子等。

字体

以下是我希望复制与fonttextlayoutgraphics2d交易的方法。第一个来源是Java方法和

下面是我尝试复制它。

有问题的是以下类和方法:

  • Font.deriveFont(float size)通过复制当前字体对象并对其应用新样式来创建新的字体对象
  • TextLayout.getAdvance()前进是从原点到最右边(最下面)字符在行方向上测量的前进距离
  • 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(双x,双y,双w,双h)

有没有办法让一个椭圆子类创建一个与Java Ellipse2D.Double相等的东西?如果是这样,怎么会这样呢?

ComponentAdapter&amp;&amp; ComponentEvent

我在java中有这些因为我的组件能够调整大小,在Android中这些视图的等价物是什么? (如果有的话)

4 个答案:

答案 0 :(得分:2)

没有与TextLayout完全等效,但您可以使用FontMetrics(请参阅Paint)类来获取提升和上升。要绘制文本,只需使用Canvas即可。没有相当于FontRenderContext(在Android上不需要它。)

Graphics2D的渲染提示等价物只是Paint类的属性。 Font.deriveFont()没有等价物,只需在Paint上设置适当的属性。

使用Canvas绘制椭圆,没有Oval类。您可以使用Path实例执行相同的操作。

答案 1 :(得分:2)

TextLayoutFontGraphics2D问题只需在Android中通过使用TextView,布局xml文件中的一些布局属性以及可能使用一些代码。为了举例说明,可以在布局xml中声明TextView,如下所示:

<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" />

大多数属性都是不言自明的,但layout_width尚未设置,因为我们会使用Font来扩充TextView,这将影响它占用的宽度。

AssetManager assetManager = getContext().getAssets();       

Typeface tf = Typeface.createFromAsset(assetManager,"GILB.TTF");                

TextView logo = (TextView)findViewById(R.id.logo);
logo.setTypeface(tf);

setTypeface()方法重载了一个额外的样式参数,该参数也可以提供粗体和/或斜体效果。

此文字在屏幕上绘制的具体位置取决于您选择的布局或布局组合,例如RelativeLayoutAbsoluteLayout等 - 有很多资源可以教你如何使用这些资源以达到良好效果。

如果这个太有限,那么你可以直接在Canvas上画画。在这里,您可以指定Paint或TextPaint对象,您可以在其中设置消除锯齿和其他一些绘画效果。

代替Ellipse2D.Double,您可以使用Canvas.drawOval(RectF oval, Paint paint) RectF对象指定椭圆的边界框。

要自动调整视图(组件)的大小,您应尽可能使用灵活的布局属性,例如wrap_contentmatch_parentfill_parent,而不是特定的“dip”大小。图形应转换为9补丁格式,以便它们可以拉伸以适应尺寸变化。

如果您确实需要计算文字的长度,或指定文字大小以适合特定的物理空间,那么您可以在SO上参考this答案。

答案 2 :(得分:1)

我想你可能在寻找android.text.layout

答案 3 :(得分:1)

这是对John J Smith的答案的评论,但对评论框来说太长了。

关于java与XML for layouts:Android在这方面非常灵活,对于视图创建,它们具有相当多的功能奇偶校验。但是,我高度建议你至少考虑使用XML作为基本布局,因为在代码中做同样的事情是容易出错并且很快就会变得冗长。您可以随时获取对这些视图元素的引用,并在代码中进行调整。此外,当迎合不同的外形时,android的一个很好的功能是你可以根据设备分辨率和像素密度指定独特的布局,这些布局和适当的资源(如图像)的选择是由自动完成的。系统。另外一个好处是你将拥有类似Spring(但更好)的布局编辑,这比进行小的更改要快于将已编译的应用程序加载到设备或模拟器上。