如何在Kotlin中不使用第三方解析器,手动解析JSON获取海报路径?
Hey there! 刚接触Kotlin就上手Udacity的热门电影项目,还打算手动解析JSON不用第三方库,这个思路很扎实~我来给你一步步拆解怎么做:
1. 手动解析TheMovieDB的JSON(Kotlin版)
Kotlin可以直接用Java内置的org.json包,写法比Java更简洁,还能兼顾安全性。假设API返回的JSON结构是包含results数组的根对象,每个电影对象里有poster_path字段,我们可以这么写解析函数:
import org.json.JSONObject import org.json.JSONArray fun parseMoviePosterPaths(jsonResponse: String): List<String> { val posterPaths = mutableListOf<String>() val rootJson = JSONObject(jsonResponse) val moviesArray = rootJson.getJSONArray("results") // Kotlin的区间循环比Java更直观 for (index in 0 until moviesArray.length()) { val movieJson = moviesArray.getJSONObject(index) // 用optString代替getString,避免字段缺失时抛出异常 val posterPath = movieJson.optString("poster_path") if (posterPath.isNotEmpty()) { posterPaths.add(posterPath) } } return posterPaths }
2. 实现3列网格展示海报
接下来用RecyclerView做3列网格布局,这部分和Java思路一致,但Kotlin语法更简洁:
第一步:布局里添加RecyclerView
在你的Activity/Fragment布局文件中加入:
<androidx.recyclerview.widget.RecyclerView android:id="@+id/moviePosterRecyclerView" android:layout_width="match_parent" android:layout_height="match_parent"/>
第二步:设置GridLayoutManager和Adapter
在Activity/Fragment的代码中初始化RecyclerView:
// 假设你已经拿到了解析后的posterPaths列表 val posterPaths = parseMoviePosterPaths(apiResponseString) val recyclerView = findViewById<RecyclerView>(R.id.moviePosterRecyclerView) // 第二个参数就是列数,这里设为3 recyclerView.layoutManager = GridLayoutManager(this, 3) recyclerView.adapter = MoviePosterAdapter(posterPaths)
第三步:编写RecyclerView Adapter
Kotlin里的Adapter可以写得更紧凑,比如:
import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.ImageView import androidx.recyclerview.widget.RecyclerView class MoviePosterAdapter(private val posterPaths: List<String>) : RecyclerView.Adapter<MoviePosterAdapter.PosterViewHolder>() { // 内部ViewHolder类,用inner关键字方便访问外部类的成员 inner class PosterViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { val posterImageView: ImageView = itemView.findViewById(R.id.posterImageView) } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PosterViewHolder { val itemView = LayoutInflater.from(parent.context) .inflate(R.layout.item_movie_poster, parent, false) return PosterViewHolder(itemView) } override fun onBindViewHolder(holder: PosterViewHolder, position: Int) { val posterPath = posterPaths[position] // *重点*:TheMovieDB的海报需要拼接完整URL,这里用w185尺寸(可以换成w342等其他尺寸) val fullPosterUrl = "https://image.tmdb.org/t/p/w185/$posterPath" // 这里推荐用图片加载库(比如Glide)加载图片,比原生更高效 // 示例:Glide.with(holder.posterImageView.context).load(fullPosterUrl).into(holder.posterImageView) } override fun getItemCount() = posterPaths.size }
第四步:海报Item布局
创建item_movie_poster.xml作为单个海报的布局:
<ImageView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/posterImageView" android:layout_width="match_parent" android:layout_height="wrap_content" android:adjustViewBounds="true" android:scaleType="centerCrop"/>
3. 和Java写法的小区别提示
- Kotlin不需要
new关键字,直接调用构造函数即可(比如JSONObject(jsonResponse)代替new JSONObject(jsonResponse)) - 循环用区间语法
0 until length,比Java的for循环更简洁易读 - 空安全处理更顺手,
optString返回空字符串而非抛出异常,配合isNotEmpty()判断更稳妥
内容的提问来源于stack exchange,提问作者mchd
相关产品推荐
相关产品推荐

