#api #kotlin #retrofit2 #okhttp #android-jetpack-compose
Вопрос:
У меня есть приложение, которое я конвертирую в Jetpack Compose. Я надеюсь создать макет карты с помощью Jetpack, а не использовать текущий XML-файл, который у меня есть.
Я не уверен, как обработать ответ от вызова GET-запроса, который я делаю в api, и проанализировать данные в Jetpack, а не в XML-макете.
Основная активность.тыс. т
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MovieSpotterTheme() {
setContentView(R.layout.activity_main)
}
}
val request = ServiceBuilder.buildService(TmdbEndpoints::class.java)
val call = request.getMovies(getString(R.string.api_key))
call.enqueue(object : Callback<PopularMovies>{
override fun onResponse(call: Call<PopularMovies>, response: Response<PopularMovies>) {
if (response.isSuccessful){
progress_bar.visibility = View.GONE
recyclerView.apply {
setHasFixedSize(true)
layoutManager = LinearLayoutManager(this@MainActivity)
adapter = MoviesAdapter(response.body()!!.results)
}
}
}
override fun onFailure(call: Call<PopularMovies>, t: Throwable) {
Toast.makeText(this@MainActivity, "${t.message}", Toast.LENGTH_SHORT).show()
}
})
}
private fun showToast(str: String) {
Toast.makeText(this, str, Toast.LENGTH_SHORT).show()
}
}
Ответ проходит через адаптер Movies (xml-макет-R. layout.movie_item)
class MoviesAdapter(val movies: List<Result>): RecyclerView.Adapter<MoviesViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MoviesViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.movie_item, parent, false)
return MoviesViewHolder(view)
}
override fun getItemCount(): Int {
return movies.size
}
override fun onBindViewHolder(holder: MoviesViewHolder, position: Int) {
return holder.bind(movies[position])
}
}
class MoviesViewHolder(itemView : View): RecyclerView.ViewHolder(itemView){
private val photo:ImageView = itemView.findViewById(R.id.movie_photo)
private val title:TextView = itemView.findViewById(R.id.movie_title)
private val overview:TextView = itemView.findViewById(R.id.movie_overview)
private val rating:TextView = itemView.findViewById(R.id.movie_rating)
fun bind(movie: Result) {
Glide.with(itemView.context).load("https://image.tmdb.org/t/p/w500${movie.poster_path}").placeholder(R.drawable.space_dog_laika1).into(photo)
title.text = "Title: " movie.title
overview.text = movie.overview
rating.text = "User Score: " movie.vote_average.toString()
}
}
movie_item
Макет является относительным, и все документы о миграции охватывают экземпляры макета ограничений.
Ответ №1:
Пропуск адаптера, по-видимому, является решением проблемы. Я все еще анализирую данные, но отправка функции response.body()!!.results
в составляемую функцию позволила мне на данный момент захватить названия фильмов:
call.enqueue(object : Callback<PopularMovies>{
override fun onResponse(call: Call<PopularMovies>, response: Response<PopularMovies>) {
if (response.isSuccessful){
progress_bar.visibility = View.GONE
recyclerView.apply {
setHasFixedSize(true)
layoutManager = LinearLayoutManager(this@MainActivity)
adapter = MoviesAdapter(response.body()!!.results)
}
}
}
override fun onFailure(call: Call<PopularMovies>, t: Throwable) {
Toast.makeText(this@MainActivity, "${t.message}", Toast.LENGTH_SHORT).show()
}
})
Изменено на:
call.enqueue(object : Callback<PopularMovies>{
override fun onResponse(call: Call<PopularMovies>, response: Response<PopularMovies>) {
if (response.isSuccessful){
progress_bar.visibility = View.GONE
setContent{
MovieList(response.body()!!.results)
}
}
}
override fun onFailure(call: Call<PopularMovies>, t: Throwable) {
Toast.makeText(this@MainActivity, "${t.message}", Toast.LENGTH_SHORT).show()
}
})
Составные элементы (ниже основной активности)
@Composable
fun MovieList(results: List<Result>) {
LazyColumn {
items(results) { result ->
MovieCardPreview(result)
}
}
}
@Composable
fun MovieCard(mov: Result){
Column(modifier = Modifier.padding(all = 8.dp)) {
Image(
painter = painterResource(R.drawable.space_dog_laika1), // This is just a placeholder photo for now
contentDescription = "Movie Poster",
modifier = Modifier
.size(40.dp)
.clip(CircleShape)
.border(1.5.dp, MaterialTheme.colors.secondary, CircleShape)
)
Row() {
Text(text = mov.title)
}
}
}