2011年7月28日 星期四

在 MapView 中新增一個 View

當點擊地標後,如果需要顯示一個按鈕,那就需要另外加入一個包含著按鈕的 View ,而在本篇則會記錄一下如何利用 Layout 產生一個客製化的 View ,並加入至 MapView 中顯示。

Layout 部分 pop.xml 原始碼 :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView android:layout_height="wrap_content" android:text="TextView" android:layout_width="wrap_content" android:id="@+id/textView1"></TextView>
<Button android:text="Button" android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>

</LinearLayout>
首先必須先建立一個 Layout ,之後將在主程式內製成一個客製化的 View ,以用來點擊地標後顯示;這個 Layout 可以直接利用 XML 編寫,或是利用 Eclipse 圖形介面做設計。




exMap 原始碼 :
public class exMap extends MapActivity {
/** Called when the activity is first created. */
GeoPoint mGeoPoint01,mGeoPoint02;
ArrayList<OverlayItem> items = new ArrayList<OverlayItem>();
Context mContext;
View popView;
MapController mMapController;
MapView mMapView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

CreatPopView();

mMapView = (MapView)findViewById(R.id.mapview);
mMapView.addView(popView,new MapView.LayoutParams(MapView.LayoutParams.WRAP_CONTENT,MapView.LayoutParams.WRAP_CONTENT, null, MapView.LayoutParams.BOTTOM_CENTER));
mMapView.setBuiltInZoomControls(true);
mMapView.setTraffic(false);
mMapController = mMapView.getController();
mMapController.setZoom(17);
mGeoPoint01 = new GeoPoint(24121194,120675526);
mGeoPoint02 = new GeoPoint(24123689,120672358);
mMapController.animateTo(mGeoPoint01);


List<Overlay> list = mMapView.getOverlays();
MyOverlay mOverlay = new MyOverlay(getResources().getDrawable(R.drawable.icon),this);

OverlayItem mOverlayItem01 = new OverlayItem(mGeoPoint01,"這裡是地標01","點擊地標");
OverlayItem mOverlayItem02 = new OverlayItem(mGeoPoint02,"這裡是地標02","點擊地標");
mOverlay.addItem(mOverlayItem01);
mOverlay.addItem(mOverlayItem02);
list.add(mOverlay);
}

@Override
protected boolean isRouteDisplayed() {
// TODO Auto-generated method stub
return false;
}

public void CreatPopView(){
popView = LayoutInflater.from(this).inflate(R.layout.pop, null);
Button btn = (Button) popView.findViewById(R.id.button1);
btn.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v){
popView.setVisibility(View.GONE);
}
});
popView.setVisibility(View.GONE);
}

class MyOverlay extends ItemizedOverlay<OverlayItem>{
public MyOverlay(Drawable defaultMarker,Context context) {
super(boundCenterBottom(defaultMarker));
mContext = context;
}

@Override
protected OverlayItem createItem(int i) {
// TODO Auto-generated method stub
return items.get(i);
}

@Override
public int size() {
// TODO Auto-generated method stub
return items.size();
}

@Override
protected boolean onTap(int index) {
popView.setVisibility(View.VISIBLE);
MapView.LayoutParams geoLP = (MapView.LayoutParams)popView.getLayoutParams();
Button btn = (Button)popView.findViewById(R.id.button1);
TextView text = (TextView)popView.findViewById(R.id.textView1);

geoLP.point = items.get(index).getPoint();
geoLP.x=15;
geoLP.y=-40;
btn.setText("PUSH");
text.setText(items.get(index).getTitle());
text.setTextColor(Color.MAGENTA);
mMapController.animateTo(items.get(index).getPoint());
mMapView.updateViewLayout(popView, geoLP);
return true;
}

public void addItem(OverlayItem item){
items.add(item);
populate();
}
}
}
在主程式這邊,首先要把剛剛的 Layout 新建為一個自訂的 View ;做法則是利用 LayoutInflater 類別,用法如下程式碼,from(this) 是指定目前使用的這個 context,inflate() 方法將 reslurce 中的 pop.xml 這個 layout 格式製成一個 View , 指定的 root View 為 null ,代表使用這個製成的 View 做為 root。
popView = LayoutInflater.from(this).inflate(R.layout.pop, null);

接著就可以取得 popView 裡的物件來使用,並監聽與設定按鈕按下時該做的動作,在這邊設定為將按鈕按下後即不顯示 popView。在程式初始後沒多久,就可以靠著呼叫 CreatPopView() 這個自訂方法來創建 popView 物件,不過 popView 物件雖然已經建立,但是在創建的初始值中,是將這個 View 設為不顯示,所以在程式執行後是看不到這個建立的 View,直到點擊地標後才會顯示。

為了在點擊地標後能夠控制顯示在 MapView 中的位置,所以在創建 MapView 後還必須將 popView 物件加入,並加入 MapView 相關 Layout 參數,之後才能夠在地圖上指定顯示位置。


接著就需要來看點擊地標後的執行動作,較為重要的是取得 MapView 的 LayoutParams ,利用取得的 LayoutParams 就可以設定顯示在地圖上的哪個位置,設定的方式可以利用經緯度也可以利用 GeoPoint ,這邊的例子使用的是 GeoPoint。

點擊地標後可以利用 getPoint() 取得點擊的地標位置,並回傳給 geoLP 這個 LayoutParams 物件的 point ,之後可以用 geoLP.x 和 geoLP.y 設定其 x、y座標的位移,達成控制顯示在螢幕上的位置。

在這順便記錄一下 Android 的繪圖座標系統,螢幕左上角為原點 (0,0) ,往右 X 值增加,往下 Y 值增加,以剛剛所提到的 geoLP 為例,當取得地標的 point 位置時,如果要將 PopView 放置在地標上方,則 Y 值必須減少,又因為 geoLP.x 和 geoLP.y 為 popView 與 MapView 的相對位置,所以只需要填寫差距值即可。


執行畫面 :

X 與 Y 皆無設定的狀態


X 與 Y 皆設為 0 ,與上圖比較可看出預設值即為0


當 X 為正值,Y為負值時,View則往右上角移動

如果要改變點擊地標產生的畫面,可以輕易的改變 Layout 來完成

0 意見:

張貼留言

Twitter Delicious Facebook Digg Stumbleupon Favorites More

 
Powered by Blogger