Programming     Travel Logs     Life Is Good     Surfing Online     About Me
Specific knowledge is found by pursuing your genuine curiosity and passion rather than whatever is hot right now.
-Naval Ravikant
2018-07-17 18:08:52

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

The code for the Search Module 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/20171009/01.jpg

/Images/20171009/02.jpg

/Images/20171009/03.jpg

/Images/20171009/04.jpg

/Images/20171009/05.jpg

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

<string name="mi_search_title">Search</string>
    <string name="caption_money_bigger_than">Money ></string>

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

<string name="mi_search_title">查询</string>
    <string name="caption_money_bigger_than">金额 ></string>

3. Add a new class named "SearchActivity" 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.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioGroup;
import android.widget.Spinner;
import android.widget.TextView;

import com.casperlee.personalexpense.global.GlobalVars;

public class SearchActivity extends AppCompatActivity {

    // Constants
    public static final int REQUEST_SELECT_DATE_RANGE = 0x1000;

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

    // SearchCondition
    private int startYear;
    private int startMonth;
    private int stopYear;
    private int stopMonth;
    private String category;
    private double minMoney;

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

        this.readExtras();
        this.initWidgets();
        this.setListeners();
    }

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

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
            case REQUEST_SELECT_DATE_RANGE:
                startYear = data.getIntExtra(SelectDateRangeActivity.KEY_START_YEAR, this.currentYear);
                startMonth = data.getIntExtra(SelectDateRangeActivity.KEY_START_MONTH, this.currentMonth);
                stopYear = data.getIntExtra(SelectDateRangeActivity.KEY_STOP_YEAR, this.currentYear);
                stopMonth = data.getIntExtra(SelectDateRangeActivity.KEY_STOP_MONTH, this.currentMonth);
                ui.CurrentDateRangeTextView.setText(String.format("%04d.%02d - %04d.%02d", startYear, startMonth, stopYear, stopMonth));
                this.doSearch();
                break;
            default:
                break;
        }
    }

    // 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);
    }
    private void initWidgets() {

        startYear = this.currentYear;
        startMonth = this.currentMonth;
        stopYear = this.currentYear;
        stopMonth = this.currentMonth;
        ui.CurrentDateRangeTextView.setText(String.format("%04d.%02d", this.currentYear, this.currentMonth));
    }
    private void setListeners() {

        OnMyCheckedChangeListener l = new OnMyCheckedChangeListener();
        ui.RangeRadioGroup.setOnCheckedChangeListener(l);

        OnMyViewClickListener l2 = new OnMyViewClickListener();
        this.ui.OKButton.setOnClickListener(l2);
    }
    private void doSearch() {

        // get search condition
        this.category = (String)ui.CategorySpinner.getSelectedItem();

        this.minMoney = 0;

        try {

            this.minMoney = Double.parseDouble(ui.MoneyEditText.getText().toString());

        } catch (NumberFormatException ex) {

            this.minMoney = 0;
        }

        String condition = this.generateSearchCondition();
        Intent intent = new Intent();
        intent.setClass(SearchActivity.this, ExpenditureDetailActivity.class);
        intent.putExtra(GlobalVars.KEY_SEARCH_CONDITION, condition);
        startActivity(intent);
    }
    private String generateSearchCondition() {

        StringBuilder sb = new StringBuilder();

        String start = String.format("%04d%02d%02d", startYear, startMonth, 1);
        String stop = String.format("%04d%02d%02d", stopYear, stopMonth, 31);

        sb.append("b.Day between '" + start + "' and '" + stop + "'\n");
        if (this.category != "Ыљга") {

            sb.append("and a.Name like '" + this.category + "%'\n");
        }

        sb.append("and b.Amount >= " + this.minMoney);
        return sb.toString();
    }

    // Event handlers
    private void performRadioButtonCheckedChanged(int checkedId) {

        switch (checkedId) {
            case R.id.CurrentMonthRadioButton:
                startYear = this.currentYear;
                startMonth = this.currentMonth;
                stopYear = this.currentYear;
                stopMonth = this.currentMonth;
                ui.CurrentDateRangeTextView.setText(String.format("%04d.%02d", this.currentYear, this.currentMonth));
                break;

            case R.id.CurrentYearRadioButton:
                startYear = this.currentYear;
                startMonth = 1;
                stopYear = this.currentYear;
                stopMonth = 12;
                ui.CurrentDateRangeTextView.setText(String.format("%04d.%02d - %04d.%02d", this.currentYear, 1, this.currentYear, 12));
                break;

            case R.id.CustomRadioButton:
                Intent intent = new Intent();
                intent.setClass(SearchActivity.this, SelectDateRangeActivity.class);
                intent.putExtra(SelectDateRangeActivity.KEY_START_YEAR, this.currentYear);
                intent.putExtra(SelectDateRangeActivity.KEY_START_MONTH, 1);
                intent.putExtra(SelectDateRangeActivity.KEY_START_DAY, 1);
                intent.putExtra(SelectDateRangeActivity.KEY_STOP_YEAR, this.currentYear);
                intent.putExtra(SelectDateRangeActivity.KEY_STOP_MONTH, 12);
                intent.putExtra(SelectDateRangeActivity.KEY_STOP_DAY, 1);
                intent.putExtra(SelectDateRangeActivity.KEY_IGNORE_DAY, true);
                this.startActivityForResult(intent, REQUEST_SELECT_DATE_RANGE);
                break;
        }
    }
    private void performOkButtonClick() {

        this.doSearch();
    }

    // Classes
    private class Layout {

        public TextView CurrentDateRangeTextView = null;
        public RadioGroup RangeRadioGroup = null;
        public Spinner CategorySpinner = null;
        public EditText MoneyEditText = null;
        public Button OKButton = null;

        // Constructors
        public Layout() {

            this.initialize();
            this.bindSpinners();
        }

        // Private methods
        private void initialize() {

            this.CurrentDateRangeTextView = (TextView)SearchActivity.this.findViewById(R.id.CurrentDateRangeTextView);
            this.RangeRadioGroup = (RadioGroup)SearchActivity.this.findViewById(R.id.RangeRadioGroup);
            this.CategorySpinner = (Spinner)SearchActivity.this.findViewById(R.id.CategorySpinner);
            this.MoneyEditText = (EditText)SearchActivity.this.findViewById(R.id.MoneyEditText);
            this.OKButton = (Button)SearchActivity.this.findViewById(R.id.OKButton);
        }
        private void bindSpinners() {

            String[] items = new String[GlobalVars.Categories.length];
            items[0] = "Ыљга";
            for (int i = 1; i < items.length; i++) {

                items[i] = GlobalVars.Categories[i - 1].getName();
            }

            this.bindSpinner(this.CategorySpinner, items);
        }
        private void bindSpinner(Spinner spinner, String[] items) {

            ArrayAdapter<String> adapter = new ArrayAdapter<String>(
                    SearchActivity.this,
                    android.R.layout.simple_spinner_item, items);
            adapter.setDropDownViewResource(android.R.layout.select_dialog_singlechoice);
            spinner.setAdapter(adapter);
        }
    }
    private class OnMyCheckedChangeListener implements RadioGroup.OnCheckedChangeListener {

        @Override
        public void onCheckedChanged(RadioGroup group, int checkedId) {

            if (group == SearchActivity.this.ui.RangeRadioGroup) {

                SearchActivity.this.performRadioButtonCheckedChanged(checkedId);
            }
        }
    }
    private class OnMyViewClickListener implements View.OnClickListener {

        @Override
        public void onClick(View v) {

            if (v == ui.OKButton) {

                SearchActivity.this.performOkButtonClick();
            }
        }
    }
}

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

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_search"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="#FF000000"
    android:gravity="left|center_vertical"
    android:paddingLeft="16dp"
    tools:context="com.casperlee.personalexpense.SearchActivity">

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

        <TextView
            style="@style/LargeWhiteText"
            android:id="@+id/CurrentDateRangeTextView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

    </LinearLayout>

    <RadioGroup
        android:id="@+id/RangeRadioGroup"
        android:orientation="horizontal"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:layout_marginBottom="16dp" >

        <RadioButton
            style="@style/MediumWhiteText"
            android:id="@+id/CurrentMonthRadioButton"
            android:checked="true"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/caption_current_month" />

        <RadioButton
            style="@style/MediumWhiteText"
            android:id="@+id/CurrentYearRadioButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/caption_current_year" />

        <RadioButton
            style="@style/MediumWhiteText"
            android:id="@+id/CustomRadioButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/caption_custom" />
    </RadioGroup>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="16dp"
        android:gravity="center_vertical">

        <TextView
            style="@style/LargeWhiteText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/caption_category" />

        <Spinner
            android:id="@+id/CategorySpinner"
            android:theme="@android:style/Theme.Light"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textAppearance="?android:attr/textAppearanceMedium"/>

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_vertical"
        android:layout_marginBottom="24dp">

        <TextView
            style="@style/LargeWhiteText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/caption_money_bigger_than" />

        <EditText
            android:id="@+id/MoneyEditText"
            android:theme="@android:style/Theme.Light"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:ems="10"
            android:inputType="numberDecimal" >

        </EditText>

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:gravity="center">

        <Button
            android:id="@+id/OKButton"
            android:theme="@android:style/Theme.Light"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:text="@string/btn_ok_caption" />

    </LinearLayout>
</LinearLayout>

4. Open the file "app -> res -> menu-> main.xml", add the following menu item into it:

<item android:id="@+id/miSearch" android:title="@string/mi_search_title"/>

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

@Override
    public boolean onOptionsItemSelected(MenuItem item) {

        Intent intent;
        switch (item.getItemId()) {

            case R.id.miSearch:
                intent = new Intent();
                intent.setClass(this, SearchActivity.class);
                intent.putExtra(GlobalVars.KEY_YEAR, this.currentYear);
                intent.putExtra(GlobalVars.KEY_MONTH, this.currentMonth);
                this.startActivity(intent);
                break;

...

6. Done!