Освой программирование играючи
/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000
Создадим новый компонент на основе TextView, который будет выводить текст вертикально.
Сначала создадим стили для будущего вертикального текста:
<?xml version="1.0" encoding="utf-8"?>
<resources
xmlns:android="http://schemas.android.com/apk/res/android">
<style name="verticalTextStyle"
parent="android:Widget.TextView">
<item name="android:padding">20dp</item>
<item name="android:textSize">20sp</item>
</style>
</resources>
Также создайте строковый ресурс в файле res/values/strings.xml:
<string name="vtext">Вертикальный текст</string>
Далее напишем отдельный класс для нового компонента. В старом варианте, который писался несколько лет назад, я использовал TextView, но сейчас студия стала советовать использовать AppCompatTextView и я согласился:
package ru.alexanderklimov.verticaltext;
import android.content.Context;
import android.graphics.Canvas;
import android.support.annotation.Nullable;
import android.support.v7.widget.AppCompatTextView;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.view.Gravity;
public class VerticalTextView extends AppCompatTextView {
final boolean topDown;
TextPaint textPaint = getPaint();
public VerticalTextView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
final int gravity = getGravity();
if (Gravity.isVertical(gravity)
&& (gravity & Gravity.VERTICAL_GRAVITY_MASK) == Gravity.BOTTOM) {
setGravity((gravity & Gravity.HORIZONTAL_GRAVITY_MASK)
| Gravity.TOP);
topDown = false;
} else {
topDown = true;
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth());
}
@Override
protected void onDraw(Canvas canvas) {
textPaint.setColor(getCurrentTextColor());
textPaint.drawableState = getDrawableState();
canvas.save();
if (topDown) {
canvas.translate(getWidth(), 0);
canvas.rotate(90);
} else {
canvas.translate(0, getHeight());
canvas.rotate(-90);
}
canvas.translate(getCompoundPaddingLeft(), getExtendedPaddingTop());
getLayout().draw(canvas);
canvas.restore();
}
}
Чтобы добавить компонент в режиме дизайна, выбираем Advanced и переносим на форму элемент <view>, откроется диалоговое окно, в котором нужно найти свой класс. В таком варианте компонент будет представлен следующим образом.
<view
android:id="@+id/verticalTextView2"
style="@style/verticalTextStyle"
class="ru.alexanderklimov.helloworld.VerticalTextView"
... />
Можно использовать другой привычный формат. Чтобы менять направление текста, поиграйтесь с атрибутом android:gravity:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<ru.alexanderklimov.verticaltext.VerticalTextView
android:id="@+id/verticalTextView1"
style="@style/verticalTextStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/vtext" />
<ru.alexanderklimov.verticaltext.VerticalTextView
android:id="@+id/verticalTextView2"
style="@style/verticalTextStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="bottom|right"
android:text="@string/vtext" />
</LinearLayout>
Пример может послужить отправной точкой для дальнейшего улучшения.
Для развлечения напишем новый компонент, который будет выводить текст под разными углами, образуя солнышко.
package ru.alexanderklimov.custom;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.support.v7.widget.AppCompatTextView;
import android.text.TextPaint;
import android.util.AttributeSet;
public class RotateTextView extends AppCompatTextView {
private TextPaint mPaint = getPaint();
public RotateTextView(Context context) {
super(context);
init();
}
public RotateTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public RotateTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int viewWidth = getWidth();
int viewHeight = getHeight();
canvas.translate(viewWidth / 2, viewHeight / 2);
for (int i = 0; i < 10; i++) {
String message = "Котик";
canvas.drawText(message, 30, 0, mPaint);
canvas.rotate(36);
}
}
private void init(){
mPaint.setColor(Color.BLUE);
mPaint.setTextSize(50);
mPaint.setAntiAlias(true);
}
}
Размещаем:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ru.alexanderklimov.custom.RotateTextView
android:id="@+id/rotateTextView1"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>