天天看點

【Android實驗】UI設計-Android電腦

目錄

  • 實驗目的
  • 實驗要求
  • 實驗過程
    • 1. 界面設計
    • 2. 功能設計
    • 3. 運算處理

自主完成一個簡單APP的設計工作,綜合應用已經學到的Android UI設計技巧,重點注意合理使用布局

  1. 完成一個電腦的設計,可以以手機自帶的電腦為參考。設計過程中,注意考慮界面的美觀性,不同機型的适應性,以及功能的完備性。
  2. 注意結合Activity的生命周期,考慮不同情況下電腦的界面狀态。
  3. 如有餘力,可以考慮實作一個高精度科學計算型的電腦。

界面仿照自己手機中電腦界面進行了設計,采用的布局是線性布局,其中比較特殊的布局是最後兩行的布局,由于“=”鍵占用兩個位置,是以采用vertical和horizontal互相配合的方式進行。

界面的展示如下:

界面代碼(activity_caculator.xml):

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:background="@drawable/a5"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="2"
        android:orientation="vertical"
        android:focusableInTouchMode="true">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Calculator"
            android:textStyle="italic"
            android:textAlignment="center"
            android:textSize="20sp" />

        <EditText
            android:id="@+id/et_input"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:text="0"
            android:enabled="true"
            android:textAlignment="textEnd"
            android:textSize="30sp"
            android:background="@null"/>
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:orientation="horizontal"
        android:weightSum="4">

        <Button style="?android:attr/buttonStyle"
            android:id="@+id/btn_clear"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="#FFE4C4"
            android:text="C"
            android:textAlignment="center"
            android:textSize="20sp"/>

        <Button style="?android:attr/buttonStyle"
            android:id="@+id/btn_divide"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="#FFE4C4"
            android:text="/"
            android:textAlignment="center"
            android:textSize="20sp"/>

        <Button style="?android:attr/buttonStyle"
            android:id="@+id/btn_times"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="#FFE4C4"
            android:text="*"
            android:textAlignment="center"
            android:textSize="20sp"/>

        <Button
            android:id="@+id/btn_delete"
            style="?android:attr/buttonStyle"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="#FFE4C4"
            android:text="DEL"
            android:textAlignment="center"
            android:textSize="20sp" />
    </LinearLayout>


    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:orientation="horizontal"
        android:layout_weight="1"
        android:weightSum="4">

        <Button style="?android:attr/buttonStyle"
            android:id="@+id/btn_7"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="#FDF5E6"
            android:text="7"
            android:textAlignment="center"
            android:textSize="20sp"/>

        <Button
            android:id="@+id/btn_8"
            style="?android:attr/buttonStyle"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="#FDF5E6"
            android:text="8"
            android:textAlignment="center"
            android:textSize="20sp" />

        <Button style="?android:attr/buttonStyle"
            android:id="@+id/btn_9"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="#FDF5E6"
            android:text="9"
            android:textAlignment="center"
            android:textSize="20sp"/>

        <Button style="?android:attr/buttonStyle"
            android:id="@+id/btn_sub"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:background="#FFC0CB"
            android:layout_weight="1"
            android:text="-"
            android:textAlignment="center"
            android:textSize="20sp"/>
    </LinearLayout>


    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:orientation="horizontal"
        android:layout_weight="1"
        android:weightSum="4">

        <Button style="?android:attr/buttonStyle"
            android:id="@+id/btn_4"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="#FDF5E6"
            android:text="4"
            android:textAlignment="center"
            android:textSize="20sp"/>

        <Button
            android:id="@+id/btn_5"
            style="?android:attr/buttonStyle"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="#FDF5E6"
            android:text="5"
            android:textAlignment="center"
            android:textSize="20sp" />

        <Button
            android:id="@+id/btn_6"
            style="?android:attr/buttonStyle"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="#FDF5E6"
            android:text="6"
            android:textAlignment="center"
            android:textSize="20sp" />

        <Button
            android:id="@+id/btn_add"
            style="?android:attr/buttonStyle"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="#FFC0CB"
            android:text="+"
            android:textAlignment="center"
            android:textSize="20sp" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:orientation="horizontal"
        android:layout_weight="2"
        android:weightSum="4">

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:layout_weight="1">

            <Button style="?android:attr/buttonStyle"
                android:id="@+id/btn_1"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:background="#FDF5E6"
                android:text="1"
                android:textAlignment="center"
                android:textSize="20sp"/>

            <Button style="?android:attr/buttonStyle"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="%"
                android:textAlignment="center"
                android:background="#FDF5E6"
                android:layout_weight="1"
                android:id="@+id/btn_remainder"
                android:textSize="20sp"/>
        </LinearLayout>
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:layout_weight="1">

            <Button style="?android:attr/buttonStyle"
                android:id="@+id/btn_2"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:background="#FDF5E6"
                android:text="2"
                android:textAlignment="center"
                android:textSize="20sp"/>

            <Button style="?android:attr/buttonStyle"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="0"
                android:textAlignment="center"
                android:background="#FDF5E6"
                android:layout_weight="1"
                android:id="@+id/btn_0"
                android:textSize="20sp"/>
        </LinearLayout>
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:layout_weight="1">
            <Button style="?android:attr/buttonStyle"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="3"
                android:textAlignment="center"
                android:background="#FDF5E6"
                android:layout_weight="1"
                android:id="@+id/btn_3"
                android:textSize="20sp"/>

            <Button
                android:id="@+id/btn_point"
                style="?android:attr/buttonStyle"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:background="#FDF5E6"
                android:text="."
                android:textAlignment="center"
                android:textSize="20sp" />
        </LinearLayout>
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:layout_weight="1">
            <Button style="?android:attr/buttonStyle"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="="
                android:textAlignment="center"
                android:background="#FFC0CB"
                android:layout_weight="1"
                android:id="@+id/btn_equal"
                android:textSize="20sp"/>
        </LinearLayout>

    </LinearLayout>
</LinearLayout>
           

在界面設計的過程中,感覺

android:layout_weight

是一個比較重要的屬性,整個界面的按比例排布都需要這個屬性來決定,如果用絕對位置會導緻翻轉以後,電腦按鈕無法按比例進行填充。

另外界面的一個特點就是沒有了ActionBar,這個通過設定

Style.xml

中的

parent

屬性,進而可以改變。

Style.xml檔案如下:

<resources>
    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>
</resources>
           

另外的app指令以及圖示替換在AndroidManifest.xml檔案中更改:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.administrator.calculator">

    <application
        android:allowBackup="true"
        android:icon="@drawable/pjthis"
        android:label="PjCalc"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.AppCompat.Light.NoActionBar">
        <activity android:name=".Caculator">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>
           

修改APP名稱在android:label屬性中修改,APP圖示在android:icon中修改,其中android:theme改為NoActionBar可以将頭部的标題去掉,增大空間。在LinearLayout中修改android:backgroud可以對背景進行修改,這裡換成了一個自定義背景。

進行事件響應的主體為:Calculator.java

對界面事件的擷取以及處理主要由該檔案處理:

代碼如下:

package com.example.administrator.calculator;

import android.content.Context;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;


public class Caculator extends AppCompatActivity implements View.OnClickListener {

    Button bt_0, bt_1, bt_2, bt_3, bt_4, bt_5, bt_6, bt_7, bt_8, bt_9;
    Button bt_clear, bt_divide, bt_times, bt_delete, bt_add, bt_sub, bt_equal, bt_remainder, bt_point;
    private EditText et_input;

    private StringBuilder fomula = new StringBuilder();

    private void initP() {
        bt_0 = (Button) findViewById(R.id.btn_0);
        bt_1 = (Button) findViewById(R.id.btn_1);
        bt_2 = (Button) findViewById(R.id.btn_2);
        bt_3 = (Button) findViewById(R.id.btn_3);
        bt_4 = (Button) findViewById(R.id.btn_4);
        bt_5 = (Button) findViewById(R.id.btn_5);
        bt_6 = (Button) findViewById(R.id.btn_6);
        bt_7 = (Button) findViewById(R.id.btn_7);
        bt_8 = (Button) findViewById(R.id.btn_8);
        bt_9 = (Button) findViewById(R.id.btn_9);
        bt_clear = (Button) findViewById(R.id.btn_clear);
        bt_divide = (Button) findViewById(R.id.btn_divide);
        bt_times = (Button) findViewById(R.id.btn_times);
        bt_delete = (Button) findViewById(R.id.btn_delete);
        bt_add = (Button) findViewById(R.id.btn_add);
        bt_sub = (Button) findViewById(R.id.btn_sub);
        bt_equal = (Button) findViewById(R.id.btn_equal);
        bt_point = (Button) findViewById(R.id.btn_point);
        bt_remainder = (Button) findViewById(R.id.btn_remainder);
        et_input = (EditText) findViewById(R.id.et_input);

        et_input.setKeyListener(null);


        bt_0.setOnClickListener(this);
        bt_1.setOnClickListener(this);
        bt_2.setOnClickListener(this);
        bt_3.setOnClickListener(this);
        bt_4.setOnClickListener(this);
        bt_5.setOnClickListener(this);
        bt_6.setOnClickListener(this);
        bt_7.setOnClickListener(this);
        bt_8.setOnClickListener(this);
        bt_9.setOnClickListener(this);
        bt_add.setOnClickListener(this);
        bt_clear.setOnClickListener(this);
        bt_divide.setOnClickListener(this);
        bt_times.setOnClickListener(this);
        bt_delete.setOnClickListener(this);
        bt_sub.setOnClickListener(this);
        bt_remainder.setOnClickListener(this);
        bt_point.setOnClickListener(this);
        bt_equal.setOnClickListener(this);

    }

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

    @Override
    public void onClick(View v) {
        int latest = 0;
        if (fomula.length() != 0) {
            latest = fomula.codePointAt(fomula.length() - 1);
        }
        else
            latest = '.';

        switch (v.getId()) {
            case R.id.btn_0:
                fomula = fomula.append("0");
                et_input.setText(fomula);
                break;
            case R.id.btn_1:
                fomula = fomula.append("1");
                et_input.setText(fomula);
                break;
            case R.id.btn_2:
                fomula = fomula.append("2");
                et_input.setText(fomula);
                break;
            case R.id.btn_3:
                fomula = fomula.append("3");
                et_input.setText(fomula);
                break;
            case R.id.btn_4:
                fomula = fomula.append("4");
                et_input.setText(fomula);
                break;
            case R.id.btn_5:
                fomula = fomula.append("5");
                et_input.setText(fomula);
                break;
            case R.id.btn_6:
                fomula = fomula.append("6");
                et_input.setText(fomula);
                break;
            case R.id.btn_7:
                fomula = fomula.append("7");
                et_input.setText(fomula);
                break;
            case R.id.btn_8:
                fomula = fomula.append("8");
                et_input.setText(fomula);
                break;
            case R.id.btn_9:
                fomula = fomula.append("9");
                et_input.setText(fomula);
                break;
            case R.id.btn_sub:
                if (latest >= '0' && latest <= '9')
                    fomula = fomula.append("-");
                else {
                    if(latest != '.')
                        fomula.delete(fomula.length()-1, fomula.length());
                    fomula = fomula.append("-");
                }
                et_input.setText(fomula);
                break;
            case R.id.btn_add:
                if (latest >= '0' && latest <= '9')
                    fomula = fomula.append("+");
                else {
                    if(latest != '.')
                        fomula.delete(fomula.length()-1, fomula.length());
                    fomula = fomula.append("+");
                }
                et_input.setText(fomula);
                break;
            case R.id.btn_times:
                if (latest >= '0' && latest <= '9')
                    fomula = fomula.append("*");
                else {
                    if(latest != '.')
                        fomula = fomula.delete(fomula.length()-1,fomula.length());
                    fomula = fomula.append("*");
                }
                et_input.setText(fomula);
                break;
            case R.id.btn_divide:
                if (latest >= '0' && latest <= '9')
                    fomula = fomula.append("/");
                else {
                    if(latest != '.')
                     fomula.delete(fomula.length()-1, fomula.length());
                    fomula = fomula.append("/");
                }
                et_input.setText(fomula);
                break;
            case R.id.btn_delete:
                if (fomula.length() > 0)
                    fomula = fomula.delete(fomula.length() - 1, fomula.length());
                et_input.setText(fomula);
                break;
            case R.id.btn_clear:
                fomula = fomula.delete(0, fomula.length());
                et_input.setText(fomula);
                break;
            case R.id.btn_equal:
                String ans="0";
                if(fomula.length()>1){
                    InfixInToDuffix inf = new InfixInToDuffix();
                    try{
                        String a = inf.toSuffix(fomula);
                        System.out.println("out:");
                        System.out.println(a);
                        ans = inf.dealEquation(a);
                        fomula = fomula.delete(0,fomula.length());
                        fomula = fomula.append(ans);
                    }catch (Exception ex){
                        ans = "error";
                        fomula = fomula.delete(0,fomula.length());
                    }
                }
                et_input.setText(ans);
                break;
            case R.id.btn_point:
                fomula = fomula.append(".");
                et_input.setText(fomula);
                break;
            case R.id.btn_remainder:
                if(latest >= '0' && latest <= '9'){
                    fomula.append("%");
                }
                else
                {
                    if(latest != '.')
                        fomula.delete(fomula.length()-1,fomula.length());
                    fomula.append("%");
                }
                et_input.setText(fomula);
                break;
        }
    }
}
           

聲明各個按鈕及部件,然後通過findViewById得到對應的對象,然後進行處理相應的處理。

其中有幾個細節需要處理,否則會導緻程式崩潰:

  • 符号處理。
    • 符号前邊不能有符号。
  • 小數點處理。
    • 如果結果是整數,不要加小數點。
    • 小數點的連續使用,如

      1.2.3.5.1。

  • 運算符号如果出現在數字之前,需要特殊判斷。
  • 多個符号連續出現問題。
    • 處理方式為将上一個符号頂替下來,換成最新的運算符。
  • 減号如果作為-負号的情況出現。

主要是通過兩個棧,将中綴轉化為字尾,然後進行求解。其中

“*/”

運算符的優先級應該與

“%”

優先級一緻,但是這裡讓

“%”

優先級低于

"*/"

,然後進行的處理。

package com.example.administrator.calculator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.lang.*;
import java.util.ArrayList;
import java.util.*;
/**
 * Created by pprp on 2018/9/22.
 */

class InfixInToDuffix {
    //使用集合定義好符号的運算優先級别
    private static final Map<Character,Integer>basic =new HashMap<Character, Integer>();
    static {
        basic.put('-',1);
        basic.put('+', 1);
        basic.put('*', 3);
        basic.put('/', 3);
        basic.put('(', 0);
        basic.put('%',2);
    }


    //将中綴表達式轉換為字尾表達式
    public String toSuffix(StringBuilder infix){
        List<String> queue = new ArrayList<String>();                                   
        List<Character> stack = new ArrayList<Character>();                            

        char[] charArr = infix.substring(0,infix.length()).trim().toCharArray();                                 
        String standard = "*/+-()%";                                                       
        char ch = '&';                                                                  
        int len = 0;                                                                    
        for (int i = 0; i < charArr.length; i++) {                                      
            ch = charArr[i];                                                            
            if(Character.isDigit(ch)) {                                                  
                len++;
            }else if(ch == '.'){                                                      
                len++;
            }else if(standard.indexOf(ch) != -1) {                                       
                if(len > 0) {                                                           
                    queue.add(String.valueOf(Arrays.copyOfRange(charArr, i - len, i)));   
                    len = 0;                                                           
                }
                if(ch == '(') {                                                            
                    stack.add(ch);                                                        
                    continue;                                                          
                }
                if (!stack.isEmpty()) {                                                    
                    int size = stack.size() - 1;                                        
                    boolean flag = false;                                             
                    while (size >= 0 && ch == ')' && stack.get(size) != '(') {            
                        queue.add(String.valueOf(stack.remove(size)));                    
                        size--;                                                        
                        flag = true;                                                  
                    }
                    if(ch==')'&&stack.get(size) == '('){
                        flag = true;
                    }
                    while (size >= 0 && !flag && basic.get(stack.get(size)) >= basic.get(ch)) {   
                        queue.add(String.valueOf(stack.remove(size)));                 
                        size--;
                    }
                }
                if(ch != ')') {                                                      
                    stack.add(ch);                                                 
                } else {                                                          
                    stack.remove(stack.size() - 1);
                }
            }
            if(i == charArr.length - 1) {                                            
                if(len > 0) {                                                     
                    queue.add(String.valueOf(Arrays.copyOfRange(charArr, i - len+1, i+1)));
                }
                int size = stack.size() - 1;                                       
                while (size >= 0) {                                                       
                    queue.add(String.valueOf(stack.remove(size)));
                    size--;
                }
            }

        }
        String a = queue.toString();
        return a.substring(1,a.length()-1);
    }


    public String dealEquation(String equation){

        String [] arr = equation.split(", ");
        List<String> list = new ArrayList<String>();


        for (int i = 0; i < arr.length; i++) {             
            int size = list.size();
            switch (arr[i]) {
                case "+": double a = Double.parseDouble(list.remove(size-2))+ Double.parseDouble(list.remove(size-2)); list.add(String.valueOf(a));     break;
                case "-": double b = Double.parseDouble(list.remove(size-2))- Double.parseDouble(list.remove(size-2)); list.add(String.valueOf(b));     break;
                case "*": double c = Double.parseDouble(list.remove(size-2))* Double.parseDouble(list.remove(size-2)); list.add(String.valueOf(c));     break;
                case "/": double d = Double.parseDouble(list.remove(size-2))/ Double.parseDouble(list.remove(size-2)); list.add(String.valueOf(d));       break;
                case "%": double e = Double.parseDouble(list.remove(size-2)) % Double.parseDouble(list.remove(size-2)); list.add(String.valueOf(e));     break;
                default: list.add(arr[i]);     break;                                    //如果是數字  直接放進list中
            }
        }
        return list.size() == 1 ? list.get(0) : "Fail" ;                 
    }
}
           

代碼改變世界