【Android開発】JavaでXMLと同様の実装を行う~TextView編~

先日「こづかい帳」の開発を進める中で、文字列を等幅フォントにする為にJava内で設定を行ったのですが、調べてみるとXML(layoutファイル)でも出来るようです。
今までJava側とXML側の使い分けについて考慮したことが無かったので、知識が非常に曖昧な状況です。
そこで勉強がてら、普段XMLのレイアウトファイルに定義している内容をJavaのみで再現してみることにしました。

本対応の目的

今回はTextViewを対象に、XMLのlayoutファイルで定義した場合と全く同じ表現をJavaのみで実装します。

各種プロパティは、私が開発時に良く使うものを中心にピックアップしています。

下記の通り、全く同様に実装することができました。

TextView_Javaのみ
Javaのみで実装
TextView_XML利用
XMLを利用して実装

layoutの準備

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

    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="@dimen/dp_m"
        android:layout_weight="3"
        android:background="@android:color/background_dark"
        android:gravity="bottom|center"
        android:padding="@dimen/dp_m"
        android:text="@string/text1"
        android:textColor="@android:color/white"
        android:textSize="@dimen/sp_l" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="@dimen/dp_m"
        android:layout_weight="2"
        android:background="@android:color/darker_gray"
        android:gravity="top|center"
        android:padding="@dimen/dp_m"
        android:text="@string/text2"
        android:textColor="@android:color/black"
        android:textSize="@dimen/sp_l"
        android:textStyle="bold|italic"
        android:typeface="monospace" />
</LinearLayout>

XMLを利用して実装する画面で指定するlayoutファイルです。

menuの準備

Javaのみの画面、XMLを利用した画面を切り替えるボタンを表示する為に使用します。

valuesの準備

<resources>
    <!-- 文字サイズ(小) -->
    <dimen name="sp_s">16sp</dimen>
    <!-- 文字サイズ(中) -->
    <dimen name="sp_m">20sp</dimen>
    <!-- 文字サイズ(大) -->
    <dimen name="sp_l">24sp</dimen>
    <!-- 余白などのサイズ(小) -->
    <dimen name="dp_s">1dp</dimen>
    <!-- 余白などのサイズ(中) -->
    <dimen name="dp_m">4dp</dimen>
    <!-- 余白などのサイズ(大) -->
    <dimen name="dp_l">8dp</dimen>
</resources>

文字サイズと余白のサイズを定義するファイルです。

<resources>
    <string name="app_name">Sample</string>
    <string name="title_java">Javaのみで表示</string>
    <string name="title_xml">xmlメインで表示</string>
    <string name="text1">(+)通常フォント・通常スタイル</string>
    <string name="text2">(-)等幅フォント・BOLD&ITALIC</string>
</resources>

文字列を定義するファイルです。

<resources>
    <!-- Base application theme. -->
    <style name="AppTheme" parent="android:Theme.Light">
    </style>
</resources>

メニューが有効になるテーマを指定しています。

Java側の記載

package jp.co.skys.android.sample;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Typeface;
import android.os.Bundle;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.ViewGroup.LayoutParams;
import android.view.Window;
import android.widget.LinearLayout;
import android.widget.TextView;

public class TextViewJavaSample extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().requestFeature(Window.FEATURE_ACTION_BAR);

        LinearLayout ll = new LinearLayout(this);
        ll.setOrientation(LinearLayout.VERTICAL);
        setContentView(ll);

        //dimens.xmlから余白用サイズを取得
        int dp_m = (int) getResources().getDimension(R.dimen.dp_m);

        //TextViewを2つ用意
        TextView tv1 = new TextView(this);
        TextView tv2 = new TextView(this);

        //layout_width、layout_height相当の設定(パラメータはwidth、heightの順番)
        LinearLayout.LayoutParams lp1 = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
        LinearLayout.LayoutParams lp2 = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);

        //layout_margin相当の設定(TextView外部の余白部分)
        lp1.setMargins(dp_m, dp_m, dp_m, dp_m); //左、上、右、下の順
        tv1.setLayoutParams(lp1);
        lp2.setMargins(dp_m, dp_m, dp_m, dp_m); //左、上、右、下の順
        tv2.setLayoutParams(lp2);

        //layout_weight相当の設定
        lp1.weight = 3;
        lp2.weight = 2;

        //background相当の設定
        tv1.setBackgroundColor(getResources().getColor(android.R.color.background_dark));
        tv2.setBackgroundColor(getResources().getColor(android.R.color.darker_gray));

        //gravity相当の設定(「LEFT、CENTER、RIGHT、TOP、BOTTOM」を組み合わせる)
        tv1.setGravity(Gravity.BOTTOM | Gravity.CENTER);
        tv2.setGravity(Gravity.TOP|Gravity.CENTER);

        //padding相当の設定(TextView内部の余白部分)
        tv1.setPadding(dp_m, dp_m, dp_m, dp_m);//左、上、右、下の順
        tv2.setPadding(dp_m, dp_m, dp_m, dp_m);//左、上、右、下の順

        //text相当の設定(Strings.xmlから取得)
        tv1.setText(getResources().getString(R.string.text1));
        tv2.setText(getResources().getString(R.string.text2));

        //textColor相当の設定
        tv1.setTextColor(getResources().getColor(android.R.color.white));
        tv2.setTextColor(getResources().getColor(android.R.color.black));

        //textSize相当の設定(dimens.xmlから取得)
        tv1.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimension(R.dimen.sp_l));
        tv2.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimension(R.dimen.sp_l));

        //textStyle、typeface相当の設定(パラメータはtypeface、textStyleの順番)
        //typefaceは「null」か「SANS(ゴシック)、SERIF(明朝)、MONOSPACE(等幅)」から選択
        //textStyleは「NORMAL、BOLD、ITALIC、BOLD_ITALIC」から選択
        tv1.setTypeface(null, Typeface.NORMAL);
        tv2.setTypeface(Typeface.MONOSPACE, Typeface.BOLD_ITALIC);

        //LinearLayoutにセット
        ll.addView(tv1, lp1);
        ll.addView(tv2, lp2);
    }

    // メニューの紐づけ
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu, menu);
        return true;
    }

    // メニュー押下時の挙動
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int itemId = item.getItemId();
        if (itemId == R.id.menu) {
            Intent intent = new Intent();
            intent.setClassName(getPackageName(), getPackageName() + ".TextViewXmlSample");
            startActivity(intent);
        }
        return true;
    }
}

JavaのみでTextViewの表示を行っています。詳細はコメント分を参照ください。

package jp.co.skys.android.sample;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.Window;

public class TextViewXmlSample extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
        setContentView(R.layout.layout);
    }

    // メニューの紐づけ
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu, menu);
        return true;
    }

    // メニュー押下時の挙動
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int itemId = item.getItemId();
        if (itemId == R.id.menu) {
            Intent intent = new Intent();
            intent.setClassName(getPackageName(), getPackageName() + ".TextViewJavaSample");
            startActivity(intent);
        }
        return true;
    }
}

XMLのlayoutファイルを読み込んでいます。

最後に

上記一式含まれるファイルを下記よりダウンロードできます。

TextViewSample.zip

自分の勉強のためにまとめましたが、ご参考になれば幸いです。

サブコンテンツ

このページの先頭へ