EndlessArrivalDepartureAdapter.java :  » UnTagged » betrains-android » be » irail » betrains » adapters » Android Open Source

Android Open Source » UnTagged » betrains android 
betrains android » be » irail » betrains » adapters » EndlessArrivalDepartureAdapter.java
package be.irail.betrains.adapters;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import tof.cv.mpp.R;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import be.irail.api.IRail;
import be.irail.api.data.ArrivalDeparture;
import be.irail.api.data.Liveboard;
import be.irail.api.data.Station;

import com.commonsware.cwac.adapter.EndlessAdapter;

public class EndlessArrivalDepartureAdapter extends EndlessAdapter {

  private static final String TAG = "EndlessArrivalDepartureAdapter";

  private final LayoutInflater mInflater;

  private final IRail mIRail;

  private final ArrivalDepartureAdapter mWrappedAdapter;

  private List<ArrivalDeparture> mNewArrivalsDepartures;

  private Station mStation;

  private String mInitialStartTime;

  private boolean mDepartures;

  private View mLoadingView = null;

  public EndlessArrivalDepartureAdapter(ArrivalDepartureAdapter wrapped, LayoutInflater inflator, IRail iRail) {
    super(wrapped);

    mWrappedAdapter = wrapped;
    mNewArrivalsDepartures = null; // Set to null so that list is
                    // initialized in cacheInBackground
    mInflater = inflator;
    mIRail = iRail;
  }

  @Override
  protected View getPendingView(ViewGroup parent) {
    if (mLoadingView == null) {
      mLoadingView = mInflater.inflate(R.layout.list_item_loading, null);
    }
    return mLoadingView;
  }

  @Override
  protected boolean cacheInBackground() {
    // Determine starting time for fetching new arrivals/departures
    String startTime;
    if (mNewArrivalsDepartures == null) {
      startTime = mInitialStartTime;
      mNewArrivalsDepartures = new ArrayList<ArrivalDeparture>();
    } else {
      startTime = toHHmm(mNewArrivalsDepartures.get(mNewArrivalsDepartures.size() - 1).getDate());
      mNewArrivalsDepartures.clear();
    }

    // Fetch livebaord
    Log.d(TAG, "Loading new arrivals/departures for time " + startTime + "...");
    Liveboard liveboard;
    try {
      liveboard = mIRail.getLiveboard(mStation, startTime, mDepartures);
    } catch (Exception e) {
      Log.e(TAG, "Could not fetch departures/arrivals: " + e);
      e.printStackTrace();
      return false;
    }

    // Get arrivals/departures
    List<ArrivalDeparture> newArrivalDepartures = liveboard.getArrivalsAndDepartures();
    if (newArrivalDepartures.isEmpty()) {
      Log.d(TAG, "No new items returned for time " + startTime + ".");
      return false;
    } else if (!mNewArrivalsDepartures.isEmpty()) {
      Date lastPreviousDate = mNewArrivalsDepartures.get(mNewArrivalsDepartures.size() - 1).getDate();
      Date lastNewData = newArrivalDepartures.get(newArrivalDepartures.size() - 1).getDate();
      if (lastPreviousDate.equals(lastNewData)) {
        Log.d(TAG, "Same items as before returned for time " + startTime + ".");
        return false;
      }
    }

    removeOverlap(newArrivalDepartures);
    mNewArrivalsDepartures = newArrivalDepartures;

    Log.d(TAG, "Finished loading " + mNewArrivalsDepartures.size() + " new arrivals/departures for " + startTime + ".");
    return true;
  }

  @Override
  protected void appendCachedData() {
    ArrivalDepartureAdapter adapter = mWrappedAdapter;
    adapter.addItems(mNewArrivalsDepartures);
  }

  /**
   * Had to override this method, otherwise IndexOutOfBoundException. Bug in
   * EndlessAdapter/AdapterWrapper?
   */
  @Override
  public long getItemId(int position) {
    if (position >= mWrappedAdapter.getCount()) {
      return -1;
    }
    return super.getItemId(position);
  }

  /**
   * Sets the query parameters used when updating the arrivals/departures.
   * 
   * @param station
   * @param startTime
   *            the starting time of the arrivals/departures; null to use the
   *            current time
   * @param departures
   *            true to fetch departures; false to fetch arrivals
   */
  public void setQueryParams(Station station, String initialStartTime, boolean departures) {
    mStation = station;
    mInitialStartTime = initialStartTime;
    mDepartures = departures;
  }

  /**
   * Removes items from the new arrivals/deparatures that overlap with the
   * last previous arrival/departure.
   * 
   * Note that this algorithm depends on the iRail API always returning
   * arrivals/departures in the same order. This does not seem to always be
   * the case though. In that case the beginning of the new list will contain
   * duplicates from the previous list.
   * 
   * @param newList  the new arrivals/departures
   */
  private void removeOverlap(List<ArrivalDeparture> newList) {
    if (mWrappedAdapter.getCount() == 0) {
      return;
    }
    ArrivalDeparture lastArrDep = (ArrivalDeparture) mWrappedAdapter.getItem(mWrappedAdapter.getCount() - 1);

    for (Iterator<ArrivalDeparture> it = newList.iterator(); it.hasNext();) {
      ArrivalDeparture newArrDep = it.next();
      if (newArrDep.getDate().before(lastArrDep.getDate())) {
        // Lists overlap, remove from new list
        it.remove();
      } else if (newArrDep.getDate().equals(lastArrDep.getDate()) && newArrDep.getPlatform().equals(lastArrDep.getPlatform())) {
        // Lists overlap, remove from new list
        it.remove();
      } else {
        // List no longer overlap, return
        return;
      }
    }
  }

  private static String toHHmm(Date date) {
    return new SimpleDateFormat("HHmm").format(date);
  }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.