重绘/刷新Itemizedoverlay? (安卓/谷歌地图API)地图、Itemizedoverlay、API

2023-09-06 02:39:00 作者:如果二请深二

我正在使用谷歌地图API的一个GPS跟踪器和显示用户使用ItemizedOverylay地图当前位置。随着用户位置的定期更换,我已经设置了一个CountDownTimer删除当前Itemizedoverlay并增加在新的位置每5秒(有没有办法改变的itemizedOverlay的位置),一个新的,但屏幕不绘制新的位置,除非是我身体触摸屏!这里是code我逐项叠加:

 进口的java.util.ArrayList;
进口的java.util.List;

进口android.app.AlertDialog;
进口android.content.Context;
进口android.graphics.drawable.Drawable;
进口android.widget.Toast;

进口com.google.android.maps.ItemizedOverlay;
进口com.google.android.maps.OverlayItem;

公共类HelloItemizedOverlay扩展ItemizedOverlay {
私人的ArrayList< OverlayItem> mOverlays =新的ArrayList< OverlayItem>();
语境mContext;

公共HelloItemizedOverlay(可绘制defaultMarker){
    / *这传递defaultMarker到默认的构造函数
     *开往它的坐标然后初始化mContext给定的背景下。* /
    超(boundCenterBottom(defaultMarker));
}
公共HelloItemizedOverlay(可绘制defaultMarker,上下文语境){
    / *这传递defaultMarker到默认的构造函数
     *开往它的坐标然后初始化mContext给定的背景下。* /
    超(boundCenterBottom(defaultMarker));
      mContext =背景;
}
@覆盖
受保护的布尔中的onTap(INT指数){
/ *本使用成员android.content.Context创建
 *新的AlertDialog.Builder并使用窃听OverlayItem的标题
 *和片段的对话框的标题和消息文本。 (你会看到
 * OverlayItem标题和摘要,当您在下面创建定义。)* /

  OverlayItem项目= mOverlays.get(指数);
  AlertDialog.Builder对话框=新AlertDialog.Builder(mContext);
  dialog.setTitle(item.getTitle());
  dialog.setMessage(item.getSnippet());
  dialog.show();
  返回true;
}
公共无效addOverlay(OverlayItem叠加){
    mOverlays.add(叠加);
    / *每次添加一个新的OverlayItem到ArrayList,你必须
     *调用填充()为ItemizedOverlay,这将读取每个
     *所述OverlayItems和$ P $的ppare他们要绘制。* /
    填充();
}
公共无效addOverlayList(名单< OverlayItem> overlayitems){
    对象温度[] = overlayitems.toArray();
    尝试{
        的for(int i = 0; I< temp.length;我++)
        {
            mOverlays.add((OverlayItem)临时[I]);
        }
    }赶上(误差e)
    {
        Toast.makeText(mContext,添加覆盖时,出事了:+ e.getMessage()
                Toast.LENGTH_LONG).show();
    }

    填充();
}
公共无效removeOverlayList(名单< OverlayItem> overlayitems){
    对象温度[] = overlayitems.toArray();
    尝试{
        的for(int i = 0; I< temp.length;我++)
        {
            mOverlays.remove((OverlayItem)临时[I]);
        }
    }赶上(误差e)
    {
        Toast.makeText(mContext,添加覆盖时,出事了:+ e.getMessage()
                Toast.LENGTH_LONG).show();
    }

    填充();
}
公共无效removeOverlay(OverlayItem叠加){
    mOverlays.remove(叠加);
    填充();
}
公共无效doPopulate()
{
    填充();
}

@覆盖
保护OverlayItem createItem中(int i)以{
    // TODO自动生成方法存根
    返回mOverlays.get(ⅰ);
}

@覆盖
公众诠释大小(){
    / *您还必须重写size()方法返回当前的
     * ArrayList中的项目数量:* /
    返回mOverlays.size();
}

}
 

有谁知道是否有一种方法或东西,我可以打电话强制重绘/刷新时,我把新的产品?

编辑:这里是MapsActivity的一个片段:

 公共类HelloGoogleMaps扩展MapActivity {

/ ************
 *地图的东西
 ***** /


HelloItemizedOverlay myPosition;
图形页面图形页面;
MapController mapController;
名单<覆盖> mapOverlays;

OverlayItem myPositionOverlayItem;

公共双myLatitude = 0;
公共双myLongitude = 0;
公共双myCoarseLatitude = 0;
公共双myCoarseLongitude = 0;

公共布尔isGPS;
公共布尔isGPSFix;
公共布尔useGPSLocation;
公共布尔useNetworkLocation;

众长mLastLocationMillis; //最后接触的GPS系统时间
/ *布尔值,所以当GPS获取您的位置将放大到你在哪里,
 *但只会做一次(一旦它被设置为true)* /
布尔pickedUpLocation;

公共mycount的计数器; //用于定时事件


/ **第一次创建活动时调用。 * /
@覆盖
公共无效的onCreate(包savedInstanceState){
    super.onCreate(savedInstanceState);
    的setContentView(R.layout.mymapview);
    pickedUpLocation = FALSE;



    图形页面=(图形页面)findViewById(R.id.mapview);
    mapView.setBuiltInZoomControls(真正的);
    mapView.setStreetView(真正的);
    / * mapcontroller控制变焦等* /
    mapController = mapView.getController();

    mapOverlays =调用MapView.getOverlays();
    可绘制my_icon = this.getResources()getDrawable(R.drawable.androidmarker_teacher)。
    myPosition =新HelloItemizedOverlay(my_icon,这一点);
    itemizedoverlay =新HelloItemizedOverlay(绘制,这一点);
    / *在地图上覆盖的所有元素通过的MapView持有,所以当你
     *要增加一些,你必须得到来自getOverlays()方法的列表。
     *然后实例用于地图标记的绘制对象,这是保存在
     *在RES /绘制/目录。该构造HelloItemizedOverlay
     *(您的自定义ItemizedOverlay)主罚绘制对象,以设置
     *默认标记所有覆盖项目。* /

    / *初始化GPS * /
    尝试{
    LocationManager mlocManager =(LocationManager)getSystemService(Context.LOCATION_SERVICE);

    LocationListener的mlocListener =新MyLocationListener();
    //获取精确的位置信息
    mlocManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,0,0,mlocListener);
    //获取粗略的位置
    mlocManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,0,0,mlocListener);
    布尔isGPS = mlocManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
    MyGPSListener myGPSListener =新MyGPSListener();
    mlocManager.addGpsStatusListener(myGPSListener);
    }
    赶上(误差e)
    {
        Toast.makeText(getApplicationContext(),错误!+ e.getMessage(),Toast.LENGTH_SHORT).show();
    }


    的GeoPoint点=新的GeoPoint((INT)(myCoarseLatitude * 1e6个),(INT)(myCoarseLongitude * 1e6个));
    myPositionOverlayItem =新OverlayItem(点!晚报guvna,这是我在哪里);



    / *剩下的就是这个OverlayItem添加到您的收藏中
     * HelloItemizedOverlay实例,则HelloItemizedOverlay添加到的MapView:* /
    myPosition.addOverlay(myPositionOverlayItem);
    mapOverlays.add(myPosition);
    / *开始计数5秒更新位置* /
    计数器=新mycount的(5000,1000);
    counter.start();
}

@覆盖
保护的布尔isRouteDisplayed(){
    // TODO自动生成方法存根
    返回false;
}
公共无效updateMyPosition()
{
    / *删除我的家伙* /
    。调用MapView.getOverlays()删除(myPosition);
    myPosition.removeOverlay(myPositionOverlayItem);
    myPosition.doPopulate();

    的GeoPoint点;
    如果(useGPSLocation)
    {
        点=新的GeoPoint((INT)(myLatitude * 1e6个),(INT)(myLongitude * 1e6个));
    }
    其他
    {
        点=新的GeoPoint((INT)(myCoarseLatitude * 1e6个),(INT)(myCoarseLongitude * 1e6个));
    }


    myPositionOverlayItem =新OverlayItem(点,你在这里,噢耶!);
    myPosition.addOverlay(myPositionOverlayItem);
    myPosition.doPopulate();
    mapOverlays.add(myPosition);
}

公共无效clearTheMap()
{
    调用MapView.getOverlays()清()。
    myPosition.doPopulate();
}


 / ******************* ******
 * 全球定位系统!!!!!!!!
 *从GPS这种方法获得你的位置
 * ************ /
公共类MyLocationListener实现LocationListener的
{

    公共无效onLocationChanged(位置LOC)
    {
        字符串商= loc.getProvider();
        如果(provider.equals(LocationManager.GPS_PROVIDER))
        {
            myLatitude = loc.getLatitude();
            myLongitude = loc.getLongitude();
            mLastLocationMillis = SystemClock.elapsedRealtime();
            如果((pickedUpLocation)及!&安培;!(myLatitude = 0))
            {
                mapController.animateTo(新的GeoPoint((int)的(myLatitude * 1e6个),(int)的(myLongitude * 1e6个)));
                pickedUpLocation =真;
            }
        }
        其他
        {
            myCoarseLatitude = loc.getLatitude();
            myCoarseLongitude = loc.getLongitude();
            如果((pickedUpLocation)及!&安培;!(myCoarseLatitude = 0))
            {
                //Toast.makeText(getBaseContext(),捡到的位置与网络 - + myCoarseLatitude ++ myCoarseLongitude,Toast.LENGTH_LONG).show();
                mapController.animateTo(新的GeoPoint((int)的(myCoarseLatitude * 1e6个),(int)的(myCoarseLongitude * 1e6个)));
                pickedUpLocation =真;
            }
        }

        / *第一次拿起您的位置将动画你在哪里* /


        / *
        字符串文本=我目前的位置是:+
        Latitud =+ loc.getLatitude()+
        Longitud =+ loc.getLongitude();

        Toast.makeText(getApplicationContext(),文本,Toast.LENGTH_SHORT).show();
        * /
    }

    公共无效onProviderDisabled(字符串提供商)
    {
        Toast.makeText(getApplicationContext(),全球定位系统已禁用,Toast.LENGTH_SHORT).show();
        myLatitude = -1;
        myLongitude = -1;
    }
    公共无效onProviderEnabled(字符串提供商)
    {
        Toast.makeText(getApplicationContext(),GPS功能的,Toast.LENGTH_SHORT).show();
        myLatitude = 0;
        myLongitude = 0;
    }

    公共无效onStatusChanged(字符串商,INT地位,捆绑演员)
    {

    }
}

/ ************
 * -GPS状态显示器 - 
 *将看看是否sattelites仍然固定到您的手机
 *如果卫星的arent可用,它需要网络(粗)的位置
 *如果修复程序获得性就会使用GPS(精)的位置
 * ************** /
私有类MyGPSListener实现GpsStatus.Listener {
    公共无效onGpsStatusChanged(INT事件){
        开关(事件){
            案例GpsStatus.GPS_EVENT_SATELLITE_STATUS:
                如果(myLatitude!= 0)
                    isGPSFix =(SystemClock.elapsedRealtime() -  mLastLocationMillis)所述; 3000;

                如果(isGPSFix){//一个修复已被收购。
                    useGPSLocation = TRUE;
                    useNetworkLocation = FALSE;
                }其他{//此修复程序已丢失。
                    useGPSLocation = FALSE;
                    useNetworkLocation = TRUE;
                }

                打破;
            案例GpsStatus.GPS_EVENT_FIRST_FIX:
                // 做一点事。
                isGPSFix = TRUE;
                useGPSLocation = TRUE;
                    useNetworkLocation = FALSE;
                打破;
        }
    }
}

/ ******************* ************
 *计数器类计时事件
 ********** /
公共类mycount的扩展CountDownTimer {

    公共mycount的(长millisInFuture,长countDownInterval){
    超(mil​​lisInFuture,countDownInterval);
    }

    @覆盖
    公共无效onFinish(){
        clearTheMap();
        updateMyPosition(); //重绘我的家伙
        myPosition.doPopulate();

        //Toast.makeText(getApplicationContext(),已发送我的位置 - 使用,Toast.LENGTH_SHORT).show();
        resetTimer();
    }

    公共无效resetTimer()
    {
        计数器=新mycount的(5000,1000);
        counter.start();
    }

    @覆盖
    公共无效onTick(长millisUntilFinished){
    /*tv.setText("Left:+ millisUntilFinished / 1000); * /

    }

    }
}
 

解决方案 networklocation

使用 mapview.invalidate()。这将最终导致重绘。

I am making a GPS tracker using google maps API and displaying the users current position on a map using ItemizedOverylay. As the users position changes regularly, I've set up a CountDownTimer to delete the current Itemizedoverlay and add a new one at the new position every 5 seconds (there is no way of changing an itemizedOverlay's position) but the screen isn't drawing the new positions unless i physically touch the screen! Here is the code for my itemized overlay:

import java.util.ArrayList;
import java.util.List;

import android.app.AlertDialog;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.widget.Toast;

import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.OverlayItem;

public class HelloItemizedOverlay extends ItemizedOverlay{
private ArrayList<OverlayItem> mOverlays = new ArrayList<OverlayItem>();
Context mContext;

public HelloItemizedOverlay(Drawable defaultMarker) {
    /*This passes the defaultMarker up to the default constructor 
     * to bound its coordinates and then initialize mContext with the given Context.*/
    super(boundCenterBottom(defaultMarker));
}
public HelloItemizedOverlay(Drawable defaultMarker, Context context) {
    /*This passes the defaultMarker up to the default constructor 
     * to bound its coordinates and then initialize mContext with the given Context.*/
    super(boundCenterBottom(defaultMarker));
      mContext = context;
}
@Override
protected boolean onTap(int index) {
/*This uses the member android.content.Context to create 
 * a new AlertDialog.Builder and uses the tapped OverlayItem's title 
 * and snippet for the dialog's title and message text. (You'll see the 
 * OverlayItem title and snippet defined when you create it below.)*/

  OverlayItem item = mOverlays.get(index);
  AlertDialog.Builder dialog = new AlertDialog.Builder(mContext);
  dialog.setTitle(item.getTitle());
  dialog.setMessage(item.getSnippet());
  dialog.show();
  return true;
}
public void addOverlay(OverlayItem overlay) {
    mOverlays.add(overlay);
    /*Each time you add a new OverlayItem to the ArrayList, you must 
     * call populate() for the ItemizedOverlay, which will read each 
     * of the OverlayItems and prepare them to be drawn.*/
    populate();
}
public void addOverlayList(List<OverlayItem> overlayitems) {
    Object temp[] = overlayitems.toArray();
    try{
        for(int i = 0;i<temp.length;i++)
        {
            mOverlays.add((OverlayItem)temp[i]);
        }
    }catch(Error e)
    {
        Toast.makeText(mContext, "Something happened when adding the overlays:"+e.getMessage() ,
                Toast.LENGTH_LONG).show();
    }

    populate();
}
public void removeOverlayList(List<OverlayItem> overlayitems) {
    Object temp[] = overlayitems.toArray();
    try{
        for(int i = 0;i<temp.length;i++)
        {
            mOverlays.remove((OverlayItem)temp[i]);
        }
    }catch(Error e)
    {
        Toast.makeText(mContext, "Something happened when adding the overlays:"+e.getMessage() ,
                Toast.LENGTH_LONG).show();
    }

    populate();
}
public void removeOverlay(OverlayItem overlay){
    mOverlays.remove(overlay);
    populate();
}
public void doPopulate()
{
    populate();
}

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

@Override
public int size() {
    /*You must also override the size() method to return the current 
     * number of items in the ArrayList:*/
    return mOverlays.size();
}

}

Does anyone know if there is a method or something I can call to force a redraw/refresh when I put the new items in?

EDIT: Here is a snippet of the MapsActivity:

public class HelloGoogleMaps extends MapActivity  {

/***************************
 * map stuff
 *****/


HelloItemizedOverlay myPosition;
MapView mapView;
MapController mapController;
List<Overlay> mapOverlays;

OverlayItem myPositionOverlayItem;

public double myLatitude = 0;
public double myLongitude = 0;
public double myCoarseLatitude = 0;
public double myCoarseLongitude = 0;

public boolean isGPS;
public boolean isGPSFix;
public boolean useGPSLocation;
public boolean useNetworkLocation;

public long mLastLocationMillis;//system time of last gps contact
/*boolean so when gps gets your location it will zoom to where you are, 
 * but will only do this once (once it's set to true)*/
boolean pickedUpLocation;

public MyCount counter;//for timing events


/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.mymapview);
    pickedUpLocation = false;



    mapView = (MapView) findViewById(R.id.mapview);
    mapView.setBuiltInZoomControls(true);
    mapView.setStreetView(true);
    /*mapcontroller controls zoom etc*/
    mapController = mapView.getController();

    mapOverlays = mapView.getOverlays();
    Drawable my_icon = this.getResources().getDrawable(R.drawable.androidmarker_teacher);
    myPosition = new HelloItemizedOverlay(my_icon, this);
    itemizedoverlay = new HelloItemizedOverlay(drawable, this);
    /*All overlay elements on a map are held by the MapView, so when you 
     * want to add some, you have to get a list from the getOverlays() method. 
     * Then instantiate the Drawable used for the map marker, which was saved in 
     * the res/drawable/ directory. The constructor for HelloItemizedOverlay 
     * (your custom ItemizedOverlay) takes the Drawable in order to set the 
     * default marker for all overlay items.*/

    /*Initialise GPS*/
    try{
    LocationManager mlocManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);

    LocationListener mlocListener = new MyLocationListener();
    //get fine location
    mlocManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, 0, 0, mlocListener);
    //get coarse location
    mlocManager.requestLocationUpdates( LocationManager.NETWORK_PROVIDER, 0, 0, mlocListener);
    boolean isGPS = mlocManager.isProviderEnabled (LocationManager.GPS_PROVIDER);
    MyGPSListener myGPSListener = new MyGPSListener();
    mlocManager.addGpsStatusListener(myGPSListener);
    }
    catch(Error e)
    {
        Toast.makeText( getApplicationContext(),"Error!"+e.getMessage(),Toast.LENGTH_SHORT).show();
    }


    GeoPoint point = new GeoPoint((int)(myCoarseLatitude * 1e6),(int) (myCoarseLongitude* 1e6));
    myPositionOverlayItem = new OverlayItem(point, "Evening guvna!", "This is where i am");



    /*All that's left is to add this OverlayItem to your collection in the 
     * HelloItemizedOverlay instance, then add the HelloItemizedOverlay to the MapView: */
    myPosition.addOverlay(myPositionOverlayItem);
    mapOverlays.add(myPosition);
    /*begin counting 5 seconds to update positions*/
    counter = new MyCount(5000,1000);
    counter.start();
}

@Override
protected boolean isRouteDisplayed() {
    // TODO Auto-generated method stub
    return false;
}
public void updateMyPosition()
{
    /*remove my guy*/
    mapView.getOverlays().remove(myPosition);
    myPosition.removeOverlay(myPositionOverlayItem);
    myPosition.doPopulate();

    GeoPoint point;
    if(useGPSLocation)
    {
        point = new GeoPoint((int)(myLatitude * 1e6),(int) (myLongitude* 1e6));
    }
    else
    {
        point = new GeoPoint((int)(myCoarseLatitude * 1e6),(int) (myCoarseLongitude* 1e6));
    }


    myPositionOverlayItem = new OverlayItem(point, "You are here", "Awww yeah!");
    myPosition.addOverlay(myPositionOverlayItem);
    myPosition.doPopulate();
    mapOverlays.add(myPosition);
}

public void clearTheMap()
{
    mapView.getOverlays().clear();
    myPosition.doPopulate();
}


 /*******************************************************
 * GPS!!!!!!!!
 * This method gets the location of you from gps
 * ************************************************/
public class MyLocationListener implements LocationListener
{

    public void onLocationChanged(Location loc)
    {
        String provider = loc.getProvider();
        if(provider.equals(LocationManager.GPS_PROVIDER))
        {
            myLatitude = loc.getLatitude();
            myLongitude = loc.getLongitude();
            mLastLocationMillis = SystemClock.elapsedRealtime();
            if((!pickedUpLocation)&&(myLatitude!=0))
            {
                mapController.animateTo(new GeoPoint((int)(myLatitude * 1e6),(int) (myLongitude* 1e6)));
                pickedUpLocation = true;
            }
        }
        else
        {
            myCoarseLatitude = loc.getLatitude();
            myCoarseLongitude = loc.getLongitude();
            if((!pickedUpLocation)&&(myCoarseLatitude!=0))  
            {
                //Toast.makeText(getBaseContext(), "picked up Location with network - "+myCoarseLatitude+" "+myCoarseLongitude, Toast.LENGTH_LONG).show();
                mapController.animateTo(new GeoPoint((int)(myCoarseLatitude * 1e6),(int) (myCoarseLongitude* 1e6)));
                pickedUpLocation = true;
            }
        }

        /*first time it picks up your location it will animate to where you are*/


        /*
        String Text = "My current location is: "+
        "Latitud = " + loc.getLatitude()+
        "Longitud = " + loc.getLongitude();

        Toast.makeText( getApplicationContext(),Text,Toast.LENGTH_SHORT).show();
        */
    }

    public void onProviderDisabled(String provider)
    {
        Toast.makeText( getApplicationContext(),"Gps Disabled",Toast.LENGTH_SHORT ).show();
        myLatitude = -1;
        myLongitude = -1;
    }
    public void onProviderEnabled(String provider)
    {
        Toast.makeText( getApplicationContext(),"Gps Enabled",Toast.LENGTH_SHORT).show();
        myLatitude = 0;
        myLongitude = 0;
    }

    public void onStatusChanged(String provider, int status, Bundle extras)
    {

    }
}

/***********************************************
 * -GPS Status monitor-
 * Will see if the sattelites are still fixed to your phone
 * If satellites arent available, it takes network (coarse) location
 * If a fix is aquired it will use GPS (fine) location 
 * **********************************/
private class MyGPSListener implements GpsStatus.Listener {
    public void onGpsStatusChanged(int event) {
        switch (event) {
            case GpsStatus.GPS_EVENT_SATELLITE_STATUS:
                if (myLatitude != 0)
                    isGPSFix = (SystemClock.elapsedRealtime() - mLastLocationMillis) < 3000;

                if (isGPSFix) { // A fix has been acquired.
                    useGPSLocation = true;
                    useNetworkLocation = false;
                } else { // The fix has been lost.
                    useGPSLocation = false;
                    useNetworkLocation = true;
                }

                break;
            case GpsStatus.GPS_EVENT_FIRST_FIX:
                // Do something.
                isGPSFix = true;
                useGPSLocation = true;
                    useNetworkLocation = false;
                break;
        }
    }
}

/*************************************************************
 * Counter class for timing events
 **********/
public class MyCount extends CountDownTimer{

    public MyCount(long millisInFuture, long countDownInterval) {
    super(millisInFuture, countDownInterval);
    }

    @Override
    public void onFinish() {
        clearTheMap();
        updateMyPosition();//redraw my guy
        myPosition.doPopulate();

        //Toast.makeText( getApplicationContext(),"Sent my position - used ",Toast.LENGTH_SHORT).show();
        resetTimer();
    }

    public void resetTimer()
    {
        counter = new MyCount(5000,1000);
        counter.start();
    }

    @Override
    public void onTick(long millisUntilFinished) {
    /*tv.setText("Left: " + millisUntilFinished/1000);*/

    }

    }
}

解决方案

Use mapview.invalidate(). This will eventually cause a redraw.