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.pswp.cn/bicheng/90307.shtml
      繁體地址,請注明出處:http://hk.pswp.cn/bicheng/90307.shtml
      英文地址,請注明出處:http://en.pswp.cn/bicheng/90307.shtml

      如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

      相關文章

      面試高頻題 力扣 417. 太平洋大西洋水流問題 洪水灌溉(FloodFill) 深度優先遍歷(dfs) 暴力搜索 C++解題思路 每日一題

      目錄零、題目描述&#xff1a;用人話再講一遍一、為什么這道題值得咱們學習&#xff1f;二、思路探索常規思路&#xff1a;逐個檢查每個格子&#xff08;會超時&#xff01;??&#xff09;三、正難則反&#xff1a;反向思維的巧妙應用 &#x1f504;&#xff08;思考時間&…

      博物館智慧導覽系統AR交互與自動感應技術:從虛實融合到智能講解的技術實踐

      本文面向博物館信息化開發者、智慧場館系統技術建設師及AR 設計工程師,從AR 交互與自動感應技術的邏輯出發,拆解AR虛實融合技術與智能講解自動感應技術的原理&#xff0c;為相關開發者實踐提供可復用的技術路徑。如需獲取博物館智慧導覽系統解決方案請前往文章最下方獲取&#…

      高效編程革命:DeepSeek V3多語言支持與性能優化實戰

      文章目錄 如何利用DeepSeek V3編寫高效程序代碼:從原理到實踐 引言 一、DeepSeek V3核心能力解析 1.1 模型架構與優勢 1.2 與傳統編程輔助工具對比 二、高效代碼編寫實踐指南 2.1 精準提示工程(Prompt Engineering) 基礎提示模板 高級提示技巧 2.2 生產級代碼生成案例 示例:…

      OkHttp 與 JSON 解析庫完美結合:Moshi/Jackson/Gson 實戰指南

      前言在現代 Android 開發中&#xff0c;網絡請求與 JSON 數據處理是密不可分的。OkHttp 作為強大的 HTTP 客戶端&#xff0c;與 JSON 解析庫&#xff08;Moshi/Jackson/Gson&#xff09;的結合使用&#xff0c;可以極大簡化網絡請求與數據解析的流程。本文將詳細介紹如何將 OkH…

      An error occurred at line: 1 in the generated java file問題處理及tomcat指定對應的jdk運行

      一、背景 tomcat7啟動后&#xff0c;加載jsp頁面報錯&#xff0c;提示無法將jsp編譯為class文件&#xff0c;主要報錯信息如下&#xff1a; An error occurred at line: 1 in the generated java file 最后確認該錯誤原因為&#xff1a;tomcat7不支持jdk1.8版本 機器上已配…

      深入剖析大模型在文本生成式 AI 產品架構中的核心地位

      一、大模型的崛起與概念解析 在人工智能技術飛速迭代的當下&#xff0c;大模型已成為驅動行業發展的核心引擎。從技術定義來看&#xff0c;大模型&#xff08;Large Model&#xff09; 是指基于深度學習架構、具備海量參數規模&#xff08;通常數十億至數萬億級別&#xff09;&…

      Vue Scoped樣式:當動態元素成為“無家可歸“的孤兒

      引言&#xff1a;一場CSS的"身份危機"想象一下&#xff1a;你精心設計了一個Vue組件&#xff0c;為每個元素添加了漂亮的樣式。你滿意地添加了scoped屬性&#xff0c;確保樣式不會"越獄"影響其他組件。然后你動態添加了一些新元素&#xff0c;卻發現它們完…

      vmware分配了ubuntu空間但是ubuntu沒有獲取

      一開始我看vmware中的ubuntu磁盤空間只有200g不夠用&#xff0c;我在vmware給Ubuntu分了300G的磁盤空間&#xff0c;但是ubuntu還是只有之前的200g 如圖在ubuntu查看后來發現&#xff0c;在磁盤軟件里面需要自己分配磁盤空間大小拓展后就可以了

      [MarkdownGithub] 使用塊引用高亮顯示“注意“和“警告“和其他注意方式的選項

      參考來源: https://github.com/orgs/community/discussions/16925 Alerts are an extension of Markdown used to emphasize critical information. On GitHub, they are displayed with distinctive colors and icons to indicate the importance of the content. 提示框是 Ma…

      mac測試ollama llamaindex

      LlamaIndexs 將大語言模型和外部數據連接在一起的工具。大模型prompt有一個長度限制&#xff0c;當外部知識的內容超過這個長度&#xff0c;無法同時將有效信息傳遞給大模型&#xff0c;因此就誕生了 LlamaIndex。 具體操作就是通過多輪對話的方式不斷提純外部數據&#xff0c…

      數據結構:字符串:大小寫轉換(changing case of a string)

      目錄 第一性問題&#xff1a;什么是“大小寫”&#xff1f; 逐步構造代碼&#xff1a;全部轉為大寫 我們現在用 第一性原理 的方式&#xff0c;從字符串與字符的本質出發&#xff0c;一步步推導出如何在 C 語言中將字符串中的字母變成全部大寫或全部小寫。 第一性問題&…

      閑庭信步使用圖像驗證平臺加速FPGA的開發:第三十二課——車牌識別的FPGA實現(4)車牌字符的分割定位

      &#xff08;本系列只需要modelsim即可完成數字圖像的處理&#xff0c;每個工程都搭建了全自動化的仿真環境&#xff0c;只需要雙擊top_tb.bat文件就可以完成整個的仿真&#xff0c;大大降低了初學者的門檻&#xff01;&#xff01;&#xff01;&#xff01;如需要該系列的工程…

      03_java_運行機制

      1. java執行流程2. 什么是編譯3. 什么是運行

      鴻蒙卡片開發保姆級教程

      卡片 1. 卡片概念 什么是卡片&#xff1f;卡片用來顯示或者提示一些基本信息或者進行一些基本操作。注意不能做重邏輯&#xff0c;所有重要邏輯全部交給應用如果是元服務如何喚醒&#xff1f;因為元服務不提供桌面應用圖標&#xff0c;我們可以通過用戶手動的方式在桌面上添加一…

      反向傳播及優化器

      反向傳播&#xff08;Backpropagation&#xff09;反向傳播是計算梯度的算法&#xff0c;核心作用是高效求解 “損失函數對模型所有參數的偏導數”&#xff08;即梯度&#xff09;。沒有反向傳播&#xff0c;深度學習的大規模訓練幾乎不可能實現。 整個過程像 “從終點回溯到起…

      【機器學習深度學習】生成式模型的評估與驗證

      目錄 前言 1. 主觀評估&#xff1a;以人為本的質量判斷 1.1 什么是主觀評估&#xff1f; 1.2 主觀評估的核心流程 1.3 主觀評估的優缺點 2. 客觀評估&#xff1a;量化的性能衡量 2.1 什么是客觀評估&#xff1f; 2.2 常見的客觀評估指標 文本生成 圖像生成 多模態生…

      Linux文件——Ext2文件系統(3)_軟硬鏈接

      文章目錄文件的軟硬鏈接軟鏈接硬鏈接軟硬鏈接對比軟硬鏈接應用軟硬鏈接注意事項總結文件的軟硬鏈接 本篇文章將重點講解文件系統中的一個重要的知識點&#xff1a; 即文件的軟硬鏈接。 軟鏈接 對于軟鏈接的講解&#xff0c;我們先來使用一個指令看看效果&#xff1a;ln -s 被…

      Java SE:類與對象的認識

      Java中的類與對象&#xff1a;構建程序世界的基石 在Java編程的世界里&#xff0c;類與對象是面向對象編程&#xff08;OOP&#xff09;的核心概念&#xff0c;它們就像構建大廈的磚瓦&#xff0c;支撐起整個程序的結構。理解類與對象&#xff0c;是掌握Java編程的關鍵一步。 類…

      Hexo - 免費搭建個人博客03 - 將個人博客托管到github,個人博客公開給大家訪問

      導言我的博客&#xff1a;https://q164129345.github.io/ 既然要將個人博客托管到github&#xff0c;首先我們肯定要有一個github賬戶。另外也需要在電腦上安裝另外一個著名的代碼管理工具git。 一、創建github倉庫二、在Hexo設置部署的內容# Deployment## Docs: https://hexo.…

      一次Oracle集群腦裂問題分析處理

      問題描述 填寫問題的基礎信息。 系統名稱 數據庫集群 IP地址 xxxxxx 操作系統 Linux 數據庫 Oracle 11.2.0.4 癥狀表現 問題的癥狀表現如下 4月26號晚22點02分左右&#xff0c;HIS集群發生腦裂&#xff0c;十幾分鐘后&#xff08;22.18&#xff09;一節點集群率先獲…