2012-04-15 26 views
0

您好我的MapView應用程序需要很長時間才能加載,所以我想在加載時顯示水平樣式的ProgressDialog。當我嘗試在onCreate/onStart方法中顯示對話框時,對話框最終顯示爲100%完成,現在我意識到這是因爲在onCreate/onStart方法之前沒有任何東西被繪製到屏幕上。如何在繪製主視圖後顯示ProgressDialog。 Android

所以我想要做的是顯示基本地圖,然後在繪製地圖後執行需求代碼,因此我還可以顯示ProgressDialog。這是可能的,如果它是如何?

在此先感謝! =]

編輯:

這裏是源代碼:

public class GoogleMapsActivity extends MapActivity { 
    private List<Overlay> mapOverlays; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 
      setContentView(R.layout.main); 

      MapView mapView = (MapView) findViewById(R.id.mapview); 
      mapView.setBuiltInZoomControls(true); 
      mapView.setSatellite(false); 
      mapView.setTraffic(false); 

      mapOverlays = mapView.getOverlays(); 

      new ProgressTask(this).execute(); 
    } 

    public void addToMap(ItemizedOverlay<OverlayItem> itemizedOverlay){ 
     mapOverlays.add(itemizedOverlay); 
    } 
} 

而且的AsyncTask類

public class ProgressTask extends AsyncTask<String, Void, Boolean> { 

    private ProgressDialog dialog; 
    private GoogleMapsActivity activity; 

    public ProgressTask(GoogleMapsActivity activity) { 
     this.activity = activity; 
     dialog = new ProgressDialog(activity); 
    } 

    @Override 
    protected void onPreExecute() { 
     dialog.setTitle("Loading Pictures"); 
     dialog.setMessage("Loading..."); 
     dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); 
     dialog.setCancelable(false); 
     dialog.show(); 
    } 

    @Override 
    protected void onPostExecute(final Boolean sucess) { 
     if (dialog.isShowing()) { 
      dialog.dismiss(); 
     } 
    } 

    @Override 
    protected Boolean doInBackground(String... args) { 
     try { 

      ArrayList<String> list = getImageLocations(); 

      String filePath; 
      String title; 

      LayerDrawable drawable; 
      ImageItemizedOverlay itemizedOverlay; 

      GeoPoint point; 
      OverlayItem overlayItem; 

      int count = 0; 

      if (list.size() > 0) { 
       dialog.setMax(list.size()); 

       for (String s : list) { 
        filePath = s; 
        point = getImageGeoPoint(s); 

        if (point != null) { 
         title = s.substring(filePath.lastIndexOf("/") + 1); 

         drawable = createLayerDrawable(filePath); 

         itemizedOverlay = new ImageItemizedOverlay(drawable, activity, filePath); 

         overlayItem = new OverlayItem(point, title, null); 

         itemizedOverlay.addOverlay(overlayItem); 
         activity.addToMap(itemizedOverlay); 
        } 
        dialog.incrementProgressBy(1); 
       } 

      } else { 
       if(dialog.isShowing()) 
        dialog.dismiss(); 

       CharSequence text = "No pictures with geolocations stored at DCIM/Camera."; 
       Toast toast = Toast.makeText(activity, text, Toast.LENGTH_LONG); 
       toast.show(); 
      } 
      CharSequence text = count + " pictures didn't have a geolocation."; 
      Toast toast = Toast.makeText(activity, text, Toast.LENGTH_LONG); 
      toast.show(); 
      return true; 
     } catch (Exception e) { 
      Log.e("tag", "error: " + e.toString(), e); 
      return false; 
     } 
    } 

    private LayerDrawable createLayerDrawable(String filePath) { 

     Bitmap bitmap = BitmapFactory.decodeFile(filePath); 
     Bitmap thumbnail = ThumbnailUtils.extractThumbnail(bitmap, 50, 50); 

     Drawable picture = new BitmapDrawable(thumbnail); 

     Drawable pin = activity.getResources() 
       .getDrawable(R.drawable.backgroundpin); 

     InsetDrawable inset = new InsetDrawable(picture, 11, 15, 11, 23); 
     Drawable[] list = { pin, inset }; 

     LayerDrawable layer = new LayerDrawable(list); 

     return layer; 
    } 

    private static GeoPoint getImageGeoPoint(String filename) { 
     GeoPoint gp = null; 
     float[] latlong = new float[2]; 

     try { 
      ExifInterface tag = new ExifInterface(filename); 

      if (tag.getLatLong(latlong)) { 
       gp = new GeoPoint((int) (latlong[0] * 1E6), 
         (int) (latlong[1] * 1E6)); 
      } else { 
       // TODO error! 
      } 

     } catch (FileNotFoundException fnf) { 
      // TODO error! 
      fnf.printStackTrace(); 
     } catch (IOException io) { 
      // TODO error! 
      io.printStackTrace(); 
     } 

     return gp; 
    } 

    private static ArrayList<String> getImageLocations() { 
     File directory = new File("mnt/sdcard/DCIM/Camera"); 

     FilenameFilter imageFilter = new FilenameFilter() { 
      public boolean accept(File dir, String name) { 
       String lowercaseName = name.toLowerCase(); 
       if (lowercaseName.endsWith(".jpg")) { 
        return true; 
       } else { 
        return false; 
       } 
      } 
     }; 

     File[] files = directory.listFiles(imageFilter); 
     ArrayList<String> paths = new ArrayList<String>(); 

     if (files != null && files.length > 0) 
      for (File f : files) { 
       paths.add(f.getAbsolutePath()); 
      } 

     return paths; 
    } 

} 
+0

你可以發佈你的源代碼,或者至少你的'onCreate'實現嗎? – 2012-04-15 20:08:33

+0

當然可以! =] – geekman92 2012-04-15 23:31:47

回答

1

如果你需要運行昂貴的代碼,應在執行後臺線程,以防止你的用戶界面鎖定。爲了顯示與此過程相關的一些UI元素,Android爲此提供了AsyncTask類。

要顯示ProgressDialog,在AsyncTask執行中實現onPreExecute()並創建並顯示對話框,然後在onPostExecute()中將其關閉。

+0

好的,謝謝我會研究這個! =] – geekman92 2012-04-15 21:17:39

+0

它非常好,非常感謝你! =] – geekman92 2012-04-15 22:18:21

+0

非常好。然而,'doInBackground'方法中的'else'語句會拋出'InvocationTargetException',因爲您不能在未創建它們的線程上更改UI元素('Toast'和'ProgressDialog')的顯示屬性。雖然,我可能會誤解'ProgressDialog' ...我想你可能會被允許從非UI線程中解僱它。 – 2012-04-16 03:19:25