Java Google地图片段替换当前片段
背景:Java Google地图片段替换当前片段,java,android,google-maps,android-fragments,android-nested-fragment,Java,Android,Google Maps,Android Fragments,Android Nested Fragment,背景: 创建一个以用户位置为中心的应用程序,并允许他们向联系人发送其位置信息。为此,我们需要一个简单的凭证检查和服务器地址,以便在首选项中进行测试 问题: 当用户从使用标记、正确地图类型(混合)等显示其位置的原始地图片段导航到另一个片段,然后想要返回到地图片段时,它默认为LatLng 0,0和通用地图(例如,不指示用户位置) 我最初的想法是在切换到另一个片段时尝试保存map片段的状态,并在从堆栈中弹出另一个片段时重新加载该状态。然而,我当时认为只要在需要切换时替换MainActivity中的当前
创建一个以用户位置为中心的应用程序,并允许他们向联系人发送其位置信息。为此,我们需要一个简单的凭证检查和服务器地址,以便在首选项中进行测试 问题:
当用户从使用标记、正确地图类型(混合)等显示其位置的原始地图片段导航到另一个片段,然后想要返回到地图片段时,它默认为LatLng 0,0和通用地图(例如,不指示用户位置) 我最初的想法是在切换到另一个片段时尝试保存map片段的状态,并在从堆栈中弹出另一个片段时重新加载该状态。然而,我当时认为只要在需要切换时替换MainActivity中的当前片段可能会更简单。因此,在打开应用程序时,MainActivity会创建一个新的MapFragment,然后将其替换为首选项片段,“保存”时会创建一个新的MapFragment以替换当前片段。我想这可能会解决我的问题,因为在初始加载时,映射函数符合我的要求 包含映射片段的MFFragment的代码:
public class MFragment extends Fragment implements android.location.LocationListener,
GooglePlayServicesClient.ConnectionCallbacks,
GooglePlayServicesClient.OnConnectionFailedListener{
private final static int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000;
private static GoogleMap map;
private static LocationClient lClient;
private final static String TAG = "MFragment";
private String provider;
private Location loc;
private LocationManager lManager;
private LatLng currentLatLng;
private final long MIN_TIME = 1000;
private final float MIN_DIST = 10;
private Update updateMarkers = new Update();
private View view;
private MapFragment mFrag;
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
mFrag = MapFragment.newInstance();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
//sets the layout for this fragment
view = inflater.inflate(R.layout.fragment_map, container, false);
//insert MapFragment into this Fragment
getActivity().getFragmentManager().beginTransaction()
.replace(R.id.mapview, mFrag)
.commit();
//get a handle on the map from the MapFragment
// map = mFrag.getMap();
//instantiates the location manager
lManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
//instantiate the location client
lClient = new LocationClient(getActivity(), this, this);
lClient.connect();
//run through initialization of all objects
setUpMapIfNeeded();
Log.d(TAG, "Successfully created MFragment");
return view;
}
/**
* instantiates map from the MapFragment if map is null.
*/
private void setUpMapIfNeeded() {
if (getActivity() != null && getActivity().getFragmentManager() != null &&
map == null) {
map = mFrag.getMap();
Log.d(TAG, "Map generated.");
setUpMap();
} else if (lClient.isConnected()) {
updateMap();
} else {
setUpMap();
}
}
/**
* sets up the location data for the map. conditional clause so that the GPS doesn't crash
* if the app can't get a location straight away.
*/
private void setUpMap() {
if (map != null) {
map.setMyLocationEnabled(true);
map.setMapType(GoogleMap.MAP_TYPE_HYBRID);
Criteria crit = new Criteria();
provider = lManager.getBestProvider(crit, false);
if (lManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
loc = lManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
} else {
loc = lManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
}
lManager.requestLocationUpdates(provider, MIN_TIME, MIN_DIST, this);
}
}
protected void updateMap() {
if (servicesConnected()) {
map.clear();
currentLatLng = new LatLng(this.loc.getLatitude(), this.loc.getLongitude());
map.animateCamera(CameraUpdateFactory.newLatLngZoom(currentLatLng, 14));
map.addMarker(new MarkerOptions()
.position(currentLatLng)
.title("You"));
map.setOnMarkerClickListener(new OnMarkerClickListener() {
@Override
public boolean onMarkerClick(Marker m) {
SMSFragment sFrag = new SMSFragment();
sFrag.setMarker(m);
getActivity().getFragmentManager().beginTransaction()
.replace(android.R.id.content, sFrag)
.commit();
return false;
}
});
}
}
/**
* checks for connection to google play services
* @return
*/
private boolean servicesConnected() {
int resultCode = GooglePlayServicesUtil
.isGooglePlayServicesAvailable(getActivity().getApplicationContext());
if (ConnectionResult.SUCCESS == resultCode) {
Log.d(TAG, getString(R.string.play_available));
return true;
} else {
if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
GooglePlayServicesUtil
.getErrorDialog(resultCode, getActivity(),
CONNECTION_FAILURE_RESOLUTION_REQUEST).show();
} else {
Log.i(TAG, "This device is not supported");
}
return false;
}
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
if (connectionResult.hasResolution()) {
try {
connectionResult
.startResolutionForResult(getActivity(), CONNECTION_FAILURE_RESOLUTION_REQUEST);
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}
} else {
Toast.makeText(getActivity(), R.string.connect_failed, Toast.LENGTH_SHORT).show();
}
}
/**
* Called after location client connects
*/
@Override
public void onConnected(Bundle arg0) {
updateMap();
}
/**
* simple display message after disconnecting.
*/
@Override
public void onDisconnected() {
Toast.makeText(getActivity(), R.string.disconnected, Toast.LENGTH_SHORT).show();
}
public void onStart() {
super.onStart();
lClient.connect();
setUpMapIfNeeded();
}
public void onResume() {
super.onResume();
lClient.connect();
setUpMapIfNeeded();
}
public void onPause() {
lClient.disconnect();
super.onPause();
}
public void onStop() {
lClient.disconnect();
super.onStop();
}
public void onDestroy() {
lClient.disconnect();
super.onDestroy();
}
@Override
public void onLocationChanged(Location location) {
this.loc = location;
updateMap();
}
@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
}
public void updateMarkers(List<Record> records){
//update map with markers corresponding to each latitude, longitude passed back from records
for (Record r : records){
map.addMarker( new MarkerOptions()
.position(new LatLng(r.getValueOfLatitude(), r.getValueOfLongitude())));
}
}
private class Update extends AsyncTask<Void, Void, Boolean> {
private List<Record> records;
protected Update() {
super();
records = new ArrayList<Record>();
}
@Override
protected Boolean doInBackground(Void... params) {
Connect conn = new Connect(getActivity());
try {
records = conn.getAll();
return true;
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
protected void onPostExecute(Boolean result) {
if (result) {
updateMarkers(records);
} else {
Toast.makeText(getActivity(), R.string.rec_fail, Toast.LENGTH_SHORT).show();
}
}
}
}
save按钮调用MainActivity中的一个方法,将当前片段替换为MapFragment,作为一种尝试性的解决方法,但其功能与我所希望的不同,并且使用FragmentManager对register按钮使用类似的方法也无法解决映射问题
感谢您的帮助。除非您真的需要,否则不要将一个片段放入另一个片段中。如果您选择这样做,您可能不会像您那样使用
活动
的碎片管理器
。相反,您必须使用容器片段的子片段管理器来创建片段事务,该事务将通过调用getChildFragmentManager()
插入子片段
这是从API级别17(Android 4.2)或使用最新的Android支持库开始支持的。我建议您在默认情况下始终使用支持库。那么,我可以问一下,在活动中处理映射的最佳方式是什么,这样活动就不需要实现大量的方法来处理它,例如setupMapiFneedd()、setUpMap()、updateMap()等,并且映射仍然能够使用一些自定义?这是我第一次在应用程序中使用映射,对于缺乏经验表示歉意。我建议您创建一个扩展MapFragment或SupportMapFragment的类,并在其中放入映射逻辑、setupMapifNeedd()方法和其他方法。
register = (Button) v.findViewById(R.id.register);
save.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
saveToPreferences(v);
((MainActivity)getActivity()).replaceFragment();
}
});
register.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
getActivity().getFragmentManager().beginTransaction()
.replace(android.R.id.content, new RegFragment())
.commit();
}
});
return v;
}