com.physphil.android.restaurantroulette.RestaurantFragment.java Source code

Java tutorial

Introduction

Here is the source code for com.physphil.android.restaurantroulette.RestaurantFragment.java

Source

/**
 * Restaurant Roulette for Android
 * Copyright (C) 2014  Phil Shadlyn
 *
 * Restaurant Roulette is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * @copyright 2014 Phil Shadlyn - physphil@gmail.com
 * @license GNU General Public License - https://www.gnu.org/licenses/gpl.html
 */

package com.physphil.android.restaurantroulette;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.graphics.Typeface;
import android.location.Location;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.Fragment;
import android.support.v4.content.LocalBroadcastManager;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RatingBar;
import android.widget.Spinner;
import android.widget.TextView;

import com.physphil.android.restaurantroulette.data.DatabaseHelper;
import com.physphil.android.restaurantroulette.models.Restaurant;
import com.physphil.android.restaurantroulette.ui.CustomFontArrayAdapter;
import com.physphil.android.restaurantroulette.util.Constants;
import com.physphil.android.restaurantroulette.util.LocationHelper;
import com.physphil.android.restaurantroulette.util.Util;

/**
 * Created by pshadlyn on 2/24/14.
 */
public class RestaurantFragment extends Fragment {

    public static final String ACTION_DELETE_RESTAURANT = "com.physphil.android.restaurantroulette.ACTION_DELETE_RESTAURANT";
    public static final String ACTION_RESTAURANT_UPDATED = "com.physphil.android.restaurantroulette.ACTION_RESTAURANT_UPDATED";
    public static final String EXTRA_RESTAURANT_ID = "com.physphil.android.restaurantroulette.EXTRA_RESTAURANT_ID";
    public static final String EXTRA_UPDATED = "com.physphil.android.restaurantroulette.EXTRA_UPDATED";
    private static final String PREFS_SHOW_HELP_RESTAURANT = "show_help_restaurant";

    private DatabaseHelper mDatabaseHelper;
    private Restaurant mRestaurant;
    private EditText etName;
    private Spinner spinnerGenre;
    private RatingBar rbUserRating;
    private RatingBar rbPriceLevel;
    private EditText etNotes;
    private Button btnDirections;
    private Typeface mTf;
    private LocationHelper mLocationHelper;

    /**
     * Keeps track of if restaurant entry was modified by user
     */
    private boolean mUpdated;

    public RestaurantFragment() {
    }

    /**
     * @param id database id of restaurant to show
     * @return new RestaurantFragment
     */
    public static RestaurantFragment newInstance(String id) {

        RestaurantFragment fragment = new RestaurantFragment();
        Bundle args = new Bundle();

        args.putString(EXTRA_RESTAURANT_ID, id);
        fragment.setArguments(args);

        return fragment;
    }

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

        mTf = Typeface.createFromAsset(getActivity().getAssets(), Constants.FONT_DEFAULT);

        etName = (EditText) v.findViewById(R.id.restaurant_name);
        spinnerGenre = (Spinner) v.findViewById(R.id.spinner_restaurant_genre);
        rbUserRating = (RatingBar) v.findViewById(R.id.rating_bar_restaurant);
        rbPriceLevel = (RatingBar) v.findViewById(R.id.price_restaurant);
        etNotes = (EditText) v.findViewById(R.id.restaurant_notes);
        btnDirections = (Button) v.findViewById(R.id.btn_get_directions);

        setFonts(v);

        return v;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        setHasOptionsMenu(true);
        mDatabaseHelper = DatabaseHelper.getInstance(getActivity());
        mLocationHelper = new LocationHelper(getActivity());
        String id;

        if (savedInstanceState != null) {
            id = savedInstanceState.getString(EXTRA_RESTAURANT_ID);
            mUpdated = savedInstanceState.getBoolean(EXTRA_UPDATED, false);
        } else {
            id = getArguments().getString(EXTRA_RESTAURANT_ID);
            mUpdated = false;
        }

        // If a valid restaurant id from the db exists, populate views with restaurant info
        if (id != null) {

            // Get existing object from database
            mRestaurant = mDatabaseHelper.getRestaurantById(id);
        } else {

            mRestaurant = new Restaurant();
        }

        initializeViewContent();
    }

    @Override
    public void onResume() {
        super.onResume();

        LocalBroadcastManager.getInstance(getActivity()).registerReceiver(mReceiver,
                new IntentFilter(LocationHelper.ACTION_LOCATION_RETRIEVED));

        final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
        boolean showHelp = prefs.getBoolean(PREFS_SHOW_HELP_RESTAURANT, true);
        if (showHelp) {

            showHelpDialog();
        }
    }

    @Override
    public void onPause() {
        super.onPause();

        // Save all entered restaurant info to database
        //        mRestaurant.setName(etName.getText().toString());
        //        mRestaurant.setNotes(etNotes.getText().toString());

        // Only save to db if entry was updated by user
        if (mUpdated) {

            // Save all entered restaurant info to db
            mDatabaseHelper.addRestaurant(mRestaurant);

            // Send broadcast to update listview
            Intent i = new Intent(ACTION_RESTAURANT_UPDATED);
            LocalBroadcastManager.getInstance(getActivity()).sendBroadcast(i);
        }

        LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(mReceiver);
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);

        // Save restaurant id for recreation
        outState.putString(EXTRA_RESTAURANT_ID, mRestaurant.getRestaurantId());
        outState.putBoolean(EXTRA_UPDATED, mUpdated);
    }

    /**
     * Set default font for all views
     * @param v parent view containing all views which require font to be set
     */
    private void setFonts(View v) {

        // Set font for text fields
        etName.setTypeface(mTf);
        etNotes.setTypeface(mTf);
        btnDirections.setTypeface(mTf);

        // Set font for static text
        ((TextView) v.findViewById(R.id.restaurant_name_text)).setTypeface(mTf);
        ((TextView) v.findViewById(R.id.restaurant_genre_text)).setTypeface(mTf);
        ((TextView) v.findViewById(R.id.restaurant_rating_text)).setTypeface(mTf);
        ((TextView) v.findViewById(R.id.restaurant_price_text)).setTypeface(mTf);
        ((TextView) v.findViewById(R.id.restaurant_notes_text)).setTypeface(mTf);
    }

    private void initializeViewContent() {

        etName.setText(mRestaurant.getName());
        etName.setSelection(etName.getText().length());
        etNotes.setText(mRestaurant.getNotes());

        // Get random hint and assign it to notes field
        String[] hints = getResources().getStringArray(R.array.notes_hints);
        int i = (int) (Math.floor(Math.random() * hints.length));
        etNotes.setHint(hints[i]);

        // Add text watchers to update mRestaurant object when edited by user
        etName.addTextChangedListener(new TextWatcher() {

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

                mRestaurant.setName(s.toString());
                mUpdated = true;
                Log.d("PS", "name changed");
            }

            @Override
            public void afterTextChanged(Editable s) {
            }
        });

        etNotes.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

                mRestaurant.setNotes(s.toString());
                mUpdated = true;
                Log.d("PS", "notes changed");
            }

            @Override
            public void afterTextChanged(Editable s) {
            }
        });

        rbUserRating.setRating(mRestaurant.getUserRating());
        rbUserRating.setOnRatingBarChangeListener(new RatingBar.OnRatingBarChangeListener() {

            @Override
            public void onRatingChanged(RatingBar ratingBar, float rating, boolean fromUser) {

                // Set new rating every time it changes
                mRestaurant.setUserRating((int) rating);
                mUpdated = true;
                Log.d("PS", "rating changed");
            }
        });

        rbPriceLevel.setRating(mRestaurant.getPriceLevel());
        rbPriceLevel.setOnRatingBarChangeListener(new RatingBar.OnRatingBarChangeListener() {

            @Override
            public void onRatingChanged(RatingBar ratingBar, float rating, boolean fromUser) {

                // Set new price level every time it changes
                mRestaurant.setPriceLevel((int) rating);
                mUpdated = true;
                Log.d("PS", "price changed");
            }
        });

        // Set spinner adapter and initialize.
        String[] genres = getResources().getStringArray(R.array.genres);
        spinnerGenre.setAdapter(
                new CustomFontArrayAdapter(getActivity(), android.R.layout.simple_spinner_dropdown_item, genres));
        spinnerGenre.setSelection(getIndex(spinnerGenre, mRestaurant.getGenre()), false);

        // Add listener to set genre when changed
        spinnerGenre.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {

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

                mRestaurant.setGenre((String) spinner.getItemAtPosition(position));
                mUpdated = true;
                Log.d("PS", "genre changed");
            }

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

        // Get directions button
        btnDirections.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {

                //showOnMap();
                //Util.showOnMap(getActivity(), mRestaurant.getName());
                mLocationHelper.connectAndGetLocation();
            }
        });
    }

    /**
     * Gets position of genre in spinner
     * @param spinner
     * @param genre
     * @return index of Genre in Spinner, returns index of Other if not found or if genre is null
     */
    private int getIndex(Spinner spinner, String genre) {

        if (genre != null) {

            for (int i = 0; i < spinner.getCount(); i++) {

                if (spinner.getItemAtPosition(i).equals(genre)) {

                    return i;
                }
            }
        }

        // Item not found, set as 'Other', which is always last position in spinner. Also set genre in Restaurant object as 'Other'
        int index = spinner.getCount() - 1;
        mRestaurant.setGenre((String) spinner.getItemAtPosition(index));
        return index;
    }

    private void showHelpDialog() {

        Util.showHelpDialog(getActivity(), R.string.title_edit_restaurant, R.string.dialog_edit_restaurant_help,
                PREFS_SHOW_HELP_RESTAURANT);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        switch (item.getItemId()) {

        case R.id.menu_help:
            showHelpDialog();
            return true;

        default:
            return super.onOptionsItemSelected(item);
        }
    }

    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {

            if (intent.getAction().equals(LocationHelper.ACTION_LOCATION_RETRIEVED)) {

                // Search on map for restaurant. Location will be null if not contained in intent
                Location location = intent.getParcelableExtra(LocationHelper.EXTRA_LOCATION);
                Util.showOnMap(getActivity(), mRestaurant.getName(), location);
                mLocationHelper.disconnect();
            }
        }
    };

}