在android中添加图层的方法,一般来说是定义一个overlay对象,比如说属于MyOverlay类,MyOverlay是继承于ItemizedOverlay<Item>的,然后定义一个overlayitem,继承于OverLayItem,在使用的时候就是新建一个overlayitem对象,overlayitem =new overlayitem (GeoPoint point, String directiondir, String routetag),point包含了这个点的经纬度,后面两个数据就是你在点击这个点的时候可以显示的数据,当然至于你想怎么显示就看每个人不同的想法了。overlay在定义的时候会传入一个图片参数,以便显示,然后就是把overlayitem对象加到overlay中,在点击图片的时候会调用MyOverlay中的OnTop方法。至于我们要显示的两个信息,就是overlayitem对象中的后两个参数,我们可以根据点击时得到的index来创建一个item,然后调用item的gettitle getsnippet方法来获得两个参数。
今天我们要来做的是点击了一个图标以后弹出一个小框,上面可以显示信息,有链接,点击空白的地方小框消失。
首先我们新建一个工程,TestActivity,看看权限问题。。没有。只是为了显示这个框,所以我就定了一个点并且没有做其他的结合
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mapView = (MapView) findViewById(R.id.mapView); mapView.setStreetView(true); mapView.setBuiltInZoomControls(true); mapOverlays = mapView.getOverlays(); myloctionController=mapView.getController(); Drawable routeDrawable=getResources().getDrawable(R.drawable.bus);//显示公交路线的图标 MyOverlay Route_Overlay=new MyOverlay(routeDrawable, this,mapView); GeoPoint point=new GeoPoint((int)31.152295107937604*1000000,(int)121.12701416015625*1000000); //标题内容这里仅仅作为demo,真正用到的时候可以在setdata中设置 BusOverlayItem overlayitem = new BusOverlayItem(point,"标题","内容"); Route_Overlay.addOverlay(overlayitem); mapOverlays.clear(); mapOverlays=mapView.getOverlays(); mapOverlays.add(Route_Overlay); myloctionController.animateTo(point); myloctionController.setZoom(10); myloctionController.setCenter(point); }oncreate很简单,我们先总的来说下继承关系。MyOverlay继承于BalloonItemizedOverlay<BusOverlayItem>,它又继承于ItemizedOverlay<Item>。对于BusOverlayItem,它继承与OverlayItem。而还有一个BusPopupView类继承于BalloonoverLayView <Item extends OverlayItem>,再继承与FrameLayout。首先说MyOverlay,作为一个图层是用来添加图层项 的,BusOverlayItem的话就是图层项,然后BusPopupView就是弹出框的实体类(父类中FrameLayout就是用来显示弹出框的)。
我们点击每个图层项 的时候,会进入MyOverlay的OnTop方法,这里我们这个方法中就一句话,就是调用父类的ontop方法。在BalloonItemizedOverlay<BusOverlayItem>的ontop方法中
@Override protected boolean onTap(int index) { currentFocussedIndex = index; currentFocussedItem = (item) createItem(index); boolean isRecycled = false; if (null==balloonview) { balloonview=createBalloonOverlayView(); clickRegion=(View)balloonview.findViewById(R.id.balloon_main_layout); //还没懂这句话的含义 clickRegion.setOnTouchListener(createBalloonTouchListener()); isRecycled = false; }else { isRecycled = true; } //显示框的数据设置 balloonview.setData(currentFocussedItem); //addview的参数设定 GeoPoint point = currentFocussedItem.getPoint(); MapView.LayoutParams params = new MapView.LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, point, MapView.LayoutParams.BOTTOM_CENTER); params.mode = MapView.LayoutParams.MODE_MAP; //使得弹出框可见 balloonview.setVisibility(View.VISIBLE); if (isRecycled) { balloonview.setLayoutParams(params); } else { mapView.addView(balloonview, params); } //mc.animateTo(point); return true; }这里面的balloonview就是弹出框对应view对象。首先我们判断它是不是空的。空的话就调用createBalloonOverlayView();这个函数中我们生成一个Buspopupview对象
//这里是父类中虚方法的实现 protected BalloonOverlayView<BusOverlayItem> createBalloonOverlayView() { BuspopupView view=new BuspopupView(getMapView().getContext(),70);//最后一个是偏移量 return view; }
Buspopupview的构造函数如下:
public BuspopupView(Context context, int offset) { super(context,offset); //在父类中是生成了layout和一个view对象,但是那是在父类中,而后面要添加的对象是一个BusPopupView对象, //这个addview把父类相关信息保存到子类中把 FrameLayout.LayoutParams params = new FrameLayout.LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); params.gravity = Gravity.NO_GRAVITY; //这里是把指定的layout这个子类view添加到Buspopupview中去 //params the layout parameters to set on the child addView(layoutview, params); }
如果想要使得弹出框中的链接可用,我们只要想buspopupview构造函数中添加如下代码,具体的点击之后要实现的操作就自己实现了,这些变量都是buspopupview的变量
favorite = (ImageView) layoutview.findViewById(R.id.balloon_item_favorite); moreInfo = (TextView) layoutview.findViewById(R.id.balloon_item_moreinfo); moreInfoText = Html.fromHtml("\n<a href='com.bostonbusmap://moreinfo'>More info</a>\n"); reportProblem = (TextView) layoutview.findViewById(R.id.balloon_item_report); reportProblemText = Html.fromHtml("\n<a href='com.bostonbusmap://reportproblem'>Report<br/>Problem</a>\n"); alertsTextView = (TextView) layoutview.findViewById(R.id.balloon_item_alerts); alertsTextView.setVisibility(View.GONE); noAlertsText = Html.fromHtml("<font color='grey'>No alerts</font>"); favorite.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { System.out .println("BuspopupView.BuspopupView(...).new OnClickListener() {...}.onClick()"); } }); moreInfo.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { System.out.println("BuspopupView.BuspopupView()");} } ); reportProblem.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { System.out .println("BuspopupView.BuspopupView(...).new OnClickListener() {...}.onClick()");} }); alertsTextView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { System.out .println("BuspopupView.BuspopupView(...).new OnClickListener() {...}.onClick()"); } });
在buspopupview的构造函数中首先调用的是父类的构造方法:
public BalloonOverlayView(Context context,int offset) { super(context); //设置框的位置 左,顶,右,底 setPadding(10, 0, 10, 45); //LinearLayout layout=new LinearLayout(context); layout.setVisibility(VISIBLE); //This class is used to instantiate layout XML file into its corresponding View objects LayoutInflater inflater=(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); layoutview=inflater.inflate(R.layout.balloon_map_overlay,layout); //弹出框中的两行信息,可见R.id.balloon_item_title框图中 title = (TextView) layoutview.findViewById(R.id.balloon_item_title); snippet = (TextView) layoutview.findViewById(R.id.balloon_item_snippet); }这个父类的构造方法中首先设置了框架的位置,设置一个layout,然后加载弹出框的布局文件,生成一个视图对象。顺便得到title和snippet两个东西。既然父类中已经加载了这个布局文件,那么生成的视图对象就是布局文件中的样子了。回到子类的构造函数中去,把这个试图对象添加到Buspopupview中去,最后返回给之前我们提到的balloonview对象。然后要做的就是setdata,发送数据就是给title和snippet两个东西赋值嘛,既然对象都得到了,那就是赋什么值就是显示什么了。再接着的就是把这个视图对象添加到mapview中去,当然添加过程中还是要一些参数的,我们还是要查查看资料。
给出弹出框的布局文件,可以看看:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/balloon_main_layout" android:orientation="vertical" android:paddingBottom="5dip" android:paddingTop="5dip" android:paddingLeft="10dip" android:background="@drawable/tooltip" android:paddingRight="10dip" > <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/balloon_item_favorite" android:background="@drawable/empty_star" android:layout_alignParentRight="true"></ImageView> <TextView android:layout_height="wrap_content" android:layout_width="wrap_content" android:id="@+id/balloon_item_title" android:text="balloon_item_title" android:textSize="15dip" android:textColor="#FF000000" android:bufferType="spannable" android:layout_toLeftOf="@+id/balloon_item_favorite" android:layout_alignParentLeft="true"></TextView> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/balloon_item_moreinfo" android:bufferType="spannable" android:layout_toLeftOf="@+id/balloon_item_snippet" android:layout_below="@+id/balloon_item_favorite" android:layout_alignRight="@+id/balloon_item_favorite" android:text="@string/moreinfo" android:layout_marginTop="20dip" android:paddingTop="20dip" android:paddingLeft="5dip" android:paddingBottom="10dip"></TextView> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/balloon_item_alerts" android:bufferType="spannable" android:layout_toLeftOf="@+id/balloon_item_snippet" android:layout_below="@+id/balloon_item_moreinfo" android:layout_alignRight="@+id/balloon_item_moreinfo" android:text="@string/noalerts" android:layout_marginTop="10dip" android:paddingTop="10dip" android:paddingLeft="5dip" android:paddingBottom="10dip"> </TextView> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/balloon_item_report" android:bufferType="spannable" android:layout_alignRight="@+id/balloon_item_favorite" android:layout_below="@+id/balloon_item_alerts" android:text="@string/reportproblem" android:layout_marginTop="10dip" android:paddingTop="5dip" android:paddingLeft="5dip" android:paddingBottom="10dip"></TextView> <TextView android:layout_height="wrap_content" android:layout_width="wrap_content" android:id="@+id/balloon_item_snippet" android:text="balloon_item_snippet" android:textSize="18dip" android:textColor="#FF000000" android:bufferType="spannable" android:layout_below="@+id/balloon_item_title" android:layout_toLeftOf="@+id/balloon_item_report" android:layout_alignLeft="@+id/balloon_item_title" ></TextView> </RelativeLayout>
public MyOverlay(Drawable defaultMarker,Context context,MapView mapView) { super(boundCenterBottom(defaultMarker),mapView); this.context = context; this.mapView=mapView; //NOTE: remember to set updateable! this.setOnFocusChangeListener(new OnFocusChangeListener() { //如果点击的焦点变化了之后,就进入这个函数 @Override public void onFocusChanged(ItemizedOverlay overlay,OverlayItem newFocus) { //if you click on a bus, it would normally draw the selected bus without this code //but in certain cases (you click away from any bus, then click on the bus again) it got confused and didn't draw //things right. This corrects that (hopefully) setLastFocusedIndex(NOT_SELECTED); setFocus((BusOverlayItem)newFocus); if (newFocus == null) { hideBalloon();//点击的一个地方看看会不会有这个OverlayItem,如果没有就把提示框消失掉 } } }); }