Programming     Travel Logs     Life Is Good     Surfing Online     About Me
Judgement requires experience, but can be built faster by learning foundational skills.
-Naval Ravikant
2018-07-17 17:58:09

Copy this link when reproducing:
http://www.casperlee.com/en/y/blog/202

This module allows user to check the summary of the current month. Besides the summary information sorted by Categories, the system also tries to predict how much the user will spend till the end of the month. It is very straightforward, so there is no extra explanations needed, I'll just list all the changes of the code in this article, in stead of explaining too much. Just like before, let's take it easy and enjoy a few beautiful photos first.

/Images/20171005/01.jpg

/Images/20171005/02.jpg

/Images/20171005/03.jpg

/Images/20171005/04.jpg

/Images/20171005/05.jpg

/Images/20171005/06.jpg

1. Open the file "app -> res -> values -> strings.xml", add the following strings into it:

<string name="caption_total">Total:</string>
    <string name="caption_predict">Predict:</string>
    <string name="caption_return">Return</string>

2. Open the file "app -> res -> values -> string.xml (zh)", add the following strings into it:

<string name="caption_total">总计:</string>
    <string name="caption_predict">预计:</string>
    <string name="caption_return">返回</string>

3. Open the file "app -> java -> com.casperlee.personalexpense -> global -> GlobalVars", add the following code:

public static final String KEY_YEAR = "CurrentYear";
    public static final String KEY_MONTH = "CurrentMonth";
    public static final String KEY_DAY = "CurrentDay";
    public static final String KEY_SEARCH_CONDITION = "SearchCondition";

4. Open the file "app -> java -> com.casperlee.personalexpense -> global -> GlobalFuncs", add the following code:

public static String GetMonthString(int year, int month) {

        return String.format("%04d%02d", year, month);
    }
    public static String GetDayString(int year, int month, int day){

        return String.format("%04d%02d%02d", year, month, day);
    }

5. Add a new entity class named "CategorySummaryEntity" in the folder "app -> java -> com.casperlee.personalexpense -> entities", and put the following code in:

package com.casperlee.personalexpense.entities;

public class CategorySummaryEntity {

    public String Category;
    public double LimitMoney;
    public double Amount;
    public double Predict;
}

6. Open the file "app -> java -> com.casperlee.personalexpense -> dal -> ExpenditureDal", add the following code:

...
import com.casperlee.personalexpense.entities.CategorySummaryEntity;
...
    public CategorySummaryEntity[] getCategorySummaryItemsByDate(String dayStr) {

        String sql = "select a.Name, a.LimitMoney, sum(b.Amount) from Category a, Expenditure b"
                + " where a.ID = b.Category"
                + " and b.Day like '" + dayStr + "%'"
                + " group by a.Name, a.LimitMoney"
                + " order by a.ID";
        Cursor cursor = db.rawQuery(sql, null);
        try {

            if (cursor.getCount() <= 0) {

                return null;

            } else {

                CategorySummaryEntity[] es = new CategorySummaryEntity[cursor.getCount()];

                cursor.moveToFirst();
                int i = 0;
                while (!cursor.isAfterLast()) {

                    CategorySummaryEntity e = new CategorySummaryEntity();
                    e.Category = cursor.getString(0);
                    e.LimitMoney = cursor.getDouble(1);
                    e.Amount = cursor.getDouble(2);
                    es[i++] = e;
                    cursor.moveToNext();
                }

                return es;
            }

        } finally {

            cursor.close();
        }
    }
...

7. Open the file "app -> java -> com.casperlee.personalexpense -> bll -> ExpenditureBll", add the following code:

...
import com.casperlee.personalexpense.entities.CategorySummaryEntity;
import com.casperlee.personalexpense.global.GlobalFuncs;
import java.util.Calendar;
...
    public CategorySummaryEntity[] getCategorySummaryItemsByDate(Context context,
                                                                 int year, int monthOfYear, int dayOfMonth) {

        CategorySummaryEntity[] ret = ExpenditureDal.getInstance().getCategorySummaryItemsByDate(
                GlobalFuncs.GetMonthString(year, monthOfYear));

        if (ret != null) {

            this.calcPredict(ret, year, monthOfYear, dayOfMonth);
        }

        return ret;
    }
    public ExpenditureEntity[] getExpenditureDetailByCondition(Context context,
                                                               String searchCondition) {

        ExpenditureEntity[] ret = ExpenditureDal.getInstance().getExpenditureDetailByCondition(searchCondition);
        return ret;
    }

    // Private methods
    private void calcPredict(CategorySummaryEntity[] items, int year, int monthOfYear, int dayOfMonth) {

        // Get total days this month.
        Calendar c = Calendar.getInstance();
        c.set(Calendar.YEAR, year);
        c.set(Calendar.MONTH, monthOfYear - 1);
        c.set(Calendar.DAY_OF_MONTH, 1);
        c.add(Calendar.MONTH, 1);
        c.add(Calendar.DAY_OF_MONTH, -1);
        int totalDays = c.get(Calendar.DAY_OF_MONTH);

        for (int i = 0; i < items.length; i++) {

            CategorySummaryEntity item = items[i];
            if (item.LimitMoney == 0) {

                item.Predict = item.Amount;

            } else {

                item.Predict = item.Amount / (double)dayOfMonth * (double)totalDays;
            }
        }
    }
...

8. Add a new Activity class named "MonthSummaryActivity" in the folder "app -> java -> com.casperlee.personalexpense", and put the following code in:

package com.casperlee.personalexpense;

import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.graphics.Color;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;

import com.casperlee.personalexpense.bll.CategoryBll;
import com.casperlee.personalexpense.bll.ExpenditureBll;
import com.casperlee.personalexpense.entities.CategorySummaryEntity;
import com.casperlee.personalexpense.global.GlobalFuncs;
import com.casperlee.personalexpense.global.GlobalVars;

public class MonthSummaryActivity extends AppCompatActivity {

    // Fields
    private int currentYear;
    private int currentMonth;
    private int currentDay;
    private Layout ui;

    // Entrances
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_month_summary);
        this.ui = new Layout();

        this.readExtras();
        this.setListeners();
        this.readSummary();
    }
    @Override
    protected void onResume() {
        if (getRequestedOrientation() != ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        }
        super.onResume();
    }

    // Private functions
    private void readExtras() {

        Intent intent = this.getIntent();
        this.currentYear = intent.getIntExtra(GlobalVars.KEY_YEAR,
                1978);
        this.currentMonth = intent.getIntExtra(GlobalVars.KEY_MONTH,
                9);
        this.currentDay = intent.getIntExtra(GlobalVars.KEY_DAY,
                24);
    }
    private void setListeners() {

        this.setViewClickListeners();
        this.setItemClickListeners();
        this.setItemLongClickListeners();
    }
    private void readSummary() {

        CategorySummaryEntity[] summaryEntities = ExpenditureBll.getInstance()
                .getCategorySummaryItemsByDate(this, this.currentYear,
                        this.currentMonth, this.currentDay);
        if (summaryEntities == null) {

            summaryEntities = new CategorySummaryEntity[0];
        }

        SummaryAdapter adapter = new SummaryAdapter();
        adapter.setData(this.currentYear, this.currentMonth, this.currentDay, summaryEntities);
        this.ui.SummaryListView.setAdapter(adapter);
        adapter.notifyDataSetChanged();
    }
    private void setViewClickListeners() {

        OnMyViewClickListener l = new OnMyViewClickListener();
        this.ui.OKButton.setOnClickListener(l);
    }
    private void setItemClickListeners() {

        OnMyItemClickListener l = new OnMyItemClickListener();
        this.ui.SummaryListView.setOnItemClickListener(l);
    }
    private void setItemLongClickListeners() {

        OnMyItemLongClickListener l = new OnMyItemLongClickListener();
        this.ui.SummaryListView.setOnItemLongClickListener(l);
    }
    private String generateSearchCondition(int position) {

        StringBuilder sb = new StringBuilder();

        sb.append("b.Day like '" + GlobalFuncs.GetMonthString(this.currentYear, this.currentMonth) + "%'\n");
        sb.append("and a.Name like '" + ((CategorySummaryEntity)this.ui.SummaryListView.getItemAtPosition(position)).Category + "%'\n");
        return sb.toString();
    }

    // Classes
    private class Layout {

        public Button OKButton = null;
        public ListView SummaryListView = null;

        public Layout() {

            this.initialize();
        }

        private void initialize() {

            this.OKButton = (Button) MonthSummaryActivity.this
                    .findViewById(R.id.OKButton);
            this.SummaryListView = (ListView) MonthSummaryActivity.this
                    .findViewById(R.id.SummaryListView);
        }
    }
    private class SummaryAdapter extends BaseAdapter {

        private CategorySummaryEntity[] summaryEntities;
        private int currYear;
        private int currMonth;
        private int currDay;
        private LayoutInflater inflater;
        private int selectedIndex = -1;

        public SummaryAdapter() {

            this.inflater = getLayoutInflater();
            this.initDefaultSummary();
        }

        @Override
        public int getCount() {

            return this.summaryEntities.length + 1;
        }

        @Override
        public Object getItem(int position) {

            position--;
            if (position < 0 || position > this.summaryEntities.length - 1) {

                return null;
            }

            return this.summaryEntities[position];
        }

        @Override
        public long getItemId(int position) {

            return position;
        }

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

            String strPredict = getResources().getString(R.string.caption_predict);
            View v;
            if (convertView != null
                    && convertView.getId() == R.id.SimpleListviewItemLayout) {

                v = convertView;

            } else {

                v = this.inflater.inflate(
                        R.layout.widget_listview_item_simple_layout, parent,
                        false);
            }

            TextView tv = (TextView)v.findViewById(R.id.ItemTextView);
            if (position == 0) {

                // The first row: datetime
                tv.setText(String.format("%04d-%02d-%02d", this.currYear, this.currMonth, this.currDay));
                tv.setTextColor(Color.rgb(255, 100, 0));

            } else if (position == this.summaryEntities.length) {

                // The last row: total
                CategorySummaryEntity e = this.summaryEntities[position - 1];
                tv.setText(String.format("%s%.1f %s%.1f", e.Category, e.Amount, strPredict, e.Predict));
                tv.setTextColor(Color.rgb(255, 100, 0));

            } else {

                CategorySummaryEntity e = this.summaryEntities[position - 1];
                tv.setText(String.format("%s%.1f %s%.1f", e.Category, e.Amount, strPredict, e.Predict));
                if (e.LimitMoney != 0 && e.Predict > e.LimitMoney) {

                    tv.setTextColor(Color.RED);

                } else {

                    tv.setTextColor(Color.WHITE);
                }
            }

            if (this.selectedIndex == 0 || this.selectedIndex == this.summaryEntities.length) {

                // The first row and the last row are forbidden to be selected.
                this.selectedIndex = -1;
            }

            if (position == this.selectedIndex) {

                v.setBackgroundColor(Color.rgb(0, 100, 255));

            } else {

                v.setBackgroundColor(Color.BLACK);
            }

            return v;
        }

        public void setData(int year, int month, int day, CategorySummaryEntity[] entities) {

            this.currYear = year;
            this.currMonth = month;
            this.currDay = day;
            if (entities == null) {

                return;
            }

            double sum = 0;
            double predictSum = 0;
            this.summaryEntities = new CategorySummaryEntity[entities.length + 1];
            for (int i = 0; i < entities.length; i++) {

                this.summaryEntities[i] = entities[i];
                sum += entities[i].Amount;
                predictSum += entities[i].Predict;
            }

            CategorySummaryEntity e = new CategorySummaryEntity();
            e.Category = getString(R.string.caption_total);
            e.LimitMoney = 0;
            e.Amount = sum;
            e.Predict = predictSum;
            this.summaryEntities[entities.length] = e;
        }
        public void setSelectedIndex(int index) {

            this.selectedIndex = index;
        }

        private void initDefaultSummary() {

            this.summaryEntities = new CategorySummaryEntity[1];
            CategorySummaryEntity e = new CategorySummaryEntity();
            e.Category = getString(R.string.caption_total);
            e.LimitMoney = 0;
            e.Amount = 0;
            this.summaryEntities[0] = e;
        }
    }
    private class OnMyViewClickListener implements View.OnClickListener {

        @Override
        public void onClick(View v) {

            if (v == MonthSummaryActivity.this.ui.OKButton) {

                MonthSummaryActivity.this.finish();
            }
        }
    }
    private class OnMyItemClickListener implements AdapterView.OnItemClickListener {

        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position,
                                long id) {

            if (parent == MonthSummaryActivity.this.ui.SummaryListView) {

                SummaryAdapter adapter = ((SummaryAdapter)parent.getAdapter());
                adapter.setSelectedIndex(position);
                adapter.notifyDataSetChanged();

                if (position == 0 || position == parent.getCount() - 1) {

                    return;
                }

                String condition = MonthSummaryActivity.this.generateSearchCondition(position);
                Intent intent = new Intent();
                intent.setClass(MonthSummaryActivity.this, ExpenditureDetailActivity.class);
                intent.putExtra(GlobalVars.KEY_SEARCH_CONDITION, condition);
                MonthSummaryActivity.this.startActivity(intent);
            }
        }
    }
    private class OnMyItemLongClickListener implements AdapterView.OnItemLongClickListener {

        @Override
        public boolean onItemLongClick(AdapterView<?> parent, View view,
                                       int position, long id) {

            if (parent == MonthSummaryActivity.this.ui.SummaryListView) {

                SummaryAdapter adapter = ((SummaryAdapter)parent.getAdapter());
                adapter.setSelectedIndex(position);
                adapter.notifyDataSetChanged();
            }

            return false;
        }
    }
}

Here is the code of its layout ("app -> res -> layout -> activity_month_summary.xml"):

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_month_summary"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="#FF000000"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.casperlee.personalexpense.MonthSummaryActivity">

    <LinearLayout
        android:id="@+id/ButtonLayout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentBottom="true"
        android:padding="6dp"
        android:gravity="center">

        <Button
            android:id="@+id/OKButton"
            android:layout_width="160dp"
            android:layout_height="wrap_content"
            android:text="@string/caption_return"
            android:textAppearance="?android:attr/textAppearanceLarge"/>

    </LinearLayout>
    <ListView
        android:id="@+id/SummaryListView"
        android:layout_above="@+id/ButtonLayout"
        android:paddingTop="32dp"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:background="#FF000000"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
    </ListView>
</RelativeLayout>

9. Add a new layout file named "widget_listview_item_double_label_layout.xml" in the folder "app -> res -> layout", and put the following text in:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/SimpleListviewItemLayout"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="#FF000000"
    android:paddingLeft="3dp"
    android:paddingRight="3dp"
    android:paddingTop="9dp"
    android:paddingBottom="9dp" >

    <TextView
        android:id="@+id/ItemTopTextView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingLeft="6dp"
        android:text=""
        android:textColor="#FFFFFFFF"
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <TextView
        android:id="@+id/ItemBottomTextView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingLeft="6dp"
        android:text=""
        android:textColor="#FF3333FF"
        android:textAppearance="?android:attr/textAppearanceMedium" />

</LinearLayout>

10. Add a new Activity class named "ExpenditureDetailActivity" in the folder "app -> java -> com.casperlee.personalexpense", and put the following code in:

package com.casperlee.personalexpense;

import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.graphics.Color;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;

import com.casperlee.personalexpense.bll.ExpenditureBll;
import com.casperlee.personalexpense.entities.CategoryEntity;
import com.casperlee.personalexpense.entities.ExpenditureEntity;
import com.casperlee.personalexpense.global.GlobalVars;

public class ExpenditureDetailActivity extends AppCompatActivity {

    // Fields
    private Layout ui;
    private String searchCondition;

    // Entrances
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_expenditure_detail);
        this.ui = new Layout();

        this.readExtras();
        this.setListeners();
        this.readDetail();
    }
    @Override
    protected void onResume() {
        if (getRequestedOrientation() != ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        }
        super.onResume();
    }

    // Private functions
    private void readExtras() {

        Intent intent = this.getIntent();
        this.searchCondition = intent.getStringExtra(GlobalVars.KEY_SEARCH_CONDITION);
    }
    private void setListeners() {

        this.setViewClickListeners();
        this.setItemClickListeners();
        this.setItemLongClickListeners();
    }
    private void readDetail() {

        ExpenditureEntity[] entities = ExpenditureBll.getInstance()
                .getExpenditureDetailByCondition(this, this.searchCondition);
        if (entities == null) {

            entities = new ExpenditureEntity[0];
        }

        DetailAdapter adapter = new DetailAdapter();
        adapter.setData(entities, GlobalVars.Categories);
        this.ui.DetailListView.setAdapter(adapter);
        adapter.notifyDataSetChanged();
    }
    private void setViewClickListeners() {

        OnMyViewClickListener l = new OnMyViewClickListener();
        this.ui.OKButton.setOnClickListener(l);
    }
    private void setItemClickListeners() {

        OnMyItemClickListener l = new OnMyItemClickListener();
        this.ui.DetailListView.setOnItemClickListener(l);
    }
    private void setItemLongClickListeners() {

        OnMyItemLongClickListener l = new OnMyItemLongClickListener();
        this.ui.DetailListView.setOnItemLongClickListener(l);
    }


    // Classes
    private class Layout {

        public Button OKButton = null;
        public ListView DetailListView = null;

        public Layout() {

            this.initialize();
        }

        private void initialize() {

            this.OKButton = (Button) ExpenditureDetailActivity.this
                    .findViewById(R.id.OKButton);
            this.DetailListView = (ListView) ExpenditureDetailActivity.this
                    .findViewById(R.id.DetailListView);
        }
    }
    private class OnMyViewClickListener implements View.OnClickListener {

        @Override
        public void onClick(View v) {

            if (v == ExpenditureDetailActivity.this.ui.OKButton) {

                ExpenditureDetailActivity.this.finish();
            }
        }
    }
    private class OnMyItemClickListener implements AdapterView.OnItemClickListener {

        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position,
                                long id) {

            if (parent == ExpenditureDetailActivity.this.ui.DetailListView) {

                DetailAdapter adapter = ((DetailAdapter)parent.getAdapter());
                adapter.setSelectedIndex(position);
                adapter.notifyDataSetChanged();
            }
        }
    }
    private class OnMyItemLongClickListener implements AdapterView.OnItemLongClickListener {

        @Override
        public boolean onItemLongClick(AdapterView<?> parent, View view,
                                       int position, long id) {

            if (parent == ExpenditureDetailActivity.this.ui.DetailListView) {

                DetailAdapter adapter = ((DetailAdapter)parent.getAdapter());
                adapter.setSelectedIndex(position);
                adapter.notifyDataSetChanged();
            }

            return false;
        }

    }
    private class DetailAdapter extends BaseAdapter {

        // Fields
        private ExpenditureEntity[] expenditureEntities;
        private CategoryEntity[] categoryEntities;
        private LayoutInflater inflater;
        private int selectedIndex = -1;

        // Constructors
        public DetailAdapter() {

            this.inflater = getLayoutInflater();
            this.initDefault();
        }

        // Overrided methods
        @Override
        public int getCount() {

            return this.expenditureEntities.length;
        }
        @Override
        public Object getItem(int position) {

            if (position < 0 || position > this.expenditureEntities.length - 1) {

                return null;
            }

            return this.expenditureEntities[position];
        }
        @Override
        public long getItemId(int position) {

            return position;
        }
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {

            View v;
            if (convertView != null
                    && convertView.getId() == R.id.DetailListView) {

                v = convertView;

            } else {

                v = this.inflater.inflate(
                        R.layout.widget_listview_item_double_label_layout, parent,
                        false);
            }

            TextView tvTop = (TextView)v.findViewById(R.id.ItemTopTextView);
            TextView tvBottom = (TextView)v.findViewById(R.id.ItemBottomTextView);

            ExpenditureEntity e = this.expenditureEntities[position];
            tvTop.setText(String.format("%s %s %.1f", e.getDay(), this.getCategoryString(e.getCategoryID()), e.getAmount()));
            tvBottom.setText(e.getRemark());

            if (position == this.selectedIndex) {

                v.setBackgroundColor(Color.rgb(0, 100, 255));

            } else {

                v.setBackgroundColor(Color.BLACK);
            }

            return v;
        }

        public void setData(ExpenditureEntity[] entities, CategoryEntity[] cEntities) {

            if (entities == null || cEntities == null) {

                return;
            }

            this.expenditureEntities = entities;
            this.categoryEntities = cEntities;
        }
        public void setSelectedIndex(int index) {

            this.selectedIndex = index;
        }

        // Private methods
        private void initDefault() {

            this.expenditureEntities = new ExpenditureEntity[0];
            this.categoryEntities = new CategoryEntity[0];
        }
        private String getCategoryString(int id) {

            String ret = "δ֪";
            for (int i = 0; i < this.categoryEntities.length; i++) {

                if (this.categoryEntities[i].getId() == id) {

                    return this.categoryEntities[i].getName();
                }
            }

            return ret;
        }
    }
}

Here is the code of its layout ("app -> res -> layout -> activity_expenditure_detail.xml"):

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_expenditure_detail"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="#FF000000"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.casperlee.personalexpense.ExpenditureDetailActivity">

    <LinearLayout
        android:id="@+id/ButtonLayout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentBottom="true"
        android:padding="6dp"
        android:gravity="center">

        <Button
            android:id="@+id/OKButton"
            android:layout_width="160dp"
            android:layout_height="wrap_content"
            android:text="@string/caption_return"
            android:textAppearance="?android:attr/textAppearanceLarge"/>

    </LinearLayout>
    <ListView
        android:id="@+id/DetailListView"
        android:layout_above="@+id/ButtonLayout"
        android:paddingTop="32dp"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:background="#FF000000"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
    </ListView>

</RelativeLayout>

11. Open the file "app -> java -> com.casperlee.personalexpense -> AddExpenseActivity", add the following code into it:

...
import com.casperlee.personalexpense.global.GlobalFuncs;
...
    private void PerformTotalMoneyTextClick() {

        Intent intent = new Intent();

        Calendar c = Calendar.getInstance();
        if (this.currentYear == c.get(Calendar.YEAR)
                && this.currentMonth == c.get(Calendar.MONTH) + 1
                && this.currentDay == c.get(Calendar.DAY_OF_MONTH)) {

            intent.setClass(this, MonthSummaryActivity.class);

        } else {

            /*
            intent.setClass(this, AccumulateActivity.class);
            */
        }

        intent.putExtra(GlobalVars.KEY_YEAR, this.currentYear);
        intent.putExtra(GlobalVars.KEY_MONTH, this.currentMonth);
        intent.putExtra(GlobalVars.KEY_DAY, this.currentDay);
        this.startActivity(intent);
    }
...

12. Done!