在MapFragment中显示进度条

时间:2013-06-06 16:33:33

标签: android android-layout

我正在使用MapFragment在地图上显示一些POI。我不明白如何显示,以及我必须定义的进度条,以通知用户POI下载过程。我已经有了一个进度视图的代码,在XML中定义为包含ProgressBar和TextView的LinearLayout。

这是FragmentMap代码。我正在使用SherlockActionBar和Android Support v4。

public class MapFragment extends SherlockMapFragment {

private static final String TAG = MapFragment.class.getSimpleName(); 
private GoogleMap mMap;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    try {
         MapsInitializer.initialize(this.getActivity());
     } catch (GooglePlayServicesNotAvailableException e) {
         e.printStackTrace();
     }
    View root = super.onCreateView(inflater, container, savedInstanceState);
    int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getActivity().getBaseContext());
    // Showing status
    if(status==ConnectionResult.SUCCESS) {
         mMap = getMap();
    }
    else {
        int requestCode = 10;
        Dialog dialog = GooglePlayServicesUtil.getErrorDialog(status, getActivity(), requestCode);
        dialog.show();
    }

    mMap.setMyLocationEnabled(true);

    LocationManager locationManager = (LocationManager) getActivity().getSystemService(Activity.LOCATION_SERVICE);
    Criteria criteria = new Criteria();
    criteria.setAccuracy(Criteria.ACCURACY_FINE);
    String provider = locationManager.getBestProvider(criteria, true);
    Location myLocation= locationManager.getLastKnownLocation(provider);
    /*
    if(!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
        Intent gpsOptionsIntent = new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);  
            startActivity(gpsOptionsIntent);
    }
     */
    if(myLocation!=null)
        mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(myLocation.getLatitude(), myLocation.getLongitude()), 15));

    new FetchAllPoiAsyncTask().execute();
    return root;
}

private class FetchAllPoiAsyncTask extends AsyncTask<Void, Void, PoiCategory[]> {
    @Override
    protected PoiCategory[] doInBackground(Void... params) {
        // TODO Auto-generated method stub
        HttpHeaders requestHeaders= getApplicationContext().createAuthenticatedHttpHeader();

        List<MediaType> acceptableMediaTypes = new ArrayList<MediaType>();
        acceptableMediaTypes.add(MediaType.APPLICATION_JSON);
        requestHeaders.setAccept(acceptableMediaTypes);
        // Populate the headers in an HttpEntity object to use for the request
        HttpEntity<?> requestEntity = new HttpEntity<Object>(requestHeaders);
        // Create a new RestTemplate instance
        RestTemplate restTemplate = new RestTemplate(true);
        // Perform the HTTP GET request
        try {
            ResponseEntity<PoiCategory[]> poiAll = restTemplate.exchange(getActivity().getString(R.string.poiAll_url), HttpMethod.GET, requestEntity, PoiCategory[].class, "provider1234");
            return poiAll.getBody();
        }
        catch(Exception e) {
            Log.e(TAG, e.getLocalizedMessage(), e);
            return null;
        }
    }

    @Override
    protected void onPostExecute(final PoiCategory[] poiCategories) {
        if(poiCategories==null)
            Toast.makeText(getApplicationContext(), "An error occurred retrieving POIs", Toast.LENGTH_LONG).show();
        Log.d(TAG, "Retrieved "+poiCategories.length+" categories;");
        for(PoiCategory category : poiCategories) {
            Log.d(TAG, "Category "+category.getLabel()+" has "+category.getPoiList().length+" POIs;");
            Poi[] poiList = category.getPoiList();
            for(Poi poi : poiList) {
                mMap.addMarker(new MarkerOptions()
                                    .position(parsePoiPosition(poi))
                                    .title(poi.getTitle())
                                    .snippet(poi.getDescription()));
            }
        }
    }
}

private MainApplication getApplicationContext(){
    return (MainApplication) getActivity().getApplicationContext();
}

public static LatLng parsePoiPosition(Poi poi) {
    double lat = Double.parseDouble(poi.getPositionLat());
    double lng = Double.parseDouble(poi.getPositionLong());
    LatLng result = new LatLng(lat, lng);
    return result;
}
}

我在DrawerLayout中使用此MapFragment,通过片段事务动态添加它。如何在asyncTask下载POI时添加进度视图,将其设置为可见和不可见?我必须将它添加到FragmentMap或容器DrawerLayout?

修改

我尝试用这种方式修改MapFragment:

  1. 在progress_bar.xml中定义布局(稍后显示)
  2. 通过inflater.inflate()
  3. 在containerView中对其进行充气
  4. 在onPreExecute()/ onPostExecute()中设置可见/不可见
  5. 但它不起作用。未显示ProgressBar,并且在地图中显示POI后一段时间(我添加了Thread.sleep(5000)来模拟长时间的下载)

    这是FragmentMap修改过的代码。 showProgress()方法已经过测试,在另一个活动中运行良好。

    公共类MapFragment扩展了SherlockMapFragment {

    private static final String TAG = MapFragment.class.getSimpleName(); 
    private GoogleMap mMap;
    private View mDownloadProgressView;
    
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        try {
             MapsInitializer.initialize(this.getActivity());
         } catch (GooglePlayServicesNotAvailableException e) {
             e.printStackTrace();
         }
        View root = super.onCreateView(inflater, container, savedInstanceState);
    
        inflater.inflate(R.layout.progress_bar, container);
        mDownloadProgressView= (View) getActivity().findViewById(R.id.download_progress);
    
        int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getActivity().getBaseContext());
        // Showing status
        if(status==ConnectionResult.SUCCESS) {
             mMap = getMap();
        }
        else {
            int requestCode = 10;
            Dialog dialog = GooglePlayServicesUtil.getErrorDialog(status, getActivity(), requestCode);
            dialog.show();
        }
    
        mMap.setMyLocationEnabled(true);
    
        LocationManager locationManager = (LocationManager) getActivity().getSystemService(Activity.LOCATION_SERVICE);
        Criteria criteria = new Criteria();
        criteria.setAccuracy(Criteria.ACCURACY_FINE);
        String provider = locationManager.getBestProvider(criteria, true);
        Location myLocation= locationManager.getLastKnownLocation(provider);
        /*
        if(!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
            Intent gpsOptionsIntent = new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);  
                startActivity(gpsOptionsIntent);
        }
         */
        if(myLocation!=null)
            mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(myLocation.getLatitude(), myLocation.getLongitude()), 15));
    
        new FetchAllPoiAsyncTask().execute();
        return root;
    }
    
    private class FetchAllPoiAsyncTask extends AsyncTask<Void, Void, PoiCategory[]> {
    
        @Override
        protected void onPreExecute(){
            showProgress(true);
        }
    
        @Override
        protected PoiCategory[] doInBackground(Void... params) {
            // TODO Auto-generated method stub
            HttpHeaders requestHeaders= getApplicationContext().createAuthenticatedHttpHeader();
    
            List<MediaType> acceptableMediaTypes = new ArrayList<MediaType>();
            acceptableMediaTypes.add(MediaType.APPLICATION_JSON);
            requestHeaders.setAccept(acceptableMediaTypes);
            // Populate the headers in an HttpEntity object to use for the request
            HttpEntity<?> requestEntity = new HttpEntity<Object>(requestHeaders);
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            // Create a new RestTemplate instance
            RestTemplate restTemplate = new RestTemplate(true);
            // Perform the HTTP GET request
            try {
                ResponseEntity<PoiCategory[]> poiAll = restTemplate.exchange(getActivity().getString(R.string.poiAll_url), HttpMethod.GET, requestEntity, PoiCategory[].class, "provider1234");
                return poiAll.getBody();
            }
            catch(Exception e) {
                Log.e(TAG, e.getLocalizedMessage(), e);
                return null;
            }
        }
    
        @Override
        protected void onPostExecute(final PoiCategory[] poiCategories) {
            showProgress(false);
            if(poiCategories==null)
                Toast.makeText(getApplicationContext(), "An error occurred retrieving POIs", Toast.LENGTH_LONG).show();
            Log.d(TAG, "Retrieved "+poiCategories.length+" categories;");
            for(PoiCategory category : poiCategories) {
                Log.d(TAG, "Category "+category.getLabel()+" has "+category.getPoiList().length+" POIs;");
                Poi[] poiList = category.getPoiList();
                for(Poi poi : poiList) {
                    mMap.addMarker(new MarkerOptions()
                                        .position(parsePoiPosition(poi))
                                        .title(poi.getTitle())
                                        .snippet(poi.getDescription()));
                }
            }
        }
    }
    
    private MainApplication getApplicationContext(){
        return (MainApplication) getActivity().getApplicationContext();
    }
    
    public static LatLng parsePoiPosition(Poi poi) {
        double lat = Double.parseDouble(poi.getPositionLat());
        double lng = Double.parseDouble(poi.getPositionLong());
        LatLng result = new LatLng(lat, lng);
        return result;
    }
    
    /**
     * Shows the progress UI
     */
    @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
    private void showProgress(final boolean show) {
        // On Honeycomb MR2 we have the ViewPropertyAnimator APIs, which allow
        // for very easy animations. If available, use these APIs to fade-in
        // the progress spinner.
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
            int shortAnimTime = getResources().getInteger(
                    android.R.integer.config_shortAnimTime);
            mDownloadProgressView.setVisibility(View.VISIBLE);
            mDownloadProgressView.animate().setDuration(shortAnimTime)
                    .alpha(show ? 1 : 0)
                    .setListener(new AnimatorListenerAdapter() {
                        @Override
                        public void onAnimationEnd(Animator animation) {
                            mDownloadProgressView.setVisibility(show ? View.VISIBLE
                                    : View.GONE);
                        }
                    });
        } else {
            // The ViewPropertyAnimator APIs are not available, so simply show
            // and hide the relevant UI components.
            mDownloadProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
        }
    }
    

    }

    这是progressBar.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/download_progress"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:gravity="center_horizontal"
        android:orientation="vertical"
        android:visibility="gone" >
    
        <ProgressBar
            style="?android:attr/progressBarStyleLarge"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="8dp" />
    
        <TextView
            android:id="@+id/download_poi_status_message"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="16dp"
            android:fontFamily="sans-serif-light"
            android:text="@string/downlaod_progress_message"
            android:textAppearance="?android:attr/textAppearanceMedium" />
    </LinearLayout>
    

2 个答案:

答案 0 :(得分:1)

Yould可以弹出一个包含进度的对话框,但是如果你不想阻止用户使用地图,那么另一种选择是覆盖地图片段顶部的另一个布局并将进度条放在那里布局

答案 1 :(得分:0)

您可以在xml文件中创建ProgressBar,将visible属性设置为不可见...现在在onPreExecute方法中设置View中的可见性。 VISIBLE和postExecute再次隐形。