Где я должен поместить zoomIn в мою MapActivity?

1

Я пишу приложение для Android, и я хотел бы увеличить масштаб, как только карта будет загружена. Я получаю следующую ошибку:

java.lang.IllegalArgumentException: width and height must be > 0

Эта MapActivity - ширина и высота должны быть> 0 вопроса, говорит о том, что проблема заключается в методе zoomIn() в методе onCreate(). Но я получаю такую же ошибку, когда я помещаю ее в метод onResume().

Я искал часы, и я не могу найти ничего об этом на http://developer.android.com или в другом месте... Также я не могу найти способ получить временную точку, в которую была загружена карта, "MapLoadedListener" или что-то в этом роде...

EDIT Вот мой код:

public class AMap extends MapActivity{

private final String LOG_TAG = this.getClass().getSimpleName();
private Context mContext;
private Chronometer timer;
private TextView tvCountdown;
private RelativeLayout rl;
private MapView mapView;
private MapController mapController;
private List<Overlay> mapOverlays;
private PlayersOverlay playersOverlay;
private Drawable drawable;      
private Builder endDialog;
private ContextThemeWrapper ctw;
private Handler mHandler = new Handler();
private Player player = new Player();
private StartTask startTask;
private EndTask endTask;    
private MyDBAdapter mdba;
private Cursor playersCursor; 
private UpdateBroadcastReceiver r;  


@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.map_view);
    mContext = AMap.this;

    // set map
    mapView = (MapView) findViewById(R.id.mapview);
    mapView.setBuiltInZoomControls(true);
    mapView.setFocusable(true);   

    // find the relative layout
    rl = (RelativeLayout) findViewById(R.id.rl);        

    // set the chronometer
    timer = (Chronometer) findViewById(R.id.tv_timer);
    timer.setBackgroundColor(Color.DKGRAY);

    // set the countdown textview
    tvCountdown = (TextView) findViewById(R.id.tv_countdown);


    // Open DB connection and get players Cursor
    mdba = new MyDBAdapter(mContext); 
    mdba.open();
    playersCursor = mdba.getGame();

    // Get this player id and location
    Intent starter = this.getIntent();
    player.setId(starter.getIntExtra("id", 0));
    player.setLatitude(starter.getDoubleExtra("lat", 0));
    player.setLongitude(starter.getDoubleExtra("lon", 0));  

    // Set this player location as map center
    GeoPoint geoPoint = new GeoPoint((int) (player.getLatitude()*1E6), (int) (player.getLongitude()*1E6));      
    mapController = mapView.getController();
    mapController.setCenter(geoPoint);      
    mapController.setZoom(15);

    Log.d(LOG_TAG, "My playersCursor has "+playersCursor.getCount()+" rows");    
    // drawable is needed but not used
    drawable = this.getResources().getDrawable(R.drawable.ic_launcher);

    // set PlayersOverlay (locations and statuses)
    playersOverlay = new PlayersOverlay(player.getId(), playersCursor, drawable, this);  
    mapOverlays = mapView.getOverlays();
    mapOverlays.add(playersOverlay);  

    mHandler.postDelayed(mUpdateTimeTask, 100);        
}



private Runnable mUpdateTimeTask = new Runnable() {
   public void run() {
       int h = mapView.getLayoutParams().height;
       int w = mapView.getLayoutParams().width;
       Log.d(LOG_TAG, "w = "+w+" , h = "+h);         
       mHandler.postAtTime(this, SystemClock.elapsedRealtime() + 1000);
   }
};



 @Override
 public void onAttachedToWindow(){
        Log.d(LOG_TAG, "Attached to Window");
        int h = mapView.getLayoutParams().height;
        int w = mapView.getLayoutParams().width;
        Log.d(LOG_TAG, " Attached to window: w = "+w+" , h = "+h);
        //mapController.zoomInFixing(screenPoint.x, screenPoint.y);
 }



 public void onWindowFocusChanged(boolean hasFocus){
        Log.d(LOG_TAG, "Focus changed to: "+hasFocus);
        int h = mapView.getLayoutParams().height;
        int w = mapView.getLayoutParams().width;
        Log.d(LOG_TAG, " Window focus changed: w = "+w+" , h = "+h);
        //mapController.zoomInFixing(screenPoint.x, screenPoint.y);
 }



@Override
protected void onStart(){
    super.onStart();

    // Create and register the broadcast receiver for messages from service
    IntentFilter filter = new IntentFilter(AppConstants.iGAME_UPDATE);
    r = new UpdateBroadcastReceiver();
    registerReceiver(r, filter);     


    // Create the dialog for end of game
    ctw = new ContextThemeWrapper(mContext, android.R.style.Theme_Translucent_NoTitleBar_Fullscreen);
    endDialog = new AlertDialog.Builder(ctw);
    endDialog.setMessage("End of Game");
    endDialog.setCancelable(false);
    endDialog.setNeutralButton("OK", new OnClickListener(){

        @Override
        public void onClick(DialogInterface dialog, int which) {
            Intent highScores = new Intent(AMap.this, HighScores.class);
            startActivity(highScores);                      
            playersCursor.close();
            finish();               
        }

    });

}



@Override
protected void onStop() {       

    if(!playersCursor.isClosed())
        playersCursor.close();

    unregisterReceiver(r);
    mdba.close();       
    super.onStop();
}



@Override
protected boolean isRouteDisplayed() {
    return false;
}



// Receives signal from NetworkService that DB has been updated
public class UpdateBroadcastReceiver extends BroadcastReceiver {

    boolean startSignal, update, endSignal;

    @Override
    public void onReceive(Context context, Intent intent) {

        endSignal = intent.getBooleanExtra("endSignal", false);
        if(endSignal){
            Log.d(LOG_TAG, "Game Update BroadcastReceiver received End Signal");
            endTask = new EndTask();
            endTask.execute();  
            return;
        }


        update = intent.getBooleanExtra("update", false);
        if(update){
            Log.d(LOG_TAG, "Game Update BroadcastReceiver received game update");
            playersCursor.requery();
            mapView.invalidate();
            return;
        }


        startSignal = intent.getBooleanExtra("startSignal", false);
        if(startSignal){                
            Log.d(LOG_TAG, "Game Update BroadcastReceiver received Start Signal");
            startTask = new StartTask();
            startTask.execute();        
            return;
        }
    }
}



class StartTask extends AsyncTask<Void,Integer,Void>{

    private final ToneGenerator tg = new ToneGenerator(AudioManager.STREAM_NOTIFICATION, 100);
    private final long DELAY = 1200;

    @Override
    protected Void doInBackground(Void... params) {

        int i = 3;
        while(i>=0){

            publishProgress(i);
            try {
                Thread.sleep(DELAY);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            i--;
        }

        return null;
    }


    @Override
    protected void onProgressUpdate(Integer... progress){

        tg.startTone(ToneGenerator.TONE_PROP_PROMPT);
        tvCountdown.setText(""+progress[0]);
    }


    @Override
    protected void onPostExecute(Void result) {         
        rl.removeView(tvCountdown);
        timer.setBase(SystemClock.elapsedRealtime());
        timer.start();
        //enable screen touches
        playersOverlay.setGameStarted(true);
    }       
}



class EndTask extends AsyncTask<Void,Void,Void>{

    @Override
    protected void onPreExecute(){
        //disable screen touches
        playersOverlay.setEndOfGame(true);
        timer.stop();
    }

    @Override
    protected Void doInBackground(Void... params) {
        return null;
    }

    @Override
    protected void onPostExecute(Void result) {         
        try{
            endDialog.show();
        }catch(Exception e){
            Toast.makeText(mContext, "End of game", Toast.LENGTH_LONG);
            Intent highScores = new Intent(AMap.this, HighScores.class);
            startActivity(highScores);                      
            playersCursor.close();
            finish();
        }
        mHandler.removeCallbacks(mUpdateTimeTask);
    }
}

}

ЗАКЛЮЧИТЕЛЬНЫЙ РЕДАКТ: Я закончил использовать этот код. Я хотел многократно увеличивать масштаб, поэтому я использую обработчик и runnable, который вызывает себя каждые 1500 мс, начиная с onWindowFocusChanged. Там MapView имеет определенные положительные значения для ширины и высоты. OnAttachedToWindow может не работать, потому что он возвращает 0 для ширины и высоты.

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.map_view);
    mContext = AMap.this;

    // set map
    mapView = (MapView) findViewById(R.id.mapview);
    mapView.setBuiltInZoomControls(true);
    mapView.setFocusable(true);   


    // Set this player location as map center
    geoPoint = new GeoPoint((int) (37.974718*1E6), (int) (23.733684*1E6));  
    projection = mapView.getProjection();
    screenPoint = new Point();
    projection.toPixels(geoPoint, screenPoint);
    mapController = mapView.getController();
    mapController.setCenter(geoPoint);      
    mapController.setZoom(1);

    // drawable is needed but not used  
    Timer t = new Timer();
    HTask ht  = new HTask();
    t.schedule(ht, 15000);

}


 public void onWindowFocusChanged(boolean hasFocus){
        Log.d(LOG_TAG, "Focus changed to: "+hasFocus+" ("+i+")");       
        int h = mapView.getHeight();
        int w = mapView.getWidth();
        Log.d(LOG_TAG, " Window focus changed: w = "+w+" , h = "+h);
        if(w > 0 && h > 0)  {           
            mHandler.postDelayed(mUpdateTimeTask, 100); 
        }           
 }



private Runnable mUpdateTimeTask = new Runnable() {
   public void run() {
        int h = mapView.getHeight();
        int w = mapView.getWidth();
        if(h>0 && w>0){   
                mapController.zoomIn();
                mapController.animateTo(geoPoint);
                mHandler.postAtTime(this, SystemClock.uptimeMillis() + 1500);
        }

   }
};


class HTask extends TimerTask{

    @Override
    public void run() {
        mHandler.removeCallbacks(mUpdateTimeTask);          
    }   
}
Теги:
google-maps
zoom
loading
map

1 ответ

1
Лучший ответ

Просто переопределите onAttachedToWindow() вашей MapActivity, увеличьте масштаб, и все будет хорошо. Он вызывается, если MapView привязан к окну, а thethefore имеет ширину и высоту

Изменить из-за обновления кода:

Я не смущаюсь. вот некоторые вещи, я бы изменился, потому что они выглядят странно для меня:

private Runnable mUpdateTimeTask = new Runnable() {
   public void run() {
       //WHY you asking LayoutPARAMS for their dimensions? try this:
       int h = mapView.getHeight();
       int w = mapView.getWidth();
       Log.d(LOG_TAG, "w = "+w+" , h = "+h);         
       mHandler.postAtTime(this, SystemClock.elapsedRealtime() + 1000);
   }
 };

тоже самое:

@Override
public void onAttachedToWindow(){
    Log.d(LOG_TAG, "Attached to Window");
    int h = mapView.getHeight();
    int w = mapView.getWidth();
    Log.d(LOG_TAG, " Attached to window: w = "+w+" , h = "+h);
    //mapController.zoomInFixing(screenPoint.x, screenPoint.y);
}
public void onWindowFocusChanged(boolean hasFocus){
    ....

также, я не вижу, что вы вызываете zoomIn в любом месте

  • 0
    Только что попробовал, я получаю ту же ошибку. Должен ли я сделать что-то конкретное, чтобы прикрепить mapView к окну?
  • 0
    действительно уверены, что вы не называете zoomIn везде? Это работает для меня на моем Samsung Nexus S. Решением Hackish будет настройка таймера, который будет срабатывать каждую секунду, пока MapView не будет иметь ширину и высоту.
Показать ещё 4 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню