当前位置: 首页 > news >正文

android studio(NewsApiDemo)100%kotlin

api接口地址:https://newsapi.org/docs/get-started

项目成品地址:https://github.com/RushHan824/NewsApiDemo

项目效果展示:

 MVVM数据流

 UML图


本系列文章将带你从零实现一个新闻列表App,适合零基础读者。一步步来,力求让每个人都能跟着做出来。

第一步:分析API和JSON,写好数据类。

1. 打开API网址,获取返回的JSON数据。

        

2. 观察JSON结构,分析每个字段。

        这里注意会有null的字段 所以kotlin中创建变量的时候需要注意

3. 用Kotlin写出对应的数据类,为后续网络请求和数据展示打好基础。

        创建一个数据类 data class

        然后根据上图的json结构 把数据类一层一层构建出来 还是比较简单的 结果如下图

        当然要注意上面说到的null字段问题 而kotlin中val搭配问好?比较好

                比如:val title: String? 就表示可能会null 安全且规范


第二步:配置Retrofit,完成网络请求

        1.添加依赖

                在build.gradle中添加Retrofit和Gson等依赖。

                如下图 注意是app的.gradle文件 依赖可以一起添加了

//实现网络请求的第一步:加上retrofit和gson的依赖implementation("com.squareup.retrofit2:retrofit:2.9.0")implementation("com.squareup.retrofit2:converter-gson:2.9.0")//livedata viewmodel依赖implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2")implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.6.2")//Glide 图片加载implementation("com.github.bumptech.glide:glide:4.16.0")annotationProcessor("com.github.bumptech.glide:compiler:4.16.0")

        2.定义api接口

                创建接口,声明请求方法和返回类型。

interface Top_ApiService {@GET("top-headlines")suspend fun get_topNews(@Query("country") country: String,@Query("apiKey") apiKey: String):News_Items
}
//我们访问一个网页需要网址 组成可以是baseurl+路径+参数
//这里@GET就是一种请求方式 表示从网页里拿数据 括号里"top-headlines"可以表示具体的路径
//suspend挂起 和kotlin中协程一起搭配 不会阻塞主线程 执行网络请求这样的耗时操作的时候 可以避免界面卡顿
//接下去两个Query就是两个参数
//最后返回类型是数据类
//返回类型通常是我们根据JSON结构定义的数据类(如News_Items),Retrofit会自动帮我们把JSON解析成这个类的对象

        3.配置RetrofitClient                

object RetrofitClient {//object关键字声明了一个单例对象 这样RetrofitClient在全局只有一个实例 方便全局调用 不用每次都新建private val client = OkHttpClient.Builder()//OkHttpClient 是Retrofit底层用来发网络请求的库.addInterceptor(Interceptor { chain ->val request = chain.request().newBuilder().header("User-Agent", "Mozilla/5.0 (Android)").build()chain.proceed(request)//表示继续执行请求})//这里用Builder()自定义了一个OkHttpClient 加了一个拦截器Interceptor//拦截器可以在请求发出前、响应返回后做一些统一处理//这里的拦截器给每个请求都加上了一个User-Agent请求头(模拟浏览器或App身份,有些API会校验这个) 对于现在用的api 不加这个拦截器不行.build()val api: Top_ApiService by lazy {//懒加载的属性 只有第一次用到时才会初始化 节省资源Retrofit.Builder().baseUrl("https://newsapi.org/v2/")//设置api基础网址.addConverterFactory(GsonConverterFactory.create())//用gson把json自动转换成kotlin对象.client(client).build()//创建retrofit对象.create(Top_ApiService::class.java)//创建API接口的实现对象}
}

第三步:MVVM架构与数据流转

        1.Repository层

class Repository(private val api: Top_ApiService){//数据仓库//作用是在这里写一下api调用方法的具体实现suspend fun getTopNews(country: String,apiKey: String):News_Items{return api.get_topNews(country,apiKey)}
}
//在MVVM架构中 Repository负责从网络或本地数据库获取数据 并将数据提供给ViewModel 这样可以让ViewModel只关注数据的展示逻辑 而不用关心数据是怎么来的
//getTopNews方法:调用API接口获取新闻数据,参数和返回值都和API接口保持一致。用suspend修饰,表示要在协程中调用,避免阻塞主线程

            2.ViewModel层

    class NewsViewModel(private val repository: Repository):ViewModel(){private val _newsList = MutableLiveData<News_Items>()val newsList:LiveData<News_Items> = _newsListfun fetchTopNews(country:String,apikey:String){viewModelScope.launch{try{val result=repository.getTopNews(country,apikey)_newsList.value=result}catch(_:Exception){ }}}
    }
    //ViewModel:用于管理界面数据,保证数据在界面旋转等情况下不会丢失。
    //      比如你在看新闻列表,突然手机横屏了,Activity会被销毁再重建。
    //      如果你把数据直接写在Activity里,界面重建后,数据会丢失,需要重新请求。
    //ViewModel的作用就是:即使界面重建,ViewModel里的数据还在,不会丢失,这样用户体验更好。//LiveData/MutableLiveData:实现数据的观察者模式,界面可以自动感知数据变化并刷新。
    //viewModelScope.launch:在ViewModel自带的协程作用域中启动协程,进行异步操作(如网络请求),不会阻塞主线程。
    //异常捕获:防止网络请求失败导致程序崩溃,可以在catch里加上错误提示

              3.Activity层            

      class NewsFeedActivity : AppCompatActivity() {private lateinit var viewModel: NewsViewModelprivate lateinit var adapter: NewsAdapteroverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_news_feed)val recyclerView = findViewById<RecyclerView>(R.id.newsRecyclerView)recyclerView.layoutManager = StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL)//设置布局管理器 瀑布流adapter = NewsAdapter()//创建适配器recyclerView.adapter = adapter//绑定适配器val repository = Repository(RetrofitClient.api)//创建数据仓库对象viewModel = NewsViewModel(repository)//延迟初始化viewmodelviewModel.newsList.observe(this) { newsItems ->adapter.submitList(newsItems.articles)}
      //        通过 observe 订阅 newsList 数据
      //        当新闻数据发生变化时 自动调用 lambda 表达式 把新数据提交给 Adapter 刷新界面viewModel.fetchTopNews("us", "08928b7fed414010820d9af990c05f89")}
      }

      第四步:RecyclerView展示新闻列表

              1.编写Adapter

      class NewsAdapter : RecyclerView.Adapter<NewsAdapter.NewsViewHolder>() {private var articles: List<Article> = emptyList()fun submitList(list: List<Article>) {//提交articles = listnotifyDataSetChanged()//通知recyclerview 数据发生变化 刷新一下}override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): NewsViewHolder {val view = LayoutInflater.from(parent.context).inflate(R.layout.item_news, parent, false)return NewsViewHolder(view)}//复制粘贴override fun onBindViewHolder(holder: NewsViewHolder, position: Int) {holder.bind(articles[position])}//当前位置数据绑定override fun getItemCount(): Int = articles.size//告诉recyclerview有多少条数据class NewsViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {//private val titleTextView: TextView = itemView.findViewById(R.id.newsTitle)private val imageView: ImageView = itemView.findViewById(R.id.newsImage)fun bind(article: Article) {//将article数据绑定到控件上titleTextView.text = article.titleGlide.with(itemView.context).load(article.urlToImage).into(imageView)//Glide高效加载网络图片,防止界面卡顿}}
      }//NewsAdapter:是 RecyclerView 的“桥梁”,负责把新闻数据展示到每一行 item 上
      //onCreateViewHolder:每当需要一个新的 item 行时,加载 item_news.xml 布局,生成 ViewHolder
      //onBindViewHolder:把对应位置的数据绑定到 ViewHolder 上
      //NewsViewHolder:用来缓存和管理 item_news.xml 里的控件,避免重复查找

          2.编写item布局

      http://www.lryc.cn/news/597181.html

      相关文章:

    1. 【前端】当前主流的 CSS 预处理器语言Sass / SCSS、Less、Stylus
    2. kotlin基础【2】
    3. BaaS平台(Supabase)
    4. 数据结构自学Day13 -- 快速排序--“前后指针法”
    5. 《计算机网络》实验报告六 电子邮件
    6. 数据结构(2)顺序表算法题
    7. 【数据结构】二叉树的链式结构--用C语言实现
    8. 数据结构系列之AVL树
    9. Java冒泡排序的不同实现
    10. Excel自动分列开票工具推荐
    11. 耐达讯自动化EtherCAT转RS232:示波器连接的“开挂秘籍”
    12. IDEA如何管理多个Java版本。
    13. 图机器学习(16)——图数据与自然语言处理
    14. 使用idea 将一个git分支的部分记录合并到git另一个分支
    15. idea部署新项目时,用自定义的maven出现的问题解决
    16. 【网络编程】二、socket编程
    17. Excel 将数据导入到SQLServer数据库
    18. Linux文件——Ext2文件系统(3)_软硬链接
    19. Encore.ts:下一代高性能 TypeScript 后端框架的崛起
    20. Qt(基本组件和基本窗口类)
    21. 开源深度学习新宠:Burn框架助您无忧高效建模
    22. Django实战:Python代码规范指南
    23. 开源 Arkts 鸿蒙应用 开发(九)通讯--tcp客户端
    24. Neo4j如何修改用户密码?
    25. Android14 锁屏密码修改为至少6位
    26. ESP32-CAM实战:DIY基于OpenAI的AI视觉识别相机
    27. DeepSeek Janus Pro本地部署与调用
    28. Object Sense (OSE):一款从编辑器脚本发展起来的编程语言
    29. 【markdown】 VSCode 使用 Markdown Preview Enhanced 插件转PDF
    30. 【前端】ikun-pptx编辑器前瞻问题三: pptx的图片如何提取,并在前端渲染。