| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607 |
- package com.ivalentin.gm;
- import java.text.DateFormat;
- import java.text.ParseException;
- import java.text.SimpleDateFormat;
- import java.util.Calendar;
- import java.util.Date;
- import java.util.Locale;
- import com.google.android.gms.maps.CameraUpdate;
- import com.google.android.gms.maps.CameraUpdateFactory;
- import com.google.android.gms.maps.GoogleMap;
- import com.google.android.gms.maps.MapView;
- import com.google.android.gms.maps.MapsInitializer;
- import com.google.android.gms.maps.OnMapReadyCallback;
- import com.google.android.gms.maps.model.LatLng;
- import com.google.android.gms.maps.model.MarkerOptions;
- import android.annotation.SuppressLint;
- import android.app.Dialog;
- import android.content.Context;
- import android.content.DialogInterface;
- import android.content.DialogInterface.OnCancelListener;
- import android.content.DialogInterface.OnShowListener;
- import android.database.Cursor;
- import android.database.sqlite.SQLiteDatabase;
- import android.graphics.drawable.Drawable;
- import android.os.Bundle;
- import android.support.v4.app.Fragment;
- import android.support.v4.content.res.ResourcesCompat;
- import android.text.Editable;
- import android.text.TextWatcher;
- import android.util.Log;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.view.Window;
- import android.view.View.OnClickListener;
- import android.view.ViewGroup;
- import android.view.WindowManager;
- import android.widget.Button;
- import android.widget.EditText;
- import android.widget.LinearLayout;
- import android.widget.TextView;
- /**
- * Fragment to be inflated showing the festivals schedule.
- * Contains a date selector and a ScrollView with all the activities for the day.
- *
- * @author Inigo Valentin
- *
- */
- public class ScheduleLayout extends Fragment implements OnMapReadyCallback{
-
- //Array with data about the days of the festival
- private String[][] days = new String[GM.TOTAL_DAYS][4];
-
- //Currently selected day
- private int selected;
-
- //Indicates official schedule
- private int schedule;
-
- //Arrow buttons
- private Button btL, btR;
-
- //TextViews in the date selector
- private TextView tvDayNumber, tvDayTitle, tvDayMonth;
-
- //Map stuff for the dialog
- private MapView mapView;
- private Bundle bund;
- private GoogleMap map;
- private LatLng location;
- private View view;
- private String markerName = "";
-
- /**
- * Run when the fragment is inflated.
- * Assigns views, gets the date and does the first call to the populateSchedule function.
- *
- * @param inflater A LayoutInflater to manage views
- * @param container The container View
- * @param savedInstanceState Bundle containing the state
- *
- * @see android.support.v4.app.Fragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle)
- */
- @SuppressLint("InflateParams") //Throws unknown error when done properly.
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
-
- //Set bundle for the map
- bund = savedInstanceState;
-
- //Load the layout
- view = inflater.inflate(R.layout.fragment_layout_schedule, null);
-
- //Get schedule type
- Bundle bundle = this.getArguments();
- schedule = bundle.getInt(GM.SCHEDULE, GM.SECTION_LABLANCA_SCHEDULE);
-
- //Set the title
- if (schedule == GM.SECTION_LABLANCA_SCHEDULE)
- ((MainActivity) getActivity()).setSectionTitle(view.getContext().getString(R.string.menu_lablanca_schedule));
- else
- ((MainActivity) getActivity()).setSectionTitle(view.getContext().getString(R.string.menu_lablanca_gm_schedule));
-
-
- //Populate days array
- days[GM.DAY_25] = new String[] {"2015-07-25", "25", getString(R.string.month_07), getString(R.string.day_title_25)};
- days[GM.DAY_4] = new String[] {"2015-08-04", "4", getString(R.string.month_08), getString(R.string.day_title_4)};
- days[GM.DAY_5] = new String[] {"2015-08-05", "5", getString(R.string.month_08), getString(R.string.day_title_5)};
- days[GM.DAY_6] = new String[] {"2015-08-06", "6", getString(R.string.month_08), getString(R.string.day_title_6)};
- days[GM.DAY_7] = new String[] {"2015-08-07", "7", getString(R.string.month_08), getString(R.string.day_title_7)};
- days[GM.DAY_8] = new String[] {"2015-08-08", "8", getString(R.string.month_08), getString(R.string.day_title_8)};
- days[GM.DAY_9] = new String[] {"2015-08-09", "9", getString(R.string.month_08), getString(R.string.day_title_9)};
-
- //Assign parent layout
- final LinearLayout list = (LinearLayout) view.findViewById(R.id.ll_schedule_list);
-
- //Assign textViews
- tvDayNumber = (TextView) view.findViewById(R.id.tv_schedule_day_number);
- tvDayMonth = (TextView) view.findViewById(R.id.tv_schedule_day_month);
- tvDayTitle = (TextView) view.findViewById(R.id.tv_schedule_day_title);
-
- //Assign buttons
- btL = (Button) view.findViewById(R.id.bt_schedule_l);
- btR = (Button) view.findViewById(R.id.bt_schedule_r);
- btL.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- if (selected > GM.DAY_25){
- selected --;
-
- //If August 4 selected and GM schedule, skip
- if (selected == GM.DAY_4 && schedule != GM.SECTION_LABLANCA_SCHEDULE)
- selected --;
-
- String filter = ((EditText) view.findViewById(R.id.et_schedule_filter)).getText().toString();
- populateSchedule(selected, list, schedule, filter);
- }
- }
- });
- btR.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- if (selected < GM.DAY_9){
- selected ++;
-
- //If August 4 selected and GM schedule, skip
- if (selected == GM.DAY_4 && schedule != GM.SECTION_LABLANCA_SCHEDULE)
- selected ++;
-
- String filter = ((EditText) view.findViewById(R.id.et_schedule_filter)).getText().toString();
- populateSchedule(selected, list, schedule, filter);
- }
- }
- });
-
- //Assign the filter text
- EditText etFilter = (EditText) view.findViewById(R.id.et_schedule_filter);
- etFilter.addTextChangedListener(new TextWatcher() {
- @Override
- public void afterTextChanged(Editable s) { }
- @Override
- public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
- @Override
- public void onTextChanged(CharSequence s, int start, int before, int count) {
- //Repopulate when the text is changed
- populateSchedule(selected, list, schedule, s.toString());
-
- }
- });
-
- //Get the date
- DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.US);
- Date date = new Date();
- String curDate = dateFormat.format(date);
-
- //Try to find out if the current date is before, after, or in the middle of the festivals.
- try {
- if (dateFormat.parse(curDate).before(dateFormat.parse(days[GM.DAY_25][0]))){
- selected = GM.DAY_25;
- }
- else if (dateFormat.parse(curDate).after(dateFormat.parse(days[GM.DAY_9][0]))){
- selected = GM.DAY_9;
- }
- else{
- for (int i = 0; i < GM.TOTAL_DAYS; i++){
- if (curDate.equals(days[i][0])){
- selected = i;
- }
- }
- }
- //If August 4 and Margolari schedule, move one day forward
- if (selected == GM.DAY_4 && schedule != GM.SECTION_LABLANCA_SCHEDULE){
- selected ++;
- }
- }
- catch (ParseException e) {
- selected = GM.DAY_25;
- Log.e("Error selecting date", e.toString());
- }
-
- //Populate the activity list
- populateSchedule(selected, list, schedule, "");
-
- //Return the fragment view
- return view;
- }
-
- /**
- * Populates the list of activities with the ones n the selected day.
- *
- * @param selected The day to show activities from
- * @param list The layout where the items will be added
- * @param schedule GM.SECTION_SCHEDULE if city schedule, GM.SECTION_GM_SCHEDULE if gm schedule
- * @param f Search filter texts
- */
- @SuppressLint("InflateParams") //Views are added from a loop: I can't specify the parent when inflating.
- private void populateSchedule(int selected, LinearLayout list, int schedule, String f){
-
- //A layout to be populated with one activity
- LinearLayout entry, content;
-
- //The filter
- String filter = f.toLowerCase(Locale.US);
-
- //An inflater
- LayoutInflater factory = LayoutInflater.from(getActivity());
-
- //Views in each row
- TextView tvRowTitle, tvRowTime, tvRowDesc, tvRowPlace, tvRowId;
-
- //Icon next to the location text
- Drawable icon = ResourcesCompat.getDrawable(getResources(), R.drawable.pinpoint, null);
- //icon.setBounds(0, 0, 80, 80);
-
- //Set date selector texts
- tvDayNumber.setText(days[selected][1]);
- tvDayMonth.setText(days[selected][2]);
- tvDayTitle.setText(days[selected][3]);
-
- //Show or hide the arrow buttons
- switch (selected){
- case GM.DAY_25:
- btL.setVisibility(View.INVISIBLE);
- btR.setVisibility(View.VISIBLE);
- break;
- case GM.DAY_9:
- btL.setVisibility(View.VISIBLE);
- btR.setVisibility(View.INVISIBLE);
- break;
- default:
- btL.setVisibility(View.VISIBLE);
- btR.setVisibility(View.VISIBLE);
- }
-
- //Read from database
- SQLiteDatabase db = getActivity().openOrCreateDatabase(GM.DB_NAME, Context.MODE_PRIVATE, null);
- Cursor cursor;
-
- //Elements to parse, format and operate with dates
- Calendar cal;
- Date maxDate, minDate;
- String maxDateStr, minDateStr;
- SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US);
- SimpleDateFormat dayFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.US);
- cal = Calendar.getInstance();
-
- //Get date of the selected daye
- try {
- cal.setTime(dayFormat.parse(days[selected][0]));
- } catch (ParseException e) {
- Log.e("Error parsing date", e.toString());
- }
-
- //Set margins so the days goes from 6:00 in the morning to 5:59 the next day, instead of from 00:00 to 23:59
- cal.add(Calendar.HOUR_OF_DAY, 6);
- minDate = cal.getTime();
-
- //If its the last day, include events of the next one
- if (selected == GM.DAY_9)
- cal.add(Calendar.HOUR_OF_DAY, 36);
- else
- cal.add(Calendar.HOUR_OF_DAY, 24);
- maxDate = cal.getTime();
- maxDateStr = dateFormat.format(maxDate);
- minDateStr = dateFormat.format(minDate);
-
- //Get data from database
- if (schedule == GM.SECTION_LABLANCA_GM_SCHEDULE)
- cursor = db.rawQuery("SELECT event.id, event.name, event.description, event.place, place.id, place.name, event.start FROM " + GM.DB_EVENT + ", " + GM.DB_PLACE + " WHERE " + GM.DB_EVENT_GM + " = 1 AND place.id = event.place AND start BETWEEN '" + minDateStr + "' AND '" + maxDateStr + "' AND (lower(event.name) LIKE '%" + filter + "%' OR lower(event.description) LIKE '%" + filter + "%' OR lower(place.name) LIKE '%" + filter + "%') ORDER BY " + GM.DB_EVENT_START + ";", null);
- else
- cursor = db.rawQuery("SELECT event.id, event.name, event.description, event.place, place.id, place.name, event.start FROM " + GM.DB_EVENT + ", " + GM.DB_PLACE + " WHERE " + GM.DB_EVENT_SCHEDULE + " = 1 AND place.id = event.place AND start BETWEEN '" + minDateStr + "' AND '" + maxDateStr + "' AND (lower(event.name) LIKE '%" + filter + "%' OR lower(event.description) LIKE '%" + filter + "%' OR lower(place.name) LIKE '%" + filter + "%') ORDER BY " + GM.DB_EVENT_START + ";", null);
-
- //Clear the list
- list.removeAllViews();
-
- //Loop
- while (cursor.moveToNext()){
-
-
- //Create a new row
- entry = (LinearLayout) factory.inflate(R.layout.row_schedule, null);
-
- //Set id
- tvRowId = (TextView) entry.findViewById(R.id.tv_row_schedule_id);
- tvRowId.setText(cursor.getString(0));
-
- //Set title
- tvRowTitle = (TextView) entry.findViewById(R.id.tv_row_schedule_title);
- tvRowTitle.setText(cursor.getString(1));
-
- //Set description
- tvRowDesc = (TextView) entry.findViewById(R.id.tv_row_schedule_description);
- tvRowDesc.setText(cursor.getString(2));
-
- //Set place
- tvRowPlace = (TextView) entry.findViewById(R.id.tv_row_schedule_place);
- tvRowPlace.setText(cursor.getString(5));
- icon.setBounds(0, 0, (int) (tvRowPlace.getTextSize() * 1.5), (int) (tvRowPlace.getTextSize() * 1.5));
- tvRowPlace.setCompoundDrawables(icon, null, null, null);
-
- //Set time
- tvRowTime = (TextView) entry.findViewById(R.id.tv_row_schedule_time);
- String tm = cursor.getString(6).substring(cursor.getString(6).length() - 8, cursor.getString(6).length() - 3);
- tvRowTime.setText(tm);
-
- //Set onClick event
- content = (LinearLayout) entry.findViewById(R.id.ll_row_schedule_content);
- content.setOnClickListener(new OnClickListener(){
- @Override
- public void onClick(View v) {
- TextView tvName = (TextView) v.findViewById(R.id.tv_row_schedule_id);
- int id = Integer.parseInt(tvName.getText().toString());
- showDialog(id);
- }
- });
-
- //Add to the list
- list.addView(entry);
- }
-
- //Invalidate the list so it is redrawn
- list.invalidate();
-
- //Close cursor and database
- cursor.close();
- db.close();
- }
-
-
- /**
- * Shows a dialog with info about the selected event.
- *
- * @param id The event id
- */
- private void showDialog(final int id){
-
- //Create the dialog
- final Dialog dialog = new Dialog(getActivity());
-
- //Set up dialog window
- dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
- dialog.setContentView(R.layout.dialog_schedule);
-
- //Date formatters
- SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US);
- SimpleDateFormat dayFormat = new SimpleDateFormat("yyyy-MM-dd-", Locale.US);
- SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm", Locale.US);
-
- //Set the custom dialog components - text, image and button
- TextView tvTitle = (TextView) dialog.findViewById(R.id.tv_dialog_schedule_title);
- TextView tvDescription = (TextView) dialog.findViewById(R.id.tv_dialog_schedule_description);
- TextView tvHost = (TextView) dialog.findViewById(R.id.tv_dialog_schedule_host);
- TextView tvDate = (TextView) dialog.findViewById(R.id.tv_dialog_schedule_date);
- TextView tvTime = (TextView) dialog.findViewById(R.id.tv_dialog_schedule_time);
- TextView tvPlace = (TextView) dialog.findViewById(R.id.tv_dialog_schedule_place);
- TextView tvAddress = (TextView) dialog.findViewById(R.id.tv_dialog_schedule_address);
- Button btClose = (Button) dialog.findViewById(R.id.bt_schedule_close);
-
- //Get info about the event
- SQLiteDatabase db = getActivity().openOrCreateDatabase(GM.DB_NAME, Context.MODE_PRIVATE, null);
- Cursor cursor = db.rawQuery("SELECT event.id, event.name, description, start, end, place.name, address, lat, lon, host FROM event, place WHERE place.id = event.place AND event.id = " + id + ";", null);
- if (cursor.getCount() > 0){
- cursor.moveToNext();
-
- //Set title
- tvTitle.setText(cursor.getString(1));
- markerName = cursor.getString(1);
-
- //Set description
- tvDescription.setText(cursor.getString(2));
-
- //Set host
- if (cursor.getString(9) != null){
- Cursor hostCursor = db.rawQuery("SELECT name FROM people WHERE id = " + cursor.getString(9) + ";", null);
- if (hostCursor.moveToNext()){
- tvHost.setVisibility(View.VISIBLE);
- tvHost.setText(String.format(getString(R.string.schedule_host), hostCursor.getString(0)));
- }
- }
- else{
- tvHost.setVisibility(View.GONE);
- }
-
- //Set date
- try{
- Date day = dateFormat.parse(cursor.getString(3));
- Date date = new Date();
- //If the event is today, show "Today" instead of the date
- if (dayFormat.format(day).equals(dayFormat.format(date)))
- tvDate.setText(dialog.getContext().getString(R.string.today));
-
- else{
- Calendar cal = Calendar.getInstance();
- cal.setTime(date);
- cal.add(Calendar.HOUR_OF_DAY, 24);
-
- //If the event is tomorrow, show "Tomorrow" instead of the date
- if (dayFormat.format(cal.getTime()).equals(dayFormat.format(date))){
- tvDate.setText(dialog.getContext().getString(R.string.tomorrow));
- }
-
- //Else, show the date
- else{
- SimpleDateFormat printFormat = new SimpleDateFormat("dd MMMM", Locale.US);
- tvDate.setText(printFormat.format(day));
- }
- }
- }
- catch (Exception ex){
- Log.e("Error parsing date", ex.toString());
- }
-
- //Set time
- try{
- if (cursor.getString(4) == null)
- tvTime.setText(timeFormat.format(dateFormat.parse(cursor.getString(3))));
- else
- tvTime.setText(timeFormat.format(dateFormat.parse(cursor.getString(3))) + " - " + timeFormat.format(dateFormat.parse(cursor.getString(4))));
- }
- catch (ParseException ex){
- Log.e("Error parsing time", ex.toString());
- }
-
- //Set the place
- tvPlace.setText(cursor.getString(5));
- tvAddress.setText(cursor.getString(6));
-
- //Set up map
- location = new LatLng(Double.parseDouble(cursor.getString(7)), Double.parseDouble(cursor.getString(8)));
- mapView = (MapView) dialog.findViewById(R.id.mv_dialog_schedule_map);
- mapView.onCreate(bund);
-
- //Close the db connection
- cursor.close();
- db.close();
-
- //Set close button
- btClose.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- dialog.dismiss();
- }
- });
-
- //Actions to take when the dialog is cancelled
- dialog.setOnCancelListener(new OnCancelListener(){
- @Override
- public void onCancel(DialogInterface dialog) {
- if (map != null)
- map.setMyLocationEnabled(false);
- if (mapView != null){
- mapView.onResume();
- mapView.onDestroy();
- }
- }
- });
-
- //Show the dialog
- WindowManager.LayoutParams lp = dialog.getWindow().getAttributes();
- lp.dimAmount = 0.0f;
- dialog.show();
-
- //Start the map
- startMap();
- mapView.onResume();
- dialog.setOnShowListener(new OnShowListener(){
- @Override
- public void onShow(DialogInterface dialog) {
- // Gets to GoogleMap from the MapView and does initialization stuff
- startMap();
-
- }
- });
-
- }
- }
-
- /**
- * Starts the map in the dialog.
- */
- private void startMap(){
- mapView.getMapAsync(this);
- }
-
- /**
- * Called when the fragment is brought back into the foreground.
- * Resumes the map and the location manager.
- *
- * @see android.support.v4.app.Fragment#onResume()
- */
- @Override
- public void onResume() {
- if (mapView != null)
- mapView.onResume();
- if (map != null)
- map.setMyLocationEnabled(true);
- super.onResume();
- }
- /**
- * Called when the fragment is destroyed.
- * Finishes the map.
- *
- * @see android.support.v4.app.Fragment#onDestroy()
- */
- @Override
- public void onDestroy() {
- super.onDestroy();
- if (map != null)
- map.setMyLocationEnabled(false);
- if (mapView != null){
- mapView.onResume();
- mapView.onDestroy();
- }
- }
-
- /**
- * Called when the fragment is paused.
- * Finishes the map.
- *
- * @see android.support.v4.app.Fragment#onPause()
- */
- @Override
- public void onPause() {
- super.onDestroy();
- if (map != null)
- map.setMyLocationEnabled(false);
- if (mapView != null){
- mapView.onPause();
- }
- }
- /**
- * Called in a situation of low memory.
- * Lets the map handle this situation.
- *
- * @see android.support.v4.app.Fragment#onLowMemory()
- */
- @Override
- public void onLowMemory() {
- super.onLowMemory();
- if (mapView != null){
- mapView.onResume();
- mapView.onLowMemory();
- }
- }
- /**
- * Called when the map is ready to be displayed.
- * Sets the map options and a marker for the map.
- *
- * @param googleMap The map to be shown
- *
- * @see com.google.android.gms.maps.OnMapReadyCallback#onMapReady(com.google.android.gms.maps.GoogleMap)
- */
- @Override
- public void onMapReady(GoogleMap googleMap) {
- this.map = googleMap;
- map.setMyLocationEnabled(true);
-
- map.getUiSettings().setMyLocationButtonEnabled(false);
- map.setMyLocationEnabled(true);
- // Needs to call MapsInitializer before doing any CameraUpdateFactory calls
- try {
- MapsInitializer.initialize(this.getActivity());
- CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(location, 14);
- map.animateCamera(cameraUpdate);
- } catch (Exception e) {
- Log.e("Error initializing maps", e.toString());
- }
- //Set GM marker
- MarkerOptions mo = new MarkerOptions();
- mo.title(markerName);
- mo.position(location);
- map.addMarker(mo);
-
- }
-
- }
|