-
Notifications
You must be signed in to change notification settings - Fork 3
Module Search
Specialized module for simple implementation of Search functionality including SearchToolbar and SearchResultList component. Every feature is customizable by end developer (can be turned on/off or styled).
Before you start, please use README to learn how to integrate this module into your project.
The most basic example. It shows the Search module with zero lines of configuration.
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="@+id/searchFragment"
class="com.sygic.maps.module.search.SearchFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
or runtime:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
...
val searchFragment = SearchFragment()
searchFragment.maxResultsCount = 8
searchFragment.searchLocation = GeoCoordinates(48.145900, 17.126851)
supportFragmentManager.beginTransaction().replace(R.id.container, searchFragment).commit()
}
It shows the Search module integrated into the Browse Map module. Note: setting up the SearchModuleConnectionProvider will automatically display the SearchFab button into the Browse Map fragment.
Xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragmentContainer"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Activity
class SearchFromBrowseMapActivity : CommonSampleActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_search_from_browse_map)
val viewModel = ViewModelProviders.of(this).get(SearchFromBrowseMapActivityViewModel::class.java).apply {
showToastObservable.observe(this@SearchFromBrowseMapActivity, Observer { longToast(it) })
}
if (savedInstanceState == null) {
setFragmentModuleConnection(
placeBrowseMapFragment().apply {
cameraDataModel.zoomLevel = 11F
cameraDataModel.position = GeoCoordinates(48.145764, 17.126015)
}, viewModel
)
} else {
setFragmentModuleConnection(
supportFragmentManager.findFragmentByTag(BROWSE_MAP_FRAGMENT_TAG) as BrowseMapFragment, viewModel
)
}
}
// Note: You can also create this Fragment just like in other examples directly in an XML layout file, but
// performance or other issues may occur (https://stackoverflow.com/a/14810676/3796931).
private fun placeBrowseMapFragment() =
BrowseMapFragment().also {
supportFragmentManager
?.beginTransaction()
?.replace(R.id.fragmentContainer, it, BROWSE_MAP_FRAGMENT_TAG)
?.commit()
}
private fun setFragmentModuleConnection(
fragment: BrowseMapFragment,
moduleConnectionProvider: ModuleConnectionProvider
) = fragment.setSearchConnectionProvider(moduleConnectionProvider)
}
ViewModel
class SearchFromBrowseMapActivityViewModel : ViewModel(), ModuleConnectionProvider {
val showToastObservable: LiveData<String> = SingleLiveEvent()
override val fragment: Fragment
get() {
val searchFragment = SearchFragment()
searchFragment.setResultCallback { showToastObservable.asSingleEvent().value = it.joinToString() }
return searchFragment
}
}
It shows the Search module integrated into the Browse Map module with pins added after a search result is confirmed. Note: setting up the SearchModuleConnectionProvider will automatically display the SearchFab button into the Browse Map fragment.
Xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragmentContainer"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Activity
class SearchFromBrowseMapWithPinsActivity : CommonSampleActivity() {
private lateinit var viewModel: SearchFromBrowseMapWitchPinsActivityViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_search_from_browse_map_pins)
viewModel = ViewModelProviders.of(this)
.get(SearchFromBrowseMapWitchPinsActivityViewModel::class.java)
val browseMapFragment = if (savedInstanceState == null) {
placeBrowseMapFragment().apply { cameraDataModel.zoomLevel = 2F }
} else {
supportFragmentManager.findFragmentByTag(BROWSE_MAP_FRAGMENT_TAG) as BrowseMapFragment
}
setFragmentModuleConnection(browseMapFragment, viewModel)
}
// Note: You can also create this Fragment just like in other examples directly in an XML layout file, but
// performance or other issues may occur (https://stackoverflow.com/a/14810676/3796931).
private fun placeBrowseMapFragment() =
BrowseMapFragment().also {
supportFragmentManager
?.beginTransaction()
?.replace(R.id.fragmentContainer, it, BROWSE_MAP_FRAGMENT_TAG)
?.runOnCommit {
viewModel.mapDataModel = it.mapDataModel
viewModel.cameraDataModel = it.cameraDataModel
}
?.commit()
}
private fun setFragmentModuleConnection(
fragment: BrowseMapFragment,
moduleConnectionProvider: ModuleConnectionProvider
) = fragment.setSearchConnectionProvider(moduleConnectionProvider)
}
ViewModel
private const val CAMERA_RECTANGLE_MARGIN = 80
class SearchFromBrowseMapWitchPinsActivityViewModel : ViewModel(), ModuleConnectionProvider {
var mapDataModel: SimpleMapDataModel? = null
var cameraDataModel: SimpleCameraDataModel? = null
private val callback: ((results: List<GeocodingResult>) -> Unit) = { results ->
mapDataModel?.removeAllMapMarkers()
if (results.isNotEmpty()) {
results.toGeoCoordinatesList().let { geoCoordinatesList ->
if (geoCoordinatesList.isNotEmpty()) {
if (geoCoordinatesList.size == 1) {
mapDataModel?.addMapMarker(geoCoordinatesList.first())
cameraDataModel?.position = geoCoordinatesList.first()
cameraDataModel?.zoomLevel = 10F
} else {
val geoBoundingBox = GeoBoundingBox(geoCoordinatesList.first(), geoCoordinatesList.first())
geoCoordinatesList.forEach { geoCoordinates ->
mapDataModel?.addMapMarker(geoCoordinates)
geoBoundingBox.union(geoCoordinates)
}
cameraDataModel?.setMapRectangle(geoBoundingBox, CAMERA_RECTANGLE_MARGIN)
}
}
}
}
}
override val fragment: Fragment
get() {
val searchFragment = SearchFragment()
searchFragment.searchLocation = cameraDataModel?.position ?: GeoCoordinates.Invalid
searchFragment.setResultCallback(callback)
return searchFragment
}
}
The same as the default example, but with a pre-filled search input field.
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="@+id/searchFragment"
class="com.sygic.maps.module.search.SearchFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:sygic_initial_search_input="London Eye" />
</FrameLayout>
or runtime:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
...
val searchFragment = SearchFragment()
searchFragment.searchInput = "London Eye"
supportFragmentManager.beginTransaction().replace(R.id.container, searchFragment).commit()
}