TableLayout で電卓を作ろう

| コメント(0)
参考書ではLinearLayoutでのボタン説明であった。ボタンが一直線に並ぶだけなので、
TableLayout に挑戦してみた。
test4.bmp
使い方は、layout の中に row を作り、その中にbutton を一列分配置し、
続いて 作りたい行列分だけ繰り返す。サンプルはforの2重ループを使った
4x4のボタン配置です。

//テーブルレイアウト
public class Test extends Activity {
    private final static int WC=TableLayout.LayoutParams.WRAP_CONTENT;
    private final static int FP=TableLayout.LayoutParams.FILL_PARENT;

    //アプリの初期化
    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        requestWindowFeature(Window.FEATURE_NO_TITLE);

        //レイアウトの生成
        TableLayout layout=new TableLayout(this);
        layout.setBackgroundColor(Color.WHITE);
        layout.setGravity(Gravity.CENTER);//中央寄せ
        setContentView(layout);
        
        for (int j=0;j<4;j++) {
            //行の生成
            TableRow row=new TableRow(this);
            row.setLayoutParams(new TableLayout.LayoutParams(FP,WC));
            row.setGravity(Gravity.CENTER);//中央寄せ
            layout.addView(row);
            
            //要素の追加
            for (int i=0;i<4;i++) {
                Button button=new Button(this);
                button.setText("("+i+","+j+")");
                row.addView(button);
            }
        }
    } 
}

しかし、これだとボタンのテキストを自由に入れられない。そこでテキストを配列で
用意し、配列の要素数だけボタンを作れるように改造した。

//テーブルレイアウト
public class Test extends Activity {
    private final static int WC=TableLayout.LayoutParams.WRAP_CONTENT;
    private final static int FP=TableLayout.LayoutParams.FILL_PARENT;

    //アプリの初期化
    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        
        String[] content={"A","N","D","R","O","I","D","!","test","Button","!"};
        
test5.bmp
        //レイアウトの生成
        TableLayout layout=new TableLayout(this);
        layout.setBackgroundColor(Color.WHITE);
        layout.setGravity(Gravity.CENTER);//中央寄せ
        setContentView(layout);
        TableRow row = null;
        
        for (int j=0;j<content.length;j++) {
            //行の生成
         if(j==0 || j%4==0) {
        row=new TableRow(this);
           row.setLayoutParams(new TableLayout.LayoutParams(FP,WC));
           row.setGravity(Gravity.CENTER);//中央寄せ
           layout.addView(row);
       }
            //要素の追加
            Button button=new Button(this);
            button.setText(content[j]);
            row.addView(button,new TableRow.LayoutParams(50, 50));
        }
   } 
}
 
%4 の4を変えると1行のボタン数が変わる。また、配列contentの要素を書きたすだけで
ボタンが簡単に変更出来る。

最後に電卓に挑戦だ! プログラムはこの下の「続きを読む」をクリック
---------------------------------------------------------------------------------------------------
//電卓が完成しましたのでUPします。
test6.bmp
ボタンの練習のついでにと思ったのですが、全てのバグ取りに
1週間もかってしまいました\(^o^)/。
17桁まで計算できます。(少数は15桁)
定数計算もできます。例)2x3=6 2=4 5=10

package net.npaka.test;

import java.text.DecimalFormat;

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.view.Window;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView.BufferType;

//テーブルレイアウト
public class Test extends Activity implements OnClickListener {
private final static int WC=TableLayout.LayoutParams.WRAP_CONTENT;
private final static int FP=TableLayout.LayoutParams.WRAP_CONTENT;
DecimalFormat df2 = new DecimalFormat("0.##################");
TableLayout layout;
String numStr="0"; //計算結果の数値を文字列として保持する
EditText disText; //電卓表示部の作成
int clacF=0; //四則計算(+ - * /) 
String keyStr = ""; //表示する数字(入力)
double total = 0; //計算結果の数値
double num2 = 0; //計算の置き数(定数計算用)    
EditText lo; //電卓表示部の作成
EditText lp; //電卓表示部の作成


//アプリの初期化
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
requestWindowFeature(Window.FEATURE_NO_TITLE);

String[] content={"√","+/-","CE","÷","7","8","9","×","4","5","6","-","1","2","3","+","0","00",".","="};
        
//レイアウトの生成
layout=new TableLayout(this);
layout.setBackgroundColor(Color.WHITE);
layout.setGravity(Gravity.CENTER);//中央寄せ
   setContentView(layout);
TableRow row=null;
disText=new EditText(this);
disText.setText(numStr, BufferType.NORMAL);
disText.setWidth(100);
  
disText.setTextSize(20.0f);
//    la.setAlignment(Alignment.ALIGN_OPPOSITE);
disText.setGravity(Gravity.LEFT);
layout.addView(disText,new LayoutParams(250, 50));

for (int i=0;i<content.length;i++) {
//行の生成
if (i==0 || i%4==0) {
row=new TableRow(this);
row.setLayoutParams(new TableLayout.LayoutParams(FP,WC));
row.setGravity(Gravity.CENTER);//中央寄せ
layout.addView(row);
}
//要素の追加
//ボタンの追加
Button button=new Button(this);
button.setText(content[i]);
// button.setId(i);
button.setOnClickListener(this);
row.addView(button,new TableRow.LayoutParams(63, 63));
}
}

public void onClick(View view) {
//クリックの処理
Button numButton = (Button)view;
String bn=(String) numButton.getText();
if ("CE".equals(bn)) {
total=0;
numStr="0";
clacF=0;
keyStr="";
num2=0;
disText.setText("0");
}
else if (".".equals(bn)) {
if ("".equals(keyStr)) { //初めてのキーが"."なら"0."に変更
keyStr="0.";
}
if (keyStr.indexOf('.') == -1) { //.の二重に入力防止
    keyStr = keyStr + ".";
}
disText.setText(keyStr);
}

else if ("+/-".equals(bn)) {
minusMethod();
}
else if ("√".equals(bn)) {
sqrtMethod();
}
else if ("+".equals(bn)) {
calcMethod();
num2=0;
clacF=1;
}
else if ("-".equals(bn)) {
calcMethod();
num2=0;
clacF=2;
}
else if ("×".equals(bn)) {
calcMethod();
num2=0;
clacF=3;
}
else if ("÷".equals(bn)) {
calcMethod();
num2=0;
clacF=4;
}
else if ("=".equals(bn)) {
if (num2!=0) {
total=num2;
}
num2=total;
equalMethod();
}
else {
keyStr = keyStr + bn; //keyStrはボタンに表記されている数字
if ("000".equals(keyStr) ) { //000の場合
keyStr = keyStr.substring(1); //先頭の0を取る
}
if(keyStr.length() == 2 && keyStr.charAt(0) == '0' && keyStr.charAt(1) != '.'){
//先頭に0の付いた数字の場合(01や02)
keyStr = keyStr.substring(1); //先頭の0を取る
}
disText.setText(keyStr); //表示
}
}
public void calcMethod() {
if ("".equals(keyStr)) return;

if (num2!=0) {
total=Double.valueOf(keyStr);
keyStr="";
return;
}
equalMethod();
}
public void equalMethod() {
if ("".equals(keyStr)) return;

Double d = Double.valueOf(keyStr); //Double型に変換する
switch(clacF){
case 1: //(+)
total = total + d.doubleValue();
break;
case 2: //(-)
total = total - d.doubleValue();
break;
case 3: //(*)
total = total * d.doubleValue();
break;
case 4: //(/)
total = total / d.doubleValue();
break;
case 5: //(√)
total = Math.sqrt(d);
break;
default: //上記以外
total = d.doubleValue();
break;
}

df2.setMaximumIntegerDigits(17);
numStr=df2.format(total);

disText.setText(numStr);
keyStr = "";
}

public void minusMethod() {
if ("0".equals(keyStr)) return;
if ("".equals(keyStr)) { //計算の実行結果がある?
if(numStr.charAt(0) == '-') {
numStr = numStr.substring(1,numStr.length()); //先頭の-記号を取る
}
else {
numStr = "-" + numStr; //先頭に-記号を付ける
}
total= Double.valueOf(numStr);
disText.setText(numStr);
}else{ //計算が実行されていない場合
if(keyStr.charAt(0) == '-') {
keyStr = keyStr.substring(1,keyStr.length());
}
else {
keyStr = "-" + keyStr;
}
disText.setText(keyStr);
}
}

public void sqrtMethod() {
if ("".equals(keyStr)) { //計算の実行結果がある?
if (Double.valueOf(numStr)<0) return; //マイナスの√は実行しない }
numStr=Double.toString(Math.sqrt(Double.valueOf(numStr)));
total= Double.valueOf(numStr);
numStr=df2.format(total);

disText.setText(numStr);
}else{ //計算が実行されていない場合
if (Double.valueOf(keyStr)<0) return; //マイナスの√は実行しない }

keyStr=Double.toString(Math.sqrt(Double.valueOf(keyStr)));
keyStr=df2.format(Double.valueOf(keyStr));
disText.setText(keyStr);
}
}
}



現在、さらにデザインを改良予定。そのうち発表できればと思っております。
バグなどありましたらコメントを入れてください。

<<神戸でHP作成&個人レッスンなら http://petafield.com まで>>

コメントする