Преобразуйте XML-макет в Jetpack, составленный после запроса API Get с помощью Retrofit2 и OkHttp3

#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)
        }
    }
}