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中并没有对左右滑动做过多的处理。

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