我正在使用 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:
- 在progress_bar.xml 中定义一个布局(稍后显示)
- 通过 inflater.inflate() 在 containerView 中充气
- 在 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>