diff --git a/app/build.gradle b/app/build.gradle
index b098b26e9..1211138a7 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -33,6 +33,8 @@ dependencies {
implementation dependenciesList.mapboxMapSdk
implementation dependenciesList.mapboxServices
+ implementation dependenciesList.lifecycleExtensions
+
// Support libraries
implementation dependenciesList.supportAnnotation
implementation dependenciesList.supportAppcompatV7
diff --git a/gradle/dependencies.gradle b/gradle/dependencies.gradle
index a81172e72..ddc54b6f7 100644
--- a/gradle/dependencies.gradle
+++ b/gradle/dependencies.gradle
@@ -29,8 +29,9 @@ ext {
commonsIO : '2.5',
robolectric : '3.4.2',
lifecycleCompiler : '1.0.0',
- lifecycleRuntime : '1.0.3',
+ lifecycleExtensions: '1.0.0',
room : '1.0.0',
+ androidArchCore : '1.0.0',
okhttp : '3.9.0'
]
@@ -71,7 +72,7 @@ ext {
supportConstraintLayout: "com.android.support.constraint:constraint-layout:${version.constraintLayout}",
// architecture
- lifecycleExtensions : "android.arch.lifecycle:extensions:${version.lifecycleRuntime}",
+ lifecycleExtensions : "android.arch.lifecycle:extensions:${version.lifecycleExtensions}",
lifecycleCompiler : "android.arch.lifecycle:compiler:${version.lifecycleCompiler}",
roomRuntime : "android.arch.persistence.room:runtime:${version.room}",
roomCompiler : "android.arch.persistence.room:compiler:${version.room}",
@@ -95,6 +96,7 @@ ext {
hamcrest : "org.hamcrest:hamcrest-junit:${version.hamcrest}",
commonsIO : "commons-io:commons-io:${version.commonsIO}",
robolectric : "org.robolectric:robolectric:${version.robolectric}",
+ androidArchCore : "android.arch.core:core-testing:${version.androidArchCore}",
// okhttp
okhttp : "com.squareup.okhttp3:okhttp:${version.okhttp}",
diff --git a/plugin-places/build.gradle b/plugin-places/build.gradle
index c7237bf66..66845dc8c 100644
--- a/plugin-places/build.gradle
+++ b/plugin-places/build.gradle
@@ -40,6 +40,7 @@ dependencies {
implementation dependenciesList.supportRecyclerView
implementation dependenciesList.supportV4
+ implementation dependenciesList.lifecycleExtensions
implementation dependenciesList.roomRuntime
annotationProcessor dependenciesList.roomCompiler
@@ -48,6 +49,7 @@ dependencies {
// Unit testing
testImplementation dependenciesList.junit
testImplementation dependenciesList.mockito
+ testImplementation dependenciesList.androidArchCore
javadocDeps dependenciesList.mapboxMapSdk
}
\ No newline at end of file
diff --git a/plugin-places/schemas/com.mapbox.plugins.places.autocomplete.data.SearchHistoryDatabase/1.json b/plugin-places/schemas/com.mapbox.plugins.places.autocomplete.data.SearchHistoryDatabase/1.json
new file mode 100644
index 000000000..7339fcd5c
--- /dev/null
+++ b/plugin-places/schemas/com.mapbox.plugins.places.autocomplete.data.SearchHistoryDatabase/1.json
@@ -0,0 +1,39 @@
+{
+ "formatVersion": 1,
+ "database": {
+ "version": 1,
+ "identityHash": "6785f3a8f4d6195ea76771bea75e1fd5",
+ "entities": [
+ {
+ "tableName": "searchhistory",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`placeId` TEXT NOT NULL, `carmen_feature` TEXT, PRIMARY KEY(`placeId`))",
+ "fields": [
+ {
+ "fieldPath": "placeId",
+ "columnName": "placeId",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "carmenFeature",
+ "columnName": "carmen_feature",
+ "affinity": "TEXT",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "placeId"
+ ],
+ "autoGenerate": false
+ },
+ "indices": [],
+ "foreignKeys": []
+ }
+ ],
+ "setupQueries": [
+ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
+ "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"6785f3a8f4d6195ea76771bea75e1fd5\")"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/plugin-places/schemas/com.mapbox.plugins.places.autocomplete.data.SearchHistoryDatabase/2.json b/plugin-places/schemas/com.mapbox.plugins.places.autocomplete.data.SearchHistoryDatabase/2.json
new file mode 100644
index 000000000..995743fee
--- /dev/null
+++ b/plugin-places/schemas/com.mapbox.plugins.places.autocomplete.data.SearchHistoryDatabase/2.json
@@ -0,0 +1,39 @@
+{
+ "formatVersion": 1,
+ "database": {
+ "version": 2,
+ "identityHash": "6785f3a8f4d6195ea76771bea75e1fd5",
+ "entities": [
+ {
+ "tableName": "searchhistory",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`placeId` TEXT NOT NULL, `carmen_feature` TEXT, PRIMARY KEY(`placeId`))",
+ "fields": [
+ {
+ "fieldPath": "placeId",
+ "columnName": "placeId",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "carmenFeature",
+ "columnName": "carmen_feature",
+ "affinity": "TEXT",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "placeId"
+ ],
+ "autoGenerate": false
+ },
+ "indices": [],
+ "foreignKeys": []
+ }
+ ],
+ "setupQueries": [
+ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
+ "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"6785f3a8f4d6195ea76771bea75e1fd5\")"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/plugin-places/src/main/AndroidManifest.xml b/plugin-places/src/main/AndroidManifest.xml
index e6a4a9999..3b5fffaf2 100644
--- a/plugin-places/src/main/AndroidManifest.xml
+++ b/plugin-places/src/main/AndroidManifest.xml
@@ -4,15 +4,10 @@
-
\ No newline at end of file
diff --git a/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/DataRepository.java b/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/DataRepository.java
new file mode 100644
index 000000000..8f9ed4cc4
--- /dev/null
+++ b/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/DataRepository.java
@@ -0,0 +1,49 @@
+package com.mapbox.plugins.places.autocomplete;
+
+import android.arch.lifecycle.LiveData;
+import android.arch.lifecycle.MediatorLiveData;
+import android.arch.lifecycle.Observer;
+import android.support.annotation.Nullable;
+
+import com.mapbox.plugins.places.autocomplete.data.SearchHistoryDatabase;
+import com.mapbox.plugins.places.autocomplete.data.entity.SearchHistoryEntity;
+
+import java.util.List;
+
+public class DataRepository {
+
+ private static DataRepository instance;
+
+ private final SearchHistoryDatabase database;
+ private MediatorLiveData> observableSearchHistory;
+
+ private DataRepository(final SearchHistoryDatabase database) {
+ this.database = database;
+ observableSearchHistory = new MediatorLiveData<>();
+
+ observableSearchHistory.addSource(database.searchHistoryDao().getAll(),
+ new Observer>() {
+ @Override
+ public void onChanged(@Nullable List searchHistoryEntities) {
+ if (database.getDatabaseCreated().getValue() != null) {
+ observableSearchHistory.postValue(searchHistoryEntities);
+ }
+ }
+ });
+ }
+
+ public static DataRepository getInstance(final SearchHistoryDatabase database) {
+ if (instance == null) {
+ instance = new DataRepository(database);
+ }
+ return instance;
+ }
+
+ public LiveData> getSearchHistory() {
+ return observableSearchHistory;
+ }
+
+ public void addSearchHistoryEntity(SearchHistoryEntity searchHistory) {
+ SearchHistoryDatabase.insertData(database, searchHistory);
+ }
+}
diff --git a/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/OnCardItemClickListener.java b/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/OnCardItemClickListener.java
deleted file mode 100644
index 3c827598e..000000000
--- a/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/OnCardItemClickListener.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package com.mapbox.plugins.places.autocomplete;
-
-import com.mapbox.geocoding.v5.models.CarmenFeature;
-
-/**
- * Used internally to detect when a user has selected an item from one of the results list.
- *
- * @since 0.1.0
- */
-interface OnCardItemClickListener {
- void onItemClick(CarmenFeature carmenFeature);
-}
\ No newline at end of file
diff --git a/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/PlaceAutocomplete.java b/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/PlaceAutocomplete.java
index 1112a9e0f..fcf81d0fe 100644
--- a/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/PlaceAutocomplete.java
+++ b/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/PlaceAutocomplete.java
@@ -12,6 +12,8 @@
import com.mapbox.geocoding.v5.GeocodingCriteria.GeocodingTypeCriteria;
import com.mapbox.geocoding.v5.models.CarmenFeature;
import com.mapbox.geojson.Point;
+import com.mapbox.plugins.places.autocomplete.data.SearchHistoryDatabase;
+import com.mapbox.plugins.places.autocomplete.ui.PlaceAutocompleteActivity;
import java.util.ArrayList;
import java.util.Arrays;
@@ -69,9 +71,9 @@ public static CarmenFeature getPlace(Intent data) {
* @since 0.1.0
*/
public static void clearRecentHistory(Context context) {
- SearchHistoryDatabase database = Room.databaseBuilder(context,
- SearchHistoryDatabase.class, PlaceConstants.SEARCH_HISTORY_DATABASE_NAME).build();
- new RecentSearchAsyncTask(database).execute();
+// SearchHistoryDatabase database = Room.databaseBuilder(context,
+// SearchHistoryDatabase.class, PlaceConstants.SEARCH_HISTORY_DATABASE_NAME).build();
+// new RecentSearchAsyncTask(database).execute();
}
/**
@@ -268,12 +270,8 @@ public IntentBuilder backgroundColor(@ColorInt int backgroundColor) {
*/
public Intent build(Activity activity) {
intent.putStringArrayListExtra(PlaceConstants.COUNTRIES, countries);
-
- if (mode == MODE_FULLSCREEN) {
- intent.setClass(activity, PlaceCompleteFullActivity.class);
- } else {
- intent.setClass(activity, PlaceCompleteCardActivity.class);
- }
+ intent.putExtra(PlaceConstants.MODE, mode);
+ intent.setClass(activity, PlaceAutocompleteActivity.class);
return intent;
}
}
diff --git a/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/PlaceCompleteCardActivity.java b/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/PlaceCompleteCardActivity.java
deleted file mode 100644
index a8e142921..000000000
--- a/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/PlaceCompleteCardActivity.java
+++ /dev/null
@@ -1,169 +0,0 @@
-package com.mapbox.plugins.places.autocomplete;
-
-import android.arch.persistence.room.Room;
-import android.content.Intent;
-import android.graphics.Color;
-import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.support.v7.app.AppCompatActivity;
-import android.view.View;
-import android.view.ViewTreeObserver;
-import android.widget.ScrollView;
-
-import com.mapbox.geocoding.v5.MapboxGeocoding;
-import com.mapbox.geocoding.v5.models.CarmenFeature;
-import com.mapbox.geocoding.v5.models.GeocodingResponse;
-import com.mapbox.places.R;
-import com.mapbox.plugins.places.common.KeyboardUtils;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import retrofit2.Call;
-import retrofit2.Callback;
-import retrofit2.Response;
-
-import static android.view.View.INVISIBLE;
-import static android.view.View.VISIBLE;
-
-
-public class PlaceCompleteCardActivity extends AppCompatActivity implements
- SearchView.QueryListener, Callback, SearchView.BackButtonListener,
- ViewTreeObserver.OnScrollChangedListener, OnCardItemClickListener {
-
- private MapboxGeocoding.Builder geocoderBuilder;
- private ResultView searchResultView;
- private ResultView starredView;
- private ResultView recentSearchResults;
- private ScrollView resultScrollView;
- private SearchView searchView;
- private SearchHistoryDatabase database;
- private View rootView;
- private View dropShadow;
-
- @Override
- protected void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_complete_card);
- bindViews();
- bindClickListeners();
-
- Intent intent = getIntent();
-
- // Theme settings
- rootView.setBackgroundColor(intent.getIntExtra(PlaceConstants.BACKGROUND, Color.TRANSPARENT));
-
- fillFavoritePlacesList(intent);
- geocoderBuilder = Utils.initiateSearchQuery(intent);
-
- // Get and populate the recent history list
- database = Room.databaseBuilder(getApplicationContext(),
- SearchHistoryDatabase.class, PlaceConstants.SEARCH_HISTORY_DATABASE_NAME).build();
- new RecentSearchAsyncTask(database, recentSearchResults).execute();
-
- resultScrollView.getViewTreeObserver().addOnScrollChangedListener(this);
- }
-
- private void fillFavoritePlacesList(@NonNull Intent intent) {
- List serialized = intent.getStringArrayListExtra(PlaceConstants.INJECTED_PLACES);
- if (serialized == null || serialized.isEmpty()) {
- return;
- }
- List starredFeatures = new ArrayList<>();
- for (String serializedCarmenFeature : serialized) {
- starredFeatures.add(CarmenFeature.fromJson(serializedCarmenFeature));
- }
- starredView.getResultsList().addAll(starredFeatures);
- }
-
- private void bindClickListeners() {
- recentSearchResults.setOnItemClickListener(this);
- searchResultView.setOnItemClickListener(this);
- starredView.setOnItemClickListener(this);
- searchView.setBackButtonListener(this);
- searchView.setQueryListener(this);
- }
-
- private void bindViews() {
- rootView = findViewById(R.id.root_layout);
- searchResultView = findViewById(R.id.searchResultView);
- resultScrollView = findViewById(R.id.scroll_view_results);
- recentSearchResults = findViewById(R.id.recentSearchResults);
- starredView = findViewById(R.id.starredView);
- searchView = findViewById(R.id.searchView);
- dropShadow = findViewById(R.id.scroll_drop_shadow);
- }
-
- @Override
- public void onScrollChanged() {
- if (resultScrollView != null) {
- if (resultScrollView.getScrollY() != 0) {
- KeyboardUtils.hideKeyboard(resultScrollView);
- }
- dropShadow.setVisibility(
- resultScrollView.canScrollVertically(-1) ? VISIBLE : INVISIBLE
- );
- }
- }
-
- @Override
- public void onQueryChange(CharSequence charSequence) {
- String query = charSequence.toString();
- if (query.isEmpty()) {
- searchResultView.getResultsList().clear();
- searchResultView.setVisibility(searchResultView.getResultsList().isEmpty() ? View.GONE : VISIBLE);
- searchResultView.notifyDataSetChanged();
- return;
- }
- geocoderBuilder.query(query)
- .build().enqueueCall(this);
- }
-
- @Override
- public void onResponse(Call call, Response response) {
- if (response.isSuccessful()) {
- searchResultView.getResultsList().clear();
- searchResultView.getResultsList().addAll(response.body().features());
- searchResultView.setVisibility(searchResultView.getResultsList().isEmpty() ? View.GONE : VISIBLE);
- searchResultView.notifyDataSetChanged();
- }
- }
-
- @Override
- public void onFailure(Call call, Throwable throwable) {
-
- }
-
- @Override
- public void onItemClick(CarmenFeature carmenFeature) {
- String json = carmenFeature.toJson();
- if (!carmenFeature.properties().has(PlaceConstants.SAVED_PLACE)) {
- RecentSearch recentSearch = new RecentSearch(carmenFeature.id(), json);
- new RecentSearchAsyncTask(database, recentSearch).execute();
- }
-
- Intent intent = new Intent();
- intent.putExtra(PlaceConstants.RETURNING_CARMEN_FEATURE, json);
- setResult(AppCompatActivity.RESULT_OK, intent);
- finish();
- }
-
- @Override
- protected void onDestroy() {
- if (searchView != null) {
- searchView.removeBackButtonListener();
- searchView.removeQueryListener();
- }
- if (resultScrollView != null) {
- resultScrollView.getViewTreeObserver().removeOnScrollChangedListener(this);
- }
- super.onDestroy();
- }
-
- @Override
- public void onBackButtonPress() {
- setResult(AppCompatActivity.RESULT_CANCELED);
- finish();
- }
-}
\ No newline at end of file
diff --git a/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/PlaceCompleteFullActivity.java b/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/PlaceCompleteFullActivity.java
deleted file mode 100644
index f96b49b46..000000000
--- a/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/PlaceCompleteFullActivity.java
+++ /dev/null
@@ -1,86 +0,0 @@
-package com.mapbox.plugins.places.autocomplete;
-
-import android.content.Intent;
-import android.graphics.Color;
-import android.os.Bundle;
-import android.support.annotation.Nullable;
-import android.support.v7.app.AppCompatActivity;
-import android.view.View;
-
-import com.mapbox.geocoding.v5.MapboxGeocoding;
-import com.mapbox.geocoding.v5.models.GeocodingResponse;
-import com.mapbox.places.R;
-
-import retrofit2.Call;
-import retrofit2.Callback;
-import retrofit2.Response;
-
-public class PlaceCompleteFullActivity extends AppCompatActivity implements
- SearchView.QueryListener, Callback, SearchView.BackButtonListener {
-
- private MapboxGeocoding.Builder geocoderBuilder;
- private ResultView searchResultView;
- private View rootView;
-
- @Override
- protected void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_complete_full);
- bindViews();
-
- Intent intent = getIntent();
-
- rootView.setBackgroundColor(intent.getIntExtra(PlaceConstants.BACKGROUND, Color.TRANSPARENT));
-
- geocoderBuilder = Utils.initiateSearchQuery(intent);
- searchResultView = findViewById(R.id.searchResultView);
-
- SearchView searchView = findViewById(R.id.searchView);
- searchView.setBackButtonListener(this);
- searchView.setQueryListener(this);
- }
-
- @Override
- public void onQueryChange(CharSequence charSequence) {
- String query = charSequence.toString();
- if (query.isEmpty()) {
- searchResultView.getResultsList().clear();
- searchResultView.notifyDataSetChanged();
- return;
- }
- geocoderBuilder.query(query)
- .build().enqueueCall(this);
- }
-
- private void bindViews() {
- rootView = findViewById(R.id.root_layout);
- searchResultView = findViewById(R.id.searchResultView);
- }
-
- @Override
- public void onResponse(Call call, Response response) {
- if (response.isSuccessful()) {
- searchResultView.getResultsList().clear();
- searchResultView.getResultsList().addAll(response.body().features());
- searchResultView.notifyDataSetChanged();
- }
- }
-
- @Override
- public void onFailure(Call call, Throwable t) {
-
- }
-
-
- @Override
- protected void onDestroy() {
-// searchBar.removeBackButtonListener();
-// searchBar.removeQueryListener();
- super.onDestroy();
- }
-
- @Override
- public void onBackButtonPress() {
- finish();
- }
-}
diff --git a/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/PlaceConstants.java b/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/PlaceConstants.java
index 066964aa5..3ec847fb6 100644
--- a/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/PlaceConstants.java
+++ b/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/PlaceConstants.java
@@ -1,23 +1,23 @@
package com.mapbox.plugins.places.autocomplete;
-final class PlaceConstants {
+public final class PlaceConstants {
private PlaceConstants() {
}
- static final String RETURNING_CARMEN_FEATURE = "com.mapbox.mapboxsdk.plugins.places.carmenfeat";
- static final String SEARCH_HISTORY_DATABASE_NAME = "com.mapbox.mapboxsdk.plugins.places.database";
- static final String ACCESS_TOKEN = "com.mapbox.mapboxsdk.plugins.places.accessToken";
- static final String BBOX_SOUTHWEST_POINT
+ public static final String RETURNING_CARMEN_FEATURE = "com.mapbox.mapboxsdk.plugins.places.carmenfeat";
+ public static final String ACCESS_TOKEN = "com.mapbox.mapboxsdk.plugins.places.accessToken";
+ public static final String BBOX_SOUTHWEST_POINT
= "com.mapbox.mapboxsdk.plugins.places.bbox.southwestPoint";
- static final String BBOX_NORTHEAST_POINT
+ public static final String BBOX_NORTHEAST_POINT
= "com.mapbox.mapboxsdk.plugins.places.bbox.northeastPoint";
- static final String COUNTRIES = "com.mapbox.mapboxsdk.plugins.places.countries";
- static final String PROXIMITY = "com.mapbox.mapboxsdk.plugins.places.proximity";
- static final String TYPE = "com.mapbox.mapboxsdk.plugins.places.types";
- static final String LANGUAGE = "com.mapbox.mapboxsdk.plugins.places.language";
- static final String LIMIT = "com.mapbox.mapboxsdk.plugins.places.limit";
- static final String INJECTED_PLACES = "com.mapbox.mapboxsdk.plugins.places.injectPlaces";
- static final String BACKGROUND = "com.mapbox.mapboxsdk.plugins.places.backgroundColor";
- static final String SAVED_PLACE = "com.mapbox.mapboxsdk.plugins.places.savedcarmenfeat";
+ public static final String COUNTRIES = "com.mapbox.mapboxsdk.plugins.places.countries";
+ public static final String PROXIMITY = "com.mapbox.mapboxsdk.plugins.places.proximity";
+ public static final String TYPE = "com.mapbox.mapboxsdk.plugins.places.types";
+ public static final String LANGUAGE = "com.mapbox.mapboxsdk.plugins.places.language";
+ public static final String LIMIT = "com.mapbox.mapboxsdk.plugins.places.limit";
+ public static final String INJECTED_PLACES = "com.mapbox.mapboxsdk.plugins.places.injectPlaces";
+ public static final String BACKGROUND = "com.mapbox.mapboxsdk.plugins.places.backgroundColor";
+ public static final String SAVED_PLACE = "com.mapbox.mapboxsdk.plugins.places.savedcarmenfeat";
+ public static final String MODE = "com.mapbox.mapboxsdk.plugins.places.mode";
}
diff --git a/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/RecentSearchAsyncTask.java b/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/RecentSearchAsyncTask.java
deleted file mode 100644
index 38a3c03c8..000000000
--- a/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/RecentSearchAsyncTask.java
+++ /dev/null
@@ -1,71 +0,0 @@
-package com.mapbox.plugins.places.autocomplete;
-
-import android.os.AsyncTask;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.view.View;
-
-import com.mapbox.geocoding.v5.models.CarmenFeature;
-
-import java.util.ArrayList;
-import java.util.List;
-
-class RecentSearchAsyncTask extends AsyncTask {
-
- private final SearchHistoryDatabase database;
- private List carmenFeatures = new ArrayList<>();
- private ResultView recentSearchResults;
- private RecentSearch recentSearch;
-
- RecentSearchAsyncTask(@NonNull SearchHistoryDatabase database) {
- this.database = database;
- }
-
- RecentSearchAsyncTask(@NonNull SearchHistoryDatabase database,
- @Nullable ResultView recentSearchResults) {
- this.database = database;
- this.recentSearchResults = recentSearchResults;
- }
-
- RecentSearchAsyncTask(@NonNull SearchHistoryDatabase database,
- @Nullable RecentSearch recentSearch) {
- this.database = database;
- this.recentSearch = recentSearch;
- }
-
- @Override
- protected Void doInBackground(Void... voids) {
-
- if (recentSearchResults != null) {
- for (RecentSearch recentSearch : database.recentSearchesDao().getAll()) {
- CarmenFeature carmenFeature = CarmenFeature.fromJson(recentSearch.getCarmenFeature());
- carmenFeatures.add(carmenFeature);
- }
- } else if (recentSearch != null) {
- RecentSearch sameRecentSearch = database.recentSearchesDao()
- .findByCarmenFeature(recentSearch.getPlaceId());
- if (sameRecentSearch != null) {
- return null;
- }
-
- database.recentSearchesDao().insertAll(recentSearch);
- } else {
- for (RecentSearch recentSearch : database.recentSearchesDao().getAll()) {
- database.recentSearchesDao().delete(recentSearch);
- }
- }
-
- return null;
- }
-
- @Override
- protected void onPostExecute(Void aVoid) {
- super.onPostExecute(aVoid);
- if (recentSearchResults != null) {
- recentSearchResults.getResultsList().addAll(carmenFeatures);
- if (!carmenFeatures.isEmpty()) {
- recentSearchResults.setVisibility(View.VISIBLE);
- }
- }
- }
-}
\ No newline at end of file
diff --git a/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/RecentSearchesDao.java b/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/RecentSearchesDao.java
deleted file mode 100644
index fa3875d69..000000000
--- a/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/RecentSearchesDao.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.mapbox.plugins.places.autocomplete;
-
-import android.arch.persistence.room.Dao;
-import android.arch.persistence.room.Delete;
-import android.arch.persistence.room.Insert;
-import android.arch.persistence.room.Query;
-
-import java.util.List;
-
-@Dao
-public interface RecentSearchesDao {
- @Query("SELECT * FROM recentsearch")
- List getAll();
-
- @Query("SELECT * FROM recentsearch WHERE placeId IN (:placeIds)")
- List loadAllByIds(String[] placeIds);
-
- @Query("SELECT * FROM recentsearch WHERE placeId IN (:placeId)")
- RecentSearch findByCarmenFeature(String placeId);
-
- @Insert
- void insertAll(RecentSearch... recentSearch);
-
- @Delete
- void delete(RecentSearch recentSearch);
-}
\ No newline at end of file
diff --git a/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/SearchHistoryDatabase.java b/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/SearchHistoryDatabase.java
deleted file mode 100644
index 76d0dfcd5..000000000
--- a/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/SearchHistoryDatabase.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package com.mapbox.plugins.places.autocomplete;
-
-import android.arch.persistence.room.Database;
-import android.arch.persistence.room.RoomDatabase;
-
-@Database(entities = {RecentSearch.class}, version = 1)
-public abstract class SearchHistoryDatabase extends RoomDatabase {
- public abstract RecentSearchesDao recentSearchesDao();
-}
diff --git a/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/data/SearchHistoryDatabase.java b/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/data/SearchHistoryDatabase.java
new file mode 100644
index 000000000..97b3b3515
--- /dev/null
+++ b/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/data/SearchHistoryDatabase.java
@@ -0,0 +1,89 @@
+package com.mapbox.plugins.places.autocomplete.data;
+
+import android.arch.lifecycle.LiveData;
+import android.arch.lifecycle.MutableLiveData;
+import android.arch.persistence.db.SupportSQLiteDatabase;
+import android.arch.persistence.room.Database;
+import android.arch.persistence.room.Room;
+import android.arch.persistence.room.RoomDatabase;
+import android.arch.persistence.room.TypeConverters;
+import android.content.Context;
+import android.os.AsyncTask;
+import android.support.annotation.NonNull;
+
+import com.mapbox.plugins.places.autocomplete.data.converter.CarmenFeatureConverter;
+import com.mapbox.plugins.places.autocomplete.data.dao.SearchHistoryDao;
+import com.mapbox.plugins.places.autocomplete.data.entity.SearchHistoryEntity;
+
+@Database(entities = {SearchHistoryEntity.class}, version = 2)
+@TypeConverters(CarmenFeatureConverter.class)
+public abstract class SearchHistoryDatabase extends RoomDatabase {
+
+ private static final String DATABASE_NAME = "com.mapbox.mapboxsdk.plugins.places.database";
+ private static SearchHistoryDatabase instance;
+
+ public abstract SearchHistoryDao searchHistoryDao();
+
+ private final MutableLiveData isDatabaseCreated = new MutableLiveData<>();
+
+ public static SearchHistoryDatabase getInstance(final Context context) {
+ if (instance == null) {
+ instance = buildDatabase(context.getApplicationContext());
+ instance.updateDatabaseCreated(context.getApplicationContext());
+ }
+ return instance;
+ }
+
+ private static SearchHistoryDatabase buildDatabase(final Context appContext) {
+ return Room.databaseBuilder(appContext,
+ SearchHistoryDatabase.class, DATABASE_NAME).addCallback(new Callback() {
+ @Override
+ public void onCreate(@NonNull SupportSQLiteDatabase db) {
+ super.onCreate(db);
+ SearchHistoryDatabase database = SearchHistoryDatabase.getInstance(appContext);
+ database.setDatabaseCreated();
+ }
+ }).fallbackToDestructiveMigration().build();
+ // TODO remove fallbackToDestructiveMigration
+ }
+
+ /**
+ * Check whether the database already exists and expose it via {@link #getDatabaseCreated()}
+ */
+ private void updateDatabaseCreated(final Context context) {
+ if (context.getDatabasePath(DATABASE_NAME).exists()) {
+ setDatabaseCreated();
+ }
+ }
+
+ private void setDatabaseCreated() {
+ isDatabaseCreated.postValue(true);
+ }
+
+ public static void insertData(final SearchHistoryDatabase database,
+ final SearchHistoryEntity searchHistory) {
+ new InsertSearchEntity(database, searchHistory).execute();
+ }
+
+ public LiveData getDatabaseCreated() {
+ return isDatabaseCreated;
+ }
+
+
+ private static class InsertSearchEntity extends AsyncTask {
+
+ private final SearchHistoryDatabase database;
+ private final SearchHistoryEntity searchHistory;
+
+ InsertSearchEntity(SearchHistoryDatabase database, SearchHistoryEntity searchHistory) {
+ this.searchHistory = searchHistory;
+ this.database = database;
+ }
+
+ @Override
+ protected Void doInBackground(Void... voids) {
+ database.searchHistoryDao().insert(searchHistory);
+ return null;
+ }
+ }
+}
diff --git a/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/data/converter/CarmenFeatureConverter.java b/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/data/converter/CarmenFeatureConverter.java
new file mode 100644
index 000000000..d83b25e60
--- /dev/null
+++ b/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/data/converter/CarmenFeatureConverter.java
@@ -0,0 +1,19 @@
+package com.mapbox.plugins.places.autocomplete.data.converter;
+
+import android.arch.persistence.room.TypeConverter;
+import android.support.annotation.NonNull;
+
+import com.mapbox.geocoding.v5.models.CarmenFeature;
+
+public class CarmenFeatureConverter {
+
+ @TypeConverter
+ public static CarmenFeature toCarmenFeature(String serializedCarmenFeature) {
+ return serializedCarmenFeature == null ? null : CarmenFeature.fromJson(serializedCarmenFeature);
+ }
+
+ @TypeConverter
+ public static String fromCarmenFeature(@NonNull CarmenFeature carmenFeature) {
+ return carmenFeature.toJson();
+ }
+}
diff --git a/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/data/dao/SearchHistoryDao.java b/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/data/dao/SearchHistoryDao.java
new file mode 100644
index 000000000..8934fe0b3
--- /dev/null
+++ b/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/data/dao/SearchHistoryDao.java
@@ -0,0 +1,34 @@
+package com.mapbox.plugins.places.autocomplete.data.dao;
+
+import android.arch.lifecycle.LiveData;
+import android.arch.persistence.room.Dao;
+import android.arch.persistence.room.Delete;
+import android.arch.persistence.room.Insert;
+import android.arch.persistence.room.OnConflictStrategy;
+import android.arch.persistence.room.Query;
+
+import com.mapbox.plugins.places.autocomplete.data.entity.SearchHistoryEntity;
+
+import java.util.List;
+
+@Dao
+public interface SearchHistoryDao {
+
+ @Query("SELECT * FROM searchhistory")
+ LiveData> getAll();
+
+ @Query("SELECT * FROM searchhistory WHERE placeId IN (:placeIds)")
+ LiveData> loadAllByIds(String[] placeIds);
+
+ @Query("SELECT * FROM searchhistory WHERE placeId IN (:placeId)")
+ LiveData findByCarmenFeature(String placeId);
+
+ @Insert(onConflict = OnConflictStrategy.REPLACE)
+ void insertAll(List searchHistory);
+
+ @Insert(onConflict = OnConflictStrategy.REPLACE)
+ void insert(SearchHistoryEntity searchHistory);
+
+ @Delete
+ void delete(SearchHistoryEntity searchHistory);
+}
\ No newline at end of file
diff --git a/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/RecentSearch.java b/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/data/entity/SearchHistoryEntity.java
similarity index 52%
rename from plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/RecentSearch.java
rename to plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/data/entity/SearchHistoryEntity.java
index fb89ac835..4d34b5e74 100644
--- a/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/RecentSearch.java
+++ b/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/data/entity/SearchHistoryEntity.java
@@ -1,14 +1,17 @@
-package com.mapbox.plugins.places.autocomplete;
+package com.mapbox.plugins.places.autocomplete.data.entity;
import android.arch.persistence.room.ColumnInfo;
import android.arch.persistence.room.Entity;
import android.arch.persistence.room.PrimaryKey;
import android.support.annotation.NonNull;
-@Entity
-public class RecentSearch {
+import com.mapbox.geocoding.v5.models.CarmenFeature;
+import com.mapbox.plugins.places.autocomplete.model.SearchHistory;
- public RecentSearch(@NonNull String placeId, String carmenFeature) {
+@Entity(tableName = "searchhistory")
+public class SearchHistoryEntity implements SearchHistory {
+
+ public SearchHistoryEntity(@NonNull String placeId, CarmenFeature carmenFeature) {
this.placeId = placeId;
this.carmenFeature = carmenFeature;
}
@@ -18,8 +21,9 @@ public RecentSearch(@NonNull String placeId, String carmenFeature) {
private String placeId;
@ColumnInfo(name = "carmen_feature")
- private String carmenFeature;
+ private CarmenFeature carmenFeature;
+ @Override
@NonNull
public String getPlaceId() {
return placeId;
@@ -29,11 +33,12 @@ public void setPlaceId(@NonNull String placeId) {
this.placeId = placeId;
}
- public String getCarmenFeature() {
+ @Override
+ public CarmenFeature getCarmenFeature() {
return carmenFeature;
}
- public void setCarmenFeature(String carmenFeature) {
+ public void setCarmenFeature(CarmenFeature carmenFeature) {
this.carmenFeature = carmenFeature;
}
}
diff --git a/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/model/SearchHistory.java b/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/model/SearchHistory.java
new file mode 100644
index 000000000..02a73d3b6
--- /dev/null
+++ b/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/model/SearchHistory.java
@@ -0,0 +1,9 @@
+package com.mapbox.plugins.places.autocomplete.model;
+
+import com.mapbox.geocoding.v5.models.CarmenFeature;
+
+public interface SearchHistory {
+ String getPlaceId();
+
+ CarmenFeature getCarmenFeature();
+}
diff --git a/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/ui/PlaceAutocompleteActivity.java b/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/ui/PlaceAutocompleteActivity.java
new file mode 100644
index 000000000..c9c7323c4
--- /dev/null
+++ b/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/ui/PlaceAutocompleteActivity.java
@@ -0,0 +1,175 @@
+package com.mapbox.plugins.places.autocomplete.ui;
+
+import android.arch.lifecycle.Observer;
+import android.arch.lifecycle.ViewModelProviders;
+import android.content.Intent;
+import android.graphics.Color;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.v7.app.AppCompatActivity;
+import android.view.View;
+import android.view.ViewTreeObserver;
+import android.widget.ScrollView;
+
+import com.mapbox.geocoding.v5.models.CarmenFeature;
+import com.mapbox.geocoding.v5.models.GeocodingResponse;
+import com.mapbox.places.R;
+import com.mapbox.plugins.places.autocomplete.DataRepository;
+import com.mapbox.plugins.places.autocomplete.PlaceConstants;
+import com.mapbox.plugins.places.autocomplete.data.entity.SearchHistoryEntity;
+import com.mapbox.plugins.places.autocomplete.viewmodel.PlaceAutocompleteViewModel;
+import com.mapbox.plugins.places.common.KeyboardUtils;
+
+import java.util.List;
+
+import static android.view.View.GONE;
+import static android.view.View.INVISIBLE;
+import static android.view.View.VISIBLE;
+
+public class PlaceAutocompleteActivity extends AppCompatActivity implements ResultClickCallback,
+ SearchView.QueryListener, SearchView.BackButtonListener,
+ ViewTreeObserver.OnScrollChangedListener {
+
+ private PlaceAutocompleteViewModel viewModel;
+ private ResultView searchHistoryView;
+ private ResultView searchResultView;
+ private ScrollView resultScrollView;
+ private ResultView starredView;
+ private SearchView searchView;
+ private View dropShadowView;
+ private View rootView;
+
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ Intent intent = getIntent();
+ setActivityContentView(intent);
+ bindViews();
+ bindClickListeners();
+
+ // View model
+ PlaceAutocompleteViewModel.Factory factory = new PlaceAutocompleteViewModel.Factory(
+ getApplication(), intent);
+ viewModel = ViewModelProviders.of(this, factory).get(PlaceAutocompleteViewModel.class);
+ viewModel.buildGeocodingRequest();
+
+ // Theme settings
+ rootView.setBackgroundColor(intent.getIntExtra(PlaceConstants.BACKGROUND, Color.TRANSPARENT));
+ resultScrollView.getViewTreeObserver().addOnScrollChangedListener(this);
+
+ updateFavoritePlacesView();
+ subscribe();
+ }
+
+ @Override
+ public void onScrollChanged() {
+ if (resultScrollView != null) {
+ if (resultScrollView.getScrollY() != 0) {
+ KeyboardUtils.hideKeyboard(resultScrollView);
+ }
+ dropShadowView.setVisibility(
+ resultScrollView.canScrollVertically(-1) ? VISIBLE : INVISIBLE
+ );
+ }
+ }
+
+ @Override
+ public void onQueryChange(CharSequence charSequence) {
+ viewModel.onQueryChange(charSequence);
+ if (charSequence.length() <= 0) {
+ searchResultView.getResultsList().clear();
+ searchResultView.setVisibility(searchResultView.getResultsList().isEmpty() ? GONE : VISIBLE);
+ searchResultView.notifyDataSetChanged();
+ }
+ }
+
+ @Override
+ public void onClick(CarmenFeature carmenFeature) {
+ Intent intent = viewModel.onItemClicked(carmenFeature);
+ setResult(AppCompatActivity.RESULT_OK, intent);
+ finish();
+ }
+
+ @Override
+ protected void onDestroy() {
+ if (resultScrollView != null) {
+ resultScrollView.getViewTreeObserver().removeOnScrollChangedListener(this);
+ }
+ super.onDestroy();
+ }
+
+ @Override
+ public void onBackButtonPress() {
+ setResult(AppCompatActivity.RESULT_CANCELED);
+ finish();
+ }
+
+ private void setActivityContentView(Intent intent) {
+ if (intent.getIntExtra(PlaceConstants.MODE, 1) == 2) {
+ setContentView(R.layout.activity_complete_card);
+ } else {
+ setContentView(R.layout.activity_complete_full);
+ }
+ }
+
+ private void bindClickListeners() {
+ searchHistoryView.setOnItemClickListener(this);
+ searchResultView.setOnItemClickListener(this);
+ starredView.setOnItemClickListener(this);
+ searchView.setBackButtonListener(this);
+ searchView.setQueryListener(this);
+ }
+
+ private void bindViews() {
+ searchHistoryView = findViewById(R.id.searchHistoryResultsView);
+ resultScrollView = findViewById(R.id.scroll_view_results);
+ searchResultView = findViewById(R.id.searchResultView);
+ dropShadowView = findViewById(R.id.scroll_drop_shadow);
+ starredView = findViewById(R.id.favoriteResultView);
+ searchView = findViewById(R.id.searchView);
+ rootView = findViewById(R.id.root_layout);
+ }
+
+ private void updateSearchHistoryView(@Nullable List searchHistoryEntities) {
+ searchHistoryView.getResultsList().clear();
+ if (searchHistoryEntities != null) {
+ for (SearchHistoryEntity entity : searchHistoryEntities) {
+ searchHistoryView.getResultsList().add(entity.getCarmenFeature());
+ }
+ }
+ searchHistoryView.notifyDataSetChanged();
+ searchHistoryView.setVisibility(
+ searchHistoryView.getResultsList().isEmpty() ? GONE : VISIBLE
+ );
+ }
+
+ private void updateSearchResultView(@Nullable GeocodingResponse response) {
+ searchResultView.getResultsList().clear();
+ searchResultView.getResultsList().addAll(response.features());
+ searchResultView.setVisibility(searchResultView.getResultsList().isEmpty() ? GONE : VISIBLE);
+ searchResultView.notifyDataSetChanged();
+ }
+
+ private void updateFavoritePlacesView() {
+ List favoriteFeatures = viewModel.getFavoritePlaces();
+ starredView.getResultsList().addAll(favoriteFeatures);
+ }
+
+ private void subscribe() {
+ viewModel.geocodingLiveData.observe(this, new Observer() {
+ @Override
+ public void onChanged(@Nullable GeocodingResponse geocodingResponse) {
+ updateSearchResultView(geocodingResponse);
+ }
+ });
+
+ // Subscribe to the search history database
+ DataRepository.getInstance(viewModel.getDatabase()).getSearchHistory().observe(this,
+ new Observer>() {
+ @Override
+ public void onChanged(@Nullable List searchHistoryEntities) {
+ updateSearchHistoryView(searchHistoryEntities);
+ }
+ });
+ }
+}
\ No newline at end of file
diff --git a/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/ResultCardView.java b/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/ui/ResultCardView.java
similarity index 93%
rename from plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/ResultCardView.java
rename to plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/ui/ResultCardView.java
index 2d8f8f434..923636cb5 100644
--- a/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/ResultCardView.java
+++ b/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/ui/ResultCardView.java
@@ -1,4 +1,4 @@
-package com.mapbox.plugins.places.autocomplete;
+package com.mapbox.plugins.places.autocomplete.ui;
import android.content.Context;
import android.support.annotation.NonNull;
diff --git a/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/ui/ResultClickCallback.java b/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/ui/ResultClickCallback.java
new file mode 100644
index 000000000..9c0758855
--- /dev/null
+++ b/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/ui/ResultClickCallback.java
@@ -0,0 +1,7 @@
+package com.mapbox.plugins.places.autocomplete.ui;
+
+import com.mapbox.geocoding.v5.models.CarmenFeature;
+
+interface ResultClickCallback {
+ void onClick(CarmenFeature carmenFeature);
+}
\ No newline at end of file
diff --git a/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/ResultView.java b/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/ui/ResultView.java
similarity index 93%
rename from plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/ResultView.java
rename to plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/ui/ResultView.java
index 1502177b3..2e91e45e1 100644
--- a/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/ResultView.java
+++ b/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/ui/ResultView.java
@@ -1,4 +1,4 @@
-package com.mapbox.plugins.places.autocomplete;
+package com.mapbox.plugins.places.autocomplete.ui;
import android.content.Context;
import android.support.annotation.NonNull;
@@ -56,7 +56,7 @@ void inflateView(Context context) {
inflate(context, R.layout.view_results, this);
}
- public void setOnItemClickListener(OnCardItemClickListener onItemClickListener) {
+ public void setOnItemClickListener(ResultClickCallback onItemClickListener) {
if (adapter != null) {
adapter.setOnItemClickListener(onItemClickListener);
}
diff --git a/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/SearchResultAdapter.java b/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/ui/SearchResultAdapter.java
similarity index 79%
rename from plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/SearchResultAdapter.java
rename to plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/ui/SearchResultAdapter.java
index 37745a1df..f4185de4d 100644
--- a/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/SearchResultAdapter.java
+++ b/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/ui/SearchResultAdapter.java
@@ -1,6 +1,7 @@
-package com.mapbox.plugins.places.autocomplete;
+package com.mapbox.plugins.places.autocomplete.ui;
import android.content.Context;
+import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
@@ -10,6 +11,7 @@
import com.mapbox.geocoding.v5.models.CarmenFeature;
import com.mapbox.places.R;
+import com.mapbox.plugins.places.autocomplete.PlaceConstants;
import java.util.List;
@@ -17,7 +19,10 @@ public class SearchResultAdapter extends RecyclerView.Adapter results;
private final Context context;
@@ -33,14 +38,14 @@ public SearchViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new SearchViewHolder(view);
}
- public void setOnItemClickListener(OnCardItemClickListener onItemClickListener) {
- this.onItemClickListener = onItemClickListener;
+ public void setOnItemClickListener(ResultClickCallback resultClickCallback) {
+ this.resultClickCallback = resultClickCallback;
}
@Override
public void onBindViewHolder(SearchViewHolder holder, int position) {
- if (onItemClickListener != null) {
- holder.bind(results.get(position), onItemClickListener);
+ if (resultClickCallback != null) {
+ holder.bind(results.get(position), resultClickCallback);
}
if (results.get(position).properties().has(PlaceConstants.SAVED_PLACE)) {
@@ -77,11 +82,11 @@ static class SearchViewHolder extends RecyclerView.ViewHolder {
addressView = itemView.findViewById(R.id.tv_address);
}
- public void bind(final CarmenFeature carmenFeature, final OnCardItemClickListener listener) {
+ public void bind(final CarmenFeature carmenFeature, final ResultClickCallback listener) {
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
- listener.onItemClick(carmenFeature);
+ listener.onClick(carmenFeature);
}
});
}
diff --git a/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/SearchView.java b/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/ui/SearchView.java
similarity index 83%
rename from plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/SearchView.java
rename to plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/ui/SearchView.java
index b77306186..ca902bfbe 100644
--- a/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/SearchView.java
+++ b/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/ui/SearchView.java
@@ -1,5 +1,9 @@
-package com.mapbox.plugins.places.autocomplete;
+package com.mapbox.plugins.places.autocomplete.ui;
+import android.arch.lifecycle.Lifecycle;
+import android.arch.lifecycle.LifecycleObserver;
+import android.arch.lifecycle.LifecycleOwner;
+import android.arch.lifecycle.OnLifecycleEvent;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
@@ -13,7 +17,8 @@
import com.mapbox.places.R;
-public class SearchView extends LinearLayout implements ImageButton.OnClickListener, TextWatcher {
+public class SearchView extends LinearLayout implements ImageButton.OnClickListener, TextWatcher,
+ LifecycleObserver {
@Nullable
private BackButtonListener backButtonListener;
@@ -45,6 +50,7 @@ private void initialize() {
backButton.setOnClickListener(this);
clearButton.setOnClickListener(this);
searchEditText.addTextChangedListener(this);
+ ((LifecycleOwner) getContext()).getLifecycle().addObserver(this);
}
@Override
@@ -58,6 +64,12 @@ public void onClick(View view) {
}
}
+ @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
+ public void onDestroy() {
+ backButtonListener = null;
+ queryListener = null;
+ }
+
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
if (queryListener != null) {
@@ -80,23 +92,15 @@ public void setBackButtonListener(@Nullable BackButtonListener backButtonListene
this.backButtonListener = backButtonListener;
}
- public void removeBackButtonListener() {
- backButtonListener = null;
- }
-
public void setQueryListener(@Nullable QueryListener queryListener) {
this.queryListener = queryListener;
}
- public void removeQueryListener() {
- queryListener = null;
- }
-
- public interface QueryListener {
+ interface QueryListener {
void onQueryChange(CharSequence charSequence);
}
- public interface BackButtonListener {
+ interface BackButtonListener {
void onBackButtonPress();
}
}
\ No newline at end of file
diff --git a/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/Utils.java b/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/utils/Utils.java
similarity index 87%
rename from plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/Utils.java
rename to plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/utils/Utils.java
index 9f7801b79..60dffb0a7 100644
--- a/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/Utils.java
+++ b/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/utils/Utils.java
@@ -1,16 +1,18 @@
-package com.mapbox.plugins.places.autocomplete;
+package com.mapbox.plugins.places.autocomplete.utils;
import android.content.Intent;
import com.mapbox.geocoding.v5.MapboxGeocoding;
import com.mapbox.geojson.Point;
+import com.mapbox.plugins.places.autocomplete.PlaceConstants;
public class Utils {
private Utils() {
}
- static MapboxGeocoding.Builder initiateSearchQuery(Intent intent) {
+ // TODO move to viewmodel and delete class
+ public static MapboxGeocoding.Builder initiateSearchQuery(Intent intent) {
MapboxGeocoding.Builder geocoderBuilder = MapboxGeocoding.builder().autocomplete(true);
geocoderBuilder.accessToken(intent.getStringExtra(PlaceConstants.ACCESS_TOKEN));
geocoderBuilder.limit(intent.getIntExtra(PlaceConstants.LIMIT, 5));
diff --git a/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/viewmodel/PlaceAutocompleteViewModel.java b/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/viewmodel/PlaceAutocompleteViewModel.java
new file mode 100644
index 000000000..40d9b3761
--- /dev/null
+++ b/plugin-places/src/main/java/com/mapbox/plugins/places/autocomplete/viewmodel/PlaceAutocompleteViewModel.java
@@ -0,0 +1,117 @@
+package com.mapbox.plugins.places.autocomplete.viewmodel;
+
+import android.app.Application;
+import android.arch.lifecycle.AndroidViewModel;
+import android.arch.lifecycle.MutableLiveData;
+import android.arch.lifecycle.ViewModel;
+import android.arch.lifecycle.ViewModelProvider;
+import android.content.Intent;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
+import com.mapbox.geocoding.v5.MapboxGeocoding;
+import com.mapbox.geocoding.v5.models.CarmenFeature;
+import com.mapbox.geocoding.v5.models.GeocodingResponse;
+import com.mapbox.plugins.places.autocomplete.DataRepository;
+import com.mapbox.plugins.places.autocomplete.PlaceConstants;
+import com.mapbox.plugins.places.autocomplete.data.SearchHistoryDatabase;
+import com.mapbox.plugins.places.autocomplete.data.entity.SearchHistoryEntity;
+import com.mapbox.plugins.places.autocomplete.utils.Utils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import retrofit2.Call;
+import retrofit2.Callback;
+import retrofit2.Response;
+
+public class PlaceAutocompleteViewModel extends AndroidViewModel
+ implements Callback {
+
+ public final MutableLiveData geocodingLiveData = new MutableLiveData<>();
+ private MapboxGeocoding.Builder geocoderBuilder;
+ private final Intent intent;
+
+ PlaceAutocompleteViewModel(@NonNull Application application, @NonNull Intent intent) {
+ super(application);
+ this.intent = intent;
+ }
+
+ public void buildGeocodingRequest() {
+ geocoderBuilder = Utils.initiateSearchQuery(intent);
+ }
+
+ public void onQueryChange(CharSequence sequence) {
+ String query = sequence.toString();
+ if (query.isEmpty()) {
+ return;
+ }
+ geocoderBuilder.query(query).build().enqueueCall(this);
+ }
+
+ public Intent onItemClicked(CarmenFeature carmenFeature) {
+ saveCarmenFeatureToDatabase(carmenFeature);
+
+ String json = carmenFeature.toJson();
+ Intent returningIntent = new Intent();
+ returningIntent.putExtra(PlaceConstants.RETURNING_CARMEN_FEATURE, json);
+ return returningIntent;
+ }
+
+ public List getFavoritePlaces() {
+ List serialized = intent.getStringArrayListExtra(PlaceConstants.INJECTED_PLACES);
+ List favoriteFeatures = new ArrayList<>();
+ if (serialized == null || serialized.isEmpty()) {
+ return favoriteFeatures;
+ }
+ for (String serializedCarmenFeature : serialized) {
+ favoriteFeatures.add(CarmenFeature.fromJson(serializedCarmenFeature));
+ }
+ return favoriteFeatures;
+ }
+
+ @Override
+ public void onResponse(@NonNull Call call,
+ @NonNull Response response) {
+ if (response.isSuccessful()) {
+ geocodingLiveData.setValue(response.body());
+ }
+ }
+
+ @Override
+ public void onFailure(@NonNull Call call,
+ @NonNull Throwable throwable) {
+
+ }
+
+ public SearchHistoryDatabase getDatabase() {
+ return SearchHistoryDatabase.getInstance(this.getApplication().getApplicationContext());
+ }
+
+ private void saveCarmenFeatureToDatabase(CarmenFeature carmenFeature) {
+ // Check that the carmenFeature hasn't already been added
+ if (carmenFeature.properties().has(PlaceConstants.SAVED_PLACE)) {
+ return;
+ }
+ SearchHistoryEntity searchHistory = new SearchHistoryEntity(carmenFeature.id(), carmenFeature);
+ DataRepository.getInstance(getDatabase()).addSearchHistoryEntity(searchHistory);
+ }
+
+ public static class Factory extends ViewModelProvider.NewInstanceFactory {
+
+ private final Application application;
+ private final Intent intent;
+
+ public Factory(@NonNull Application application, @NonNull Intent intent) {
+ this.application = application;
+ this.intent = intent;
+ }
+
+ @Override
+ @NonNull
+ public T create(@Nullable Class modelClass) {
+ //noinspection unchecked
+ return (T) new PlaceAutocompleteViewModel(application, intent);
+ }
+ }
+}
diff --git a/plugin-places/src/main/res/layout/activity_complete_card.xml b/plugin-places/src/main/res/layout/activity_complete_card.xml
index f82f6c6f2..be7a2fb77 100644
--- a/plugin-places/src/main/res/layout/activity_complete_card.xml
+++ b/plugin-places/src/main/res/layout/activity_complete_card.xml
@@ -19,7 +19,7 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
-
-
-
-
diff --git a/plugin-places/src/main/res/layout/activity_complete_full.xml b/plugin-places/src/main/res/layout/activity_complete_full.xml
index 4a74042ed..b7351e48f 100644
--- a/plugin-places/src/main/res/layout/activity_complete_full.xml
+++ b/plugin-places/src/main/res/layout/activity_complete_full.xml
@@ -8,25 +8,21 @@
android:layout_height="match_parent">
-
+ app:layout_constraintTop_toBottomOf="@+id/toolbar">
-
+
+
+ app:layout_constraintTop_toTopOf="@+id/scroll_drop_shadow">
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/plugin-places/src/main/res/layout/item_search_result.xml b/plugin-places/src/main/res/layout/item_search_result.xml
index f01c0d62a..d01e1e0f8 100644
--- a/plugin-places/src/main/res/layout/item_search_result.xml
+++ b/plugin-places/src/main/res/layout/item_search_result.xml
@@ -5,7 +5,9 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="60dp"
- android:background="@color/cardview_light_background">
+ android:background="@color/cardview_light_background"
+ android:clickable="true"
+ android:focusable="true">