如何在Kotlin Compose TextField中添加Place Autocomplete?
在Compose TextField中实现地点自动补全功能
前置准备
确保已在项目中集成Google Places SDK:
- 在
build.gradle中添加依赖:implementation "com.google.android.libraries.places:places:3.4.0" - 在
AndroidManifest.xml中配置API密钥:<meta-data android:name="com.google.android.geo.API_KEY" android:value="你的API密钥"/>
核心实现步骤
1. 初始化Places客户端
在ViewModel中初始化Places客户端,避免重复创建:
class PlaceAutocompleteViewModel : ViewModel() { private lateinit var placesClient: PlacesClient fun initPlacesClient(context: Context) { placesClient = Places.createClient(context) } // 后续请求方法写在此处 }
2. 管理Composable状态
在Composable中定义输入文本和建议列表的状态:
@Composable fun PlaceAutocompleteTextField(viewModel: PlaceAutocompleteViewModel = viewModel()) { var searchQuery by remember { mutableStateOf("") } var placeSuggestions by remember { mutableStateOf(emptyList<AutocompletePrediction>()) } // 监听输入变化,触发地点建议请求 LaunchedEffect(searchQuery) { if (searchQuery.length >= 2) { // 输入至少2个字符再发起请求 delay(300) // 防抖处理,避免频繁调用API placeSuggestions = viewModel.fetchPlaceSuggestions(searchQuery) } else { placeSuggestions = emptyList() } } // 构建UI布局 Column { TextField( value = searchQuery, onValueChange = { searchQuery = it }, label = { Text("输入地点") }, modifier = Modifier.fillMaxWidth() ) // 显示地点建议列表 if (placeSuggestions.isNotEmpty()) { LazyColumn(modifier = Modifier.fillMaxWidth()) { items(placeSuggestions) { prediction -> Text( text = prediction.getPrimaryText(null).toString(), modifier = Modifier .fillMaxWidth() .padding(16.dp) .clickable { // 点击建议项,填充到TextField searchQuery = prediction.getFullText(null).toString() // 可选:获取完整地点详情 viewModel.fetchPlaceDetails(prediction.placeId) } ) Divider() } } } } }
3. 实现地点建议与详情请求
在ViewModel中添加获取建议和详情的方法:
class PlaceAutocompleteViewModel : ViewModel() { // ... 初始化代码 suspend fun fetchPlaceSuggestions(query: String): List<AutocompletePrediction> { val request = FindAutocompletePredictionsRequest.builder() .setQuery(query) .setCountry("CN") // 可选:设置国家过滤 .build() return try { val response = placesClient.findAutocompletePredictions(request).await() response.autocompletePredictions } catch (e: Exception) { emptyList() } } suspend fun fetchPlaceDetails(placeId: String): Place? { val request = FetchPlaceRequest.builder(placeId, listOf(Place.Field.ID, Place.Field.NAME, Place.Field.ADDRESS)) .build() return try { val response = placesClient.fetchPlace(request).await() response.place } catch (e: Exception) { null } } }
关键注意事项
- 防抖处理:通过
delay(300)避免用户每输入一个字符就发起API请求,减少资源消耗 - 权限配置:如果需要基于用户位置提供精准建议,需申请
ACCESS_FINE_LOCATION或ACCESS_COARSE_LOCATION权限,并在运行时请求 - 请求生命周期:借助
viewModelScope管理协程,ViewModel销毁时自动取消未完成的请求,避免内存泄漏 - 文本格式化:
AutocompletePrediction的getPrimaryText和getFullText方法可获取格式化地点文本,第二个参数可传入SpannableString实现匹配内容高亮
内容的提问来源于stack exchange,提问作者Cipri
相关产品推荐
相关产品推荐

