Android Google Places API:如何禁用搜索栏地点直接选中功能
实现自定义地点选择流程:搜索建议导航到地图后确认选择
我来帮你搞定这个需求——让用户在搜索栏选中地点建议后,先跳转到地图定位该地点,等用户手动确认后再完成选择。首先得提醒你:PlacePicker已经被Google弃用了,官方现在推荐用Autocomplete组件配合自定义地图页面来实现这类灵活的需求,下面是具体的实现步骤和代码:
1. 准备工作:添加依赖和权限
首先在你的build.gradle(Module级别)里添加Places API的依赖:
dependencies { implementation 'com.google.android.libraries.places:places:2.5.0' }
然后在AndroidManifest.xml里添加必要的权限和API密钥:
<!-- 位置权限 --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <!-- Google Maps API密钥 --> <meta-data android:name="com.google.android.geo.API_KEY" android:value="你的Google Places API密钥" />
2. 替换PlacePicker为Autocomplete搜索栏
原来的PlacePicker没法满足“先导航到地图再确认”的需求,我们用AutocompleteSupportFragment来做搜索栏,它可以提供地点建议,而且我们能完全控制选中建议后的行为:
在你的主页面布局里添加AutocompleteFragment:
<fragment android:id="@+id/autocomplete_fragment" android:name="com.google.android.libraries.places.widget.AutocompleteSupportFragment" android:layout_width="match_parent" android:layout_height="wrap_content" />
然后在主页面的Java代码里配置这个搜索栏:
public class MainActivity extends AppCompatActivity { private static final int REQUEST_CODE_CONFIRM_PLACE = 1001; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 初始化Autocomplete搜索栏 AutocompleteSupportFragment autocompleteFragment = (AutocompleteSupportFragment) getSupportFragmentManager().findFragmentById(R.id.autocomplete_fragment); // 设置要获取的地点字段(这里我们需要名称、经纬度和ID) autocompleteFragment.setPlaceFields(Arrays.asList(Place.Field.ID, Place.Field.NAME, Place.Field.LAT_LNG)); // 可选:设置搜索过滤条件,比如只搜索某个国家的地点 autocompleteFragment.setCountry("EG"); // 设置地点选中监听 autocompleteFragment.setOnPlaceSelectedListener(new PlaceSelectionListener() { @Override public void onPlaceSelected(@NonNull Place place) { // 用户选中了搜索建议,不要直接返回结果,跳转到地图确认页面 Intent intent = new Intent(MainActivity.this, MapConfirmationActivity.class); intent.putExtra("PLACE_NAME", place.getName()); intent.putExtra("PLACE_LAT", place.getLatLng().latitude); intent.putExtra("PLACE_LNG", place.getLatLng().longitude); startActivityForResult(intent, REQUEST_CODE_CONFIRM_PLACE); } @Override public void onError(@NonNull Status status) { // 处理搜索错误 Toast.makeText(MainActivity.this, "搜索出错:" + status.getStatusMessage(), Toast.LENGTH_SHORT).show(); } }); } // 处理地图确认页面返回的结果 @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_CODE_CONFIRM_PLACE && resultCode == RESULT_OK) { if (data != null) { // 获取用户确认后的地点信息 String selectedPlaceName = data.getStringExtra("SELECTED_PLACE_NAME"); double lat = data.getDoubleExtra("SELECTED_PLACE_LAT", 0); double lng = data.getDoubleExtra("SELECTED_PLACE_LNG", 0); LatLng selectedPlaceLatLng = new LatLng(lat, lng); // 这里可以做你需要的后续处理,比如显示地点信息、保存到数据库等 Toast.makeText(this, "已确认选择:" + selectedPlaceName, Toast.LENGTH_SHORT).show(); } } } }
3. 创建地图确认页面
接下来创建一个专门的地图页面,用来展示选中的地点,让用户确认:
首先是地图页面的布局activity_map_confirmation.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <!-- 地图控件 --> <fragment android:id="@+id/map" android:name="com.google.android.gms.maps.SupportMapFragment" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" /> <!-- 确认按钮 --> <Button android:id="@+id/btn_confirm_place" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="确认选择此地点" android:layout_margin="16dp" /> </LinearLayout>
然后是地图页面的Java代码MapConfirmationActivity.java:
public class MapConfirmationActivity extends AppCompatActivity implements OnMapReadyCallback { private GoogleMap mMap; private LatLng selectedPlaceLatLng; private String selectedPlaceName; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_map_confirmation); // 获取从主页面传递过来的地点信息 selectedPlaceName = getIntent().getStringExtra("PLACE_NAME"); double lat = getIntent().getDoubleExtra("PLACE_LAT", 0); double lng = getIntent().getDoubleExtra("PLACE_LNG", 0); selectedPlaceLatLng = new LatLng(lat, lng); // 初始化地图 SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager() .findFragmentById(R.id.map); mapFragment.getMapAsync(this); // 设置确认按钮的点击事件 Button confirmBtn = findViewById(R.id.btn_confirm_place); confirmBtn.setOnClickListener(v -> { // 返回确认后的地点信息给主页面 Intent resultIntent = new Intent(); resultIntent.putExtra("SELECTED_PLACE_NAME", selectedPlaceName); resultIntent.putExtra("SELECTED_PLACE_LAT", selectedPlaceLatLng.latitude); resultIntent.putExtra("SELECTED_PLACE_LNG", selectedPlaceLatLng.longitude); setResult(RESULT_OK, resultIntent); finish(); // 关闭当前页面 }); } @Override public void onMapReady(GoogleMap googleMap) { mMap = googleMap; // 移动地图到选中的地点,设置合适的缩放级别 mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(selectedPlaceLatLng, 15)); // 在地图上添加标记,显示地点名称 mMap.addMarker(new MarkerOptions() .position(selectedPlaceLatLng) .title(selectedPlaceName)); } }
关键逻辑说明
- 用户在搜索栏输入时,AutocompleteFragment会自动返回地点建议;
- 用户点击建议后,我们不会直接把地点设为结果,而是把地点的经纬度和名称传递到地图页面;
- 地图页面加载后会自动定位到该地点并添加标记,用户点击“确认”按钮后,才把地点信息返回给主页面;
- 主页面通过
onActivityResult接收确认后的地点,再进行后续处理。
这样就完全实现了你想要的“先导航到地图确认,再完成选择”的流程,而且比弃用的PlacePicker更灵活可控。
内容的提问来源于stack exchange,提问作者ahmed kamal
相关产品推荐
相关产品推荐

