在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>
以上步骤完成,我们就成功的把xml文件显示成一个弹出框 的视图了,已经添加到mapview中去了嘛。现在这个框是显示着的,那么不点击图标的时候怎么让他消失呢?我们在
busoverlay的构造函数中添加一个消息响应,焦点在图标上的时候就会显示框了,否则就隐藏掉。
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,如果没有就把提示框消失掉
}
}
});
}