osmdroid API解读(十一)
来源:互联网 发布:中国移动杭州数据 编辑:程序博客网 时间:2024/06/05 15:16
osmdroid API解读(十一)
osmdroid-android org.osmdroid.views.overlay包
表示覆盖物的基类,可以在MapView的顶层显示。为了添加一个overlay,需要创建一个此类的子类实体,并添加到MapView.getOverlays()的列表中。
此类实现了类似于android.view.GestureDetector.SimpleOnGestureListener和GestureDetector.OnGestureListener的手势监听器。不同之处在于为方法添加了新的参数。
1. Overlay
public abstract class Overlay implements OverlayConstants { //静态常量 private static AtomicInteger sOrdinal = new AtomicInteger(); protected static final float SHADOW_X_SKEW = -0.8999999761581421f; protected static final float SHADOW_Y_SCALE = 0.5f; private static final Rect mRect = new Rect(); //可用性 private boolean mEnabled = true; //过期 @Deprecated public Overlay(final Context ctx) { } public Overlay() { } /** * Sets whether the Overlay is marked to be enabled. This setting does nothing by default, but * should be checked before calling draw(). */ //该图层是否被标记为可用。默认为可用,在使用draw()方法前应调用 public void setEnabled(final boolean pEnabled) { this.mEnabled = pEnabled; } public boolean isEnabled() { return this.mEnabled; } /** * Since the menu-chain will pass through several independent Overlays, menu IDs cannot be fixed * at compile time. Overlays should use this method to obtain and store a menu id for each menu * item at construction time. This will ensure that two overlays don't use the same id. * * @return an integer suitable to be used as a menu identifier */ //由于 menu-chain 传递通过多个独立的覆盖物,menu IDs并不能在编译时固定。此方法用于为构造menu item时获取并存储一个menu id。此方法可以确保两个图层不使用相同的id。 protected final static int getSafeMenuId() { return sOrdinal.getAndIncrement(); } protected final static int getSafeMenuIdSequence(final int count) { return sOrdinal.getAndAdd(count); } //在map上绘制overlay。此方法在所有活动图层设置为shadow=true以画下阴影层调用,然后再设置shadow=false再次调用。调用者应该在调用此方法之前检查isEnabled()。默认情况下不画任何东西。 public abstract void draw(final Canvas c, final MapView osmv, final boolean shadow); // =========================================================== // Methods // =========================================================== /** * Override to perform clean up of resources before shutdown. By default does nothing. * */ //应该被复写在关闭之前执行清理资源工作 public void onDetach(final MapView mapView) { } //默认情况下不做任何时,返回false。如果你处理了则返回true。若返回true,其他图层将对此事件不做任何处理。 public boolean onKeyDown(final int keyCode, final KeyEvent event, final MapView mapView) { return false; } public boolean onKeyUp(final int keyCode, final KeyEvent event, final MapView mapView) { return false; } public boolean onTrackballEvent(final MotionEvent event, final MapView mapView) { return false; } //利用此可阻止触摸相关的的事件。 public boolean onTouchEvent(final MotionEvent event, final MapView mapView) { return false; } /** GestureDetector.OnDoubleTapListener **/ public boolean onDoubleTap(final MotionEvent e, final MapView mapView) { return false; } public boolean onDoubleTapEvent(final MotionEvent e, final MapView mapView) { return false; } public boolean onSingleTapConfirmed(final MotionEvent e, final MapView mapView) { return false; } /** OnGestureListener **/ public boolean onDown(final MotionEvent e, final MapView mapView) { return false; } public boolean onFling(final MotionEvent pEvent1, final MotionEvent pEvent2, final float pVelocityX, final float pVelocityY, final MapView pMapView) { return false; } public boolean onLongPress(final MotionEvent e, final MapView mapView) { return false; } public boolean onScroll(final MotionEvent pEvent1, final MotionEvent pEvent2, final float pDistanceX, final float pDistanceY, final MapView pMapView) { return false; } public void onShowPress(final MotionEvent pEvent, final MapView pMapView) { return; } public boolean onSingleTapUp(final MotionEvent e, final MapView mapView) { return false; } //方便平移画Drawable的方法,x、y时像素坐标。你可以通过MapView.getProjection()方法将经纬度坐标转换为像素坐标。 protected synchronized static void drawAt(final Canvas canvas, final Drawable drawable, final int x, final int y, final boolean shadow, final float aMapOrientation) { canvas.save(); canvas.rotate(-aMapOrientation, x, y); drawable.copyBounds(mRect); drawable.setBounds(mRect.left + x, mRect.top + y, mRect.right + x, mRect.bottom + y); drawable.draw(canvas); drawable.setBounds(mRect); canvas.restore(); } /** * Interface definition for overlays that contain items that can be snapped to (for example, * when the user invokes a zoom, this could be called allowing the user to snap the zoom to an * interesting point.) */ //用于对overlays的包含项进行改变。比如当使用者调用缩放,允许使用者将缩放水平调整到相应的值。 public interface Snappable { //检查给定的x、y是否接近于某个项,从而将当前动作调整到此项上 boolean onSnapToItem(int x, int y, Point snapPoint, IMapView mapView); }}
1.1 IconOverlay
图标型Overlay,可以在Overlay中放入一个icon
public class IconOverlay extends Overlay { //通常icon在像素坐标系中的位置 public static final float ANCHOR_CENTER=0.5f, ANCHOR_LEFT=0.0f, ANCHOR_TOP=0.0f, ANCHOR_RIGHT=1.0f, ANCHOR_BOTTOM=1.0f; protected Drawable mIcon = null;//图标 protected IGeoPoint mPosition = null;//位置 protected float mBearing = 0.0f; protected float mAnchorU = ANCHOR_CENTER , mAnchorV=ANCHOR_CENTER; protected float mAlpha = 1.0f; //opaque protected boolean mFlat = false; //billboard; protected Point mPositionPixels = new Point(); public IconOverlay() { } public IconOverlay(IGeoPoint position, Drawable icon) { set(position, icon); } //画图标到图上 @Override public void draw(Canvas canvas, MapView mapView, boolean shadow) { if (shadow) return; if (mIcon == null) return; if (mPosition == null) return; final Projection pj = mapView.getProjection(); pj.toPixels(mPosition, mPositionPixels); int width = mIcon.getIntrinsicWidth(); int height = mIcon.getIntrinsicHeight(); Rect rect = new Rect(0, 0, width, height); rect.offset(-(int)(mAnchorU*width), -(int)(mAnchorV*height)); mIcon.setBounds(rect); mIcon.setAlpha((int) (mAlpha * 255)); float rotationOnScreen = (mFlat ? -mBearing : mapView.getMapOrientation()-mBearing); drawAt(canvas, mIcon, mPositionPixels.x, mPositionPixels.y, false, rotationOnScreen); } public IGeoPoint getPosition() { return mPosition; } public IconOverlay set(IGeoPoint position, Drawable icon) { this.mPosition = position; this.mIcon = icon; return this; } public IconOverlay moveTo(final MotionEvent event, final MapView mapView){ final Projection pj = mapView.getProjection(); moveTo(pj.fromPixels((int) event.getX(), (int) event.getY()), mapView); return this; } public IconOverlay moveTo(final IGeoPoint position, final MapView mapView){ mPosition = position; mapView.invalidate(); return this; }}
1.1.1 ClickableIconOverlay
可点击图标的Overlay,在IconOverlay基础上添加了点击处理机制
public abstract class ClickableIconOverlay<DataType> extends IconOverlay { protected int mId = 0; private DataType mData = null; //非UI线程创建 protected ClickableIconOverlay(DataType data) { mData = data; } //标记被点击回调方法 abstract protected boolean onMarkerClicked(MapView mapView, int markerId, IGeoPoint makerPosition, DataType markerData); //回收利用本类 public ClickableIconOverlay set(int id, IGeoPoint position, Drawable icon, DataType data) { set(position, icon); mId = id; mData = data; return this; } //确定该点是否是该图标的事件 protected boolean hitTest(final MotionEvent event, final MapView mapView){ final Projection pj = mapView.getProjection(); // sometime at higher zoomlevels pj is null if ((mPosition == null) || (mPositionPixels == null) || (pj == null)) return false; pj.toPixels(mPosition, mPositionPixels); final Rect screenRect = pj.getIntrinsicScreenRect(); int x = -mPositionPixels.x + screenRect.left + (int) event.getX(); int y = -mPositionPixels.y + screenRect.top + (int) event.getY(); boolean hit = mIcon.getBounds().contains(x, y); return hit; } //处理单次tap事件 @Override public boolean onSingleTapConfirmed(final MotionEvent event, final MapView mapView) { boolean touched = hitTest(event, mapView); if (touched) { return onMarkerClicked(mapView, mId, mPosition, mData); } else { return super.onSingleTapConfirmed(event, mapView); } } //处理长按事件,本类中并未处理 public boolean onLongPress(final MotionEvent event, final MapView mapView) { boolean touched = hitTest(event, mapView); if (touched) { return onMarkerLongPress(mapView, mId, mPosition, mData); } else { return super.onLongPress(event, mapView); } } protected boolean onMarkerLongPress(MapView mapView, int markerId, IGeoPoint geoPosition, Object data) { return false; } public static ClickableIconOverlay find(List<ClickableIconOverlay> list, int id) { for (ClickableIconOverlay item : list) { if ((item != null) && (item.mId == id)) return item; } return null; } public int getID() { return mId; } public DataType getData() { return mData; }}
1.2 关于ItemOverlay
1.2.0 OverlayItem
可以被显示在ItemizedOverlay或ItemizedIconOverlay的选项。描述了一个有标题和描述的坐标
public class OverlayItem { public static final int ITEM_STATE_FOCUSED_MASK = 4; public static final int ITEM_STATE_PRESSED_MASK = 1; public static final int ITEM_STATE_SELECTED_MASK = 2; protected static final Point DEFAULT_MARKER_SIZE = new Point(26, 94); public enum HotspotPlace { NONE, CENTER, BOTTOM_CENTER, TOP_CENTER, RIGHT_CENTER, LEFT_CENTER, UPPER_RIGHT_CORNER, LOWER_RIGHT_CORNER, UPPER_LEFT_CORNER, LOWER_LEFT_CORNER } protected final String mUid; protected final String mTitle; protected final String mSnippet; protected final IGeoPoint mGeoPoint; protected Drawable mMarker; protected HotspotPlace mHotspotPlace; public OverlayItem(final String aTitle, final String aSnippet, final IGeoPoint aGeoPoint) { this(null, aTitle, aSnippet, aGeoPoint); } public OverlayItem(final String aUid, final String aTitle, final String aDescription, final IGeoPoint aGeoPoint) { this.mTitle = aTitle; this.mSnippet = aDescription; this.mGeoPoint = aGeoPoint; this.mUid = aUid; } //Get & Set 要标记的的图标 public Drawable getMarker(final int stateBitset) { // marker not specified if (mMarker == null) { return null; } // set marker state appropriately setState(mMarker, stateBitset); return mMarker; } public void setMarker(final Drawable marker) { this.mMarker = marker; } //设置相应状态的图片以匹配相应状态的bitset public static void setState(final Drawable drawable, final int stateBitset) { final int[] states = new int[3]; int index = 0; if ((stateBitset & ITEM_STATE_PRESSED_MASK) > 0) states[index++] = android.R.attr.state_pressed; if ((stateBitset & ITEM_STATE_SELECTED_MASK) > 0) states[index++] = android.R.attr.state_selected; if ((stateBitset & ITEM_STATE_FOCUSED_MASK) > 0) states[index++] = android.R.attr.state_focused; drawable.setState(states); } public Drawable getDrawable() { return this.mMarker; } public int getWidth() { return this.mMarker.getIntrinsicWidth(); } public int getHeight() { return this.mMarker.getIntrinsicHeight(); } ...}
1.2.1 ItemizedOverlay
画一系列的标志点到图上。具有低索引的item最后被画,因此作为顶端标记。它也首先检查ontap。这个类是通用类,因此你可以自定义ItemizedOverlay子类,并用ontap()回传。
public abstract class ItemizedOverlay<Item extends OverlayItem> extends Overlay implements Overlay.Snappable { protected final Drawable mDefaultMarker;//默认的图标 private final ArrayList<Item> mInternalItemList;//内部点 private boolean[] mInternalItemDisplayedList;//确定是否显示 private final Rect mRect = new Rect(); private final Point mCurScreenCoords = new Point(); protected boolean mDrawFocusedItem = true; private Item mFocusedItem; private boolean mPendingFocusChangedEvent = false; private OnFocusChangeListener mOnFocusChangeListener; private final float[] mMatrixValues = new float[9]; private final Matrix mMatrix = new Matrix(); protected float scaleX=1f; protected float scaleY=1f; protected abstract Item createItem(int i); @Deprecated public ItemizedOverlay(Context ctx, final Drawable pDefaultMarker) { this(pDefaultMarker); } public ItemizedOverlay(final Drawable pDefaultMarker) { super(); if (pDefaultMarker == null) { throw new IllegalArgumentException("You must pass a default marker to ItemizedOverlay."); } this.mDefaultMarker = pDefaultMarker; mInternalItemList = new ArrayList<Item>(); } @Override public void onDetach(MapView mapView){ if (mDefaultMarker!=null){ //release the bitmap } } @Override public void draw(Canvas canvas, MapView mapView, boolean shadow) { if (shadow) { return; } if (mPendingFocusChangedEvent && mOnFocusChangeListener != null) mOnFocusChangeListener.onFocusChanged(this, mFocusedItem); mPendingFocusChangedEvent = false; final Projection pj = mapView.getProjection(); final int size = this.mInternalItemList.size(); if (mInternalItemDisplayedList == null || mInternalItemDisplayedList.length != size) { mInternalItemDisplayedList = new boolean[size]; } canvas.getMatrix(mMatrix);//获取画布的矩阵 mMatrix.getValues(mMatrixValues);//將值clone到mMatrixValues中 //确定缩放比例 scaleX = (float) Math.sqrt(mMatrixValues[Matrix.MSCALE_X] * mMatrixValues[Matrix.MSCALE_X] + mMatrixValues[Matrix.MSKEW_Y] * mMatrixValues[Matrix.MSKEW_Y]); scaleY = (float) Math.sqrt(mMatrixValues[Matrix.MSCALE_Y] * mMatrixValues[Matrix.MSCALE_Y] + mMatrixValues[Matrix.MSKEW_X] * mMatrixValues[Matrix.MSKEW_X]); /* Draw in backward cycle, so the items with the least index are on the front. */ for (int i = size - 1; i >= 0; i--) { final Item item = getItem(i); if (item == null) { continue; } pj.toPixels(item.getPoint(), mCurScreenCoords); mInternalItemDisplayedList[i] = onDrawItem(canvas,item, mCurScreenCoords, mapView.getMapOrientation()); } } //子类利用createItem(int)后,在使用其它方法前,应立即使用该方法 protected final void populate() { final int size = size(); mInternalItemList.clear(); mInternalItemList.ensureCapacity(size); for (int a = 0; a < size; a++) { mInternalItemList.add(createItem(a)); } mInternalItemDisplayedList = null; } 获取某位置的选项 public final Item getItem(final int position) { try { return mInternalItemList.get(position); }catch(final IndexOutOfBoundsException e) { return null; } } //将一个item画到画布上 protected boolean onDrawItem(final Canvas canvas, final Item item, final Point curScreenCoords, final float aMapOrientation) { final int state = (mDrawFocusedItem && (mFocusedItem == item) ? OverlayItem.ITEM_STATE_FOCUSED_MASK : 0); final Drawable marker = (item.getMarker(state) == null) ? getDefaultMarker(state) : item .getMarker(state); final HotspotPlace hotspot = item.getMarkerHotspot(); boundToHotspot(marker, hotspot); int x = mCurScreenCoords.x; int y = mCurScreenCoords.y; canvas.save(); canvas.rotate(-aMapOrientation, x, y); marker.copyBounds(mRect); marker.setBounds(mRect.left + x, mRect.top + y, mRect.right + x, mRect.bottom + y); canvas.scale(1 / scaleX, 1 / scaleY, x, y); final boolean displayed = Rect.intersects(marker.getBounds(), canvas.getClipBounds()); if (displayed) { marker.draw(canvas); } marker.setBounds(mRect); canvas.restore(); return displayed; /* final int state = (mDrawFocusedItem && (mFocusedItem == item) ? OverlayItem.ITEM_STATE_FOCUSED_MASK : 0); final Drawable marker = (item.getMarker(state) == null) ? getDefaultMarker(state) : item .getMarker(state); final HotspotPlace hotspot = item.getMarkerHotspot(); boundToHotspot(marker, hotspot); // draw it Overlay.drawAt(canvas, marker, curScreenCoords.x, curScreenCoords.y, false, aMapOrientation);*/ } //获取显示的选项列表 public List<Item> getDisplayedItems() { final List<Item> result = new ArrayList<>(); if (mInternalItemDisplayedList == null) { return result; } for (int i = 0 ; i < mInternalItemDisplayedList.length ; i ++) { if (mInternalItemDisplayedList[i]) { result.add(getItem(i)); } } return result; } //获取默认的图片 protected Drawable getDefaultMarker(final int state) { OverlayItem.setState(mDefaultMarker, state); return mDefaultMarker; } protected boolean hitTest(final Item item, final android.graphics.drawable.Drawable marker, final int hitX, final int hitY) { return marker.getBounds().contains(hitX, hitY); } @Override public boolean onSingleTapConfirmed(MotionEvent e, MapView mapView) { final Projection pj = mapView.getProjection(); final Rect screenRect = pj.getIntrinsicScreenRect(); final int size = this.size(); for (int i = 0; i < size; i++) { final Item item = getItem(i); if (item == null) { continue; } pj.toPixels(item.getPoint(), mCurScreenCoords); final int state = (mDrawFocusedItem && (mFocusedItem == item) ? OverlayItem.ITEM_STATE_FOCUSED_MASK : 0); final Drawable marker = (item.getMarker(state) == null) ? getDefaultMarker(state) : item.getMarker(state); boundToHotspot(marker, item.getMarkerHotspot()); if (hitTest(item, marker, -mCurScreenCoords.x + screenRect.left + (int) e.getX(), -mCurScreenCoords.y + screenRect.top + (int) e.getY())) { // We have a hit, do we get a response from onTap? if (onTap(i)) { // We got a response so consume the event return true; } } } return super.onSingleTapConfirmed(e, mapView); } protected boolean onTap(int index) { return false; } public void setDrawFocusedItem(final boolean drawFocusedItem) { mDrawFocusedItem = drawFocusedItem; } public void setFocus(final Item item) { mPendingFocusChangedEvent = item != mFocusedItem; mFocusedItem = item; } public Item getFocus() { return mFocusedItem; } protected synchronized Drawable boundToHotspot(final Drawable marker, HotspotPlace hotspot) { final int markerWidth = marker.getIntrinsicWidth(); final int markerHeight = marker.getIntrinsicHeight(); mRect.set(0, 0, 0 + markerWidth, 0 + markerHeight); if (hotspot == null) { hotspot = HotspotPlace.BOTTOM_CENTER; } switch (hotspot) { default: case NONE: break; case CENTER: mRect.offset(-markerWidth / 2, -markerHeight / 2); break; case BOTTOM_CENTER: mRect.offset(-markerWidth / 2, -markerHeight); break; case TOP_CENTER: mRect.offset(-markerWidth / 2, 0); break; case RIGHT_CENTER: mRect.offset(-markerWidth, -markerHeight / 2); break; case LEFT_CENTER: mRect.offset(0, -markerHeight / 2); break; case UPPER_RIGHT_CORNER: mRect.offset(-markerWidth, 0); break; case LOWER_RIGHT_CORNER: mRect.offset(-markerWidth, -markerHeight); break; case UPPER_LEFT_CORNER: mRect.offset(0, 0); break; case LOWER_LEFT_CORNER: mRect.offset(0, -markerHeight); break; } marker.setBounds(mRect); return marker; } public void setOnFocusChangeListener(OnFocusChangeListener l) { mOnFocusChangeListener = l; } public static interface OnFocusChangeListener { void onFocusChanged(ItemizedOverlay<?> overlay, OverlayItem newFocus); }}
1.2.1.1 ItemizedIconOverlay
带有icon item的Overlay。
public class ItemizedIconOverlay<Item extends OverlayItem> extends ItemizedOverlay<Item> { ...}
1.2.1.2 ItemizedOverlayWithFocus
有焦点的、带有icon item的Overlay。
public class ItemizedOverlayWithFocus<Item extends OverlayItem> extends ItemizedIconOverlay<Item> { ...}
1.2.2 ItemizedOverlayControlView
用于ItemizedOverlay中item的的控制。
public class ItemizedOverlayControlView extends LinearLayout { protected ImageButton mPreviousButton; protected ImageButton mNextButton; protected ImageButton mCenterToButton; protected ImageButton mNavToButton; protected ItemizedOverlayControlViewListener mLis; ... public interface ItemizedOverlayControlViewListener { public void onPrevious(); public void onNext(); public void onCenter(); public void onNavTo(); }}
1.3 MapEventsOverlay
用于检查地图事件的空覆盖物,并把事件传递给MapEventsReceiver
public class MapEventsOverlay extends Overlay { private MapEventsReceiver mReceiver; @Deprecated public MapEventsOverlay(Context ctx, MapEventsReceiver receiver) { this(receiver); } //传递一个地图事件接收者 public MapEventsOverlay(MapEventsReceiver receiver) { super(); mReceiver = receiver; } @Override public void draw(Canvas c, MapView osmv, boolean shadow) { //Nothing to draw } @Override public boolean onSingleTapConfirmed(MotionEvent e, MapView mapView){ Projection proj = mapView.getProjection(); GeoPoint p = (GeoPoint)proj.fromPixels((int)e.getX(), (int)e.getY()); return mReceiver.singleTapConfirmedHelper(p); } @Override public boolean onLongPress(MotionEvent e, MapView mapView) { Projection proj = mapView.getProjection(); GeoPoint p = (GeoPoint)proj.fromPixels((int)e.getX(), (int)e.getY()); //throw event to the receiver: return mReceiver.longPressHelper(p); }}
1.4 NonAcceleratedOverlay
将不兼容硬件加速的Overlay用于硬件加速的MapView。它会为Overlay创建一个屏幕尺寸的位图,然后再画Bitmap到硬件加速的canvas上。由于有多余的工作,所以不会画shadow图层
public abstract class NonAcceleratedOverlay extends Overlay { ...}
1.5 OverlayWithIW
一个包含title、snippet、description的Overlay,这些信息可以在一个弹出的InfoWindow窗口中显示,处理tap事件并在相应的位置显示InfoWindow。
public abstract class OverlayWithIW extends Overlay { //InfoWindow handling protected String mTitle, mSnippet, mSubDescription; protected InfoWindow mInfoWindow; protected Object mRelatedObject; ...}
1.5.1 Marker
marker是一个放在特殊点的icon,可以弹出InfoWindow
- icon可以是任何Android标准的Drawable
- icon可以随时改变
- InfoWindow持有标准的Android View,它可以像处理Android组件如按钮等
- 支持sub-description,显示在snippet下以小的字体显示在InfoWindow中。
- 支持在InfoWindow中显示图片。
- 支持触摸marker后将地图居中在marker位置
- 如果使用的是同一个InfoWindow打开一个InfoWindow自动关闭其他的InfoWindow显示
事件监听应该设置给每一个marker
public class Marker extends OverlayWithIW {
...
}
1.5.2 Polyline
Polyline是一个点列表,线段连接点与点。
public class Polyline extends OverlayWithIW { ...}
1.5.3 polygon
polygon是地球表面的多边形,可以有一个弹出的InfoWindow。
public class Polygon extends OverlayWithIW {
...
}
1.5.3.1 LinearRing
多边形区域的轮廓线,或多边形区域的一个洞。
class LinearRing implements SegmentClipper.SegmentClippable{ ...}
1.6 ScaleBarOverlay
比例尺Overlay
public class ScaleBarOverlay extends Overlay implements GeoConstants { ...}
1.7 ZoomButtonsOverlay
替换标准的ZoomButtonsController
public class ZoomButtonsOverlay extends Overlay { ...}
1.8 CopyrightOverlay
所有权Overlay
public class CopyrightOverlay extends Overlay { ...}
2 多个Overlay的管理与使用
2.1 OverlayManager
Overlay管理者,用于管理多个
public interface OverlayManager extends List<Overlay> { ...}
2.1.1 DefaultOverlayManager
默认的瓦片管理者需要添加一个地图式瓦片Overlay以及多个Overlay。
public class DefaultOverlayManager extends AbstractList<Overlay> implements OverlayManager {private TilesOverlay mTilesOverlay;private final CopyOnWriteArrayList<Overlay> mOverlayList; ...}
2.2 FolderOverlay
一个管理多个Overlay的Overlay,内部含有一个OverlayManager属性,用于真正管理多个Overlay。
public class FolderOverlay extends Overlay { protected OverlayManager mOverlayManager; protected String mName, mDescription; ...}
- osmdroid API解读(十一)
- osmdroid API解读(一)
- osmdroid API解读(二)
- osmdroid API解读(三)
- osmdroid API解读(四)
- osmdroid API解读(五)
- osmdroid API解读(六)
- osmdroid API解读(七)
- osmdroid API解读(八)
- osmdroid API解读(九)
- osmdroid API解读(十)
- osmdroid API解读(十二)
- osmdroid API解读(十三)
- osmdroid API解读(十四)
- osmdroid API解读(十五)
- Caffe源码解读(十一):自定义一个layer
- 解读javamail API 之一(概述篇)
- 解读官方Android MediaPlayer API(1)
- cad看图软件看图软件哪个好?
- jqgrid的增删改查
- input输入框只能输入正整数
- FreeSWITCH学习笔记 第一场 第六个镜头 控制台与客户端(FS_Cli)
- CI框架中pdo的使用方法
- osmdroid API解读(十一)
- 移动端布局
- java中的转义字符
- 牛顿方法(Newton's Method)
- 【我的Java笔记】形式参数&返回值
- Spring在web开发中的应用与Spring整合junit4测试
- zookeeper实现分布式锁
- JAVA实现不规则图形界面
- LCA倍增法