Create MerchantMarkerRederer to create custom merchant and custom merchant cluster icons to show on the map. Use the same merchant cluster icon as in palmpay.io but with white text.

This commit is contained in:
Severiano Jaramillo 2019-01-23 12:17:46 -06:00
parent 6abcf6ed13
commit a913f380bb
4 changed files with 88 additions and 17 deletions

View file

@ -21,15 +21,13 @@ import retrofit2.Call
import retrofit2.Response import retrofit2.Response
import retrofit2.Retrofit import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory import retrofit2.converter.gson.GsonConverterFactory
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.drawable.Drawable
import android.preference.PreferenceManager import android.preference.PreferenceManager
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import com.google.android.gms.maps.model.* import com.google.android.gms.maps.model.*
import com.google.maps.android.clustering.ClusterManager import com.google.maps.android.clustering.ClusterManager
import cy.agorise.bitsybitshareswallet.database.entities.Merchant import cy.agorise.bitsybitshareswallet.database.entities.Merchant
import cy.agorise.bitsybitshareswallet.utils.Constants import cy.agorise.bitsybitshareswallet.utils.Constants
import cy.agorise.bitsybitshareswallet.utils.MerchantMarkerRenderer
import cy.agorise.bitsybitshareswallet.utils.toast import cy.agorise.bitsybitshareswallet.utils.toast
@ -46,8 +44,6 @@ class MerchantsFragment : Fragment(), OnMapReadyCallback, retrofit2.Callback<Fea
private var mClusterManager: ClusterManager<Merchant>? = null private var mClusterManager: ClusterManager<Merchant>? = null
private lateinit var merchantIcon: BitmapDescriptor
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
@ -61,8 +57,6 @@ class MerchantsFragment : Fragment(), OnMapReadyCallback, retrofit2.Callback<Fea
// Obtain the SupportMapFragment and get notified when the map is ready to be used. // Obtain the SupportMapFragment and get notified when the map is ready to be used.
val mapFragment = childFragmentManager.findFragmentById(R.id.map) as SupportMapFragment val mapFragment = childFragmentManager.findFragmentById(R.id.map) as SupportMapFragment
mapFragment.getMapAsync(this) mapFragment.getMapAsync(this)
merchantIcon = getMarkerIconFromDrawable(resources.getDrawable(R.drawable.ic_pin_merchants, null))
} }
private fun verifyLocationPermission() { private fun verifyLocationPermission() {
@ -109,6 +103,8 @@ class MerchantsFragment : Fragment(), OnMapReadyCallback, retrofit2.Callback<Fea
// Setup clusters to group markers when possible // Setup clusters to group markers when possible
mClusterManager = ClusterManager(context, mMap) mClusterManager = ClusterManager(context, mMap)
val renderer = MerchantMarkerRenderer(context, mMap, mClusterManager)
mClusterManager?.renderer = renderer
// Point the map's listeners at the listeners implemented by the cluster manager. // Point the map's listeners at the listeners implemented by the cluster manager.
mMap.setOnCameraIdleListener(mClusterManager) mMap.setOnCameraIdleListener(mClusterManager)
@ -151,19 +147,11 @@ class MerchantsFragment : Fragment(), OnMapReadyCallback, retrofit2.Callback<Fea
val res: FeathersResponse<Merchant>? = response.body() val res: FeathersResponse<Merchant>? = response.body()
val merchants = res?.data ?: return val merchants = res?.data ?: return
mClusterManager?.addItems(merchants) mClusterManager?.addItems(merchants)
mClusterManager?.cluster()
} else { } else {
Log.e("error_bitsy", response.errorBody()?.string()) Log.e("error_bitsy", response.errorBody()?.string())
} }
} }
override fun onFailure(call: Call<FeathersResponse<Merchant>>, t: Throwable) { /* Do nothing */ } override fun onFailure(call: Call<FeathersResponse<Merchant>>, t: Throwable) { /* Do nothing */ }
private fun getMarkerIconFromDrawable(drawable: Drawable): BitmapDescriptor {
val canvas = Canvas()
val bitmap = Bitmap.createBitmap(drawable.intrinsicWidth, drawable.intrinsicHeight, Bitmap.Config.ARGB_8888)
canvas.setBitmap(bitmap)
drawable.setBounds(0, 0, drawable.intrinsicWidth, drawable.intrinsicHeight)
drawable.draw(canvas)
return BitmapDescriptorFactory.fromBitmap(bitmap)
}
} }

View file

@ -0,0 +1,83 @@
package cy.agorise.bitsybitshareswallet.utils
import android.content.Context
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.drawable.Drawable
import android.util.SparseArray
import android.view.ViewGroup
import com.google.android.gms.maps.GoogleMap
import com.google.android.gms.maps.model.BitmapDescriptor
import com.google.android.gms.maps.model.BitmapDescriptorFactory
import com.google.android.gms.maps.model.MarkerOptions
import com.google.maps.android.clustering.Cluster
import com.google.maps.android.clustering.ClusterManager
import com.google.maps.android.clustering.view.DefaultClusterRenderer
import com.google.maps.android.ui.IconGenerator
import com.google.maps.android.ui.SquareTextView
import cy.agorise.bitsybitshareswallet.R
import cy.agorise.bitsybitshareswallet.database.entities.Merchant
/**
* This class is used to create custom merchant and merchant cluster icons to show on the map.
*/
class MerchantMarkerRenderer(val context: Context?, map: GoogleMap?, clusterManager: ClusterManager<Merchant>?) :
DefaultClusterRenderer<Merchant>(context, map, clusterManager) {
// Icons used to display merchants and merchants' clusters on the map
private var merchantIcon: BitmapDescriptor
private val mIcons = SparseArray<BitmapDescriptor>()
private val mDensity: Float
private val mIconGenerator = IconGenerator(context)
init {
merchantIcon = getMarkerIconFromDrawable(
context?.resources?.getDrawable(R.drawable.ic_merchant_pin, null))
mDensity = context?.resources?.displayMetrics?.density ?: 2.0F
this.mIconGenerator.setContentView(this.makeSquareTextView(context))
this.mIconGenerator.setTextAppearance(com.google.maps.android.R.style.amu_ClusterIcon_TextAppearance)
this.mIconGenerator.setBackground(context?.resources?.getDrawable(R.drawable.ic_merchant_cluster, null))
}
override fun onBeforeClusterItemRendered(item: Merchant?, markerOptions: MarkerOptions?) {
markerOptions?.icon(merchantIcon)
}
override fun onBeforeClusterRendered(cluster: Cluster<Merchant>?, markerOptions: MarkerOptions?) {
val bucket = getBucket(cluster)
var descriptor: BitmapDescriptor? = mIcons.get(bucket)
if (descriptor == null) {
descriptor = BitmapDescriptorFactory.fromBitmap(mIconGenerator.makeIcon(getClusterText(bucket)))
mIcons.put(bucket, descriptor)
}
markerOptions?.icon(descriptor)
}
override fun shouldRenderAsCluster(cluster: Cluster<Merchant>?): Boolean {
return (cluster?.size ?: 0) > 1
}
private fun makeSquareTextView(context: Context?): SquareTextView {
val squareTextView = SquareTextView(context)
val layoutParams = ViewGroup.LayoutParams(-2, -2)
squareTextView.layoutParams = layoutParams
squareTextView.id = com.google.maps.android.R.id.amu_text
val padding = (24.0f * this.mDensity).toInt()
squareTextView.setPadding(padding, padding, padding, padding)
return squareTextView
}
private fun getMarkerIconFromDrawable(drawable: Drawable?): BitmapDescriptor {
val canvas = Canvas()
val bitmap = Bitmap.createBitmap(drawable?.intrinsicWidth ?: 24,
drawable?.intrinsicHeight ?: 24, Bitmap.Config.ARGB_8888)
canvas.setBitmap(bitmap)
drawable?.setBounds(0, 0, drawable.intrinsicWidth, drawable.intrinsicHeight)
drawable?.draw(canvas)
return BitmapDescriptorFactory.fromBitmap(bitmap)
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

View file

@ -1,7 +1,7 @@
<vector android:height="51dp" <vector android:height="51dp"
android:viewportHeight="225.302" android:viewportHeight="225.302"
android:viewportWidth="154.618" android:viewportWidth="154.618"
android:width="31dp" android:width="35dp"
xmlns:android="http://schemas.android.com/apk/res/android"> xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#0E9257" android:pathData="M151.705 76.396C151.705 35.31 118.397 2 77.31 2 36.219 2 2.913 35.31 2.913 76.396c0 20.073 7.961 38.277 20.889 51.66l-0.09 0.969s43.451 42.428 51.781 93.092h4.121c8.332-50.664 51.537-93.092 51.537-93.092l-0.352-0.457c12.936-13.388 20.906-32.087 20.906-52.172z" android:strokeColor="#FFFFFF" android:strokeWidth="5"/> <path android:fillColor="#0E9257" android:pathData="M151.705 76.396C151.705 35.31 118.397 2 77.31 2 36.219 2 2.913 35.31 2.913 76.396c0 20.073 7.961 38.277 20.889 51.66l-0.09 0.969s43.451 42.428 51.781 93.092h4.121c8.332-50.664 51.537-93.092 51.537-93.092l-0.352-0.457c12.936-13.388 20.906-32.087 20.906-52.172z" android:strokeColor="#FFFFFF" android:strokeWidth="5"/>
<path android:fillColor="#FFFFFF" android:pathData="M14.478 77.906c0-34.705 28.131-62.835 62.832-62.835 34.706 0 62.836 28.13 62.836 62.835 0 34.7-28.13 62.837-62.836 62.837-34.702 0-62.832-28.137-62.832-62.837z" android:strokeColor="#A5D5A7" android:strokeWidth="2.5162"/> <path android:fillColor="#FFFFFF" android:pathData="M14.478 77.906c0-34.705 28.131-62.835 62.832-62.835 34.706 0 62.836 28.13 62.836 62.835 0 34.7-28.13 62.837-62.836 62.837-34.702 0-62.832-28.137-62.832-62.837z" android:strokeColor="#A5D5A7" android:strokeWidth="2.5162"/>