Wie können wir ein Kartenmarkierungssymbol mit einer Vektor-Asset- Datei erreichen, wie Google es programmgesteuert so zeigt:
Aktualisieren:
map.addMarker(new MarkerOptions()
.position(latLng)
.icon(BitmapDescriptorFactory.fromResource(R.drawable.your_vector_asset))
.title(title);
Dies funktioniert nicht, wenn es sich um Vektor-Assets handelt. Der Hauptgrund, die Frage zu stellen. Der Fehler mit dem obigen Code:
java.lang.IllegalArgumentException: Bild konnte nicht dekodiert werden. Das bereitgestellte Bild muss eine Bitmap sein.
Antworten:
Ich suchte nach genau der gleichen Anforderung und als ich diese Frage sah, war ich zuerst glücklich, aber genau wie bei @Shuddh war ich mit den gegebenen Antworten nicht zufrieden.
Um meine Geschichte kurz zu machen, verwende ich folgenden Code für diese Anforderung:
private BitmapDescriptor bitmapDescriptorFromVector(Context context, @DrawableRes int vectorDrawableResourceId) { Drawable background = ContextCompat.getDrawable(context, R.drawable.ic_map_pin_filled_blue_48dp); background.setBounds(0, 0, background.getIntrinsicWidth(), background.getIntrinsicHeight()); Drawable vectorDrawable = ContextCompat.getDrawable(context, vectorDrawableResourceId); vectorDrawable.setBounds(40, 20, vectorDrawable.getIntrinsicWidth() + 40, vectorDrawable.getIntrinsicHeight() + 20); Bitmap bitmap = Bitmap.createBitmap(background.getIntrinsicWidth(), background.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); background.draw(canvas); vectorDrawable.draw(canvas); return BitmapDescriptorFactory.fromBitmap(bitmap); }
und ein Anwendungsbeispiel:
.icon(bitmapDescriptorFromVector(this, R.drawable.ic_car_white_24dp));
Hinweis: Möglicherweise möchten Sie für Ihre Vektoren eine andere Begrenzung verwenden. Meine Vektoren hatten eine Größe von 24 dp und ich habe ein 48 dp-PNG-Bild (blauer Teil, der auch ein Vektor sein kann) als Hintergrund verwendet.
UPDATE: Hinzufügen eines Screenshots nach Anforderung.
quelle
val left = (background.intrinsicWidth - vectorDrawable.intrinsicWidth) / 2
val top = (background.intrinsicHeight - vectorDrawable.intrinsicHeight) / 3
vectorDrawable.setBounds(left, top, left + vectorDrawable.intrinsicWidth, top + vectorDrawable.intrinsicHeight)
Sie können diese Methode verwenden:
private BitmapDescriptor bitmapDescriptorFromVector(Context context, int vectorResId) { Drawable vectorDrawable = ContextCompat.getDrawable(context, vectorResId); vectorDrawable.setBounds(0, 0, vectorDrawable.getIntrinsicWidth(), vectorDrawable.getIntrinsicHeight()); Bitmap bitmap = Bitmap.createBitmap(vectorDrawable.getIntrinsicWidth(), vectorDrawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); vectorDrawable.draw(canvas); return BitmapDescriptorFactory.fromBitmap(bitmap); }
Ihr Code sieht also folgendermaßen aus:
map.addMarker(new MarkerOptions() .position(latLng) .icon(bitmapDescriptorFromVector(getActivity(), R.drawable.your_vector_asset)) .title(title);
Edit :
In Kotlin sieht es vielleicht so aus:
private fun bitmapDescriptorFromVector(context: Context, vectorResId: Int): BitmapDescriptor? { return ContextCompat.getDrawable(context, vectorResId)?.run { setBounds(0, 0, intrinsicWidth, intrinsicHeight) val bitmap = Bitmap.createBitmap(intrinsicWidth, intrinsicHeight, Bitmap.Config.ARGB_8888) draw(Canvas(bitmap)) BitmapDescriptorFactory.fromBitmap(bitmap) } }
quelle
Es könnte etwas spät sein, aber dies funktioniert hervorragend mit Google Maps v2:
public static BitmapDescriptor getBitmapFromVector(@NonNull Context context, @DrawableRes int vectorResourceId, @ColorInt int tintColor) { Drawable vectorDrawable = ResourcesCompat.getDrawable( context.getResources(), vectorResourceId, null); if (vectorDrawable == null) { Log.e(TAG, "Requested vector resource was not found"); return BitmapDescriptorFactory.defaultMarker(); } Bitmap bitmap = Bitmap.createBitmap(vectorDrawable.getIntrinsicWidth(), vectorDrawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); vectorDrawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); DrawableCompat.setTint(vectorDrawable, tintColor); vectorDrawable.draw(canvas); return BitmapDescriptorFactory.fromBitmap(bitmap); }
Initialisiert als:
Verwendung:
googleMap.addMarker(MarkerOptions().icon(getMarkerIcon()).position(latLng));
Hinweis:
getMarkerIcon()
Gibt nur die initialisierte Nicht-Null-locationMarkerIcon
Mitgliedsvariable zurück.Bildschirmfoto:
quelle
.anchor(0.5f, 1f);
Hier ist der Code für Kotlin-Liebhaber;)
private fun bitMapFromVector(vectorResID:Int):BitmapDescriptor { val vectorDrawable=ContextCompat.getDrawable(context!!,vectorResID) vectorDrawable!!.setBounds(0,0,vectorDrawable!!.intrinsicWidth,vectorDrawable.intrinsicHeight) val bitmap=Bitmap.createBitmap(vectorDrawable.intrinsicWidth,vectorDrawable.intrinsicHeight,Bitmap.Config.ARGB_8888) val canvas=Canvas(bitmap) vectorDrawable.draw(canvas) return BitmapDescriptorFactory.fromBitmap(bitmap) }
quelle
setBounds
Teil?Vektorressource in Bitmap-Objekt konvertieren und verwenden
BitmapDescriptorFactory.fromBitmap(bitmap)
Bitmap-Konverter:
public static Bitmap getBitmapFromVectorDrawable(Context context, int drawableId) { Drawable drawable = AppCompatResources.getDrawable(context, drawableId) if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { drawable = (DrawableCompat.wrap(drawable)).mutate(); } Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); drawable.draw(canvas); return bitmap; }
quelle
Wenn jemand, der in Kotlin sucht, hier die Methode für Sie ist:
private fun bitmapDescriptorFromVector(context: Context, vectorResId:Int):BitmapDescriptor { var vectorDrawable = ContextCompat.getDrawable(context, vectorResId); vectorDrawable!!.setBounds(0, 0, vectorDrawable.getIntrinsicWidth(), vectorDrawable.getIntrinsicHeight()); var bitmap = Bitmap.createBitmap(vectorDrawable.getIntrinsicWidth(), vectorDrawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); var canvas = Canvas(bitmap); vectorDrawable.draw(canvas); return BitmapDescriptorFactory.fromBitmap(bitmap); }
Die obige Methode konvertiert Ihr Vektorsymbol in Bitmapdescritor
map.addMarker(new MarkerOptions() .position(latLng) .icon(bitmapDescriptorFromVector(getActivity(), R.drawable.your_vector_asset)) .title(title)
und dieser für das Setzen von Markierungen für Ihre Karte, danke für Leo Droidcoder von seiner Antwort, nur ich habe ihn in Kotlin konvertiert
quelle
In Kotlin: Ich habe den folgenden Code verwendet, um das SVG-Bild auf Marker anzuzeigen. Hier habe ich keine Hintergrundfarbe / SVG verwendet.
fun getBitmapDescriptorFromVector(context: Context, @DrawableRes vectorDrawableResourceId: Int): BitmapDescriptor? { val vectorDrawable = ContextCompat.getDrawable(context, vectorDrawableResourceId) val bitmap = Bitmap.createBitmap(vectorDrawable!!.intrinsicWidth, vectorDrawable.intrinsicHeight, Bitmap.Config.ARGB_8888) val canvas = Canvas(bitmap) vectorDrawable.setBounds(0, 0, canvas.width, canvas.height) vectorDrawable.draw(canvas) return BitmapDescriptorFactory.fromBitmap(bitmap) }
Verwenden Sie wie folgt:
googleMap?.addMarker(MarkerOptions().position(LatLng(it.latitude!!, it.longitude!!)) .title(it.airLineDetails))?.setIcon( getBitmapDescriptorFromVector(requireContext(), R.drawable.ic_flight_blue))
Bildschirmfoto:
quelle
Versuche dies
getBitmap
public Bitmap getBitmap(Context context, int drawableId) { Drawable drawable = ContextCompat.getDrawable(context, drawableId); if (drawable instanceof BitmapDrawable) { return BitmapFactory.decodeResource(context.getResources(), drawableId); } else if (drawable instanceof VectorDrawable) { return getBitmap((VectorDrawable) drawable); } else { throw new IllegalArgumentException("unsupported drawable type"); } }
ic_map_marker.xml
<vector android:height="32dp" android:viewportHeight="512.0" android:viewportWidth="512.0" android:width="32dp" xmlns:android="http://schemas.android.com/apk/res/android"> <path android:fillColor="#f32f00" android:pathData="M288,284.8V480l-64,32V284.8c10.3,2.1 21,3.3 32,3.3S277.7,286.9 288,284.8zM384,128c0,70.7 -57.3,128 -128,128c-70.7,0 -128,-57.3 -128,-128S185.3,0 256,0C326.7,0 384,57.3 384,128zM256,64c0,-17.7 -14.3,-32 -32,-32s-32,14.3 -32,32s14.3,32 32,32S256,81.7 256,64z"/> </vector>
quelle
Für einen Kotlin-Benutzer. Bitte überprüfen Sie den folgenden Code. Wie ich es in der Fragment-Klasse getan habe.
class MapPinFragment : Fragment() { private lateinit var googleMap1: GoogleMap override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) } override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { return inflater.inflate(R.layout.fragment_map_pin, container, false) } override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) mapView.onCreate(savedInstanceState) mapView.onResume() } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) mapView.getMapAsync { googleMap -> googleMap1 = googleMap as GoogleMap addCustomMarker() } } private fun addCustomMarker() { Log.d("addCustomMarker", "addCustomMarker()") if (googleMap1 == null) { return } // adding a marker on map with image from drawable googleMap1.addMarker( MarkerOptions() .position(LatLng(23.0225 , 72.5714)) .icon(BitmapDescriptorFactory.fromBitmap(getMarkerBitmapFromView())) ) } override fun onDestroy() { super.onDestroy() if (mapView != null) mapView.onDestroy() } override fun onLowMemory() { super.onLowMemory() mapView.onLowMemory() } private fun getMarkerBitmapFromView(): Bitmap? { val customMarkerView: View? = layoutInflater.inflate(R.layout.view_custom_marker, null) // val markerImageView: ImageView = // customMarkerView.findViewById<View>(R.id.profile_image) as ImageView customMarkerView?.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED ); customMarkerView?.layout(0, 0, customMarkerView.measuredWidth, customMarkerView.measuredHeight); customMarkerView?.buildDrawingCache(); val returnedBitmap = Bitmap.createBitmap( customMarkerView!!.measuredWidth, customMarkerView.measuredHeight, Bitmap.Config.ARGB_8888 ) val canvas = Canvas(returnedBitmap) canvas.drawColor(Color.WHITE, PorterDuff.Mode.SRC_IN) val drawable = customMarkerView.background drawable?.draw(canvas); customMarkerView.draw(canvas); return returnedBitmap; } }
quelle