Je suis un développeur débutant qui essaie de construire une application de base de données de films en utilisant l'API tmdb et Kotlin. Jusqu'à présent, j'ai suivi un tutoriel pour obtenir l'idée de base, mais comme mon application est différente, je dois mettre en œuvre la logique moi-même.
Dans mon adaptateur onBindViewHolder()
je concatène la chaîne base_URL avec mon poster_path et je passe cela dans Picasso pour remplir mon RecyclerView avec des images provenant des données JSON. Voilà, c'est fait :
override fun onBindViewHolder(holder: PosterHolder, position: Int) {
Picasso
.get()
.load("" + R.string.base_URL + "" + movieData.moviePoster)
.into(holder.imageView)
holder.view.movie_poster?.scaleType = ImageView.ScaleType.FIT_CENTER
}
Comme vous pouvez le voir, le chemin d'affichage est appelé à partir de la classe de données ( movieData.moviePoster
). Je peux le faire parce que c'est le constructeur de mon adaptateur :
class PosterAdapter(val movieData: Movies) : RecyclerView.Adapter<PosterHolder>(){...}
mais maintenant, dans l'activité principale de mon activité onCreate()
l'appel pour attacher l'adaptateur au RecyclerView nécessite le même constructeur.
class MainActivity() : AppCompatActivity(), LoaderManager.LoaderCallbacks<List<Movies>> {
...
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val recyclerView = findViewById<RecyclerView>(R.id.recycler_view);
recyclerView.layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
recyclerView.layoutManager = GridLayoutManager(this, 3);
recyclerView.adapter = PosterAdapter() <- this is it
runLoaders()
}
...
}
J'ai essayé d'appeler le même Movies
dans le constructeur de mon activité principale, mais une erreur s'est produite car le constructeur de l'activité principale devait être vide.
Comment créer un objet à passer dans les paramètres de mon adaptateur dans la MainActivity ? J'ai essayé d'en créer un globalement mais cela m'a obligé à l'initialiser en tant que null
.
Movies.kt (par demande)
data class Movies(val movieTitle: String,
val moviePoster: String,
val overview: String,
val ratings: Int,
val releaseDate: String)
PosterAdapter.kt
class PosterAdapter(val movieData: Movies) : RecyclerView.Adapter<PosterHolder>(){
val movieList = mutableListOf<Movies>()
override fun getItemCount(): Int { return movieList.size }
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PosterHolder{
val layoutInflater = LayoutInflater.from(parent?.context)
val listItem = layoutInflater.inflate(R.layout.list_item, parent, false)
return PosterHolder(listItem)
}
override fun onBindViewHolder(holder: PosterHolder, position: Int) {
Picasso
.get()
.load("" + R.string.base_URL + "" + movieData.moviePoster)
.into(holder.imageView)
holder.view.movie_poster?.scaleType = ImageView.ScaleType.FIT_CENTER
}
}
class PosterHolder(val view: View) : RecyclerView.ViewHolder(view), View.OnClickListener {
var imageView: ImageView? = null
fun PosterHolder(view: View){ this.imageView = view.findViewById<View>(R.id.movie_poster) as ImageView }
override fun onClick(p0: View?) {}
}
QueryUtils.kt
object QueryUtils {
private val logTag = QueryUtils::class.java.simpleName
fun fetchMovieData(requestURL: String): List<Movies>? {
val url = createURL(requestURL)
var jsonResponse : String? = null
try{
jsonResponse = getResponseFromHttpURL(url)
}catch (e: IOException){
Log.e(logTag, "Problem making the HTTP request", e)
}
return extractFeatureFromJSON(jsonResponse)
}
private fun createURL(requestURL: String): URL? {
var url : URL? = null
try{
url = URL(requestURL)
}catch (e: MalformedURLException){
Log.e(logTag, "Problem building the URL", e)
}
return url
}
@Throws(IOException::class)
private fun getResponseFromHttpURL(url: URL?): String? {
//first, open the connection using the url object that was created in createURL method.
//the "as" keyword casts "urlConnection" as HttpURLConnection.
val urlConnection = url?.openConnection() as HttpURLConnection?
try {
if(urlConnection?.responseCode == HttpURLConnection.HTTP_OK){
//The if statement runs if the connection is successful.
//We're retrieving all the data from the input stream after the connection.
val inputStream = urlConnection.inputStream
val scanner = Scanner(inputStream)
scanner.useDelimiter("\\A")
if(scanner.hasNext()){
return scanner.next()
}
}else{
//Throw a log message in case of a faulty response code.
Log.e(logTag, "Error response code: " + urlConnection?.responseCode)
}
}finally {
//end the connection to reclaim the resources to prevent memory leaks
urlConnection?.disconnect()
}
return null
}
private fun extractFeatureFromJSON(jsonResponse: String?): List<Movies>? {
if(jsonResponse == null || jsonResponse.isEmpty()){
return null
}
val movies = mutableListOf<Movies>()
try{
val baseJSONresponse = JSONObject(jsonResponse)
val titleJSON = baseJSONresponse.getString("original_title")
val posterJSON = baseJSONresponse.getString("poster_path")
val overviewJSON = baseJSONresponse.getString("overview")
val ratingsJSON = baseJSONresponse.getInt("vote_average")
val releaseDateJSON = baseJSONresponse.getString("release_date")
movies.add(Movies(titleJSON, posterJSON, overviewJSON, ratingsJSON, releaseDateJSON))
}catch (e: JSONException){
Log.e(logTag, "Problem parsing JSON results", e)
}
return movies
}
}