概要
❶
の様に「塗りつぶした円の中央に数字を表示したい」という発注が来たので実現する方法について調査してみました
Shape Drawable を使用してみる
TextView の background に android:shape="oval"
と android:shape="ring"
の Shape Drawable を指定する方法を試してみます。
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="@android:color/holo_blue_bright" />
</shape>
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="ring"
android:useLevel="false">
<solid android:color="@android:color/holo_blue_bright" />
</shape>
<?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="wrap_content"
android:orientation="horizontal">
<android.support.v4.widget.Space
android:layout_width="10dp"
android:layout_height="10dp" />
<android.support.v7.widget.AppCompatTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/oval_background"
android:gravity="center"
android:padding="4dp"
android:text="め"
android:textColor="@android:color/black" />
<android.support.v4.widget.Space
android:layout_width="10dp"
android:layout_height="10dp" />
<android.support.v7.widget.AppCompatTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/ring_background"
android:gravity="center"
android:padding="4dp"
android:text="組"
android:textColor="@android:color/black" />
</LinearLayout>
package jp.co.package.example;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
/**
* 円の中に文字を表示する TextView のサンプル
*/
public class CircleTextViewActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_circle_textview);
}
}
結果
-
android:shape="oval"
の場合は塗りつぶしとpadding
の反映はされますが、サイズをwrap_content
にしていると円ではなく楕円形になってしまいます。 -
android:shape="ring"
の場合は文字通り輪にはなりますが、中を塗りつぶすことはできませんでした。また上記の書き方ではpadding
を反映することができませんでした
EqualWidthHeightTextView を試してみる
Stack Overflow の回答から引用してプロジェクト内にコピーしてみます。
※ テキストが 10
未満のときに android:gravity="center"
で中央寄せにする場合は android:inputType="number"
を追加する必要があります
※ EqualWidthHeightTextView というクラス名ですが、SquareTextView という名前にしてもよいのではないかと思ったりします
結果
円の中に文字列を表示することができました (画像は省略)。
CircularTextView を試してみる
Stack Overflow の回答から引用してプロジェクト内にコピーしてみます。
<?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="vertical">
<jp.co.package.example.CircularTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="4dp"
android:text="俺"
android:textColor="@android:color/white" />
<!-- 省略 -->
</LinearLayout>
結果
android:layout_width="wrap_content"
と
android:layout_height="wrap_content"
にした状態で、円の中に文字を表示することができました
しかし稀に円の描画が若干遅れるのが気になる……
付加価値
circularTextView.setStrokeWidth(2);
circularTextView.setStrokeColor("#da721c");
とすることで Stroke の設定も可能です
デメリット
遭遇した事例としては Android 7.0 (Nougat) の端末で 設定 > [高コントラストフォント] を ON にすると CircularTextView が膨張するという事案が発生しました
まとめ
個人的には EqualWidthHeightTextView の使用をお勧めします