Android Open Source - journal Main Activity






From Project

Back to project page journal.

License

The source code is released under:

MIT License

If you think the Android project journal listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 * The MIT License (MIT)/*  www .j  a  v a2  s.  c  o  m*/
 * 
 * Copyright (c) 2014 by cochrane343
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

package cochrane343.journal;

import android.app.AlertDialog;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import android.os.Parcelable;
import android.preference.PreferenceManager;
import android.support.v4.app.FragmentManager;
import android.support.v4.view.ViewPager;
import android.support.v7.app.ActionBarActivity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.CheckBox;
import android.widget.Toast;
import cochrane343.journal.contentprovider.JournalContract.Expense;
import cochrane343.journal.dialogs.ExpenseDialogFragment;
import cochrane343.journal.dialogs.ExpenseDialogListener;

/**
 * @author cochrane343
 */
public class MainActivity extends ActionBarActivity
    implements ExpenseEditListener, ExpenseDialogListener {
    
    private static final String BUNDLE_KEY_MONTHLY_PAGER_ADAPTER_STATE = "monthlyPagerAdapterState";
    private static final String FRAGMENT_TAG_EXPENSE_DIALOG = "expenseDialog";
    
    /**
     * The view pager used to swipe through months
     */
    private ViewPager viewPager;
    private MonthlyExpensesPagerAdapter monthlyExpensesPagerAdapter;
    
    /* - - - - - Activity Lifecycle - - - - - - - - - - */
    
    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        setContentView(R.layout.main_activity);
            
        monthlyExpensesPagerAdapter = new MonthlyExpensesPagerAdapter(getSupportFragmentManager());
        
        viewPager = (ViewPager) findViewById(R.id.main_activity_view_pager);
        viewPager.setAdapter(monthlyExpensesPagerAdapter);
        
        if (savedInstanceState != null) {
            final Parcelable monthlyPagerAdapterState = 
                savedInstanceState.getParcelable(BUNDLE_KEY_MONTHLY_PAGER_ADAPTER_STATE);
            monthlyExpensesPagerAdapter.restoreState(monthlyPagerAdapterState, getClassLoader());
        } else {
            viewPager.setCurrentItem(DateTimeHelper.getMonthsSinceEpoch());     
        }
    }

    /**
     * Inflates the menu of this activity and adds action items to the action bar.
     */
    @Override
    public boolean onCreateOptionsMenu(final Menu menu) {
        final MenuInflater inflater = getMenuInflater();

        inflater.inflate(R.menu.activity_main_actions, menu);
        
        return super.onCreateOptionsMenu(menu);
    }
    
    @Override
    public void onSaveInstanceState(final Bundle savedInstanceState) {
        savedInstanceState.putParcelable(BUNDLE_KEY_MONTHLY_PAGER_ADAPTER_STATE, monthlyExpensesPagerAdapter.saveState());
        
        super.onSaveInstanceState(savedInstanceState);
    }
    
    /* - - - - - Expense Edit Listener - - - - - - - - - - */

    @Override
    public void onAddExpense(final String description, final long costInCents,
            final long category) {
        final int selectedMonth = viewPager.getCurrentItem();
        final boolean selectedMonthIsCurrentMonth = selectedMonth == DateTimeHelper.getMonthsSinceEpoch();
        
        if (selectedMonthIsCurrentMonth) {
            addExpenseToCurrentMonth(description, costInCents, category);
        } else {
            if (shouldShowPastExpenseWarning()) {
                // TODO Consider refactoring into separate method
                final LayoutInflater inflater = LayoutInflater.from(this);
                final View warningLayout = inflater.inflate(R.layout.past_expense_warning, null);
                final CheckBox doNotAskAgainCheckbox = (CheckBox) warningLayout.findViewById(R.id.do_not_show_again);

                final AlertDialog.Builder builder = new AlertDialog.Builder(this);
                builder.setView(warningLayout)
                    .setTitle(R.string.label_past_expense)
                    .setMessage(R.string.label_past_expense_message)
                    .setPositiveButton(R.string.label_yes_add_to_past, new DialogInterface.OnClickListener() { 
                        public void onClick(final DialogInterface dialog, final int which) {
                            if (doNotAskAgainCheckbox.isChecked()) {
                                setShowPastExpenseWarning(false);
                            }
                            addExpenseToEndOfSelectedMonth(description, costInCents, category);
                        } })
                    .setNegativeButton(R.string.label_no_add_to_current, new DialogInterface.OnClickListener() { 
                        public void onClick(DialogInterface dialog, int which) {
                            if (doNotAskAgainCheckbox.isChecked()) {
                                setShowPastExpenseWarning(false);
                            }
                            addExpenseToCurrentMonth(description, costInCents, category);
                    } })
                    .show();
            } else {
                addExpenseToEndOfSelectedMonth(description, costInCents, category);
            }
        }
    }
    
    /**
     * Adds a new expense with a current timestamp.
     * Used to add expenses to the ongoing month.
     * @since 0.11.0
     */
    private void addExpenseToCurrentMonth(final String description, final long costInCents,
            final long category) {
        final long currentTimestamp = DateTimeHelper.getNow().getMillis();
        
        addExpense(description, costInCents, category, currentTimestamp);
    }
    
    /**
     * Adds a new expense with the end of the currently selected month as timestamp.
     * Used to add expenses to past months.
     * @since 0.11.0
     */
    private void addExpenseToEndOfSelectedMonth(final String description, final long costInCents,
            final long category) {
        final int selectedMonth = viewPager.getCurrentItem();
        final long endOfSelectedMonthTimestamp = DateTimeHelper.getEndOfMonth(selectedMonth).getMillis();
        
        addExpense(description, costInCents, category, endOfSelectedMonthTimestamp);
    }
    
    /**
     * @since 0.11.0
     */
    private void addExpense(final String description, final long costInCents,
            final long category, final long timestamp) {
        final ContentValues newExpense = getContentValues(description, costInCents, category);
        
        newExpense.put(Expense._TIMESTAMP, timestamp);
        
        getContentResolver().insert(Expense.EXPENSES_URI, newExpense);

        Toast.makeText(this, R.string.toast_added_expense, Toast.LENGTH_SHORT).show();
    }
    
    @Override
    public void onUpdateExpense(final long expenseId, final String description,
            final long costInCents, final long category) {
        final ContentValues newExpense = getContentValues(description, costInCents,category);
        
        final Uri uri = ContentUris.withAppendedId(Expense.EXPENSES_URI, expenseId);
        
        getContentResolver().update(uri, newExpense, null, null);
        
        Toast.makeText(this, R.string.toast_updated_expense, Toast.LENGTH_SHORT).show();
    }
    
    private ContentValues getContentValues(final String description,
            final long costInCents, final long category) {
        final ContentValues newExpense = new ContentValues();
        
        newExpense.put(Expense._DESCRIPTION, description);
        newExpense.put(Expense._COST, costInCents);
        newExpense.put(Expense._CATEGORY, category);
        
        return newExpense;
    }
    
    @Override
    public void onDeleteExpense(final long expenseId) {
        final Uri uri = ContentUris.withAppendedId(Expense.EXPENSES_URI, expenseId);
        getContentResolver().delete(uri, null, null);
    }
    
    /* - - - - - User Interface Callbacks - - - - - - - - - - */
    
    /**
     * Handles presses on the action bar items.
     */
    @Override
    public boolean onOptionsItemSelected(final MenuItem item) {
        switch (item.getItemId()) {
            case R.id.action_add_expense:
                showExpenseDialogForCreate();
                return true;
            case R.id.action_settings:
                startActivity(new Intent(getApplicationContext(), SettingsActivity.class));
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }
    
    /**
     * Callback method invoked when the activity has detected the user's press of the
     * back key. Forwards the event to the currently displayed {@link MonthlyExpensesFragment}.
     * Propagates the event further if the fragment does not consume it.
     * Used to allow the user to navigate from single category display back to the
     * category overview.
     */
    @Override
    public void onBackPressed() {
        final MonthlyExpensesFragment currentFragment
                = (MonthlyExpensesFragment) monthlyExpensesPagerAdapter.instantiateItem(viewPager, viewPager.getCurrentItem());
        final boolean backPressConsumed = currentFragment.onBackPressed();
        
        if(!backPressConsumed) {
            super.onBackPressed();
        };
    }
    
    /* - - - - - Expense Dialog - - - - - - - - - - */
    
    @Override
    public void showExpenseDialogForCreate() {
        final FragmentManager fragmentManager = getSupportFragmentManager();

        final ExpenseDialogFragment expenseDialog = ExpenseDialogFragment.newInstanceForCreate();
        
        expenseDialog.show(fragmentManager, FRAGMENT_TAG_EXPENSE_DIALOG);
    }

    @Override
    public void showExpenseDialogForEdit(final long expenseId) {
        final FragmentManager fragmentManager = getSupportFragmentManager();

        final ExpenseDialogFragment expenseDialog = ExpenseDialogFragment.newInstanceForEdit(expenseId);
        
        expenseDialog.show(fragmentManager, FRAGMENT_TAG_EXPENSE_DIALOG);
    }
    
    /* - - - - - Settings - - - - - - - - - - */

    /**
     * Changes the setting for showing a warning when adding an expense to a past month.
     * @param shouldShowPastExpenseWarning true to enable the warning or false to disable it
     * @since 0.11.0
     */
    private void setShowPastExpenseWarning(final boolean shouldShowPastExpenseWarning) {
        final SharedPreferences defaultPreferences = PreferenceManager.getDefaultSharedPreferences(this);
        final SharedPreferences.Editor editor = defaultPreferences.edit();
        
        final String preferenceKey = getString(R.string.preference_key_show_past_expense_warning);
        
        editor.putBoolean(preferenceKey, shouldShowPastExpenseWarning);   

        editor.commit(); 
    }
    
    /**
     * @return true if showing a warning when adding an expense to a past month is enabled -
     * false if the warning is disabled
     * @since 0.11.0
     */
    private boolean shouldShowPastExpenseWarning() {
        final SharedPreferences defaultPreferences = PreferenceManager.getDefaultSharedPreferences(this);
        
        final String preferenceKey = getString(R.string.preference_key_show_past_expense_warning);
        
        final String preferenceDefaultString = getString(R.string.preference_default_show_past_expense_warning);
        final boolean preferenceDefault = Boolean.parseBoolean(preferenceDefaultString);
      
        return defaultPreferences.getBoolean(preferenceKey, preferenceDefault);
    }

}




Java Source Code List

cochrane343.journal.Constants.java
cochrane343.journal.CurrencyHelper.java
cochrane343.journal.DateTimeHelper.java
cochrane343.journal.ExpenseEditListener.java
cochrane343.journal.ExpensesListAdapter.java
cochrane343.journal.MainActivity.java
cochrane343.journal.MonthlyExpensesFragment.java
cochrane343.journal.MonthlyExpensesPagerAdapter.java
cochrane343.journal.SettingsActivity.java
cochrane343.journal.TranslationHelper.java
cochrane343.journal.contentprovider.JournalContentProvider.java
cochrane343.journal.contentprovider.JournalContract.java
cochrane343.journal.contentprovider.JournalDatabaseHelper.java
cochrane343.journal.dialogs.CategorySpinnerAdapter.java
cochrane343.journal.dialogs.ExpenseDialogFragment.java
cochrane343.journal.dialogs.ExpenseDialogListener.java
cochrane343.journal.exceptions.IllegalDisplayModeException.java
cochrane343.journal.exceptions.IllegalLoaderIdException.java
cochrane343.journal.exceptions.IllegalUriException.java
cochrane343.journal.exceptions.MissingFragmentArgumentException.java