Портирование Java-класса и методов на Android. (TextLayout, Font, Graphics2D и другие) - PullRequest
8 голосов
/ 26 июля 2011

Я играю в Android и пытаюсь портировать через приложение Java. Ниже приведены некоторые вопросы, касающиеся проблем, с которыми я столкнулся и хотел бы получить некоторые рекомендации.

Это довольно большой вопрос (скорее, несколько вопросов). Тем не менее, я не спрашиваю их вслепую, так как я исследовал все, что мог о них, и попытался использовать свое понимание. Я потратил время на то, чтобы задавать вопросы в надежде, что они наполовину ясно знают, чего я хочу достичь.

Я буду предлагать половину своего представителя в качестве награды, так как я надеюсь на исчерпывающие ответы и помощь, надеюсь, этого будет достаточно, чтобы соблазнить несколько человек помочь.

Заранее спасибо за ваше время и помощь! (с нетерпением жду чтения ответов).

TextLayout && Font && Graphics2D

Речь идет о следующих классах и методах:

  • TextLayout
  • TextLayout.getAdvance()
  • TextLayout.getAscent()
  • TextLayout.draw()
  • Graphics2D.getFontRenderContext()

Я не совсем уверен, что эквивалентно TextLayout в Android. Я читал, что некоторые делают 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);

Обзор / Сводка вопросов выше:

  • Что такое альтернатива Android для TextLayout?
  • Что эквивалентно TextLayout.getAdvance()? (Могу ли я использовать fontMetrics для достижения этого?)
  • Есть ли в Android эквиваленты Graphics2D.getFontRenderContext()?
  • Можете ли вы привести пример исходного кода для Android?

В настоящее время это одна из моих самых больших проблем с переносом Java на Android. Буду признателен за любую помощь, советы, примеры и т. Д.

шрифт

Ниже приведены методы, которые я хочу воспроизвести, которые относятся к font, textlayout и graphics2d. Первым источником являются методы 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 && ComponentEvent

У меня это есть в java, потому что мой компонент может быть изменен в Android, каковы их эквиваленты для представлений? (если есть)

Ответы [ 4 ]

2 голосов
/ 28 июля 2011

Вопрос TextLayout, Font и Graphics2D может быть достигнут просто в Android с помощью TextView, некоторых атрибутов макета в XML-файле макета и, возможно, дополнения его некоторым кодом. Чтобы проиллюстрировать это на примере, TextView может быть объявлено в макете XML следующим образом:

<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 не был установлен, так как мы увеличим TextView шрифтом, который будет влиять на ширину, которую он занимает.

AssetManager assetManager = getContext().getAssets();       

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

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

Метод setTypeface() перегружен дополнительным параметром стиля, который также может обеспечивать эффекты, выделенные жирным шрифтом и / или курсивом.

Конкретное положение этого текста на экране будет зависеть от макета или комбинаций макетов, которые вы выберете, например. RelativeLayout, AbsoluteLayout и т. Д. - существует множество ресурсов, которые могут научить вас, как эффективно использовать их.

Если это слишком ограничено, вы можете рисовать на холсте напрямую. Здесь вы можете указать объект Paint или TextPaint, в котором можно установить сглаживание и несколько других эффектов рисования.

Вместо Ellipse2D.Double вы можете использовать Canvas.drawOval(RectF oval, Paint paint), где объект RectF определяет ограничивающую рамку для овала.

Чтобы разрешить автоматическое изменение размеров видов (компонентов), вы должны использовать, где это возможно, гибкие атрибуты макета, такие как wrap_content, match_parent или fill_parent, а не определенные размеры 'dip'. Графика должна быть преобразована в форматы с 9 патчами, чтобы они могли растягиваться, чтобы соответствовать изменениям размера.

Если вам действительно нужно рассчитать длину текста или указать размер текста для соответствия определенному физическому пространству, тогда вы можете обратиться к этому ответу на SO.

2 голосов
/ 28 июля 2011

Нет точного эквивалента TextLayout, но вы можете использовать класс FontMetrics (см. Рисование), чтобы получить продвижение и подъем.Чтобы нарисовать текст, просто используйте Canvas.Не существует эквивалента FontRenderContext (он не нужен в Android.)

Эквивалентные подсказки отрисовки Graphics2D - это просто свойства класса Paint.Font.deriveFont () не имеет эквивалента, просто установите соответствующие свойства в Paint.

Овалы нарисованы с использованием Canvas, класс Oval отсутствует.Вы можете использовать экземпляр Path, чтобы сделать то же самое.

1 голос
/ 01 августа 2011

Это комментарий к ответу Джона Дж. Смита, но он слишком длинный для поля комментария.

О java против XML для макетов: Android очень гибок в этом отношении, и для создания представлений у них есть в значительной степени четность функций. Тем не менее, я бы очень рекомендовал бы вам использовать XML как минимум для базовых макетов, так как выполнение этого кода в коде подвержено ошибкам и очень быстро становится многословным. Вы всегда можете получить ссылки на эти элементы представления позже и настроить их в коде. Кроме того, при работе с различными форм-факторами приятной особенностью Android является то, что вы можете указать уникальные макеты в соответствии с разрешением устройства и плотностью пикселей, и выбор этих макетов и соответствующих ресурсов (таких как изображения) выполняется автоматически система. Дополнительным преимуществом является то, что у вас будет Spring-like (но лучше) редактирование макета, которое намного быстрее вносит небольшие изменения, чем загрузка скомпилированного приложения на устройство или эмулятор.

1 голос
/ 28 июля 2011

Я думаю, что вы можете искать android.text.layout

...