我正在制作一个实现这个滑出菜单的应用程序,我对这个实现非常满意。我将我的应用程序分成多个Fragment
,Activity
因此菜单的每个部分都有一个Fragment
. 关键是我有一个OnItemClickListener
允许我在之间切换Fragments
,所以我尝试了两种方法:
replace()
:它适用于所有片段,除了其中一个加载包含映射 (code below
) 的 XML 的片段。在第一次加载时没有问题,但是当我切换到另一个片段并回到带有地图的片段时,应用程序崩溃了。<fragment android:id="@+id/map" android:layout_width="match_parent" android:layout_height="match_parent" class="com.google.android.gms.maps.SupportMapFragment" /> <RelativeLayout android:id="@+id/RelativeLayout1" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <ImageButton android:id="@+id/refreshButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_alignParentTop="true" android:layout_marginTop="63dp" android:src="@drawable/refresh" android:text="Rafraichir" /> </RelativeLayout>
公共类 MapFragment 扩展 Fragment 实现 OnInfoWindowClickListener、LocationListener {
private GoogleMap gMap; Geocoder geocoder; private LocationManager locationManager; private Location userLocation; private String provider; private ImageButton refreshButton; ArrayList<Parking> Parkings; Context context; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { final View view = inflater.inflate(R.layout.fragmen_map, container, false); gMap = ((SupportMapFragment) getFragmentManager().findFragmentById( R.id.map)).getMap(); gMap.setOnInfoWindowClickListener(this); context = getActivity(); geocoder = new Geocoder(context); refreshButton = (ImageButton) view.findViewById(R.id.refreshButton); refreshButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub getParkingsConnection = new GetParkingsConnection(context); getParkingsConnection.execute(null, null, null); myParkings = new ArrayList<Parking>(); } }); // Geolocaliation LocationManager service = (LocationManager) getActivity() .getSystemService(getActivity().LOCATION_SERVICE); boolean enabled = service .isProviderEnabled(LocationManager.GPS_PROVIDER); // Check if enabled and if not send user to the GSP settings // Better solution would be to display a dialog and suggesting to // go to the settings if (!enabled) { Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS); startActivity(intent); } // Get the location manager locationManager = (LocationManager) getActivity().getSystemService( getActivity().LOCATION_SERVICE); // Define the criteria how to select the locatioin provider -> use // default Criteria criteria = new Criteria(); provider = locationManager.getBestProvider(criteria, false); Location location = locationManager.getLastKnownLocation(provider); return view; } private Double[] getLatAndLong(String addresse) { List<Address> addresses = null; Double latALng[] = new Double[2]; try { addresses = geocoder.getFromLocationName(addresse, 1); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } if (addresses.size() > 0) { double latitude = addresses.get(0).getLatitude(); double longitude = addresses.get(0).getLongitude(); latALng[0] = latitude; latALng[1] = longitude; } return latALng; } private GetParkingsConnection getParkingsConnection; JSONObject json; // Non-Statice inner class : connection au serveur private class GetParkingsConnection extends AsyncTask<String, Void, String> { Context mContext; private ProgressDialog mDialog; GetParkingsConnection(Context context) { mContext = context; } @Override protected void onPreExecute() { super.onPreExecute(); mDialog = new ProgressDialog(mContext); mDialog.setMessage("Mise à jour de la carte..."); mDialog.show(); } @Override protected String doInBackground(String... urls) { String resultat; resultat = getParkings(); return resultat; } @Override protected void onPostExecute(String result) { super.onPostExecute(result); Log.d("JSON", result); JSONArray jArray; try { json = new JSONObject(result); jArray = json.getJSONArray("parking"); System.out.println("*****Parkings*****" + jArray.length()); for (int i = 0; i < jArray.length(); i++) { JSONObject json_data = jArray.getJSONObject(i); Log.d("adresse :", json_data.getString("adresse") + ", nom :" + json_data.getString("nom") + ", latitude :" + json_data.getDouble("latitude") + ", longitude :" + json_data.getDouble("longitude")); String adresse = json_data.getString("adresse"); Double latALng[] = getLatAndLong(adresse); Double lat = latALng[0]; // json_data.getDouble("latitude"); Double lng = latALng[1]; // json_data.getDouble("longitude"); String nom = json_data.getString("nom"); LatLng parkingLocation = new LatLng(lat, lng); Marker parking = gMap.addMarker(new MarkerOptions() .position(parkingLocation) .title(nom) .snippet(adresse) .icon(BitmapDescriptorFactory .fromResource(R.drawable.my_marker))); Parking park = new Parking(parking.getId(), adresse, nom, "", lat, lng); myParkings.add(park); } } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } mDialog.dismiss(); } // Fonction effectuant uenrequête de type GET sur le fichier // getParking.php protected String getParkings() { HttpResponse response = null; String res = ""; try { HttpClient client = new DefaultHttpClient(); HttpGet request = new HttpGet(); // request.setURI(new // URI("http://pkdom.1x.biz/getParkings.php")); request.setURI(new URI( "http://glennsonna.fr/webService/getParkings")); response = client.execute(request); HttpEntity entity = response.getEntity(); // JSONObject json = new JSONObject(); res = EntityUtils.toString(entity); } catch (URISyntaxException e) { e.printStackTrace(); } catch (ClientProtocolException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return res; } } @Override public void onInfoWindowClick(Marker marker) { // TODO Auto-generated method stub Parking parkingToSend = null; // TOAST /* * int p = 0; * * while(myParkings.get(p).idMarker != marker.getId() && p < * myParkings.size()){ Log.d("Marker :" + marker.getId(), * myParkings.get(p).idMarker); * * if(myParkings.get(p).idMarker.equals(marker.getId()) ){ * parkingToSend = myParkings.get(p); Context context = * getApplicationContext(); CharSequence text = "Match" + * parkingToSend.adresse; int duration = Toast.LENGTH_SHORT; Toast toast * = Toast.makeText(context, text, duration); toast.show(); } * * p++; } */ for (int p = 0; p < myParkings.size(); p++) { Log.d("Marker :" + marker.getId(), myParkings.get(p).idMarker); if (myParkings.get(p).idMarker.equals(marker.getId())) { parkingToSend = myParkings.get(p); } } if (parkingToSend != null) { Intent i = new Intent(context.getApplicationContext(), ParkingDetail.class); i.putExtra("id", parkingToSend.idMarker); i.putExtra("adresse", parkingToSend.adresse); i.putExtra("nom", parkingToSend.nom); i.putExtra("descri", parkingToSend.description); i.putExtra("latitude", parkingToSend.lat); i.putExtra("longitude", parkingToSend.lng); startActivity(i); } } @Override public void onLocationChanged(Location user) { // TODO Auto-generated method stub Log.d("Latitude", ":" + user.getLatitude()); Log.d("Longitude", ":" + user.getLongitude()); this.gMap.setMyLocationEnabled(true); } @Override public void onProviderDisabled(String provider) { // TODO Auto-generated method stub } @Override public void onProviderEnabled(String provider) { // TODO Auto-generated method stub } @Override public void onStatusChanged(String provider, int status, Bundle extras) { // TODO Auto-generated method stub }
}
hide()
&show()
:我可以在片段之间切换,但除了第一个屏幕(地图)之外,其他所有屏幕都显示一个没有内容的空白屏幕。私人 MenuDrawer mMenuDrawer; 私有 MenuAdapter mAdapter;私有 ListView mList;私人谷歌地图 gMap;
private int mActivePosition = -1; List<Object> mmyFragment; Fragment currentFragment; myMapFragment mmyMapFragment; myMonCompteFragment mmyMonCompteFragment; myPaiementFragment mmyPaiementFragment; myReservationsFragment mmyReservationsFragment; myFavorisFragment mmyFavorisFragment; myCodePromoFragment mmyCodePromoFragment; myAboutFragment mmyAboutFragment; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // setContentView(R.layout.activity_my_map); ActionBar actionBar = this.getActionBar(); actionBar.setSubtitle("Trouvez votre parking"); actionBar.setTitle("my"); actionBar.setDisplayHomeAsUpEnabled(true); setupMenu(); setupFragments(); } private void setupMenu() { mMenuDrawer = MenuDrawer.attach(this, Position.LEFT); mMenuDrawer.setContentView(R.layout.activity_my_map); List<Object> items = new ArrayList<Object>(); items.add(new Item("Carte", R.drawable.ic_action_refresh_dark)); items.add(new Item("Mon Compte", R.drawable.ic_action_refresh_dark)); items.add(new Item("Paiement", R.drawable.ic_action_select_all_dark)); items.add(new Item("Mes Réservations", R.drawable.ic_action_select_all_dark)); items.add(new Item("Mes favoris", R.drawable.ic_action_refresh_dark)); // items.add(new Category(" ")); items.add(new Item("Code Promo", R.drawable.ic_action_refresh_dark)); items.add(new Item("A propos", R.drawable.ic_action_select_all_dark)); // A custom ListView is needed so the drawer can be notified when it's // scrolled. This is to update the position // of the arrow indicator. mList = new ListView(this); mAdapter = new MenuAdapter(items); mList.setAdapter(mAdapter); mList.setOnItemClickListener(mItemClickListener); mMenuDrawer.setMenuView(mList); } private void setupFragments() { mmyMapFragment = new myMapFragment(); mmyMonCompteFragment = new myMonCompteFragment(); mmyPaiementFragment = new myPaiementFragment(); mmyReservationsFragment = new myReservationsFragment(); mmyFavorisFragment = new myFavorisFragment(); mmyCodePromoFragment = new myCodePromoFragment(); mmyAboutFragment = new myAboutFragment(); mmyFragment = new ArrayList<Object>(); mmyFragment.add(mmyMapFragment); mmyFragment.add(mmyMonCompteFragment); mmyFragment.add(mmyPaiementFragment); mmyFragment.add(mmyReservationsFragment); mmyFragment.add(mmyFavorisFragment); mmyFragment.add(mmyCodePromoFragment); mmyFragment.add(mmyAboutFragment); FragmentManager fragmentManager = getSupportFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager .beginTransaction(); fragmentTransaction.replace(R.id.myContenu, mmyMapFragment); fragmentTransaction.commit(); currentFragment = mmyMapFragment; } private AdapterView.OnItemClickListener mItemClickListener = new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { mActivePosition = position; mMenuDrawer.setActiveView(view, position); mMenuDrawer.closeMenu(); if ((mmyFragment.get(position) != null) /*&& (mmyFragment.get(position).getClass() != currentFragment .getClass())*/) { Fragment nexFragment = (Fragment) mmyFragment .get(position); FragmentManager fragmentManager = getSupportFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager .beginTransaction(); fragmentTransaction.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out); fragmentTransaction.hide(currentFragment); if (!nexFragment.isHidden()) { //fragmentTransaction.add(nexFragment, nexFragment.getTag()); Toast.makeText( getApplicationContext(), "" + nexFragment.getClass().toString() + " : " + mmyFragment.indexOf(mmyFragment .get(position)), Toast.LENGTH_SHORT).show(); } //fragmentTransaction.addToBackStack(nexFragment.getTag()); fragmentTransaction.attach(nexFragment); fragmentTransaction.replace(R.id.myContenu, nexFragment); //fragmentTransaction.show(nexFragment); currentFragment = nexFragment; fragmentTransaction.commit();...}
一天后,我终于在这里找到了答案
所以我只是实现了下面的代码。但我必须使用replace();
,所以我会找到一种方法来保存我的地图状态。
public void onDestroyView ()
{
try{
SupportMapFragment fragment = ((SupportMapFragment) getFragmentManager().findFragmentById(R.id.map));
FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
ft.remove(fragment);
ft.commit();
}catch(Exception e){
}
super.onDestroyView();
}