中文字幕一区二区人妻电影,亚洲av无码一区二区乱子伦as ,亚洲精品无码永久在线观看,亚洲成aⅴ人片久青草影院按摩,亚洲黑人巨大videos

ListView和RecyclerView有什么區(qū)別?

發(fā)布于:2021-02-16 00:00:58

0

401

0

Android 開發(fā) ListView RecyclerView

作為Android開發(fā)人員,我們可以使用ListView或RecyclerView來實(shí)現(xiàn)滾動(dòng)列表。讓我們比較這兩種方式,發(fā)現(xiàn)每個(gè)Android開發(fā)人員都應(yīng)該知道的ListView和RecyclerView之間的5個(gè)關(guān)鍵區(qū)別。

ListView和RecyclerView–簡(jiǎn)史

作為Android開發(fā)人員,我們可以通過幾種方式實(shí)現(xiàn)滾動(dòng)列表,這主要取決于我們需要做什么。最流行的方法是使用ListView或Recycler視圖。

ListView是一個(gè)很好的老部件,從API 1開始就包含在Android SDK中。在Android棒棒糖發(fā)布之前,我們主要使用的是這個(gè)API,它并沒有那么糟糕,API基本上是直觀的。不幸的是,它只允許我們創(chuàng)建元素的垂直滾動(dòng)列表,為了使列表滾動(dòng)順利進(jìn)行,我們必須記住正確地執(zhí)行它。

此外,ListView類有點(diǎn)太重了,它有很多責(zé)任。無(wú)論何時(shí)我們必須處理列表,例如以某種方式配置它,唯一的方法就是通過ListView對(duì)象或在適配器內(nèi)部。

現(xiàn)在我們用的是循環(huán)視圖。正如我所提到的,它是在Android棒棒糖中引入的,它被證明是一個(gè)游戲規(guī)則的改變者。我們?cè)贚istView中討厭的很多東西在RecyclerView中都被修復(fù)或更改了。默認(rèn)情況下效率更高,布局是分開的,我們?cè)谶m配器內(nèi)的數(shù)據(jù)集上有更多的可能性。

如果您想了解更多關(guān)于ListView和RecyclerView的信息,可以看看我的文章,這些文章展示了如何實(shí)現(xiàn)ListView和如何實(shí)現(xiàn)RecyclerView。如果你是一個(gè)初學(xué)者,并且目標(biāo)是提供最高級(jí)別的Android應(yīng)用程序開發(fā)服務(wù),那么它們都很有幫助。

在roid上的Droids,我們?cè)谒蓄I(lǐng)域的許多項(xiàng)目中使用RecyclerView,例如物聯(lián)網(wǎng)應(yīng)用程序開發(fā)、金融應(yīng)用程序開發(fā)或移動(dòng)商務(wù)應(yīng)用程序開發(fā)。例如,我們?cè)谝粋€(gè)最大的項(xiàng)目中使用了它——開發(fā)CCC——這是中歐最大的鞋類零售公司的移動(dòng)商務(wù)應(yīng)用程序。

現(xiàn)在,讓我們深入了解ListView和RecyclerView之間的區(qū)別。

ListView與RecyclerView–關(guān)鍵區(qū)別

1.ViewHolder

ViewHolder模式允許我們使列表滾動(dòng)動(dòng)作順暢。它存儲(chǔ)列表行視圖引用,因此調(diào)用findViewById()方法只會(huì)發(fā)生幾次,而不是針對(duì)整個(gè)數(shù)據(jù)集和每個(gè)綁定視圖。

RecyclerView的適配器強(qiáng)制我們使用ViewHolder模式。創(chuàng)建部分(擴(kuò)展布局和查找視圖)和更新視圖分為兩種方法-onCreateViewHolder()onBindViewHolder()

另一方面,ListView在默認(rèn)情況下不會(huì)給我們提供這種保護(hù),因此如果不在getView()方法中實(shí)現(xiàn)ViewHolder模式,我們將以列表中低效的滾動(dòng)結(jié)束。

2.LayoutManager

布局管理器負(fù)責(zé)布局行視圖。因此,RecyclerView不必考慮如何定位行視圖。這個(gè)類允許我們選擇顯示行視圖的方式和滾動(dòng)列表的方式。例如,如果要垂直或水平滾動(dòng)列表,可以選擇LinearLayoutManager。對(duì)于網(wǎng)格,更適合選擇GridLayoutManager。

以前,使用ListView時(shí),我們只能創(chuàng)建一個(gè)垂直滾動(dòng)列表,所以沒有那么靈活。如果我們想在列表中使用網(wǎng)格,我們必須為它選擇另一個(gè)小部件-GridView。

3.ItemDecoration

ItemDecoration的職責(zé)在理論上很簡(jiǎn)單——為列表行視圖添加一些裝飾——但在實(shí)踐中,如果我們想創(chuàng)建一個(gè)自定義的,實(shí)現(xiàn)起來就很簡(jiǎn)單。在這種情況下,我們應(yīng)該擴(kuò)展ItemDecoration類并實(shí)現(xiàn)我們的解決方案。例如,默認(rèn)情況下,RecyclerView列表的行與行之間沒有分隔符,并且它與材料設(shè)計(jì)準(zhǔn)則一致。但是,如果出于某種原因要添加分隔符,可以使用DividerItemDecoration并將其添加到RecyclerView。

如果我們使用ListView,我們必須自己找出行。對(duì)于這個(gè)小部件,沒有類似ItemDecoration的助手類。

4.ItemAnimator

我想提到的RecyclerView的最后一個(gè)組件是ItemAnimator。正如我們所料,它處理行視圖動(dòng)畫,如列表的出現(xiàn)和消失,添加或刪除特定的視圖等等。

默認(rèn)情況下,RecyclerView的列表動(dòng)畫是漂亮而平滑的。當(dāng)然,我們可以通過創(chuàng)建自己的ItemAnimator來改變這一點(diǎn),這也不是那么容易。為了更簡(jiǎn)單,我們應(yīng)該擴(kuò)展simpleItemImator類并實(shí)現(xiàn)所需的方法(只需將動(dòng)畫添加到ViewHolder的視圖中)。

老實(shí)說,在ListView上實(shí)現(xiàn)動(dòng)畫是一件很麻煩的事。再說一次,我們必須想辦法處理它們。沒什么好東西。我很高興它走了。

5.Notifying adapter

我們?cè)赗ecyclerView的適配器上有幾個(gè)很酷的通知程序。我們?nèi)匀豢梢允褂?/span>notifyDataSetChanged(),但也有一些用于特定列表元素,如notifyItemInserted()notifyItemRemoved()甚至notifyItemChanged()等等。我們應(yīng)該為正在發(fā)生的事情使用最合適的動(dòng)畫,這樣正確的動(dòng)畫就會(huì)正確地啟動(dòng)。

使用ListView,我們只能在適配器上使用notifyDataSetChanged(),然后又不得不自己處理其余部分。

關(guān)于RecyclerView的兩個(gè)有用提示

既然我們已經(jīng)使用了RecyclerView,那么讓我們使用這個(gè)工具變得更簡(jiǎn)單、更愉快就更好了。這里有幾個(gè)有用的特性。

1.DiffUtil.Callback

class DiffUtilCallback(
   privateval oldItems: List,
   privateval newItems: List
) : DiffUtil.Callback() {
   override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
   return oldItems[oldItemPosition].id == newItems[newItemPosition].id
}

override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
   // It works properly if Item is a data class
   // Otherwise, we should check if all fields of the items are the same
   return oldItems[oldItemPosition] == newItems[newItemPosition]
}

override fun getOldListSize() = oldItems.size

override fun getNewListSize() = newItems.size
}

回調(diào)幫助我們跳過通知適配器的手動(dòng)處理。我們不必為每種類型的通知使用不同的方法,如notifyItemInserted()notifyItemRemoved()notifyItemChanged(),而只需使用以下簡(jiǎn)單方法:

fun renderItems(newItems: List){
   val diffResult: DiffUtil.DiffResult = DiffUtil.calculateDiff(DiffUtilCallback(oldItems, newItems))
   diffResult.dispatchUpdatesTo(this) // this : RecyclerView.Adapter
}

但即使是這種方法也不是終點(diǎn).

2.ListAdapter

ListAdapter是回收視圖上的套管。電源為DiffUtil的適配器。由于ListAdapter我們不需要:

  • 保留項(xiàng)目列表字段

  • 處理項(xiàng)目動(dòng)畫

  • 呈現(xiàn)新項(xiàng)目的寫入方法

  • 關(guān)心項(xiàng)目列表的大小

它看起來怎么樣?我們需要定義三件事:兩種方法onCreateViewHolder,onBindViewHolderDiffUtil.ItemCallback(最簡(jiǎn)單的DiffUtil.Callback)。

示例代碼:

class Adapter : ListAdapter<Item, ItemViewHolder>(DiffUtilCallback) {

   override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SpotViewHolder {
       val view = LayoutInflater.from(parent.context).inflate(R.layout.item, parent, false)
       return ItemViewHolder(view)
   }

   override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {
       holder.bind(currentList[position])
   }

   object DiffUtilCallback : DiffUtil.ItemCallback() {
       override fun areItemsTheSame(oldItem: Item, newItem: Item) = oldItem.id == newItem.id

       override fun areContentsTheSame(oldItem: Item, newItem: Item) = oldItem == newItem
   }
}

對(duì)于新項(xiàng)目的渲染,使用ListAdapteradapter.submitList(newItems)方法就足夠了。

使用RecyclerView從未如此簡(jiǎn)單和愉快。

ListView與RecyclerView–總結(jié)

ListView為我們服務(wù)了很長(zhǎng)一段時(shí)間。我們能處理大部分案件。但是現(xiàn)在用戶的需求不同了,他們更具挑戰(zhàn)性。列表設(shè)計(jì)變得越來越復(fù)雜,ListView無(wú)法幫助處理它們。材料設(shè)計(jì)也帶來了其他的變化——它既美觀又復(fù)雜。

幸運(yùn)的是,引入了RecyclerView,解決了很多問題。默認(rèn)情況下,它效率更高,動(dòng)畫更簡(jiǎn)單,布局更易于使用,API也更好。因此,如果你想知道應(yīng)該選擇哪一個(gè),你的第一個(gè)想法應(yīng)該是RecyclerView。我希望本文能幫助您理解ListView和RecyclerView之間的區(qū)別。