Я начинающий разработчик, пытающийся создать приложение базы данных фильмов, используя API tmdb и Kotlin. До сих пор я следовал руководству, чтобы понять основную идею, но поскольку мое приложение отличается от других, мне нужно самому реализовать логику.
В методе onBindViewHolder()
моего адаптера я объединяю строку base_URL с моим poster_path и передаю ее в Picasso для заполнения моего RecyclerView изображениями из данных JSON. Вот оно:
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
}
Как видите, путь к плакату вызывается из класса данных (movieData.moviePoster
). Я могу сделать это, потому что это конструктор моего адаптера:
class PosterAdapter(val movieData: Movies) : RecyclerView.Adapter<PosterHolder>(){...}
но теперь в методе onCreate()
моей MainActivity для вызова адаптера к RecyclerView требуется тот же конструктор.
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()
}
...
}
Я попытался вызвать тот же самый объект Movies
в конструкторе моей MainActivity, но он выдал ошибку, поскольку ожидал пустой конструктор для MainActivity.
Как мне создать объект для передачи в параметры моего адаптера в MainActivity? Я пытался создать глобально, но это заставило меня инициализировать его как null
.
Movies.kt (по запросу)
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
}
}