jjzjj

android - 重绘/刷新逐项叠加? (安卓/谷歌地图 API)

coder 2023-11-19 原文

我正在使用谷歌地图 API 制作 GPS 跟踪器,并使用 ItemizedOverylay 在 map 上显示用户当前位置。随着用户位置的定期变化,我设置了一个 CountDownTimer 来删除当前的 ItemizedOverlay 并每 5 秒在新位置添加一个新的(无法更改 itemizedOverlay 的位置)但是屏幕没有绘制除非我实际触摸屏幕,否则新位置!这是我的逐项叠加层的代码:

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();
}

}

有谁知道当我放入新项目时是否有方法或东西可以调用以强制重绘/刷新?

编辑:这是 MapsActivity 的 fragment :

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);*/

    }

    }
}

最佳答案

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

关于android - 重绘/刷新逐项叠加? (安卓/谷歌地图 API),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6014987/

有关android - 重绘/刷新逐项叠加? (安卓/谷歌地图 API)的更多相关文章

  1. ruby-on-rails - ActionController::RoutingError: 未初始化常量 Api::V1::ApiController - 2

    我有用于控制用户任务的Rails5API项目,我有以下错误,但并非总是针对相同的Controller和路由。ActionController::RoutingError:uninitializedconstantApi::V1::ApiController我向您描述了一些我的项目,以更详细地解释错误。应用结构路线scopemodule:'api'donamespace:v1do#=>Loginroutesscopemodule:'login'domatch'login',to:'sessions#login',as:'login',via::postend#=>Teamroutessc

  2. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  3. ruby-on-rails - Mandrill API 模板 - 2

    我正在使用Mandrill的RubyAPIGem并使用以下简单的测试模板:testastic按照Heroku指南中的示例,我有以下Ruby代码:require'mandrill'm=Mandrill::API.newrendered=m.templates.render'test-template',[{:header=>'someheadertext',:main_section=>'Themaincontentblock',:footer=>'asdf'}]mail(:to=>"JaysonLane",:subject=>"TestEmail")do|format|format.h

  4. ruby-on-rails - 在 Ruby (on Rails) 中使用 imgur API 获取图像 - 2

    我正在尝试使用Ruby2.0.0和Rails4.0.0提供的API从imgur中提取图像。我已尝试按照Ruby2.0.0文档中列出的各种方式构建http请求,但均无济于事。代码如下:require'net/http'require'net/https'defimgurheaders={"Authorization"=>"Client-ID"+my_client_id}path="/3/gallery/image/#{img_id}.json"uri=URI("https://api.imgur.com"+path)request,data=Net::HTTP::Get.new(path

  5. 安卓apk修改(Android反编译apk) - 2

    最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路

  6. ruby-on-rails - 使用 HTTParty 的非常基本的 Rails 4.1 API 调用 - 2

    Rails相对较新。我正在尝试调用一个API,它应该向我返回一个唯一的URL。我的应用程序中捆绑了HTTParty。我已经创建了一个UniqueNumberController,并且我已经阅读了几个HTTParty指南,直到我想要什么,但也许我只是有点迷路,真的不知道该怎么做。基本上,我需要做的就是调用API,获取它返回的URL,然后将该URL插入到用户的数据库中。谁能给我指出正确的方向或与我分享一些代码? 最佳答案 假设API为JSON格式并返回如下数据:{"url":"http://example.com/unique-url"

  7. ruby-on-rails - 是否使用 API - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我的公司有一个巨大的数据库,该数据库接收来自多个来源的(许多)事件,用于监控和报告目的。到目前为止,数据中的每个新仪表板或图形都是一个新的Rails应用程序,在巨大的数据库中有额外的表,并且可以完全访问数据库内容。最近,有一个想法让外部(不是我们公司,而是姊妹公司)客户访问我们的数据,并且决定我们应该公开一个只读的RESTfulAPI来查询我们的数据。我的观点是-我们是否也应该为我们的自己

  8. ruby - Ruby 中的必应搜索 API - 2

    我读了"BingSearchAPI-QuickStart"但我不知道如何在Ruby中发出这个http请求(Weary)如何在Ruby中翻译“Stream_context_create()”?这是什么意思?"BingSearchAPI-QuickStart"我想使用RubySDK,但我发现那些已被弃用前(Rbing)https://github.com/mikedemers/rbing您知道Bing搜索API的最新包装器(仅限Web的结果)吗? 最佳答案 好吧,经过一个小时的挫折,我想出了一个办法来做到这一点。这段代码很糟糕,因为它是

  9. python - 用于 Python 或 Ruby 的 Amazon Book API? - 2

    这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:AmazonAPIlibraryforPython?我正在寻找一个AmazonAPI,它可以让我:按书名或作者查找书籍显示书籍封面获取有关每本书的信息(价格、评级、评论数、格式、页数等)Python或Ruby库都可以(我只想要最容易使用的库)。有什么建议么?我知道在SO上还有其他一些关于此的帖子,但这些API似乎很快就过时了。[几个月前我尝试了几个建议的Ruby库,但无法让它们中的任何一个工作。]

  10. ruby-on-rails - 使用 gmaps4rails 动态加载谷歌地图标记 - 2

    如何只加载map边界内的标记gmaps4rails?当然,在平移和/或缩放后加载新的。与此直接相关的是,如何获取map的当前边界和缩放级别? 最佳答案 我是这样做的,我只在用户完成平移或缩放后替换标记,如果您需要不同的行为,请使用不同的事件监听器:在你看来(index.html.erb):{"zoom"=>15,"auto_adjust"=>false,"detect_location"=>true,"center_on_user"=>true}},false,true)%>在View的底部添加:functiongmaps4rail

随机推荐