Android 百度地图marker中图片不显示的解决方法(推荐)

目的:

根据提供的多个经纬度,显示所在地的marker样式,如下:

问题:

1.发现marker中在线加载的图片无法显示出来;

2.获取多个对象后,却只显示出了一个marker;

以下为官网实现方法:

通过查阅百度官网的文档,我们可以知道,地图标注物的实现方法如下:

//定义Maker坐标点
LatLng point = new LatLng(39.963175, 116.400244);
//构建Marker图标
BitmapDescriptor bitmap = BitmapDescriptorFactory
  .fromResource(R.drawable.icon_marka);
//构建MarkerOption,用于在地图上添加Marker
OverlayOptions option = new MarkerOptions()
  .position(point)
  .icon(bitmap);
//在地图上添加Marker,并显示
mBaiduMap.addOverlay(option);

那么想通过更改marker的样式,也就是option中的.icon(BitmapDescriptor)方法,只需要提供BitmapDescriptor对象即可,获取BitmapDescriptor的方式有如下几种:

(查询地址:http://wiki.lbsyun.baidu.com/cms/androidsdk/doc/v4_3_0/index.html

因为是marker不是简单的图片展示,所以这里是需要自定义view给加载进来的,因此使用的是fromView()来加载自定义视图,视图内容如下:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="30dp"
  android:id="@+id/bitmapFl"
  android:layout_height="44dp">
  <ImageView
    android:layout_width="30dp"
    android:layout_height="44dp"
    android:layout_gravity="center"
    android:src="@mipmap/anchor"/>
  <ImageView
    android:id="@+id/picSdv"
    android:layout_marginTop="1dp"
    android:layout_width="28dp"
    android:layout_height="28dp"
    android:layout_gravity="center_horizontal"
    />
</FrameLayout>

但是如果此时使用fromView来加载视图生成BitmapDescriptor就会导致:在图片未在线加载完毕时,整个view就已经生成了BitmapDescriptor,这个时候就出现了marker无法显示图片的问题(这就好比经典招数“猴子偷桃”,桃都还没有,怎么偷得出来呢)。所以解决的办法是——>等到图片加载完毕后再去生成BitmapDescriptor,从而设置MarkerOptions。

下面为我的解决方案:

以下是在fragment中加载以上的视图文件:(具体业务情况看个人的页面设计,所以使用的时候也不一定非得在这个方法里面初始化)

@Nullable
 @Override
 public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
   this.inflater = inflater;
   this.container = container;
   if (markerView == null) {
     viewHolder = new ViewHolder();
     markerView = (FrameLayout) inflater.inflate(R.layout.layout_bitmap_descriptor, container, true).findViewById(R.id.bitmapFl);//此处一定要find到bitmapFl,否则此处会报错加载的对象不是要求的布局对象
     viewHolder.imageView = (ImageView) markerView.findViewById(R.id.picSdv);
     markerView.setTag(viewHolder);
   }
   return inflater.inflate(R.layout.fragment_main, container, false);
 } 

ivate class ViewHolder {
   ImageView imageView;
 } 

因为涉及到多个marker的加载,意味着要对布局进行多次加载,所以此处使用ViewHolder来处理重复的操作。

然后进行初始化各个marker:

  /**
   * 初始化位置标注信息
   *
   * @param geoUserEntities:地理用户数据(包含头像地址、经纬度)
   */
  private void initOverlayOptions(List<GeoUserEntity> geoUserEntities) {
    baiduMap.clear();
    AvatarEntity avatarEntityTemp;
    for (int i = 0; i < geoUserEntities.size(); i++) {
      if (geoUserEntities.get(i) == null) {
        continue;
      }
      final Marker[] marker = {null};
      final GeoUserEntity geoUserEntityTemp = geoUserEntities.get(i);
      avatarEntityTemp = geoUserEntityTemp.getAvatar();
      final BitmapDescriptor[] pic = {null};
      if (avatarEntityTemp != null && !StringUtils.isEmpty(avatarEntityTemp.getImageUrl())) {
        returnPicView(avatarEntityTemp.getMid(), new ResultListener() {//图片加载完毕后的回调方法
          @Override
          public void onReturnResult(Object object) {
            super.onReturnResult(object);
            pic[0] = BitmapDescriptorFactory.fromView((View) object);
            putDataToMarkerOptions(pic[0], geoUserEntityTemp);
          }
        });
      } else if (avatarEntityTemp == null) {
        pic[0] = BitmapDescriptorFactory.fromResource(R.mipmap.anchor);
        putDataToMarkerOptions(pic[0], geoUserEntityTemp);
      }
    }
  }

  /**
   * 显示marker,设置marker传递的数据
   *
   * @param pic
   * @param geoUserEntityTemp
   */
  private void putDataToMarkerOptions(BitmapDescriptor pic, GeoUserEntity geoUserEntityTemp) {
    double[] locationTemp = geoUserEntityTemp.getLocation();
    if (locationTemp != null && locationTemp.length == 2) {
      LatLng point = new LatLng(locationTemp[1], locationTemp[0]);
      MarkerOptions overlayOptions = new MarkerOptions()
          .position(point)
          .icon(pic)
          .animateType(MarkerOptions.MarkerAnimateType.grow);//设置marker从地上生长出来的动画
      Marker marker = (Marker) baiduMap.addOverlay(overlayOptions);
      Bundle bundle = new Bundle();
      bundle.putSerializable(ConstantValues.User.GEO_USER_ENTITY, geoUserEntityTemp);
      marker.setExtraInfo(bundle);//marker点击事件监听时,可以获取到此时设置的数据
      marker.setToTop();
    }
  }

  private void returnPicView(String urlTemp, final ResultListener resultListener) {
    viewHolder = (ViewHolder) markerView.getTag();
    Glide.with(getContext())
        .load(urlTemp)
        .asBitmap()
        .transform(new GlideCircleTransform(getContext()))
        .into(new SimpleTarget<Bitmap>() {
             @Override
             public void onResourceReady(Bitmap bitmap, GlideAnimation glideAnimation) {
               viewHolder.imageView.setImageBitmap(bitmap);
               resultListener.onReturnResult(markerView);
             }
           }
        );
  }

通过returnPicView方法来进行异步图片加载,然后用自定义的ResultListener接口来回调图片加载完毕的结果,从而初始化BitmapDescriptor,进而设置MarkerOptions。

要点:

GlideCircleTransform是自定义的类,用来设置图片为圆形(之后有实现方法);

onResourceReady是Glide框架中监听图片加载完毕的回调方法,以上的实现能监听多张图片加载完毕的事件;

resultListener.onReturnResult(markerView);中的markerView是一开始自定义的marker中要加载的整个布局;

为啥不用SimpleDraweeView来实现圆形图片并进行图片下载的监听?

仅个人的使用情况:使用Glide框架无法控制SimpleDraweeView的形状;而且,SimpleDraweeView无法监听动态加载同一个view时的多张图片下载的情况,意味着只能监听到最后最后一张图片。(也就是,类似于上面的onReturnResult方法只会回调一次,这也就是本文开头提到过的问题②:获取多个对象后,却只显示出了一个marker的情况)

然后,附上GlideCircleTransform的类代码(从其它处拷贝过来的):

public class GlideCircleTransform extends BitmapTransformation {
  public Context context;
  public GlideCircleTransform(Context context) {
    super(context);
    this.context = context;
  }
  @Override
  protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
    return circleCrop(pool, toTransform);
  }
  private static Bitmap circleCrop(BitmapPool pool, Bitmap source) {
    if (source == null) return null;
    int size = Math.min(source.getWidth(), source.getHeight());
    int x = (source.getWidth() - size) / 2;
    int y = (source.getHeight() - size) / 2;
    // TODO this could be acquired from the pool too
    Bitmap squared = Bitmap.createBitmap(source, x, y, size, size);
    Bitmap result = pool.get(size, size, Bitmap.Config.ARGB_8888);
    if (result == null) {
      result = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
    }
    Canvas canvas = new Canvas(result);
    Paint paint = new Paint();
    paint.setShader(new BitmapShader(squared, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
    paint.setAntiAlias(true);
    float r = size / 2f;
    canvas.drawCircle(r, r, r, paint);
    return result;
  }
  @Override
  public String getId() {
    return getClass().getName();
  }
}

在对未知进行探索时,一点是兴奋的,两点是开心的,三点是积极的,太多太多的点则是痛苦的,而解决了迷惑之后内心是舒坦的!

以上这篇Android 百度地图marker中图片不显示的解决方法(推荐)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

您可能感兴趣的文章:

  • JS中引用百度地图并将百度地图的logo和信息去掉
  • 百度地图去掉marker覆盖物或者去掉maker的label文字方法
(0)

相关推荐

  • JS中引用百度地图并将百度地图的logo和信息去掉

    采用CSS覆盖的方法就可以了,但是官方是不允许这么做的,参考:http://developer.baidu.com/map/question.htm 复制代码 代码如下: <!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title>javascript移除百度地图LOGO和版权信息</title> <script type="text/j

  • 百度地图去掉marker覆盖物或者去掉maker的label文字方法

    如下所示: var marker = new BMap.Marker(...); //方法1 map.removeOverlay(marker); //方法2 marker.remove(); //如果是Marker设置的setLabel还可以设置其样式来隐藏 mapComponent.state.bikeMarkLabel.setStyle({ display:"none" }); 41787 label与marker的方法相同. 建议使用方法1和方法2,方法3只是隐藏而不是清除 以

  • Android 百度地图marker中图片不显示的解决方法(推荐)

    目的: 根据提供的多个经纬度,显示所在地的marker样式,如下: 问题: 1.发现marker中在线加载的图片无法显示出来: 2.获取多个对象后,却只显示出了一个marker: 以下为官网实现方法: 通过查阅百度官网的文档,我们可以知道,地图标注物的实现方法如下: //定义Maker坐标点 LatLng point = new LatLng(39.963175, 116.400244); //构建Marker图标 BitmapDescriptor bitmap = BitmapDescript

  • thinkphp,onethink和thinkox中验证码不显示的解决方法分析

    本文实例讲述了thinkphp,onethink和thinkox中验证码不显示的解决方法.分享给大家供大家参考,具体如下: 使用验证码的时候,一开始正常,后来不显示了 网上说是utf-8的编码问题,什么bom去掉,转化为无bom的格式 我都试了,没用 后来知道是在调用验证码的地方  写上 Public function verify(){ import('ORG.Util.Image'); Image::buildImageVerify(); } 改成这样就行了: Public function

  • javascript动态改变img的src属性图片不显示的解决方法

    首先讲下这个bug的出现的情况,页面中有 复制代码 代码如下: <a href="javascript:void(0)" onclick="document.getElementById('current').src='images/001.jpg';"> 这么一个a标签,onclick中的JS代码就是改变id为current的img标签的src属性,以达到动态切换图片的效果.可是不幸的是:IE是动态改变的图片的路径,但是图片却不显示出来,得右键&quo

  • Android 在其他线程中更新UI线程的解决方法

    方法一:Activity.runOnUiThread(Runnable )(经验之道: 这个最好用, 凡是要刷新页面的地方,Activity.runOnUiThread( new Runnable()  { public void run(){更新UI}}); 方法二:子线程调用Handler的sendMessage(message)发送事件. 复制代码 代码如下: mHandler = new Handler() {     @Override     public void handleMe

  • Android百度地图添加Marker失真问题的解决方案

    Marker失真问题 由于公司项目原因,用了很多次百度地图API,基础的地图定位.显示地图就不多说了,这里主要说一下百度地图添加Marker图标. 最开始接触百度地图添加Marker图标的时候,发现自己设置的图标是多大地图上就显示多大,感觉有点失真,看起来很不舒服,但通过网上搜索,并没有找到解决办法,就没怎么注意图标失真的问题,毕竟是一个小项目,不是面向大众的,最近开发的一个项目同样有这个需求,而且是面向大众开发的,我就想为什么摩拜单车的图标那么清晰,我的图标却失真. 就是这么清晰 通过Reso

  • Android百度地图应用之创建显示地图

    本文是在完成了Android百度地图应用开发基础知识的基础上继续实现的. 本文实例为大家分享了Android如何显示地图,并为后续内容做准备,供大家参考,具体内容如下  1.运行效果  本章共有25个示例,在x86模拟器中运行的效果如下: 下面介绍主要设计步骤.  2.添加资源  (1)drawable-hdpi  Resources/ drawable-hdpi下的文件:将下载的示例对应文件夹下的文件全部拖放到该文件夹下,并将所有[生成操作]属性全部设置为"AndroidResource&qu

  • Android百度地图定位、显示用户当前位置

    本文实例为大家分享了Android百度地图定位.显示用户当前位置的工具类,供大家参考,具体内容如下 1.构建定位Option的工具类 import com.baidu.location.LocationClientOption; /** * 建造 LocationClientOption 项 * * @author peter 2018-12-21 10:58 */ public class LocationClientOptionBuilder { private LocationClient

  • Android百度地图自定义公交路线导航

    一.问题描述 基于百度地图实现检索指定城市指定公交的交通路线图,效果如图所示 二.通用组件Application类,主要创建并初始化BMapManager public class App extends Application { static App mDemoApp; //百度MapAPI的管理类 public BMapManager mBMapMan = null; // 授权Key // 申请地址:http://dev.baidu.com/wiki/static/imap/key/ p

  • Android 百度地图POI搜索功能实例代码

    在没介绍正文之前先给大家说下poi是什么意思. 由于工作的关系,经常在文件中会看到POI这三个字母的缩写,但是一直对POI的概念和含义没有很详细的去研究其背后代表的意思.今天下班之前,又看到了POI这三个字母,决定认认真真的搜索一些POI具体的含义. POI是英文的缩写,原来的单词是point of interest, 直译成中文就是兴趣点的意思.兴趣点这个词最早来自于导航地图厂商.地图厂商为了提供尽可能多的位置信息,花费了很大的精力去寻找诸如加油站,餐馆,酒店,景点等目的地,这些目的地其实都可

  • Android百度地图定位后获取周边位置的实现代码

    本文实例讲解Android百度地图定位后获取周边位置的实现代码,分享给大家供大家参考,具体内容如下 效果图: 具体代码: 1.布局文件 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical&q

随机推荐