0

我正在使用 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() 在 containerView 中充气
  3. 在 onPreExecute()/onPostExecute() 中设置可见/不可见

但它不起作用。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>
4

2 回答 2

1

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

于 2013-06-06T16:39:23.277 回答
0

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

于 2013-06-06T16:50:59.497 回答