Android アプリ開発 「MATRIX」

Androidアプリの開発に役立つサンプル集

タイマーを使ってテキストビューの文字サイズを連続変更してみよう

今回は、タイマーを使ってテキストビューの文字サイズを連続変更する方法です。

画面のレイアウトは「activity_main.xmlに、制御プログラムは「MainActivity.javaに書かれています。 タイマー処理は別スレッドになるためタイマー処理の内部からメインUIスレッドにアクセスるには「Handler」が必要になります。

「Handler」を通さずにテキストビューなどにアクセスるとエラーでプログラムが停止してしまうので注意してください。

サンプルコード(MainActivity.java

public class MainActivity extends Activity {

private Timer timer;
private Tasks tasks;
private Handler handler = new Handler();
private TextView textView;
private int x;
private Button button;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

//レイアウトファイルのテキストビューと連結
textView = (TextView)findViewById(R.id.textView);
//レイアウトファイルのボタンと連結
button = (Button)findViewById(R.id.button);

//ボタンにクリックリスナーをセット
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {

//テキストサイズを「0」に設定
x = 0;
//テキストビューにテキストサイズをセット
textView.setTextSize(x);
//タイマーを準備
timer = new Timer();
//タイマー処理を準備
tasks = new Tasks();
//スケジュールを設定してタイマーを作動
timer.schedule(tasks, 1000, 10);
}
});
}

//タイマー作動時の処理
public class Tasks extends TimerTask {

@Override
public void run() {
//ハンドラーを経由してメインUIスレッドにアクセスする
handler.post(new Runnable() {
@Override
public void run() {
//テキストサイズに+1
x += 1;
//テキストビューにテキストサイズをセット
textView.setTextSize(x);
//テキストサイズが55を超えたらタイマーを停止
if(x > 55){
timer.cancel();
}
}
});
}
}
}

レイアウトファイル(activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.android.myhandler.MainActivity">

<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginTop="8dp"
android:text="Hello World!"
android:textAllCaps="false"
android:textColor="@color/colorAccent"
android:textSize="0sp"
android:textStyle="bold|italic"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:text="スタート"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />

</android.support.constraint.ConstraintLayout>

結果

「スタート」ボタンを押すと・・・

f:id:vw-dsg:20170607212624p:plain

 

画面の中央から「Hello World!」がズームインで表示されます。

f:id:vw-dsg:20170607212639p:plain

 

END

簡単にタッチパネルのイベントを検出する方法

今回は簡単にタッチパネルのイベントを検出する方法です。タッチイベントの検出はとても簡単で、プログラムの中で「onTouchEvent」メソッドをオーバーライドするだけです。 

サンプルコード(MainActivity.java

public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}

@Override
public boolean onTouchEvent(MotionEvent event) {

//タッチイベントを検出してトーストを表示
Toast.makeText(getBaseContext(), "タッチ検出", Toast.LENGTH_SHORT).show();

return super.onTouchEvent(event);
}
}

 

結果

タッチパネルに触れるとトーストで「タッチ検出」というメッセージが表示されます。

f:id:vw-dsg:20170606210449p:plain

おまけコーナー

MainActivity の extendsを「AppCompatActivity」を「Activity」に変えるとタイトルバーが表示されなくなります。

END

ビットマップ画像をそのままのサイズで画面に出力する方法

今回はビットマップ画像をそのままのサイズで画面に出力する方法です。

ビットマップ画像を画面に出力するとサイズが自動で変更されてしまい調整に苦労する場合があります。そんな時は、BitmapFactoryのオプションで自動的なサイズ変更処理をカットしてしまいましょう。

ソースコード(MainActivity.java

public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

//下記のMyViewクラスを登録して画面に出力する
setContentView(new MyView(getBaseContext()));
}

//このビュークラスで画面を生成
public class MyView extends View{

//画像を表示するためのビットマップオブジェクトを用意
private Bitmap bitmap;
//画面に描画するためのペイントオブジェクトを用意
private Paint paint = new Paint();
//読み込んだビットマップ画像に適用するオプションを用意
private BitmapFactory.Options options = new BitmapFactory.Options();

public MyView(Context context) {
super(context);
}

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);

//ビットマップのオプションで画像を拡大縮小なしで出力するように設定
options.inScaled = false;
//ビットマップオブジェクトに画像ファイルをセットして、オプションを適用
bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.nodoguro, options);
//座標0,0の位置にビットマップ画面に出力する
canvas.drawBitmap(bitmap, 0, 0, paint);
}
}
}

結果サンプル

オプションを適用しているため画像は拡大されることなく、そのままのサイズ(500px X 500px)で表示されました。

f:id:vw-dsg:20170605211921p:plain

 

オプションを指定しないとこのサンプルのように自動的に巨大化してしまい苦労します。画像をそのままのサイズで出力したいときはオプションを指定しましょう。

f:id:vw-dsg:20170605213344p:plain

 

END

 

Viewクラスで画面(canvas)に複数の円を描く方法

 Viewクラスで画面(canvas)に複数の円を描く方法です。円はプログラムで生成されたViewのcanvasにdrawCircleで直接に描かれる仕組みです。

MainActivity.java

起動直後にこのMainActivity.javaが実行される。今回はレイアウトファイル(*****.xml)ではなく「MyView.java」を呼び出して、その内部で画面を構成し描画している。

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new MyView(getBaseContext()));
}
}

MyView.java

円の描画を行っているのはこのMyView.javaの中のMyViewクラスである。

public class MyView extends View {

//変数を用意
private int x,y,z;

//コンストラクタ
public MyView(Context context) {
super(context);
setBackgroundColor(Color.BLACK);
}

//描画時に自動で呼ばれる関数
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);

//ペイントを生成
Paint paint = new Paint();

//for9回繰り返す
for(int i = 1; i < 10; i++) {

//座標x,y、円の大きさ設定
x = i * 100;
y = i * 100;
z = i + 50;

//塗りの色を赤に設定
paint.setColor(Color.RED);
//座標x,yの位置にzの大きさの円を描画
canvas.drawCircle(x, y, z, paint);
}
}
}

実行結果

赤い円が9つ描画された。

f:id:vw-dsg:20170604162831p:plain

 

END

 

LEDライトを点灯させる方法(Android 6 以降)

LEDライトを点灯させる方法(Android 6~の場合)です。APIでいうと23以降で使用きる方法です。それ以前の端末には対応していませんのでご注意ください。

画面中央に配置したボタンを押すと点灯と消灯が切り替わる仕組みになっています。

 

プログラムコード(MainActivity.java

import android.content.Context;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraManager;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {

private Button Mbutton;
private CameraManager McameraManager;
private String McameraID;
private boolean SW;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

//レイアウトファイルのボタンを登録
Mbutton = (Button)findViewById(R.id.button);
//カメラマネージャーを生成
McameraManager = (CameraManager)getSystemService(Context.CAMERA_SERVICE);

//カメラマネージャーにトーチモードのコールバックを登録
McameraManager.registerTorchCallback(new CameraManager.TorchCallback() {
//トーチモードが変更された時の処理
@Override
public void onTorchModeChanged(@NonNull String cameraId, boolean enabled) {
super.onTorchModeChanged(cameraId, enabled);
//カメラIDをセット
McameraID = cameraId;
//SWに現在の状態をセット
SW = enabled;
}
}, new Handler());

Mbutton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//カメラを取得できなかった時は何もしない
if(McameraID == null){
return;
}
try {
if(SW == false){
//SWfalseならばトーチモードをtrueにしてLDEオン
McameraManager.setTorchMode(McameraID, true);
}else{
McameraManager.setTorchMode(McameraID, false);
//SWtrueならばトーチモードをfalseにしてLDEオフ
}

} catch (CameraAccessException e) {
//エラー処理
e.printStackTrace();
}
}
});
}
}

 

画面レイアウト(activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.android.newlight.MainActivity">

<Button
android:id="@+id/button"
android:layout_width="200dp"
android:layout_height="100dp"
android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginTop="8dp"
android:text="Button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>

 

結果

f:id:vw-dsg:20170604093431p:plain

ボタン(button)はトグルスイッチになっていて、押すごとにLEDのオンとオフが切り替わります。

END

Andoroid Javaの基本データ型のまとめ

Andoroid Javaの基本データ型のまとめ。

整数型

byte ・・・ - 128 ~ 127
short ・・・ - 32768 ~ 32767
int ・・・ - 2147483648 ~ 2147483647
long ・・・ - 9223372036854775808 ~ 9223372036854775807

例)
int a;
a = 10000;
int b = 20000;

浮動小数点型

float ・・・ 4バイト
double ・・・ 8バイト

例)
float f1 = 1.23f;
double = 5.67d;

char型

char ・・・ 任意の1文字を格納

例)
char ch = '夏';

boolean型

boolean ・・・ true または false

例)
boolean neko;
neko = true;

 

END

数値を文字列に変換して一文字ずつ配列に格納する方法

数値を文字列に変換して一文字ずつ配列に格納する方法です。

ポイントは「split」関数の区切り文字を「""」(空)にするところです。こうすると文字列を一文字ずつ分解してくれます。それと同時に、分解した文字をそのまま配列変数に格納しています。

<サンプルコード> 

public class MainActivity extends AppCompatActivity {

private int kazu_int; //数値の変数を準備
private String kazu_string; //文字変数を準備
private String array_kazu[]; //配列変数を準備
private TextView textView; //表示用テキストビューを準備

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

//テキストビューにレイアウトファイルのテキストビューを連結
textView = (TextView)findViewById(R.id.textView1);

//数値「12345」を準備
kazu_int = 12345;
//数値を文字列に変換して文字変数に代入
kazu_string = String.valueOf(kazu_int);
//文字列を一文字ずつ分解して配列変数に格納
array_kazu = kazu_string.split("");

for(int i = 1; i < array_kazu.length; i++) {
//配列から一つずつ文字を取り出してテキストビューにセット
textView.setText(textView.getText() + array_kazu[i]);
}
}
}

※配列変数.lengthは、配列変数のデータ数を返してくれる関数です。 

<結果>

数値変数(int)に入っていた「12345」が配列に格納された後、ディスプレイ画面に正しく表示されました。

f:id:vw-dsg:20170530213227p:plain

重要ポイント

最後に重要なポイントをもう一つ。「split」関数で文字列を分解すると一文字ずつ配列変数に格納することができますが、なぜか先頭の配列変数には空のデータ(””)が自動的に挿入されるので注意が必要ですね。

例)文字列「ABDCE」をsplit関数で分解してそれと同時にa[]という配列変数に格納すると結果は・・・

 a[0] = ""
 a[1] = "A"
 a[2] = "B"
 a[3] = "C"
 a[4] = "D"
 a[5] = "E"

となります。

なので、split関数で配列に格納した場合は、必ず二つ目の配列(上の場合はa[1])から参照するようにしてください。

 

END