net.alexjf.tmm.fragments.DateIntervalBarFragment.java Source code

Java tutorial

Introduction

Here is the source code for net.alexjf.tmm.fragments.DateIntervalBarFragment.java

Source

/*******************************************************************************
 * Copyright (c) 2013 - Alexandre Jorge Fonseca (alexjf.net)
 * License: GPL v3 (http://www.gnu.org/licenses/gpl-3.0.txt)
 ******************************************************************************/
package net.alexjf.tmm.fragments;

import android.app.Activity;
import android.app.DatePickerDialog.OnDateSetListener;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.Spinner;
import net.alexjf.tmm.R;
import net.alexjf.tmm.utils.PreferenceManager;

import java.text.DateFormat;
import java.text.ParseException;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;

public class DateIntervalBarFragment extends Fragment implements OnDateSetListener {
    private static String KEY_CURRENTSTARTDATE = "startDate";
    private static String KEY_CURRENTENDDATE = "endDate";
    private static String KEY_SPINNERSELECTION = "spinnerSelection";
    private static String KEY_STARTDATEEDIT = "startTimeEdit";

    private static String PREFKEY_DEFAULTTIMEINTERVAL = "pref_key_default_timeinterval";

    private static String TAG_DATEPICKER = "datePicker";

    private String[] dateIntervalTypes;

    private OnDateIntervalChangedListener listener;

    private Calendar startDate;
    private Calendar endDate;
    private static DateFormat dateTimeFormat = DateFormat.getDateTimeInstance();
    private static DateFormat dateFormat = DateFormat.getDateInstance();
    private boolean startDateBeingEdited;
    private boolean allTime;

    private DatePickerFragment datePicker;

    private Spinner dateIntervalSpinner;
    private Button startDateButton;
    private Button endDateButton;
    private View customSelector;

    public interface OnDateIntervalChangedListener {
        /**
         * Receives notification of date interval change on DateIntervalBar.
         * <p/>
         * New date interval between startDate and endDate. If these are null,
         * no limit established on start/end.
         *
         * @param startDate Starting date of interval.
         * @param endDate   Ending date of interval.
         */
        public void onDateIntervalChanged(Date startDate, Date endDate);
    }

    public DateIntervalBarFragment() {
        allTime = false;
        resetDates();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, final Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment_dateinterval_bar, container, false);

        dateIntervalTypes = getResources().getStringArray(R.array.date_intervals_values);

        dateIntervalSpinner = (Spinner) v.findViewById(R.id.interval_spinner);
        startDateButton = (Button) v.findViewById(R.id.start_button);
        endDateButton = (Button) v.findViewById(R.id.end_button);
        customSelector = v.findViewById(R.id.custom_selector);

        int selectedSpinnerPos = 0;

        if (savedInstanceState != null) {
            try {
                startDate.setTime(dateTimeFormat.parse(savedInstanceState.getString(KEY_CURRENTSTARTDATE)));
            } catch (ParseException e) {
                Log.e("TMM", "Error parsing saved start date", e);
            }
            try {
                endDate.setTime(dateTimeFormat.parse(savedInstanceState.getString(KEY_CURRENTENDDATE)));
            } catch (ParseException e) {
                Log.e("TMM", "Error parsing saved end date", e);
            }

            selectedSpinnerPos = savedInstanceState.getInt(KEY_SPINNERSELECTION);
            startDateBeingEdited = savedInstanceState.getByte(KEY_STARTDATEEDIT) == 1;
        } else {
            PreferenceManager prefManager = PreferenceManager.getInstance();
            String prefDateInterval = prefManager.readUserStringPreference(PREFKEY_DEFAULTTIMEINTERVAL, null);
            if (prefDateInterval != null) {
                selectedSpinnerPos = Arrays.asList(dateIntervalTypes).indexOf(prefDateInterval);
            }
        }

        dateIntervalSpinner.setSelection(selectedSpinnerPos, false);
        final int positionToSelect = selectedSpinnerPos;

        // Hack to ignore initial onItemSelecteds due to layout and measure
        dateIntervalSpinner.post(new Runnable() {
            public void run() {
                dateIntervalSpinner.setOnItemSelectedListener(new OnItemSelectedListener() {
                    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                        setDateInterval(position);
                        notifyDatesChanged();
                    }

                    public void onNothingSelected(AdapterView<?> parent) {
                    }
                });

                setDateInterval(positionToSelect);
                notifyDatesChanged();
            }
        });

        datePicker = (DatePickerFragment) getFragmentManager().findFragmentByTag(TAG_DATEPICKER);

        if (datePicker == null) {
            datePicker = new DatePickerFragment();
        }

        datePicker.setListener(this);

        startDateButton.setOnClickListener(new OnClickListener() {
            public void onClick(View view) {
                try {
                    datePicker.setDate(dateFormat.parse(startDateButton.getText().toString()));
                } catch (ParseException e) {
                }
                startDateBeingEdited = true;
                datePicker.show(getFragmentManager(), TAG_DATEPICKER);
            }
        });

        endDateButton.setOnClickListener(new OnClickListener() {
            public void onClick(View view) {
                try {
                    datePicker.setDate(dateFormat.parse(endDateButton.getText().toString()));
                } catch (ParseException e) {
                }
                startDateBeingEdited = false;
                datePicker.show(getFragmentManager(), TAG_DATEPICKER);
            }
        });

        return v;
    }

    @Override
    public void onDestroyView() {
        // Hack to ignore initial onItemSelecteds due to layout and measure
        dateIntervalSpinner.setOnItemSelectedListener(null);
        super.onDestroyView();
    }

    ;

    @Override
    public void onDateSet(DatePicker view, int year, int month, int day) {
        Calendar calendar;

        if (startDateBeingEdited) {
            calendar = startDate;
        } else {
            calendar = endDate;
        }

        calendar.set(year, month, day);
        updateDateButtons();
        notifyDatesChanged();
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            listener = (OnDateIntervalChangedListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString() + " must implement OnDateIntervalChangedListener");
        }
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        outState.putString(KEY_CURRENTSTARTDATE, dateTimeFormat.format(startDate.getTime()));
        outState.putString(KEY_CURRENTENDDATE, dateTimeFormat.format(endDate.getTime()));
        outState.putInt(KEY_SPINNERSELECTION, dateIntervalSpinner.getSelectedItemPosition());
        outState.putByte(KEY_STARTDATEEDIT, (byte) (startDateBeingEdited ? 1 : 0));
        super.onSaveInstanceState(outState);
    }

    public boolean isAllTime() {
        return allTime;
    }

    public Date getStartDate() {
        return startDate.getTime();
    }

    public Date getEndDate() {
        return endDate.getTime();
    }

    public void setStartDate(Date date) {
        startDate.setTime(date);
        updateDateButtons();
        notifyDatesChanged();
    }

    public void setEndDate(Date date) {
        endDate.setTime(date);
        updateDateButtons();
        notifyDatesChanged();
    }

    private void notifyDatesChanged() {
        if (listener == null) {
            return;
        }

        if (allTime) {
            listener.onDateIntervalChanged(null, null);
        } else {
            listener.onDateIntervalChanged(startDate.getTime(), endDate.getTime());
        }
    }

    private void resetDates() {
        startDate = Calendar.getInstance();
        startDate.set(Calendar.HOUR_OF_DAY, 0);
        startDate.set(Calendar.MINUTE, 0);
        startDate.set(Calendar.SECOND, 0);
        endDate = Calendar.getInstance();
        endDate.set(Calendar.HOUR_OF_DAY, 23);
        endDate.set(Calendar.MINUTE, 59);
        endDate.set(Calendar.SECOND, 59);
    }

    private void setDateInterval(int position) {
        String dateIntervalType = dateIntervalTypes[position];

        if (dateIntervalType.equals("custom")) {
            allTime = false;
            customSelector.setVisibility(View.VISIBLE);
            updateDateButtons();
        }
        // If all time
        else if (dateIntervalType.equals("all_time")) {
            allTime = true;
            customSelector.setVisibility(View.GONE);
        } else {
            allTime = false;
            customSelector.setVisibility(View.GONE);
            resetDates();
            if (dateIntervalType.equals("yesterday")) {
                startDate.add(Calendar.DAY_OF_MONTH, -1);
                endDate.add(Calendar.DAY_OF_MONTH, -1);
            } else if (dateIntervalType.equals("this_week") || dateIntervalType.equals("last_week")) {
                int positionInWeek = startDate.get(Calendar.DAY_OF_WEEK) - startDate.getFirstDayOfWeek();
                startDate.add(Calendar.DAY_OF_WEEK, -positionInWeek);
                endDate.add(Calendar.DAY_OF_YEAR, 6 - positionInWeek);

                if (dateIntervalType.equals("last_week")) {
                    startDate.add(Calendar.DAY_OF_YEAR, -7);
                    endDate.add(Calendar.DAY_OF_YEAR, -7);
                }
            } else if (dateIntervalType.equals("this_month")) {
                startDate.set(Calendar.DAY_OF_MONTH, 1);
                endDate.set(Calendar.DAY_OF_MONTH, endDate.getActualMaximum(Calendar.DAY_OF_MONTH));
            } else if (dateIntervalType.equals("last_month")) {
                startDate.add(Calendar.MONTH, -1);
                endDate.add(Calendar.MONTH, -1);
                startDate.set(Calendar.DAY_OF_MONTH, 1);
                endDate.set(Calendar.DAY_OF_MONTH, endDate.getActualMaximum(Calendar.DAY_OF_MONTH));
            } else if (dateIntervalType.equals("this_year")) {
                startDate.set(Calendar.DAY_OF_YEAR, 1);
                endDate.set(Calendar.DAY_OF_YEAR, endDate.getActualMaximum(Calendar.DAY_OF_YEAR));
            }
        }
    }

    private void updateDateButtons() {
        String startDateString = dateFormat.format(startDate.getTime());
        String endDateString = dateFormat.format(endDate.getTime());

        startDateButton.setText(startDateString);
        endDateButton.setText(endDateString);
    }
}