在jetpack compose android中实现Google places自动完成文本字段实现

utugiqy6  于 2022-12-21  发布在  Android
关注(0)|答案(2)|浏览(154)

有人在jetpack compose项目中实现了google自动补全建议文本字段或片段吗?如果有的话,请指导或分享代码片段,因为我在实现它时遇到了困难。

    • 更新**

这是我触发打开全屏对话框的意图,但当我开始在对话框中键入时,对话框关闭,而且我无法找出问题所在,需要一个关于处理活动结果的线索,以便读取此组合函数中的预测结果。

Places.initialize(context, "sa")

    val fields = listOf(Place.Field.ID, Place.Field.NAME)

    val intent = Autocomplete.IntentBuilder(
        AutocompleteActivityMode.FULLSCREEN,fields).build(context)

        startActivityForResult(context as MainActivity,intent, AUTOCOMPLETE_REQUEST_CODE, Bundle.EMPTY)
uttx8gqw

uttx8gqw1#

我正在使用MVVM架构,这是我实现它的方式:
谷歌地点API
我已经创建了一个用于访问名为GooglePlacesApi

interface GooglePlacesApi {
    @GET("maps/api/place/autocomplete/json")
    suspend fun getPredictions(
        @Query("key") key: String = <GOOGLE_API_KEY>,
        @Query("types") types: String = "address",
        @Query("input") input: String
    ): GooglePredictionsResponse

    companion object{
        const val BASE_URL = "https://maps.googleapis.com/"
    }
}

的Google API的API
@Query(“types”)字段用于指定您要在查询中查找的内容,您可以查找机构等。类型可在此处找到

型号

因此,我为此实现创建了3个模型:

Google预测响应

如果您使用postman执行GET请求,则响应的外观为:
Google Prediction Response
你可以看到我们有一个带有“预测”键的对象,所以这是我们的第一个模型。

data class GooglePredictionsResponse(
    val predictions: ArrayList<GooglePrediction>
)
谷歌预测术语
data class GooglePredictionTerm(
    val offset: Int,
    val value: String
)
谷歌预测
data class GooglePrediction(
    val description: String,
    val terms: List<GooglePredictionTerm>
)

我只需要这些信息,如果你需要其他任何东西,随时修改模型或创建自己的。

谷歌地点资源库

最后我们创建一个仓库来获取信息(我使用hilt来注入我的依赖项,如果不使用它,可以忽略那些注解)

@ActivityScoped
class GooglePlacesRepository @Inject constructor(
    private val api: GooglePlacesApi,
){
    suspend fun getPredictions(input: String): Resource<GooglePredictionsResponse>{
        val response = try {
            api.getPredictions(input = input)
        } catch (e: Exception) {
            Log.d("Rently", "Exception: ${e}")
            return Resource.Error("Failed prediction")
        }

        return Resource.Success(response)
    }
}

在这里,我使用了一个额外创建的类来处理响应,这个类称为Resource

sealed class Resource<T>(val data: T? = null, val message: String? = null){
    class Success<T>(data: T): Resource<T>(data)
    class Error<T>(message: String, data:T? = null): Resource<T>(data = data, message = message)
    class Loading<T>(data: T? = null): Resource<T>(data = data)
}

查看模型

我再次使用刀柄,所以如果不使用的话忽略注解。

@HiltViewModel
class AddApartmentViewModel @Inject constructor(private val googleRepository: GooglePlacesRepository): ViewModel(){

    val isLoading = mutableStateOf(false)
    val predictions = mutableStateOf(ArrayList<GooglePrediction>())
    
    fun getPredictions(address: String) {
        viewModelScope.launch {
            isLoading.value = true
            val response = googleRepository.getPredictions(input = address)
            when(response){
                is Resource.Success -> {
                    predictions.value = response.data?.predictions!!
                }
            }

            isLoading.value = false
        }
    }

    fun onSearchAddressChange(address: String){
        getPredictions(address)
    }
}

如果你还需要什么帮助就告诉我

  • 我没有包括UI实现,因为我假设它是独立的,但这是更容易的部分;)
yizd12fk

yizd12fk2#

@Composable
fun MyComponent() {
    val context = LocalContext.current

    val intentLauncher = rememberLauncherForActivityResult(
        contract = ActivityResultContracts.StartActivityForResult()
    ) {
        when (it.resultCode) {
            Activity.RESULT_OK -> {
                it.data?.let {
                    val place = Autocomplete.getPlaceFromIntent(it)
                    Log.i("MAP_ACTIVITY", "Place: ${place.name}, ${place.id}")
                }
            }
            AutocompleteActivity.RESULT_ERROR -> {
                it.data?.let {
                    val status = Autocomplete.getStatusFromIntent(it)
                    Log.i("MAP_ACTIVITY", "Place: ${place.name}, ${place.id}")
                }
            }
            Activity.RESULT_CANCELED -> {
                // The user canceled the operation.
            }
        }
    }

    val launchMapInputOverlay = {
        Places.initialize(context, YOUR_API_KEY)
        val fields = listOf(Place.Field.ID, Place.Field.NAME)
        val intent = Autocomplete
            .IntentBuilder(AutocompleteActivityMode.OVERLAY, fields)
            .build(context)
        intentLauncher.launch(intent)
    }

    Column {
        Button(onClick = launchMapInputOverlay) {
            Text("Select Location")
        }
    }
}

相关问题