Android Open Source - ean-android Startup Search






From Project

Back to project page ean-android.

License

The source code is released under:

Copyright (c) 2013, Expedia Affiliate Network All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that redistributions of sour...

If you think the Android project ean-android 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

/*
 * Copyright (c) 2013, Expedia Affiliate Network
 * All rights reserved./*from w w w. java2 s  . c om*/
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that redistributions of source code
 * retain the above copyright notice, these conditions, and the following
 * disclaimer. 
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * The views and conclusions contained in the software and documentation are those
 * of the authors and should not be interpreted as representing official policies, 
 * either expressed or implied, of the Expedia Affiliate Network or Expedia Inc.
 */

package com.ean.mobile.activity;

import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;


import org.joda.time.LocalDate;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

import android.app.Activity;
import android.app.DatePickerDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;

import com.ean.mobile.Destination;
import com.ean.mobile.R;
import com.ean.mobile.app.SampleApp;
import com.ean.mobile.app.SampleConstants;
import com.ean.mobile.exception.EanWsError;
import com.ean.mobile.exception.UrlRedirectionException;
import com.ean.mobile.hotel.request.ListRequest;
import com.ean.mobile.request.RequestProcessor;
import com.ean.mobile.task.SuggestionFactory;

/**
 * The code behind the StartupSearch layout.
 */
public class StartupSearch extends Activity {

    private static final String DATE_FORMAT_STRING = "MM/dd/yyyy";
    private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormat.forPattern(DATE_FORMAT_STRING);

    private static final List<Spinner> CHILD_AGE_SPINNERS = new LinkedList<Spinner>();

    /**
     * {@inheritDoc}
     */
    @Override
    public final void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.startupsearch);

        SampleApp.resetDates();
        setUpDateButton(R.id.arrival_date_picker, SampleApp.arrivalDate);
        setUpDateButton(R.id.departure_date_picker, SampleApp.departureDate);

        final ArrayAdapter<Destination> suggestionAdapter
                = new DestinationSuggestionAdapter(getApplicationContext(), R.id.suggestionsView);
        final SearchBoxTextWatcher watcher = new SearchBoxTextWatcher(suggestionAdapter);

        final EditText searchBox = (EditText) findViewById(R.id.searchBox);
        searchBox.setOnKeyListener(new SearchBoxKeyListener());
        searchBox.addTextChangedListener(watcher);

        final ListView suggestions = (ListView) findViewById(R.id.suggestionsView);
        suggestions.setAdapter(suggestionAdapter);
        suggestions.setOnItemClickListener(new SuggestionListAdapterClickListener(searchBox, watcher));
    }

    private void setUpDateButton(final int resourceId, final LocalDate date) {
        final Button dateButton = (Button) findViewById(resourceId);
        dateButton.setText(DATE_TIME_FORMATTER.print(date));
    }

    /**
     * (Event handler) Handles the clicks on either of the date dialogs.
     * @param view The view (button) that fired the event.
     */
    public void showDatePickerDialog(final View view) {
        new DatePickerFragment(view.getId(), (Button) view).show(getFragmentManager(), "StartupSearchDatePicker");
    }

    /**
     * (Event handler) Handles the events that cause the search to commence.
     * @param view The view parameter for the event handler.
     */
    public void performSearch(final View view) {
        final EditText searchBox = (EditText) findViewById(R.id.searchBox);
        final String searchQuery = searchBox.getText().toString().trim();
        final ProgressDialog searchingDialog
                = ProgressDialog.show(StartupSearch.this, "", getString(R.string.searching), true);
        SuggestionFactory.killSuggestDestinationTask();
        SampleApp.clearSearch();

        final Button arrivalDatePicker = (Button) findViewById(R.id.arrival_date_picker);
        final Button departureDatePicker = (Button) findViewById(R.id.departure_date_picker);
        final Spinner adultsSpinner = (Spinner) findViewById(R.id.adults_spinner);
        final List<Integer> childAges = new LinkedList<Integer>();
        final TableLayout childAgesTable = (TableLayout) findViewById(R.id.child_ages_table);
        for (Spinner childAgeSpinner : CHILD_AGE_SPINNERS) {
            childAges.add(Integer.parseInt((String) childAgeSpinner.getSelectedItem()));
        }


        SampleApp.searchQuery = searchQuery;
        SampleApp.arrivalDate = DATE_TIME_FORMATTER.parseLocalDate(arrivalDatePicker.getText().toString());
        SampleApp.departureDate = DATE_TIME_FORMATTER.parseLocalDate(departureDatePicker.getText().toString());
        SampleApp.numberOfAdults = Integer.parseInt((String) adultsSpinner.getSelectedItem());
        SampleApp.childAges = Collections.unmodifiableList(childAges);
        
        new PerformSearchTask(searchingDialog).execute((Void) null);
    }

    /**
     * (Event handler) Adds a child to the list.
     * @param view The button used to fire this event.
     */
    public void addChildAge(final View view) {
        final TableLayout childAges = (TableLayout) findViewById(R.id.child_ages_table);
        final View childAgeSpinnerView = getLayoutInflater().inflate(R.layout.childagespinnerlayout, null);
        final TableRow childTableRow;
        if (childAges.getChildCount() == 0
                || ((TableRow) childAges.getChildAt(childAges.getChildCount() - 1)).getChildCount() == 2) {
            childTableRow = new TableRow(StartupSearch.this);
            childAges.addView(childTableRow);
        } else {
            childTableRow = (TableRow) childAges.getChildAt(childAges.getChildCount() - 1);
        }
        final Spinner childAgeSpinner = (Spinner) childAgeSpinnerView.findViewById(R.id.child_age_spinner);
        CHILD_AGE_SPINNERS.add(childAgeSpinner);
        childAgeSpinner.setSelection(1);
        childAgeSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(final AdapterView<?> parent,
                   final View view, final int position, final long id) {
                //parent is the spinner!!
                if (position == 0) {
                    CHILD_AGE_SPINNERS.remove((Spinner) parent);
                    ((TableRow) parent.getParent().getParent()).removeView((LinearLayout) parent.getParent());
                }
            }

            @Override
            public void onNothingSelected(final AdapterView<?> parent) {
                // implemented for the interface.
            }
        });
        childTableRow.addView(childAgeSpinnerView);
    }

    private final class PerformSearchTask extends AsyncTask<Void, Integer, Void> {

        private final ProgressDialog searchingDialog;

        private PerformSearchTask(final ProgressDialog searchingDialog) {
            this.searchingDialog = searchingDialog;
        }

        @Override
        protected Void doInBackground(final Void... voids) {
            try {
                final ListRequest request = new ListRequest(
                    SampleApp.searchQuery,
                    SampleApp.occupancy(),
                    SampleApp.arrivalDate,
                    SampleApp.departureDate);
                SampleApp.updateFoundHotels(RequestProcessor.run(request), true);
            } catch (EanWsError ewe) {
                // If this exception occurs, it's likely an input error and should be recoverable.
                Log.d(SampleConstants.LOG_TAG, "An APILevel Exception occurred.", ewe);
            } catch (UrlRedirectionException ure) {
                SampleApp.sendRedirectionToast(getApplicationContext());
            }
            return null;
         }

        @Override
        protected void onPostExecute(final Void aVoid) {
            startActivity(new Intent(StartupSearch.this, HotelList.class));
            try {
                searchingDialog.dismiss();
            } catch (IllegalArgumentException iae) {
                // just ignore it... it's because the window rotated at an inopportune time.
            }
        }

        @Override
        protected void onCancelled() {
            searchingDialog.dismiss();
        }
    }

    private static final class DatePickerFragment extends DialogFragment implements DatePickerDialog.OnDateSetListener {

        private final int pickerId;

        private final Button pickerButton;

        public DatePickerFragment(final int pickerId, final Button pickerButton) {
            super();
            this.pickerId = pickerId;
            this.pickerButton = pickerButton;
        }

        @Override
        public Dialog onCreateDialog(final Bundle savedInstanceState) {
            final LocalDate date;
            if (pickerId == R.id.arrival_date_picker) {
                date = SampleApp.arrivalDate;
            } else {
                date = SampleApp.departureDate;
            }

            return new DatePickerDialog(
                getActivity(),
                this,
                date.getYear(),
                date.getMonthOfYear() - 1,
                date.getDayOfMonth());
        }

        @Override
        public void onDateSet(final DatePicker datePicker, final int year, final int monthOfYear,
                final int dayOfMonth) {
            final LocalDate chosenDate = new LocalDate(year, monthOfYear + 1, dayOfMonth);
            pickerButton.setText(DATE_TIME_FORMATTER.print(chosenDate));
            switch(pickerId) {
                case R.id.arrival_date_picker:
                    SampleApp.arrivalDate = chosenDate;
                    break;
                case R.id.departure_date_picker:
                    SampleApp.departureDate = chosenDate;
                    break;
                default:
                    break;
            }
        }
    }

    private static final class SuggestionListAdapterClickListener implements AdapterView.OnItemClickListener {

        private final EditText searchBox;

        private final TextWatcher textWatcher;

        public SuggestionListAdapterClickListener(final EditText searchBox, final TextWatcher textWatcher) {
            this.searchBox = searchBox;
            this.textWatcher = textWatcher;
        }

        public void onItemClick(final AdapterView<?> parent, final View view, final int position, final long id) {
            //replace the text in the search box with the string at position.
            final Destination selectedDestination = (Destination) parent.getItemAtPosition(position);
            //disable the text change listener.
            searchBox.removeTextChangedListener(textWatcher);
            //set the text.
            searchBox.setText(selectedDestination.name);
            //clear the suggestions
            final ArrayAdapter suggestionAdapter = (ArrayAdapter) parent.getAdapter();
            suggestionAdapter.clear();
            suggestionAdapter.notifyDataSetChanged();
            //re-enable the change listener.
            searchBox.addTextChangedListener(textWatcher);
        }
    }

    private final class SearchBoxKeyListener implements View.OnKeyListener {

        public boolean onKey(final View v, final int keyCode, final KeyEvent event) {
            // Only hears hardware keys and enter per OnKeyListener's javadoc.
            // If the event is a key-down event on the "enter" button
            if (event.getAction() == KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_ENTER) {
                // Perform action on key press
                performSearch(v);
                return true;
            }
            return false;
        }
    }

    private final class SearchBoxTextWatcher implements TextWatcher {

        private final ArrayAdapter<Destination> suggestionAdapter;

        private SearchBoxTextWatcher(final ArrayAdapter<Destination> suggestionAdapter) {
            this.suggestionAdapter = suggestionAdapter;
        }

        @Override
        public void beforeTextChanged(final CharSequence charSequence, final int i, final int i2, final int i3) { }

        @Override
        public void onTextChanged(final CharSequence charSequence, final int i, final int i2, final int i3) { }

        @Override
        public void afterTextChanged(final Editable editable) {
            SuggestionFactory.suggest(editable.toString(), suggestionAdapter);
        }
    }

    private static final class DestinationSuggestionAdapter extends ArrayAdapter<Destination> {
        private final LayoutInflater layoutInflater;

        private DestinationSuggestionAdapter(final Context context, final int resource) {
            super(context, resource, new ArrayList<Destination>());
            layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public View getView(final int position, final View convertView, final ViewGroup parent) {
            View view = convertView;
            if (view == null) {
                view = layoutInflater.inflate(R.layout.destinationlistlayout, null);
            }

            final Destination destination = this.getItem(position);

            //Set the name field
            final TextView name = (TextView) view.findViewById(R.id.destinationSuggestionName);
            name.setText(destination.name);

            return view;
        }
    }
}




Java Source Code List

android.text.Html.java
android.text.Spanned.java
android.util.Log.java
com.ean.mobile.Address.java
com.ean.mobile.Constants.java
com.ean.mobile.CustomerAddress.java
com.ean.mobile.Destination.java
com.ean.mobile.Individual.java
com.ean.mobile.LatLongAddress.java
com.ean.mobile.Name.java
com.ean.mobile.activity.BookingSummary.java
com.ean.mobile.activity.HotelInformation.java
com.ean.mobile.activity.HotelList.java
com.ean.mobile.activity.ReservationDisplay.java
com.ean.mobile.activity.StartupSearch.java
com.ean.mobile.activity.package-info.java
com.ean.mobile.app.HotelImageDrawableMap.java
com.ean.mobile.app.HotelImageDrawable.java
com.ean.mobile.app.ImageFetcher.java
com.ean.mobile.app.SampleApp.java
com.ean.mobile.app.SampleConstants.java
com.ean.mobile.app.StarRating.java
com.ean.mobile.app.package-info.java
com.ean.mobile.exception.CommonParameterValidationException.java
com.ean.mobile.exception.DataValidationException.java
com.ean.mobile.exception.EanWsError.java
com.ean.mobile.exception.UriCreationException.java
com.ean.mobile.exception.UrlRedirectionException.java
com.ean.mobile.exception.package-info.java
com.ean.mobile.hotel.CancellationPolicy.java
com.ean.mobile.hotel.Cancellation.java
com.ean.mobile.hotel.ConfirmationStatus.java
com.ean.mobile.hotel.HotelImageTuple.java
com.ean.mobile.hotel.HotelInformation.java
com.ean.mobile.hotel.HotelList.java
com.ean.mobile.hotel.HotelRoom.java
com.ean.mobile.hotel.Hotel.java
com.ean.mobile.hotel.Itinerary.java
com.ean.mobile.hotel.NightlyRate.java
com.ean.mobile.hotel.Rate.java
com.ean.mobile.hotel.ReservationRoom.java
com.ean.mobile.hotel.Reservation.java
com.ean.mobile.hotel.RoomOccupancy.java
com.ean.mobile.hotel.SupplierType.java
com.ean.mobile.hotel.request.BookingRequest.java
com.ean.mobile.hotel.request.CancellationRequest.java
com.ean.mobile.hotel.request.InformationRequest.java
com.ean.mobile.hotel.request.ItineraryRequest.java
com.ean.mobile.hotel.request.ListRequest.java
com.ean.mobile.hotel.request.RoomAvailabilityRequest.java
com.ean.mobile.hotel.request.package-info.java
com.ean.mobile.hotel.package-info.java
com.ean.mobile.request.CommonParameters.java
com.ean.mobile.request.DestinationRequest.java
com.ean.mobile.request.RequestProcessor.java
com.ean.mobile.request.Request.java
com.ean.mobile.request.package-info.java
com.ean.mobile.task.ImageDrawableLoaderTask.java
com.ean.mobile.task.SuggestionFactory.java
com.ean.mobile.task.package-info.java
com.ean.mobile.package-info.java