Java tutorial
/** * Copyright 2016 Carl-Philipp Harmant * <p> * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package fr.cph.chicago.core.activity; import android.app.ListActivity; import android.content.Intent; import android.graphics.Color; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.v7.widget.Toolbar; import android.text.Editable; import android.text.TextWatcher; import android.util.Log; import android.view.WindowManager; import android.widget.EditText; import android.widget.LinearLayout; import com.annimon.stream.Stream; import com.google.android.gms.maps.CameraUpdateFactory; import com.google.android.gms.maps.GoogleMapOptions; import com.google.android.gms.maps.MapFragment; import com.google.android.gms.maps.model.CameraPosition; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.PolylineOptions; import org.apache.commons.lang3.StringUtils; import java.util.ArrayList; import java.util.List; import butterknife.BindDrawable; import butterknife.BindString; import butterknife.BindView; import butterknife.ButterKnife; import fr.cph.chicago.R; import fr.cph.chicago.core.App; import fr.cph.chicago.core.adapter.BusBoundAdapter; import fr.cph.chicago.entity.BusPattern; import fr.cph.chicago.entity.BusStop; import fr.cph.chicago.entity.Position; import fr.cph.chicago.entity.enumeration.TrainLine; import fr.cph.chicago.rx.observable.ObservableUtil; import fr.cph.chicago.util.Util; import static fr.cph.chicago.Constants.BUSES_PATTERN_URL; import static fr.cph.chicago.Constants.BUSES_STOP_URL; /** * Activity that represents the bus bound activity * * @author Carl-Philipp Harmant * @version 1 */ public class BusBoundActivity extends ListActivity { private static final String TAG = BusBoundActivity.class.getSimpleName(); @BindView(R.id.bellow) LinearLayout layout; @BindView(R.id.toolbar) Toolbar toolbar; @BindView(R.id.bus_filter) EditText filter; @BindString(R.string.bundle_bus_stop_id) String bundleBusStopId; @BindString(R.string.bundle_bus_route_id) String bundleBusRouteId; @BindString(R.string.bundle_bus_bound) String bundleBusBound; @BindString(R.string.bundle_bus_bound_title) String bundleBusBoundTitle; @BindString(R.string.bundle_bus_stop_name) String bundleBusStopName; @BindString(R.string.bundle_bus_route_name) String bundleBusRouteName; @BindString(R.string.bundle_bus_latitude) String bundleBusLatitude; @BindString(R.string.bundle_bus_longitude) String bundleBusLongitude; @BindDrawable(R.drawable.ic_arrow_back_white_24dp) Drawable arrowBackWhite; private MapFragment mapFragment; private String busRouteId; private String busRouteName; private String bound; private String boundTitle; private BusBoundAdapter busBoundAdapter; private List<BusStop> busStops; @Override public final void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); App.checkBusData(this); if (!this.isFinishing()) { setContentView(R.layout.activity_bus_bound); ButterKnife.bind(this); if (busRouteId == null || busRouteName == null || bound == null || boundTitle == null) { final Bundle extras = getIntent().getExtras(); busRouteId = extras.getString(bundleBusRouteId); busRouteName = extras.getString(bundleBusRouteName); bound = extras.getString(bundleBusBound); boundTitle = extras.getString(bundleBusBoundTitle); } busBoundAdapter = new BusBoundAdapter(); setListAdapter(busBoundAdapter); getListView().setOnItemClickListener((adapterView, view, position, id) -> { final BusStop busStop = (BusStop) busBoundAdapter.getItem(position); final Intent intent = new Intent(getApplicationContext(), BusActivity.class); final Bundle extras = new Bundle(); extras.putInt(bundleBusStopId, busStop.getId()); extras.putString(bundleBusStopName, busStop.getName()); extras.putString(bundleBusRouteId, busRouteId); extras.putString(bundleBusRouteName, busRouteName); extras.putString(bundleBusBound, bound); extras.putString(bundleBusBoundTitle, boundTitle); extras.putDouble(bundleBusLatitude, busStop.getPosition().getLatitude()); extras.putDouble(bundleBusLongitude, busStop.getPosition().getLongitude()); intent.putExtras(extras); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); }); filter.addTextChangedListener(new TextWatcher() { private List<BusStop> busStopsFiltered; @Override public void beforeTextChanged(final CharSequence s, final int start, final int count, final int after) { busStopsFiltered = new ArrayList<>(); } @Override public void onTextChanged(final CharSequence s, final int start, final int before, final int count) { if (busStops != null) { Stream.of(busStops).filter(busStop -> StringUtils.containsIgnoreCase(busStop.getName(), s)) .forEach(busStopsFiltered::add); } } @Override public void afterTextChanged(final Editable s) { busBoundAdapter.update(busStopsFiltered); busBoundAdapter.notifyDataSetChanged(); } }); Util.setWindowsColor(this, toolbar, TrainLine.NA); toolbar.setTitle(busRouteId + " - " + boundTitle); toolbar.setNavigationIcon(arrowBackWhite); toolbar.setOnClickListener(v -> finish()); ObservableUtil.createBusStopBoundObservable(getApplicationContext(), busRouteId, bound) .subscribe(onNext -> { busStops = onNext; busBoundAdapter.update(onNext); busBoundAdapter.notifyDataSetChanged(); }, onError -> { Log.e(TAG, onError.getMessage(), onError); Util.showOopsSomethingWentWrong(getListView()); }); Util.trackAction(this, R.string.analytics_category_req, R.string.analytics_action_get_bus, BUSES_STOP_URL, 0); // Preventing keyboard from moving background when showing up getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN); } } @Override public final void onStart() { super.onStart(); if (mapFragment == null) { final android.app.FragmentManager fm = getFragmentManager(); final GoogleMapOptions options = new GoogleMapOptions(); final CameraPosition camera = new CameraPosition(Util.CHICAGO, 7, 0, 0); options.camera(camera); mapFragment = MapFragment.newInstance(options); mapFragment.setRetainInstance(true); fm.beginTransaction().replace(R.id.map, mapFragment).commit(); } } @Override public final void onResume() { super.onResume(); mapFragment.getMapAsync(googleMap -> { googleMap.getUiSettings().setMyLocationButtonEnabled(false); googleMap.getUiSettings().setZoomControlsEnabled(false); Util.trackAction(this, R.string.analytics_category_req, R.string.analytics_action_get_bus, BUSES_PATTERN_URL, 0); ObservableUtil.createBusPatternObservable(getApplicationContext(), busRouteId, bound) .subscribe(busPattern -> { if (busPattern.isPresent()) { final int center = busPattern.get().getPoints().size() / 2; final Position position = busPattern.get().getPoints().get(center).getPosition(); if (position != null) { final LatLng latLng = new LatLng(position.getLatitude(), position.getLongitude()); googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 7)); googleMap.animateCamera(CameraUpdateFactory.zoomTo(9), 500, null); } else { googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(Util.CHICAGO, 10)); } drawPattern(busPattern.get()); } else { Util.showMessage(this, R.string.message_error_could_not_load_path); } }, onError -> { Util.handleConnectOrParserException(onError, null, layout, layout); Log.e(TAG, onError.getMessage(), onError); }); }); } private void drawPattern(@NonNull final BusPattern pattern) { mapFragment.getMapAsync(googleMap -> { final PolylineOptions poly = new PolylineOptions(); poly.geodesic(true).color(Color.BLACK); poly.width(7f); Stream.of(pattern.getPoints()).map(patternPoint -> new LatLng(patternPoint.getPosition().getLatitude(), patternPoint.getPosition().getLongitude())).forEach(poly::add); googleMap.addPolyline(poly); }); } @Override public void onRestoreInstanceState(final Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); busRouteId = savedInstanceState.getString(bundleBusRouteId); busRouteName = savedInstanceState.getString(bundleBusRouteName); bound = savedInstanceState.getString(bundleBusBound); boundTitle = savedInstanceState.getString(bundleBusBoundTitle); } @Override public void onSaveInstanceState(final Bundle savedInstanceState) { savedInstanceState.putString(bundleBusRouteId, busRouteId); savedInstanceState.putString(bundleBusRouteName, busRouteName); savedInstanceState.putString(bundleBusBound, bound); savedInstanceState.putString(bundleBusBoundTitle, boundTitle); super.onSaveInstanceState(savedInstanceState); } }