Cấp bậc tác giả:

JAVA

Tạo Caculator Pro

Được viết bởi QuangIT ngày 23/09/2012 lúc 03:37 PM
Đầu tiên hãy xem tổng quan giao diện mà chúng ta sẽ cùng nhau thiết kế. Các bộ phận được đánh số để bạn có thể dễ dàng quan sát cũng như màu sắc để nhận diện
  • 0
  • 8748

Tạo Caculator Pro

Đầu tiên hãy xem tổng quan giao diện mà chúng ta sẽ cùng nhau thiết kế. Các bộ phận được đánh số để bạn có thể dễ dàng quan sát cũng như màu sắc để nhận diện


Từng khu vực:

1. Hiển thị toàn bộ các số người dùng đã nhập trước đó và đang chờ tính toán cho đến khi người nhập nhấp vào nút C để xóa

2. Khi người dùng nhập số, kết quả của bộ đệm sẽ được hiển thị

3. Giá trị bộ nhớ đệm sẽ được hiển thị ở vùng này

4. Nút tổ chức bộ nhớ đệm

5. Các nút khác

6. Nút để kích hoạt và hiển thị kết quả

7. Nút tính toán + - * /

8. Phím số

9. Trở về


Các trường hợp sử dụng TouchCalculator

Máy tính của chúng ta hỗ trợ các trường hợp sử dụng sau đây:


Máy tính được khởi tạo với giá trị đầu vào từ 0 và ngay sau khi người dùng bắt đầu nhấn nút bàn phím số.

Người dùng sẽ bấm nút bàn phím số và chúng ta sẽ nối thêm mỗi giá trị số đến giá trị hiện tại khu vực # 2

Nếu người dùng nhấn nút dấu phân cách số thập phân được đặt ở Khu vực 5, chúng tôi sẽ nối thêm các dấu phân cách giá trị hiện tại của khu vực # 2

Khi người dùng nhấn một nút toán tử số học được đặt trong Khu vực 7, chúng tôi sẽ hiển thị nội dung bộ đệm đầu vào trong khu vực # 1. Nếu đầu vào bộ đệm có đầu vào, đủ để tính toán một kết quả, chúng ta cũng phải tính toán kết quả và hiển thị các giá trị trong khu vực # 2

Khi người dùng nhấn (=) nút và nếu đầu vào bộ đệm có đầu vào, đủ để sản xuất một kết quả, chúng ta sẽ tính toán kết quả và hiển thị nó trong khu vực # 2, không phải làm gì.

Khi người dùng nhấn nút Backspace (<-), chúng ta sẽ cắt các chữ số cuối cùng của giá trị được hiển thị trong khu vực # 2

Khi người dùng nhấn nút CE, chúng ta sẽ thiết lập lại giá trị hiển thị trong khu vực # 2 để nó trở thành 0

Khi người dùng nhấn nút C, chúng ta sẽ thiết lập lại bộ đệm đầu vào và giá trị hiển thị trong khu vực # 2 để nó trở thành 0

Khi ép người sử dụng (±), chúng tôi sẽ chuyển đổi các dấu hiệu của giá trị đầu vào người sử dụng hiển thị trong khu vực # 2

Khi người dùng nhấn nút MC, chúng ta phải giải phóng bộ nhớ đệm

Khi người dùng nhấn nút MR, chúng ta sẽ đọc các giá trị trong bộ nhớ đệm và hiển thị giá trị đó trong khu vực # 2

Khi người dùng nhấn nút MS, chúng ta sẽ thiết lập giá trị của bộ nhớ đệm để các giá trị hiển thị trong khu vực # 2

Khi người dùng nhấn nút M+ M-, chúng ta sẽ thêm / trừ đi giá trị hiển thị trong khu vực # 2 với giá trị hiện có của bộ nhớ đệm

Khi người dùng nhấn nút SQRT, chúng ta phải tính căn bậc hai của giá trị được hiển thị trong khu vực # 2 và hiển thị kết quả trong khu vực # 2

Khi người dùng nhấn nút 1 / x, chúng ta sẽ tính toán đối ứng của giá trị được hiển thị trong khu vực # 2 và hiển thị kết quả trong khu vực #

Khi người dùng nhấn nút %, chúng ta sẽ tính toán kết quả của bộ đệm đầu vào và tìm thấy các phần trăm kết quả và hiển thị trong khu vực # 2


Tạo giao diện sử dụng main.xml

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:orientation="vertical"

    android:layout_width="fill_parent"

    android:layout_height="fill_parent">

<TextView

    android:id="@+id/txtStack"

    android:layout_width="fill_parent"

    android:layout_height="wrap_content"

    android:textSize="15sp"

    android:gravity="right"

    android:layout_marginTop = "3sp"

    android:layout_marginLeft = "5sp"

    android:layout_marginRight = "5sp"/>


    <TextView

     android:id="@+id/txtInput"

     android:layout_width="fill_parent"

     android:layout_height="wrap_content"

     android:textSize="25sp"

     android:gravity="right"

     android:layout_marginLeft = "5sp"

    android:layout_marginRight = "5sp"/>


    <TextView

     android:id="@+id/txtMemory"

     android:layout_width="fill_parent"

     android:layout_height="wrap_content"

     android:textSize="15sp"

     android:gravity="left"

        android:layout_marginLeft = "5sp"

    android:layout_marginRight = "5sp"/>

   

<GridView xmlns:android="http://schemas.android.com/apk/res/android"

    android:id="@+id/grdButtons"

    android:layout_width="fill_parent"

    android:layout_height="fill_parent"

    android:columnWidth="90dp"

    android:numColumns="5"

    android:verticalSpacing="10dp"

    android:horizontalSpacing="10dp"

    android:stretchMode="columnWidth"

    android:gravity="center"/>

</LinearLayout>


Tạo nút bằng cách. Chuột phải layout>New Enum> 

KeypadButton.java


package by.QuangIT;


public enum KeypadButton {

MC("MC",KeypadButtonCategory.MEMORYBUFFER)

, MR("MR",KeypadButtonCategory.MEMORYBUFFER)

, MS("MS",KeypadButtonCategory.MEMORYBUFFER)

, M_ADD("M+",KeypadButtonCategory.MEMORYBUFFER)

, M_REMOVE("M-",KeypadButtonCategory.MEMORYBUFFER)

, BACKSPACE("<-",KeypadButtonCategory.CLEAR)

, CE("CE",KeypadButtonCategory.CLEAR)

, C("C",KeypadButtonCategory.CLEAR)

, ZERO("0",KeypadButtonCategory.NUMBER)

, ONE("1",KeypadButtonCategory.NUMBER)

, TWO("2",KeypadButtonCategory.NUMBER)

, THREE("3",KeypadButtonCategory.NUMBER)

, FOUR("4",KeypadButtonCategory.NUMBER)

, FIVE("5",KeypadButtonCategory.NUMBER)

, SIX("6",KeypadButtonCategory.NUMBER)

, SEVEN("7",KeypadButtonCategory.NUMBER)

, EIGHT("8",KeypadButtonCategory.NUMBER)

, NINE("9",KeypadButtonCategory.NUMBER)

, PLUS(" + ",KeypadButtonCategory.OPERATOR)

, MINUS(" - ",KeypadButtonCategory.OPERATOR)

, MULTIPLY(" * ",KeypadButtonCategory.OPERATOR)

, DIV(" / ",KeypadButtonCategory.OPERATOR)

, RECIPROC("1/x",KeypadButtonCategory.OTHER)

, DECIMAL_SEP(",",KeypadButtonCategory.OTHER)

, SIGN("±",KeypadButtonCategory.OTHER)

, SQRT("SQRT",KeypadButtonCategory.OTHER)

, PERCENT("%",KeypadButtonCategory.OTHER)

, CALCULATE("=",KeypadButtonCategory.RESULT)

, DUMMY("",KeypadButtonCategory.DUMMY);


 CharSequence mText; // Display Text

 KeypadButtonCategory mCategory;

  KeypadButton(CharSequence text,KeypadButtonCategory category) {

    mText = text;

    mCategory = category;

  }


  public CharSequence getText() {

    return mText;

  }

}


KeypadButtonCategory.java

package by.QuangIT;


public enum KeypadButtonCategory {

MEMORYBUFFER

  , NUMBER

  , OPERATOR

  , DUMMY

  , CLEAR

  , RESULT

  , OTHER

}


Tạo các nút trên bàn phím:

package by.QuangIT;


import android.content.Context;

import android.view.View;

import android.view.View.OnClickListener;

import android.view.ViewGroup;

import android.widget.BaseAdapter;

import android.widget.Button;


public class KeypadAdapter extends BaseAdapter {

private Context mContext;


// Declare button click listener variable

private OnClickListener mOnButtonClick;


public KeypadAdapter(Context c) {

mContext = c;

}


// Method to set button click listener variable

public void setOnButtonClickListener(OnClickListener listener) {

mOnButtonClick = listener;

}


public int getCount() {

return mButtons.length;

}


public Object getItem(int position) {

return mButtons[position];

}


public long getItemId(int position) {

return 0;

}


// create a new ButtonView for each item referenced by the Adapter

// create a new ButtonView for each item referenced by the Adapter

public View getView(int position, View convertView, ViewGroup parent) {

Button btn;

if (convertView == null) { // if it's not recycled, initialize some attributes

btn = new Button(mContext);

KeypadButton keypadButton = mButtons[position];

if (keypadButton != KeypadButton.DUMMY)

                     btn.setOnClickListener(mOnButtonClick);

        

//if(keypadButton != KeypadButton.CLEAR)

 //  btn.setBackgroundResource(R.drawable.keypadclear1);

// Set CalculatorButton enumeration as tag of the button so that we

// will use this information from our main view to identify what to do

btn.setTag(keypadButton);

} else {

btn = (Button) convertView;

}

btn.setText(mButtons[position].getText());

return btn;

}


// Create and populate keypad buttons array with CalculatorButton enum

// values

private KeypadButton[] mButtons = { KeypadButton.MC, KeypadButton.MR,

  KeypadButton.MS, KeypadButton.M_ADD, KeypadButton.M_REMOVE,

  KeypadButton.BACKSPACE, KeypadButton.CE, KeypadButton.C,

  KeypadButton.SIGN, KeypadButton.SQRT, KeypadButton.SEVEN,

  KeypadButton.EIGHT, KeypadButton.NINE, KeypadButton.DIV,

  KeypadButton.PERCENT, KeypadButton.FOUR, KeypadButton.FIVE,

  KeypadButton.SIX, KeypadButton.MULTIPLY, KeypadButton.RECIPROC,

  KeypadButton.ONE, KeypadButton.TWO, KeypadButton.THREE,

  KeypadButton.MINUS, KeypadButton.DECIMAL_SEP, KeypadButton.DUMMY,

  KeypadButton.ZERO, KeypadButton.DUMMY, KeypadButton.PLUS,

KeypadButton.CALCULATE };

}




Hiển thị bàn phím:

CaculatorProActivity.java


package by.QuangIT;


import java.text.DecimalFormat;

import java.text.NumberFormat;

import java.util.Iterator;

import java.util.Stack;


import android.app.Activity;

import android.os.Bundle;

import android.widget.AdapterView;

import android.widget.Button;

import android.widget.TextView;

import android.widget.AdapterView.OnItemClickListener;

import android.widget.GridView;

import android.view.View;

import android.view.View.OnClickListener;


public class CaculatorProActivity extends Activity {

GridView mKeypadGrid;

TextView userInputText;

TextView memoryStatText;


Stack<String> mInputStack;

Stack<String> mOperationStack;


KeypadAdapter mKeypadAdapter;

TextView mStackText;

boolean resetInput = false;

boolean hasFinalResult = false;


String mDecimalSeperator;

double memoryValue = Double.NaN;


/** Called when the activity is first created. */

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);


DecimalFormat currencyFormatter = (DecimalFormat) NumberFormat

.getInstance();

char decimalSeperator = currencyFormatter.getDecimalFormatSymbols()

.getDecimalSeparator();

mDecimalSeperator = Character.toString(decimalSeperator);


setContentView(R.layout.main);


// Create the stack

mInputStack = new Stack<String>();

mOperationStack = new Stack<String>();


// Get reference to the keypad button GridView

mKeypadGrid = (GridView) findViewById(R.id.grdButtons);


// Get reference to the user input TextView

userInputText = (TextView) findViewById(R.id.txtInput);

userInputText.setText("0");


memoryStatText = (TextView) findViewById(R.id.txtMemory);

memoryStatText.setText("");


mStackText = (TextView) findViewById(R.id.txtStack);


// Create Keypad Adapter

mKeypadAdapter = new KeypadAdapter(this);


// Set adapter of the keypad grid

mKeypadGrid.setAdapter(mKeypadAdapter);


// Set button click listener of the keypad adapter

mKeypadAdapter.setOnButtonClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

Button btn = (Button) v;

// Get the KeypadButton value which is used to identify the

// keypad button from the Button's tag

KeypadButton keypadButton = (KeypadButton) btn.getTag();


// Process keypad button

ProcessKeypadInput(keypadButton);

}

});


mKeypadGrid.setOnItemClickListener(new OnItemClickListener() {

public void onItemClick(AdapterView<?> parent, View v,

int position, long id) {


}

});


}


private void ProcessKeypadInput(KeypadButton keypadButton) {

//Toast.makeText(this, keypadButton.getText(), Toast.LENGTH_SHORT).show();

String text = keypadButton.getText().toString();

String currentInput = userInputText.getText().toString();


int currentInputLen = currentInput.length();

String evalResult = null;

double userInputValue = Double.NaN;


switch (keypadButton) {

case BACKSPACE: // Handle backspace

// If has operand skip backspace

if (resetInput)

return;


int endIndex = currentInputLen - 1;


// There is one character at input so reset input to 0

if (endIndex < 1) {

userInputText.setText("0");

}

// Trim last character of the input text

else {

userInputText.setText(currentInput.subSequence(0, endIndex));

}

break;

case SIGN: // Handle -/+ sign

// input has text and is different than initial value 0

if (currentInputLen > 0 && currentInput != "0") {

// Already has (-) sign. Remove that sign

if (currentInput.charAt(0) == '-') {

userInputText.setText(currentInput.subSequence(1,

currentInputLen));

}

// Prepend (-) sign

else {

userInputText.setText("-" + currentInput.toString());

}

}

break;

case CE: // Handle clear input

userInputText.setText("0");

break;

case C: // Handle clear input and stack

userInputText.setText("0");

clearStacks();

break;

case DECIMAL_SEP: // Handle decimal seperator

if (hasFinalResult || resetInput) {

userInputText.setText("0" + mDecimalSeperator);

hasFinalResult = false;

resetInput = false;

} else if (currentInput.contains("."))

return;

else

userInputText.append(mDecimalSeperator);

break;

case DIV:

case PLUS:

case MINUS:

case MULTIPLY:

if (resetInput) {

mInputStack.pop();

mOperationStack.pop();

} else {

if (currentInput.charAt(0) == '-') {

mInputStack.add("(" + currentInput + ")");

} else {

mInputStack.add(currentInput);

}

mOperationStack.add(currentInput);

}


mInputStack.add(text);

mOperationStack.add(text);


dumpInputStack();

evalResult = evaluateResult(false);

if (evalResult != null)

userInputText.setText(evalResult);


resetInput = true;

break;

case CALCULATE:

if (mOperationStack.size() == 0)

break;


mOperationStack.add(currentInput);

evalResult = evaluateResult(true);

if (evalResult != null) {

clearStacks();

userInputText.setText(evalResult);

resetInput = false;

hasFinalResult = true;

}

break;

case M_ADD: // Add user input value to memory buffer

userInputValue = tryParseUserInput();

if (Double.isNaN(userInputValue))

return;

if (Double.isNaN(memoryValue))

memoryValue = 0;

memoryValue += userInputValue;

displayMemoryStat();


hasFinalResult = true;


break;

case M_REMOVE: // Subtract user input value to memory buffer

userInputValue = tryParseUserInput();

if (Double.isNaN(userInputValue))

return;

if (Double.isNaN(memoryValue))

memoryValue = 0;

memoryValue -= userInputValue;

displayMemoryStat();

hasFinalResult = true;

break;

case MC: // Reset memory buffer to 0

memoryValue = Double.NaN;

displayMemoryStat();

break;

case MR: // Read memoryBuffer value

if (Double.isNaN(memoryValue))

return;

userInputText.setText(doubleToString(memoryValue));

displayMemoryStat();

break;

case MS: // Set memoryBuffer value to user input

userInputValue = tryParseUserInput();

if (Double.isNaN(userInputValue))

return;

memoryValue = userInputValue;

displayMemoryStat();

hasFinalResult = true;

break;

default:

if (Character.isDigit(text.charAt(0))) {

if (currentInput.equals("0") || resetInput || hasFinalResult) {

userInputText.setText(text);

resetInput = false;

hasFinalResult = false;

} else {

userInputText.append(text);

resetInput = false;

}


}

break;


}


}


private void clearStacks() {

mInputStack.clear();

mOperationStack.clear();

mStackText.setText("");

}


private void dumpInputStack() {

Iterator<String> it = mInputStack.iterator();

StringBuilder sb = new StringBuilder();


while (it.hasNext()) {

CharSequence iValue = it.next();

sb.append(iValue);


}


mStackText.setText(sb.toString());

}


private String evaluateResult(boolean requestedByUser) {

if ((!requestedByUser && mOperationStack.size() != 4)

|| (requestedByUser && mOperationStack.size() != 3))

return null;


String left = mOperationStack.get(0);

String operator = mOperationStack.get(1);

String right = mOperationStack.get(2);

String tmp = null;

if (!requestedByUser)

tmp = mOperationStack.get(3);


double leftVal = Double.parseDouble(left.toString());

double rightVal = Double.parseDouble(right.toString());

double result = Double.NaN;


if (operator.equals(KeypadButton.DIV.getText())) {

result = leftVal / rightVal;

} else if (operator.equals(KeypadButton.MULTIPLY.getText())) {

result = leftVal * rightVal;


} else if (operator.equals(KeypadButton.PLUS.getText())) {

result = leftVal + rightVal;

} else if (operator.equals(KeypadButton.MINUS.getText())) {

result = leftVal - rightVal;


}


String resultStr = doubleToString(result);

if (resultStr == null)

return null;


mOperationStack.clear();

if (!requestedByUser) {

mOperationStack.add(resultStr);

mOperationStack.add(tmp);

}


return resultStr;

}


private String doubleToString(double value) {

if (Double.isNaN(value))

return null;


long longVal = (long) value;

if (longVal == value)

return Long.toString(longVal);

else

return Double.toString(value);


}


private double tryParseUserInput() {

String inputStr = userInputText.getText().toString();

double result = Double.NaN;

try {

result = Double.parseDouble(inputStr);


} catch (NumberFormatException nfe) {

}

return result;


}


private void displayMemoryStat() {

if (Double.isNaN(memoryValue)) {

memoryStatText.setText("");

} else {

memoryStatText.setText("M = " + doubleToString(memoryValue));

}

}


}


Nguồn bài viết: Dngaz.com

BÌNH LUẬN BÀI VIẾT

Bài viết mới nhất

LIKE BOX

Bài viết được xem nhiều nhất

HỌC HTML