Calculator源碼分析

說明:該文章基於android 5.1的源碼進行分析。

  1. calculator的效果圖:
    這裏寫圖片描述

  2. packages/apps/Calculator/AndroidManifest.xml
    我們先來看看這個文件AndroidManifest.xml
    <-manifest
    xmlns:android=”http://schemas.android.com/apk/res/android”
    package=”com.android.calculator2”>
    <-application
    android:icon=”@mipmap/ic_launcher_calculator”
    android:label=”@string/app_name”
    android:theme=”@style/CalculatorTheme”>
    <-activity
    android:name=”.Calculator”
    android:label=”@string/app_name”
    android:windowSoftInputMode=”stateAlwaysHidden”>
    <-intent-filter>
    <-action android:name=”android.intent.action.MAIN” />
    <-category android:name=”android.intent.category.LAUNCHER” />
    <-category android:name=”android.intent.category.APP_CALCULATOR” />
    <-/intent-filter>
    <-/activity>
    <-/application>
    <-/manifest>

我們可以看到,這個AndroidManifest.xml 中並沒有太多的東西,只有對android:name=”.Calculator”這個是對我們有用的信息,在這裏我們要使用的就是,Calculator.java是這個app的入口函數。

  1. packages/apps/Calculator/src/com/android/calculator2/Calculator.java
    我們接着來看下Calculator.java中的內容。
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_calculator);
    ……………….
    }
    setContentView(R.layout.activity_calculator)這裏引用了佈局文件activity_calculator.xml,
    <-LinearLayout
    xmlns:android=”http://schemas.android.com/apk/res/android”
    android:layout_width=”match_parent”
    android:layout_height=”match_parent”
    android:orientation=”vertical”>
    <-include
    layout=”@layout/display”
    android:layout_width=”match_parent”
    android:layout_height=”wrap_content” />
    <-com.android.calculator2.CalculatorPadViewPager
    android:id=”@+id/pad_pager”
    android:layout_width=”match_parent”
    android:layout_height=”0dip”
    android:layout_weight=”1”
    android:overScrollMode=”never”>
    <-LinearLayout
    android:layout_width=”match_parent”
    android:layout_height=”match_parent”>
    <-include layout=”@layout/pad_numeric” />
    <-include layout=”@layout/pad_operator_one_col” />
    <-/LinearLayout>
    <-include layout=”@layout/pad_advanced” /> <-/com.android.calculator2.CalculatorPadViewPager>
    <-/LinearLayout>

這裏嵌套了好幾個layout文件,下面我們就來一一分析這些layout文件。

3.1.0 layout=”@layout/display”

<-RelativeLayout
xmlns:android=”http://schemas.android.com/apk/res/android”
android:id=”@+id/display”
android:layout_width=”match_parent”
android:layout_height=”wrap_content”
android:background=”@color/display_background_color”
android:elevation=”4dip”>

<-com.android.calculator2.CalculatorEditText
    android:id="@+id/formula"
    style="@style/DisplayEditTextStyle.Formula"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:inputType="text|textNoSuggestions"
    android:textColor="@color/display_formula_text_color" />

<-com.android.calculator2.CalculatorEditText
    android:id="@+id/result"
    style="@style/DisplayEditTextStyle.Result"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_below="@id/formula"
    android:inputType="none"
    android:focusable="false"
    android:textColor="@color/display_result_text_color" />

<-/RelativeLayout>
這裏定義了兩個text,分別是
android:id=”@+id/formula”
android:id=”@+id/result”
如圖:
這裏寫圖片描述
這裏可以看到,
“987-654”這個字串所在的id是”@+id/formula”
“333”這個字串所在的id是“@+id/result”

3.2.0 layout/pad_numeric
<-com.android.calculator2.CalculatorPadLayout
xmlns:android=”http://schemas.android.com/apk/res/android”
android:id=”@+id/pad_numeric”
style=”@style/PadLayoutStyle.Numeric”
android:background=”@color/pad_numeric_background_color”
android:columnCount=”3”
android:rowCount=”4”>
<-Button
android:id=”@+id/digit_7”
style=”@style/PadButtonStyle.Numeric”
android:onClick=”onButtonClick”
android:text=”@string/digit_7” />
<-Button
android:id=”@+id/digit_8”
style=”@style/PadButtonStyle.Numeric”
android:onClick=”onButtonClick”
android:text=”@string/digit_8” />
……………………..
<-/com.android.calculator2.CalculatorPadLayout>

這裏是對數字按鍵的佈局,0—9個按鍵,在家商小圓點和“=”共12個按鍵,這裏我們可以很清楚的看到我們的
android:columnCount=”3”
android:rowCount=”4”
這12個按鍵分成了4行3列進行佈局。

3.3.0 layout/pad_operator_one_col

<-com.android.calculator2.CalculatorPadLayout
xmlns:android=”http://schemas.android.com/apk/res/android”
android:id=”@+id/pad_operator”
style=”@style/PadLayoutStyle.Operator”
android:background=”@color/pad_operator_background_color”
android:columnCount=”1”
android:rowCount=”5”>
<-Button
android:id=”@+id/del”
style=”@style/PadButtonStyle.Operator.Text”
android:contentDescription=”@string/desc_del”
android:textSize=”15dp”
android:onClick=”onButtonClick”
android:text=”@string/del” />
<-Button
android:id=”@+id/clr”
style=”@style/PadButtonStyle.Operator.Text”
android:contentDescription=”@string/desc_clr”
android:onClick=”onButtonClick”
android:textSize=”15dp”
android:text=”@string/clr”
android:visibility=”gone” />
<-Button
android:id=”@+id/op_div”
style=”@style/PadButtonStyle.Operator”
android:contentDescription=”@string/desc_op_div”
android:onClick=”onButtonClick”
android:text=”@string/op_div” />
<-Button
android:id=”@+id/op_mul”
style=”@style/PadButtonStyle.Operator”
android:contentDescription=”@string/desc_op_mul”
android:onClick=”onButtonClick”
android:text=”@string/op_mul” />
<-Button
android:id=”@+id/op_mul”
style=”@style/PadButtonStyle.Operator”
android:contentDescription=”@string/desc_op_mul”
android:onClick=”onButtonClick”
android:text=”@string/op_mul” />
<-Button
android:id=”@+id/op_sub”
style=”@style/PadButtonStyle.Operator”
android:contentDescription=”@string/desc_op_sub”
android:onClick=”onButtonClick”
android:text=”@string/op_sub” />
<-Button
android:id=”@+id/op_add”
style=”@style/PadButtonStyle.Operator”
android:contentDescription=”@string/desc_op_add”
android:onClick=”onButtonClick”
android:text=”@string/op_add” />
<-/com.android.calculator2.CalculatorPadLayout>

功能鍵的佈局:
這裏寫圖片描述
我們看到其實這裏有佈局了6個鍵,但是android:id=”@+id/clr”這個按鍵卻沒有顯示出來,我們去看看是在哪裏把它給隱藏掉了。
在protected void onCreate(Bundle savedInstanceState)中獲得了clr的ID
mDeleteButton = findViewById(R.id.del);
mClearButton = findViewById(R.id.clr);

private void setState(CalculatorState state) {
if (mCurrentState != state) {
mCurrentState = state;
if (state == CalculatorState.RESULT || state == CalculatorState.ERROR) {
mDeleteButton.setVisibility(View.GONE);
mClearButton.setVisibility(View.VISIBLE);
} else {
mDeleteButton.setVisibility(View.VISIBLE);
mClearButton.setVisibility(View.GONE);
}
………
}
}
在不一樣的狀態下,del和clr兩個按鍵是交替進行顯示的,通過判斷state來對del和clr的顯示與否進行判斷,當顯示計算結果時候,del就隱藏,clr顯示,反之則del顯示,clr隱藏。

3.4.0 layout/pad_advanced

<-com.android.calculator2.CalculatorPadLayout
xmlns:android=”http://schemas.android.com/apk/res/android”
android:id=”@+id/pad_advanced”
style=”@style/PadLayoutStyle.Advanced”
android:background=”@color/pad_advanced_background_color”>
<-Button
android:id=”@+id/fun_sin”
style=”@style/PadButtonStyle.Advanced”
android:contentDescription=”@string/desc_fun_sin”
android:onClick=”onButtonClick”
android:text=”@string/fun_sin” />
<-Button
android:id=”@+id/fun_cos”
style=”@style/PadButtonStyle.Advanced”
android:contentDescription=”@string/desc_fun_cos”
android:onClick=”onButtonClick”
android:text=”@string/fun_cos” />
<-Button
android:id=”@+id/op_sqrt”
style=”@style/PadButtonStyle.Advanced”
android:contentDescription=”@string/desc_op_sqrt”
android:onClick=”onButtonClick”
android:text=”@string/op_sqrt” />
………………….

該layout是tan/sin等一些常用參數的button設置。

4.0 主要函數分析
上面是對主要佈局文件的分析,下面我們對一些主要的函數進行分析。

4.1.0 onBackPressed()
public void onBackPressed() {
if (mPadViewPager == null || mPadViewPager.getCurrentItem() == 0) {
// If the user is currently looking at the first pad (or the pad is not paged),
// allow the system to handle the Back button.
super.onBackPressed();
} else {
// Otherwise, select the previous pad.
mPadViewPager.setCurrentItem(mPadViewPager.getCurrentItem() - 1);
}
}
該函數對back鍵進行處理,先看mPadViewPager獲取的什麼東西,
在onCreate中我們看到
mPadViewPager = (ViewPager) findViewById(R.id.pad_pager);
回頭在activity_calculator.xml中我們看看:
<-com.android.calculator2.CalculatorPadViewPager
android:id=”@+id/pad_pager”
android:layout_width=”match_parent”
android:layout_height=”0dip”
android:layout_weight=”1”
android:overScrollMode=”never”>
<-LinearLayout
android:layout_width=”match_parent”
android:layout_height=”match_parent”>
<-include layout=”@layout/pad_numeric” />
<-include layout=”@layout/pad_operator_one_col” />
<-/LinearLayout>
<-include layout=”@layout/pad_advanced” /> <-/com.android.calculator2.CalculatorPadViewPager>
中有三個對象,所以第一個條件:
if (mPadViewPager == null || mPadViewPager.getCurrentItem() == 0)
當mPadViewPager == null或者當前顯示的的對象是pad_numeric/pad_operator_one_col的時候,就直接退出calculator,否則就先返回pad_numeric/pad_operator_one_col所在的頁面,然後在退出calculator。

4.2.0 CalculatorPadViewPager.java
我們看到,在向右滑動的時候,會sin/cos/tan等所在的view會滑出,覆蓋在原來的數字鍵盤上面,這個是怎麼實現的呢?
<-com.android.calculator2.CalculatorPadViewPager
………………..
………………………
<-include layout=”@layout/pad_numeric” />
<-include layout=”@layout/pad_operator_one_col” />
………………………
<-include layout=”@layout/pad_advanced” /> <-/com.android.calculator2.CalculatorPadViewPager>

我們看上面的三個layout都是CalculatorPadViewPager的對象,下面我們來看下CalculatorPadViewPager.java
這個文件
public class CalculatorPadViewPager extends ViewPager{
………………
}
CalculatorPadViewPager是繼承ViewPager的,由於沒有重寫
onPageScrolled();
這個函數,所以左右滑動的時候調用的就是ViewPager.onPageScrolled()進行處理,
在CalculatorPadViewPager中並沒有對左右滑動做過多的處理。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章