PlacePicker切换位置时同步更新Map Fragment中定位蓝圈
解决PlacePicker切换位置后地图圆圈同步更新的问题
嘿,我仔细看了你的代码,现在的核心问题是:当你用PlacePicker选了新位置后,MainActivity里的myPosition虽然更新了,但你的OpeningPage2 Fragment只在初始化时从Arguments里取一次位置,之后不会主动刷新,所以蓝色圆圈不会跟着移动。另外还有个小细节,MainActivity里的myPosition一开始没初始化,直接用会触发空指针异常,得先处理这个。
下面给你两种可行的解决方案,你可以根据需求选择:
方案一:简单直接——重新替换Fragment
这种方式不需要改太多代码,当PlacePicker返回新位置后,重新创建Fragment并传递新的位置参数,替换掉当前的Fragment:
修改MainActivity的代码
先初始化myPosition避免空指针,然后提取更新Fragment的逻辑为单独方法,在onActivityResult里调用:
public class MainActivity extends AppCompatActivity { private static final int PLACE_PICKER_REQUEST = 1; private static final String TAG = "MainActivity"; LatLng myPosition; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 初始化默认位置(这里用北京坐标,你可以换成获取当前位置的逻辑) myPosition = new LatLng(39.9042, 116.4074); Button btn = findViewById(R.id.changeLocation); btn.setOnClickListener(view -> showPlacePicker()); // 初始化Fragment updateMapFragment(); } private void updateMapFragment() { FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); OpeningPage2 fragment = new OpeningPage2(); Bundle bundle = new Bundle(); bundle.putString("KEY_LAT", String.valueOf(myPosition.latitude)); bundle.putString("KEY_LNG", String.valueOf(myPosition.longitude)); fragment.setArguments(bundle); ft.replace(R.id.content, fragment); ft.commit(); } private void showPlacePicker() { PlacePicker.IntentBuilder builder = new PlacePicker.IntentBuilder(); try { startActivityForResult(builder.build(this), PLACE_PICKER_REQUEST); } catch (Exception e) { Log.e(TAG, "PlacePicker error: ", e); } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == PLACE_PICKER_REQUEST) { if (resultCode == RESULT_OK) { Place place = PlacePicker.getPlace(data, getApplicationContext()); myPosition = place.getLatLng(); // 更新Fragment updateMapFragment(); } } } }
方案二:更优雅——给Fragment添加更新方法
这种方式不需要重新创建Fragment,直接调用Fragment的方法更新位置和圆圈,性能更好:
第一步:修改OpeningPage2 Fragment
添加成员变量保存圆圈引用,再添加公开的更新方法:
public class OpeningPage2 extends Fragment implements OnMapReadyCallback { private GoogleMap mMap; private UiSettings mUiSettings; private Circle circle; // 保存圆圈引用,方便后续移除 private LatLng myPosition; // ... 你的其他代码(比如ARG_PARAM1这些) @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (getArguments() != null) { String latitude = getArguments().getString("KEY_LAT"); String longitude = getArguments().getString("KEY_LNG"); double lat = Double.parseDouble(latitude); double lng = Double.parseDouble(longitude); myPosition = new LatLng(lat, lng); } } @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); SupportMapFragment mapFragment = (SupportMapFragment) getChildFragmentManager() .findFragmentById(R.id.map); mapFragment.getMapAsync(this); } @Override public void onMapReady(GoogleMap googleMap) { mMap = googleMap; mUiSettings = mMap.getUiSettings(); mUiSettings.setZoomControlsEnabled(true); mUiSettings.setCompassEnabled(true); mUiSettings.setMyLocationButtonEnabled(true); // 创建初始圆圈并保存引用 circle = mMap.addCircle(new CircleOptions() .center(myPosition) .radius(2000) .strokeColor(Color.BLACK) .fillColor(0x220000FF) .strokeWidth(1)); mMap.moveCamera(CameraUpdateFactory.newLatLng(myPosition)); } // 公开的更新位置方法,供Activity调用 public void updatePosition(LatLng newPosition) { this.myPosition = newPosition; if (mMap != null && circle != null) { // 移除旧圆圈 circle.remove(); // 创建新圆圈 circle = mMap.addCircle(new CircleOptions() .center(newPosition) .radius(2000) .strokeColor(Color.BLACK) .fillColor(0x220000FF) .strokeWidth(1)); // 移动相机到新位置 mMap.moveCamera(CameraUpdateFactory.newLatLng(newPosition)); } } }
第二步:修改MainActivity
保存Fragment引用,在onActivityResult里调用更新方法:
public class MainActivity extends AppCompatActivity { private static final int PLACE_PICKER_REQUEST = 1; private static final String TAG = "MainActivity"; LatLng myPosition; private OpeningPage2 mapFragment; // 保存Fragment引用 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 初始化默认位置 myPosition = new LatLng(39.9042, 116.4074); Button btn = findViewById(R.id.changeLocation); btn.setOnClickListener(view -> showPlacePicker()); // 初始化Fragment并保存引用 mapFragment = new OpeningPage2(); Bundle bundle = new Bundle(); bundle.putString("KEY_LAT", String.valueOf(myPosition.latitude)); bundle.putString("KEY_LNG", String.valueOf(myPosition.longitude)); mapFragment.setArguments(bundle); FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); ft.replace(R.id.content, mapFragment); ft.commit(); } private void showPlacePicker() { PlacePicker.IntentBuilder builder = new PlacePicker.IntentBuilder(); try { startActivityForResult(builder.build(this), PLACE_PICKER_REQUEST); } catch (Exception e) { Log.e(TAG, "PlacePicker error: ", e); } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == PLACE_PICKER_REQUEST) { if (resultCode == RESULT_OK) { Place place = PlacePicker.getPlace(data, getApplicationContext()); myPosition = place.getLatLng(); // 调用Fragment的更新方法 if (mapFragment != null) { mapFragment.updatePosition(myPosition); } } } } }
额外注意事项
- 别忘了在AndroidManifest.xml里配置Google Maps API密钥,以及添加必要的权限(比如
ACCESS_FINE_LOCATION、ACCESS_COARSE_LOCATION)。 - PlacePicker已经被Google弃用了,如果是新项目建议改用Place Autocomplete API或者Place Selection API,避免后续兼容性问题。
内容的提问来源于stack exchange,提问作者Jimmy
相关产品推荐
相关产品推荐

