我正在寫一個Android應用程序,我想盡快地圖已經加載zoomIn。 我得到以下錯誤:我應該在哪裏放縮放在我的MapActivity中?
java.lang.IllegalArgumentException: width and height must be > 0
這MapActivity - width and height must be > 0問題提出的問題是zoomIn()方法是在onCreate()方法。 但是,當我將它放入onResume()方法時,我得到同樣的錯誤。
我一直在尋找的小時,我找不到任何關於它在http://developer.android.com或其他地方... 此外,我找不到方法來獲取地圖已加載的時間點。 A 「MapLoadedListener」 或類似的東西...
編輯這裏是我的代碼:
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's 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's location as map's 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);
}
}
}
最後編輯: 我結束了使用此代碼。我想反覆放大,所以我使用了一個處理程序和一個從onWindowFocusChanged開始每1500ms調用一次的runnable。那裏的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's location as map's 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);
}
}
剛試過我得到了同樣的錯誤。我應該做一些特定的操作來將mapView附加到窗口中嗎? – Johny
真的很確定你不把zoomIn叫做其他地方嗎?它適用於我的三星Nexus S.一個黑客解決方案將設置一個定時器,每隔一秒會觸發,直到MapView具有寬度和高度。 –
嘿!是的,我不會在其他地方撥打zoomIn。我確實設置了一個Timer,並且我始終得到值爲-1的MapView的寬度和高度,即使地圖顯示正確。 – Johny