多类型适配器
<p>优势:</p><p>1、适配器通用,无论针对什么列表样式</p>
<p>2、viewholder分离,业务逻辑拆分到具体的item</p>
<p>3、复用性扩展性更强</p>
<p>首先看viewholder,没有复杂的业务逻辑</p>
<div class="cnblogs_code"><img id="code_img_closed_bb3b7a4f-a45c-4307-80a1-9fb2a4fdfcce" class="code_img_closed lazyload" data-src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif"><img id="code_img_opened_bb3b7a4f-a45c-4307-80a1-9fb2a4fdfcce" class="code_img_opened lazyload" style="display: none" data-src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif">
<div id="cnblogs_code_open_bb3b7a4f-a45c-4307-80a1-9fb2a4fdfcce" class="cnblogs_code_hide">
<pre>open <span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> BaseViewHolder(val mBinding: ViewBinding) : RecyclerView.ViewHolder(mBinding.root) {
fun setClick(clickRoot: View, clickListener: ((Int) </span>-> Unit)?<span style="color: rgba(0, 0, 0, 1)">) {
AnimatorUtil.pressView(
clickRoot, Runnable { clickListener</span>?<span style="color: rgba(0, 0, 0, 1)">.invoke(bindingAdapterPosition) }
)
clickRoot.setOnClickListener { clickListener</span>?<span style="color: rgba(0, 0, 0, 1)">.invoke(bindingAdapterPosition) }
}
}</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p>适配器想要通用,就不能有业务逻辑,需要解耦</p>
<div class="cnblogs_code"><img id="code_img_closed_9ce06b8e-8e56-46af-a8ab-728b31d0c6f2" class="code_img_closed lazyload" data-src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif"><img id="code_img_opened_9ce06b8e-8e56-46af-a8ab-728b31d0c6f2" class="code_img_opened lazyload" style="display: none" data-src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif">
<div id="cnblogs_code_open_9ce06b8e-8e56-46af-a8ab-728b31d0c6f2" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> android.view.ViewGroup
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> androidx.recyclerview.widget.RecyclerView
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> com.zeekr.screensaver.home.holder.ScreenMainHolderFactory
</span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)">
* </span><span style="color: rgba(128, 128, 128, 1)">@author</span><span style="color: rgba(0, 128, 0, 1)"> liuzhen
* 多类型适配器
* </span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)">
open </span><span style="color: rgba(0, 0, 255, 1)">class</span> BaseAdapter : RecyclerView.Adapter<BaseViewHolder><span style="color: rgba(0, 0, 0, 1)">() {
var itemClickListener: ((Int) </span>-> Unit)? = <span style="color: rgba(0, 0, 255, 1)">null</span>
<span style="color: rgba(0, 0, 255, 1)">private</span> val list = mutableListOf<IBaseItem><span style="color: rgba(0, 0, 0, 1)">()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) </span>=<span style="color: rgba(0, 0, 0, 1)">
ScreenMainHolderFactory.onCreateViewHolder(parent, viewType, itemClickListener)
override fun getItemCount() </span>=<span style="color: rgba(0, 0, 0, 1)"> list.size
fun getItem(position: Int) </span>=<span style="color: rgba(0, 0, 0, 1)"> list
fun getItems() </span>=<span style="color: rgba(0, 0, 0, 1)"> list
override fun getItemViewType(position: Int) </span>=<span style="color: rgba(0, 0, 0, 1)"> getItem(position).itemType.value
override fun onBindViewHolder(holder: BaseViewHolder, position: Int) {
getItem(position).bind(holder, position)
}
override fun onBindViewHolder(holder: BaseViewHolder, position: Int, payloads: List</span><Any?><span style="color: rgba(0, 0, 0, 1)">) {
getItem(position).bind(holder, position, payloads)
}
fun setItems(newList: MutableList</span><IBaseItem><span style="color: rgba(0, 0, 0, 1)">) {
list.clear()
list.addAll(newList)
}
}</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p>可以看到,简化了viewholder跟adapter,那么逻辑去哪了,在bean的上面加了一层item,可以把这个bean看成是item</p>
<p>首先需要定义一个接口,从adapter中看到所有数据类型都是 IBaseItem</p>
<div class="cnblogs_code"><img id="code_img_closed_e2e56155-3ab9-4de0-969c-548f72b38c57" class="code_img_closed lazyload" data-src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif"><img id="code_img_opened_e2e56155-3ab9-4de0-969c-548f72b38c57" class="code_img_opened lazyload" style="display: none" data-src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif">
<div id="cnblogs_code_open_e2e56155-3ab9-4de0-969c-548f72b38c57" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> com.zeekr.screensaver.home.holder.ViewType
</span><span style="color: rgba(0, 0, 255, 1)">interface</span><span style="color: rgba(0, 0, 0, 1)"> IBaseItem {
val itemType: ViewType
var isShowShimmer: Boolean
fun bind(holder: BaseViewHolder, position: Int, payloads: List</span><Any?>? = <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">)
}</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p>多类型安全,最好使用枚举</p>
<div class="cnblogs_code"><img id="code_img_closed_ece60593-63eb-4a7f-8bac-6ee3f37c313d" class="code_img_closed lazyload" data-src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif"><img id="code_img_opened_ece60593-63eb-4a7f-8bac-6ee3f37c313d" class="code_img_opened lazyload" style="display: none" data-src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif">
<div id="cnblogs_code_open_ece60593-63eb-4a7f-8bac-6ee3f37c313d" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">enum</span> <span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> ViewType(val value: Int) {
TITLE(</span>1), ITEM(2), BANNER(3), ME_ADD(4), ME_ITEM(5<span style="color: rgba(0, 0, 0, 1)">);
companion object {
fun fromValue(value: Int) </span>= values().firstOrNull { it.value ==<span style="color: rgba(0, 0, 0, 1)"> value }
}
}</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p>统一管理ViewHolder</p>
<div class="cnblogs_code"><img id="code_img_closed_caff42bc-2997-4e92-b5de-639824673c93" class="code_img_closed lazyload" data-src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif"><img id="code_img_opened_caff42bc-2997-4e92-b5de-639824673c93" class="code_img_opened lazyload" style="display: none" data-src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif">
<div id="cnblogs_code_open_caff42bc-2997-4e92-b5de-639824673c93" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 0, 1)">object ScreenMainHolderFactory {
@JvmStatic
fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int,
itemClickListener: ((Int) </span>-> Unit)?<span style="color: rgba(0, 0, 0, 1)">
): BaseViewHolder {
val inflater </span>=<span style="color: rgba(0, 0, 0, 1)"> LayoutInflater.from(parent.context)
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> when (ViewType.fromValue(viewType)) {
ViewType.TITLE </span>-><span style="color: rgba(0, 0, 0, 1)"> BaseViewHolder(
ItemMainSubTitleBinding.inflate(inflater, parent, </span><span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">)
)
ViewType.BANNER </span>-><span style="color: rgba(0, 0, 0, 1)"> BaseViewHolder(
ItemMainBannerBinding.inflate(inflater, parent, </span><span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">)
)
ViewType.ME_ADD </span>-><span style="color: rgba(0, 0, 0, 1)"> {
val binding </span>= ItemMeAddBinding.inflate(inflater, parent, <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">)
BaseViewHolder(binding).also {
it.setClick(binding.root, itemClickListener)
}
}
ViewType.ME_ITEM </span>-><span style="color: rgba(0, 0, 0, 1)"> {
val binding </span>= ItemMePhotoCardBinding.inflate(inflater, parent, <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">)
BaseViewHolder(binding).also {
it.setClick(binding.clRoot, itemClickListener)
}
}
</span><span style="color: rgba(0, 0, 255, 1)">else</span> -><span style="color: rgba(0, 0, 0, 1)"> {
val binding </span>= ItemMainPhotoCardBinding.inflate(inflater, parent, <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">)
BaseViewHolder(binding).also {
it.setClick(binding.clRoot, itemClickListener)
}
}
}
}
}</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p>viewholder中的逻辑解耦到了item类中,先定义接口IBaseItem </p>
<div class="cnblogs_code"><img id="code_img_closed_c3cd4b5c-1361-493e-a2a1-dd0292caef5b" class="code_img_closed lazyload" data-src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif"><img id="code_img_opened_c3cd4b5c-1361-493e-a2a1-dd0292caef5b" class="code_img_opened lazyload" style="display: none" data-src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif">
<div id="cnblogs_code_open_c3cd4b5c-1361-493e-a2a1-dd0292caef5b" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> com.zeekr.screensaver.home.holder.ViewType
</span><span style="color: rgba(0, 0, 255, 1)">interface</span><span style="color: rgba(0, 0, 0, 1)"> IBaseItem {
val itemType: ViewType
var isShowShimmer: Boolean
fun bind(holder: BaseViewHolder, position: Int, payloads: List</span><Any?>? = <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">)
}</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p>结合viewbinding,实现接口</p>
<div class="cnblogs_code"><img id="code_img_closed_b16c3c43-f577-438d-8054-6302872b3435" class="code_img_closed lazyload" data-src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif"><img id="code_img_opened_b16c3c43-f577-438d-8054-6302872b3435" class="code_img_opened lazyload" style="display: none" data-src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif">
<div id="cnblogs_code_open_b16c3c43-f577-438d-8054-6302872b3435" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> androidx.viewbinding.ViewBinding
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> com.zeekr.screensaver.home.holder.ViewType
</span><span style="color: rgba(0, 0, 255, 1)">abstract</span> <span style="color: rgba(0, 0, 255, 1)">class</span> BaseBindItem<V : ViewBinding><span style="color: rgba(0, 0, 0, 1)">(val viewType: ViewType) : IBaseItem {
override val itemType </span>=<span style="color: rgba(0, 0, 0, 1)"> viewType
override var isShowShimmer </span>= <span style="color: rgba(0, 0, 255, 1)">true</span>
<span style="color: rgba(0, 0, 255, 1)">abstract</span><span style="color: rgba(0, 0, 0, 1)"> fun onBindViewHolder(position: Int, mBinding: V)
open fun onBindViewHolder(position: Int, mBinding: V, payloads: List</span><Any?><span style="color: rgba(0, 0, 0, 1)">) {}
override fun bind(holder: BaseViewHolder, position: Int, payloads: List</span><Any?>?<span style="color: rgba(0, 0, 0, 1)">) {
@Suppress(</span>"UNCHECKED_CAST"<span style="color: rgba(0, 0, 0, 1)">)
val binding </span>=<span style="color: rgba(0, 0, 0, 1)"> holder.mBinding as V
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (payloads.isNullOrEmpty()) {
onBindViewHolder(position, binding)
} </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> {
onBindViewHolder(position, binding, payloads)
}
}
}</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p>这样,已经根据多类型封装好了,只要根据视图,创建类型item,直接将viewholder的业务转移到了item中</p>
<p>比如新建一个banner类型</p>
<div class="cnblogs_code"><img id="code_img_closed_a4c13000-1604-46ec-80c9-a7341fd59a35" class="code_img_closed lazyload" data-src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif"><img id="code_img_opened_a4c13000-1604-46ec-80c9-a7341fd59a35" class="code_img_opened lazyload" style="display: none" data-src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif">
<div id="cnblogs_code_open_a4c13000-1604-46ec-80c9-a7341fd59a35" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> MainBannerItem(
</span><span style="color: rgba(0, 0, 255, 1)">private</span> val list: List<ScreenItemBean><span style="color: rgba(0, 0, 0, 1)">
) : BaseBindItem</span><ItemMainBannerBinding><span style="color: rgba(0, 0, 0, 1)">(ViewType.BANNER) {
override fun onBindViewHolder(position: Int, mBinding: ItemMainBannerBinding) {
mBinding.apply {
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (isShowShimmer) bannerPage.onClear()
bannerPage.start(list, bannerCarousel)
groupContent.isInvisible </span>=<span style="color: rgba(0, 0, 0, 1)"> isShowShimmer
shimmerView.isVisible </span>=<span style="color: rgba(0, 0, 0, 1)"> isShowShimmer
shimmerView.setImageResource(R.drawable.icon_main_banner_loading)
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (isShowShimmer) shimmerView.startShimmer() <span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> shimmerView.stopShimmer()
}
}
}</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p>在新建一个卡片类型</p>
<div class="cnblogs_code"><img id="code_img_closed_94c4ad4a-2713-4b7a-b49a-0f3a33fc161c" class="code_img_closed lazyload" data-src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif"><img id="code_img_opened_94c4ad4a-2713-4b7a-b49a-0f3a33fc161c" class="code_img_opened lazyload" style="display: none" data-src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif">
<div id="cnblogs_code_open_94c4ad4a-2713-4b7a-b49a-0f3a33fc161c" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">class</span> MePhotoCardItem(var bean: ScreenItemBean, <span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)"> val currentId: Int) :
BaseBindItem</span><ItemMePhotoCardBinding><span style="color: rgba(0, 0, 0, 1)">(ViewType.ME_ITEM) {
override fun onBindViewHolder(position: Int, mBinding: ItemMePhotoCardBinding) {
mBinding.apply {
tvTitle.text </span>=<span style="color: rgba(0, 0, 0, 1)"> bean.getTitle()
tvTitle.setPXTextSize(R.dimen.common_sp_32)
tvTitle.setExtTextColor(R.color.main_card_title_color)
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (bean.isCustom()) {
GlideCacheUtils.getInstance(root.context).glideLoadPicturePath(
bean.customBitmap, ivPhoto
)
} </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> {
GlideCacheUtils.getInstance(root.context).loadHomeItemUrl(bean.getUrl(), ivPhoto)
}
linSuite.isVisible </span>=<span style="color: rgba(0, 0, 0, 1)"> bean.isCabin()
linSuite.setExtBackground(R.drawable.shape_item_main_card_suite)
ivPhotoSuite.setExtSrc(R.drawable.icon_main_card_photo_suite)
tvSuiteTitle.setPXTextSize(R.dimen.common_sp_20)
tvSuiteTitle.setExtTextColor(R.color.main_card_title_suite_color)
groupMask.isInvisible </span>= bean.getTitle()?.isEmpty() == <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">
ivCheck.isVisible </span>=<span style="color: rgba(0, 0, 0, 1)"> bean.isCheck(currentId)
clRoot.isInvisible </span>=<span style="color: rgba(0, 0, 0, 1)"> isShowShimmer
shimmerView.isVisible </span>=<span style="color: rgba(0, 0, 0, 1)"> isShowShimmer
shimmerView.setImageResource(R.drawable.icon_main_photo_card_loading)
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (isShowShimmer) shimmerView.startShimmer() <span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> shimmerView.stopShimmer()
}
}
}</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p>可以观察到,它其实充当bean的角色,又是独立的item</p>
<p>在创建一个特殊的自定义功能卡片类型</p>
<div class="cnblogs_code"><img id="code_img_closed_60c72b40-76db-4ed9-8852-a0d370c74d73" class="code_img_closed lazyload" data-src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif"><img id="code_img_opened_60c72b40-76db-4ed9-8852-a0d370c74d73" class="code_img_opened lazyload" style="display: none" data-src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif">
<div id="cnblogs_code_open_60c72b40-76db-4ed9-8852-a0d370c74d73" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">class</span> MeAddItem(@MeAddItemType val type: Int) : BaseBindItem<ItemMeAddBinding><span style="color: rgba(0, 0, 0, 1)">(ViewType.ME_ADD) {
companion object {
</span><span style="color: rgba(0, 0, 255, 1)">const</span> val TYPE_AI = 0
<span style="color: rgba(0, 0, 255, 1)">const</span> val TYPE_PHOTO = 1<span style="color: rgba(0, 0, 0, 1)">
@IntDef(TYPE_AI, TYPE_PHOTO)
@Retention(AnnotationRetention.SOURCE)
annotation </span><span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> MeAddItemType
}
override fun onBindViewHolder(position: Int, mBinding: ItemMeAddBinding) {
mBinding.apply {
when (type) {
TYPE_AI </span>-><span style="color: rgba(0, 0, 0, 1)"> ivPhoto.setImageResource(R.drawable.icon_me_card_ai)
</span><span style="color: rgba(0, 0, 255, 1)">else</span> -><span style="color: rgba(0, 0, 0, 1)"> ivPhoto.setImageResource(R.drawable.icon_me_card_photo)
}
}
}
}</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p>随意扩展</p>
<p>而adapter的使用更加简单</p>
<div class="cnblogs_code"><img id="code_img_closed_60cdaa66-e686-4875-bb81-c2b148c2beeb" class="code_img_closed lazyload" data-src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif"><img id="code_img_opened_60cdaa66-e686-4875-bb81-c2b148c2beeb" class="code_img_opened lazyload" style="display: none" data-src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif">
<div id="cnblogs_code_open_60cdaa66-e686-4875-bb81-c2b148c2beeb" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">private</span> val mAdapter =<span style="color: rgba(0, 0, 0, 1)"> BaseAdapter()
init {
val inflater </span>=<span style="color: rgba(0, 0, 0, 1)"> LayoutInflater.from(context)
mBinding </span>= LayoutScreenRecyclerBinding.inflate(inflater, <span style="color: rgba(0, 0, 255, 1)">this</span>, <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">).apply {
recyclerView.adapter </span>=<span style="color: rgba(0, 0, 0, 1)"> mAdapter
recyclerView.layoutManager </span>=<span style="color: rgba(0, 0, 0, 1)"> ScreenMainGridManager(mAdapter, context)
recyclerView.addItemDecoration(ScreenMainItemDecoration())
}
}
</span><span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)"> fun loadData() {
LogUtil.d(tag, </span>"loadData"<span style="color: rgba(0, 0, 0, 1)">)
lifecycleScope.launch(Dispatchers.Main) {
val items </span>=<span style="color: rgba(0, 0, 0, 1)"> withContext(Dispatchers.IO) {
val data </span>=<span style="color: rgba(0, 0, 0, 1)"> LocalResourceManager.getHistorySuits()
val items </span>= mutableListOf<IBaseItem><span style="color: rgba(0, 0, 0, 1)">()
items.add(MeAddItem(MeAddItem.TYPE_AI))
items.add(MeAddItem(MeAddItem.TYPE_PHOTO))
items.add(MainSubTitleItem(MainSubTitleItem.HISTORY))
data.map { items.add(MePhotoCardItem(ScreenItemBean(suit </span>=<span style="color: rgba(0, 0, 0, 1)"> it), currentId)) }
items
}
setItems(items)
}
}
</span><span style="color: rgba(0, 0, 255, 1)">private</span> fun loadData(list: List<TestBean><span style="color: rgba(0, 0, 0, 1)">) {
mBinding.root.isVisible </span>= <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">
val items </span>= mutableListOf<IBaseItem><span style="color: rgba(0, 0, 0, 1)">()
list.forEach {
items.addAll(it.map { MainPhotoCardItem(it) })
}
mAdapter.setItems(items)
}</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p>只要是基于RecyclerView,都不需要另外创建adapter,只需要新建你的类型视图,而adapter跟viewholder完全不用修改,一站式复用</p>
<p>局部刷新</p>
<div class="cnblogs_code"><img id="code_img_closed_bafdf62b-3e70-4fc0-bebc-7138d9be0ba0" class="code_img_closed lazyload" data-src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif"><img id="code_img_opened_bafdf62b-3e70-4fc0-bebc-7138d9be0ba0" class="code_img_opened lazyload" style="display: none" data-src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif">
<div id="cnblogs_code_open_bafdf62b-3e70-4fc0-bebc-7138d9be0ba0" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 0, 1)">override fun onBindViewHolder(position: Int, mBinding: ItemMainPhotoCardBinding) {
mBinding.apply {
tvTitle.text </span>=<span style="color: rgba(0, 0, 0, 1)"> bean.getTitle()
updateProgress(</span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">)
}
}
</span><span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)"> fun updateProgress(mBinding: ItemMainPhotoCardBinding) {
mBinding.apply {
ivDown.isVisible </span>= !bean.isLocal && bean.progress <= 0<span style="color: rgba(0, 0, 0, 1)">
progress.isVisible </span>= bean.progress > 0<span style="color: rgba(0, 0, 0, 1)">
progress.setProgressValue(bean.progress)
}
}
override fun onBindViewHolder(
position: Int,
mBinding: ItemMainPhotoCardBinding,
payloads: List</span><Any?><span style="color: rgba(0, 0, 0, 1)">
) {
when (payloads[</span>0<span style="color: rgba(0, 0, 0, 1)">]) {
PAYLOAD_PROGRESS_TYPE </span>-><span style="color: rgba(0, 0, 0, 1)"> updateProgress(mBinding)
}
}</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p>自定义Decoration</p>
<div class="cnblogs_code"><img id="code_img_closed_efde6a3c-af76-4717-ae89-8784d4779c04" class="code_img_closed lazyload" data-src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif"><img id="code_img_opened_efde6a3c-af76-4717-ae89-8784d4779c04" class="code_img_opened lazyload" style="display: none" data-src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif">
<div id="cnblogs_code_open_efde6a3c-af76-4717-ae89-8784d4779c04" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> ScreenMainItemDecoration : RecyclerView.ItemDecoration() {
</span><span style="color: rgba(0, 0, 255, 1)">private</span> val bottomSideMargin =<span style="color: rgba(0, 0, 0, 1)">
Utils.getApp().resources.getDimensionPixelOffset(R.dimen.common_dp_128)
override fun getItemOffsets(
outRect: Rect,
view: View,
parent: RecyclerView,
state: RecyclerView.State
) {
val position </span>=<span style="color: rgba(0, 0, 0, 1)"> parent.getChildAdapterPosition(view)
val count </span>= parent.adapter?.itemCount ?: 0<span style="color: rgba(0, 0, 0, 1)">
val isLastItem </span>= position == count - 1<span style="color: rgba(0, 0, 0, 1)">
outRect.bottom </span>= <span style="color: rgba(0, 0, 255, 1)">if</span> (isLastItem) bottomSideMargin <span style="color: rgba(0, 0, 255, 1)">else</span> 0<span style="color: rgba(0, 0, 0, 1)">
}
}</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p> </p><br><br>
来源:https://www.cnblogs.com/LiuZhen/p/18959361
頁:
[1]