百度地图4.1_1开发教程(3)Marker

来源:互联网 发布:stm32f1数据手册 编辑:程序博客网 时间:2024/05/15 01:32
本章将讲述如何利用Marker在地图生成点,并实现点击Marker弹出该点对应的信息。1.点击点获取坐标2.在我的项目里,会将地图上的一些飞机作为Marker,点击并弹出该飞机对应的详情3.点击地图其他区域,将清除所有飞机类的marker4.地图的触摸,单击等监听最终效果图如下:(实际项目中,请注意美观)

最终效果图

获取坐标

首先,在布局加上显示坐标的控件,这里用一个textView来显示
<TextView        android:id="@+id/activity_main_tv_detail"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:background="@android:color/darker_gray"        android:hint="点击显示当前地理详情"/>
接下来在类里调用API:
//地图触摸事件        mBaiduMap.setOnMapTouchListener(new BaiduMap.OnMapTouchListener()        {            @Override            public void onTouch(MotionEvent motionEvent)            {            }        });        // 地图单击事件        mBaiduMap.setOnMapClickListener(new BaiduMap.OnMapClickListener()        {            @Override            public void onMapClick(LatLng latLng)            {                currentPt = latLng;                updateMapState();            }            @Override            public boolean onMapPoiClick(MapPoi mapPoi)            {                if (tv_detail.getText() == null || "".equals(tv_detail.getText()))                {                }                currentPt = mapPoi.getPosition();                updateMapState();                return false;            }        });
    /**     * 更新地图状态显示面板     */    private void updateMapState()    {        if (tv_detail == null)        {            return;        }        String state = "";        if (currentPt == null)        {            state = "点击、长按、双击地图以获取经纬度和地图状态";        } else        {            state = String.format("当前经度: %f 当前纬度:%f",                    currentPt.longitude, currentPt.latitude);        }        state += "\n";        MapStatus ms = mBaiduMap.getMapStatus();        state += String.format(                "zoom=%.1f rotate=%d overlook=%d",                ms.zoom, (int) ms.rotate, (int) ms.overlook);        tv_detail.setText(state);    }
至此,获取地图的坐标就完成了。


## 显示Marker、地图触摸事件、移除Marker等 ##
接下来,我们实现一个稍微复杂的功能,如图上底部所示,点击SwitchCompat,动态在地图上显示一堆点(marker),点击marker,展现该点的详细信息
在布局加入:

    <LinearLayout        android:id="@+id/activity_main_ll_bottomlayout"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_alignParentBottom="true"        android:orientation="horizontal"        android:showDividers="middle">        <android.support.v7.widget.SwitchCompat            android:id="@+id/activity_main_sc_marker"            android:layout_width="0dp"            android:layout_height="wrap_content"            android:layout_weight="1"            android:background="@color/colorPrimary"            android:padding="10dp"            android:text="一堆点"            android:textColor="@android:color/white"            android:textOff="-.-"            android:textOn="^.^"            toggle:showText="true"/>    </LinearLayout>    <!-- 飞机信息 -->    <LinearLayout        android:id="@+id/activity_main_flightinfo_ll_info"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_alignParentBottom="true"        android:animateLayoutChanges="true"        android:background="@android:color/white"        android:clickable="true"        android:focusable="true"        android:focusableInTouchMode="true"        android:orientation="vertical"        android:padding="10dp"        android:visibility="gone">        <LinearLayout            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:orientation="horizontal"            android:padding="10dp">            <TextView                android:id="@+id/activity_main_flightinfo_tv_num"                android:layout_width="0dp"                android:layout_height="wrap_content"                android:layout_weight="1"                android:text="飞机编号:"                android:textSize="18sp"/>            <TextView                android:id="@+id/activity_main_flightinfo_tv_model"                android:layout_width="0dp"                android:layout_height="wrap_content"                android:layout_weight="1"                android:text="飞机型号"                android:textSize="18sp"/>        </LinearLayout>        <LinearLayout            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:orientation="horizontal"            android:padding="10dp">            <TextView                android:id="@+id/activity_main_flightinfo_tv_startPlace"                android:layout_width="0dp"                android:layout_height="wrap_content"                android:layout_weight="1"                android:text="出发地:"                android:textSize="18sp"/>            <TextView                android:id="@+id/activity_main_flightinfo_tv_endPlace"                android:layout_width="0dp"                android:layout_height="wrap_content"                android:layout_weight="1"                android:text="抵达地:"                android:textSize="18sp"/>        </LinearLayout>        <LinearLayout            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:orientation="horizontal"            android:padding="10dp">            <TextView                android:id="@+id/pop_window_flight_info_tv_startTime"                android:layout_width="0dp"                android:layout_height="wrap_content"                android:layout_weight="1"                android:text="出发时间:"                android:textSize="18sp"/>            <TextView                android:id="@+id/pop_window_flight_info_tv_endTime"                android:layout_width="0dp"                android:layout_height="wrap_content"                android:layout_weight="1"                android:text="抵达时间:"                android:textSize="18sp"/>        </LinearLayout>    </LinearLayout>
飞机详情信息此时是隐藏的,只有在单机到marker的时候才显示出来。接下来,显示飞机信息一定要有实体类。新建MarkerInfo:注:省略Getter and Setter方法,请自行生成,或拷贝文章末尾的Demo
    // 飞机编号    private String num;    // 飞机型号    private String model;    // 出发地    private String startPlace;    // 抵达地    private String endPlace;    // 出发时间    private String startTime;    // 抵达时间    private String endTime;    // 纬度    private double latitude;    // 经度    private double longitude;    public static List<MarkerInfo> mMarkerInfos= new ArrayList<>();; // 飞机信息列表    public MarkerInfo()    {    }    public MarkerInfo(  String num, String model, String startPlace, String endPlace,                      String startTime, String endTime , double latitude, double longitude)    {        super();        this.num = num;        this.model = model;        this.startPlace = startPlace;        this.endPlace = endPlace;        this.startTime = startTime;        this.endTime = endTime;        this.latitude = latitude;        this.longitude = longitude;    }    static // 模拟数据,在地图上添加3个marker,所对应的数据    {        mMarkerInfos.add(new MarkerInfo(  "bh101", "model1", "北京", "天津", "10:00", "11:00",                39.963175, 116.400244 ));        mMarkerInfos.add(new MarkerInfo(  "bh102", "model2", "北京", "石家庄", "10:00", "11:30",                39.963175, 116.400244 ));        mMarkerInfos.add(new MarkerInfo(  "bh103", "model3", "北京", "呼和浩特", "10:00", "12:00",                39.963175, 116.400244 ));    }    public String getNum()    {        return num;    }
下面准备工作结束在类里申明控件和findViewById,此处省略若干行代码接下来申明
    // 报告点    private List<Marker> markerList; // 飞机点列表    private Marker mMarker; // 飞机点    private BitmapDescriptor marker_flight;    private InfoWindow mInfoWindow;
list存放我们的marker,如果不用list,将来移除的marker只能是一个点,而不是所有,因此,添加和移除都需要遍历
        sc_marker.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()        {            @Override            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)            {                if(isChecked)                {                    if (markerList == null) // 如果markerList为空,说明此时没有生成报告点                    {                        addFlightInfo(MarkerInfo.mMarkerInfos); // 添加报告点的方法                    }                } else                {                    if (markerList != null)                    {                        for (int i = 0; i < markerList.size(); i++)                        {                            markerList.get(i).remove();                        }                        markerList = null;                    }                }            }        });
为开关控件添加监听,当选中状态的时候,如果列表没有marker,则走添加marker的方法,在取消状态的时候,仅当list不为空的时候,才去移除marker,在移除结束后,将list置为空是我自己的写法以防意外发生。如果你逻辑比较强认为这里不需要加,也可以。接下来看一下添加 marker的方法:
    /**     * 添加飞机信息     *     * @param flightInfos     */    private void addFlightInfo(List<MarkerInfo> flightInfos)    {        LatLng latlng = null;        OverlayOptions overlayOptions = null;        markerList = new ArrayList<>();        marker_flight = BitmapDescriptorFactory                .fromResource(R.mipmap.ic_flight); // 飞机图标        for (MarkerInfo infos : flightInfos)        {            latlng = new LatLng(infos.getLatitude(), infos.getLongitude()); // 经纬度            overlayOptions = new MarkerOptions().position(latlng).icon(marker_flight).zIndex(9).animateType(MarkerOptions.MarkerAnimateType.grow);            mMarker = (Marker) (mBaiduMap.addOverlay(overlayOptions));            Bundle bundle = new Bundle();            bundle.putSerializable("info", infos);            mMarker.setExtraInfo(bundle);            markerList.add(mMarker);        }        // 将地图移动到最后一个经纬度位置        MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(latlng);        mBaiduMap.setMapStatus(u);    }
我们在调用方法的时候,把MarkerInfo里的模拟数据加载进来,在循环中将对应的经纬度取出来,放在latlng对象中,在new MarkerOptions的时候,将坐标传了进去,并设置了飞机图标、marker所在层级、生长动画,最后使用mBaiduMap的addOverlay方法,添加marker,最后,使用bundle对象将infos的内容保存到了marker中。这样,就生成了一堆飞机点。接下来,我们看一下点击时间:
// mark事件监听        mBaiduMap.setOnMarkerClickListener(new BaiduMap.OnMarkerClickListener()        {            @Override            public boolean onMarkerClick(Marker marker)            {                MarkerInfo info = (MarkerInfo) marker.getExtraInfo().get("info");                InfoWindow.OnInfoWindowClickListener listener = null;                TextView text = new TextView(getApplicationContext());                text.setBackgroundResource(R.mipmap.location_tips);                text.setPadding(30, 30, 30, 30);                text.setTextColor(getResources().getColor(android.R.color.white));                text.setText(info.getNum());                // 将marker所在的经纬度的信息转化成屏幕上的坐标                LatLng ll = marker.getPosition();                listener = new InfoWindow.OnInfoWindowClickListener()                {                    @Override                    public void onInfoWindowClick()                    {                        mBaiduMap.hideInfoWindow();                    }                };                mInfoWindow = new InfoWindow(BitmapDescriptorFactory.fromView(text), ll, -47, listener);                // 设置详细信息到布局                setInfoToLayout(ll_info, info);                ll_info.setVisibility(View.VISIBLE); // 显示飞机详情布局                mBaiduMap.showInfoWindow(mInfoWindow); // 显示弹窗                return true;            }        });
首先,marker.getExtraInfo().get("info")取得了marker对应的数据,这里我们动态添加了一个TextView,显示飞机的型号。,在listener中,如果点击到了弹出的textView,就让它消失,最后,setInfoToLayout()来将bundle里的数据显示到详情布局中,并设为可见状态,最后showInfoWindow显示出来,就基本完成了。下面看一下setInfoToLayout(ll_info, info);方法:
    /**     * 为布局添加飞机详情信息     *     * @param ll_info     * @param info     */    private void setInfoToLayout(LinearLayout ll_info, MarkerInfo info)    {        ViewHolder viewHolder = null;        if (ll_info.getTag() == null)        {            viewHolder = new ViewHolder();            viewHolder.tv_num = (TextView) ll_info.findViewById(R.id.activity_main_flightinfo_tv_num);            viewHolder.tv_model = (TextView) ll_info.findViewById(R.id.activity_main_flightinfo_tv_model);            viewHolder.tv_startPlace = (TextView) ll_info.findViewById(R.id.activity_main_flightinfo_tv_startPlace);            viewHolder.tv_endPlace = (TextView) ll_info.findViewById(R.id.activity_main_flightinfo_tv_endPlace);            viewHolder.tv_startTime = (TextView) ll_info.findViewById(R.id.pop_window_flight_info_tv_startTime);            viewHolder.tv_endTime = (TextView) ll_info.findViewById(R.id.pop_window_flight_info_tv_endTime);            ll_info.setTag(viewHolder);        }        viewHolder = (ViewHolder) ll_info.getTag();        viewHolder.tv_num.setText("飞机编号:" + info.getNum());        viewHolder.tv_model.setText("飞机型号:" + info.getModel());        viewHolder.tv_startPlace.setText("出发地:" + info.getStartPlace());        viewHolder.tv_endPlace.setText("抵达地:" + info.getEndPlace());        viewHolder.tv_startTime.setText("出发时间:" + info.getStartTime());        viewHolder.tv_endTime.setText("抵达时间:" + info.getEndTime());    }    private class ViewHolder    {        TextView tv_num, tv_model, tv_startPlace, tv_endPlace, tv_startTime, tv_endTime;    }
至此,功能就实现了,但是每次弹出详情只能点击TextView才能消失,感觉这样做体验不太舒服,因此,可以在地图的触摸时间加入对应的事件:
//地图触摸事件        mBaiduMap.setOnMapTouchListener(new BaiduMap.OnMapTouchListener()        {            @Override            public void onTouch(MotionEvent motionEvent)            {                ll_info.setVisibility(View.GONE);                mBaiduMap.hideInfoWindow();            }        });
ok,到此已经完成了本章的内容。如果有帮到你,请点赞。有疑问的可以留言,我会抽时间帮忙解决。Demo下载地址

http://download.csdn.net/detail/u012552275/9680875

参考文章:

http://blog.csdn.net/lmj623565791/article/details/37737213

2 0
原创粉丝点击