添加grid item后列表不显示

来源:6-3 高易用HiDataItem组件封装-2

我有明珠一颗

2021-09-07 15:31:16

问题描述:

不添加grid item及之后的item,可以显示。添加了就不能显示。


相关截图:

https://img.mukewang.com/climg/61371335099ae5c006921280.jpg

相关代码:

package org.devio.`as`.hi.hiitem.hiitem2

import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView

abstract class HiDataItem<DATA, VH : RecyclerView.ViewHolder>(data: DATA?) {

val TAG: String = "HiDataItem"
private var mAdapter: HiAdapter? = null
var mData: DATA? = null

init {
this.mData = data
}

abstract fun onBindData(holder: VH, position: Int)

/**
* 返回item布局文件id
*/
open fun getLayoutRes(): Int {
return -1;
}

/**
* 返回item view
*/
open fun getItemView(parent: ViewGroup): View? {
return null
}

fun setAdapter(adapter: HiAdapter) {
this.mAdapter = adapter
}

/**
* 刷新列表
*/
fun refreshItem() {
if (mAdapter != null) {
mAdapter!!.refreshItem(this)
}
}

/**
* 移除item
*/
fun removeItem() {
if (mAdapter != null) {
mAdapter!!.removeItem(this)
}
}

/**
* 此item在列表中占有几列???
*/
open fun getSpanSize(): Int {
return 0
}

//提供空实现,子类可以实现,也可以不实现
open fun onViewAttachedToWindow(holder: VH){

}

open fun onViewDetachedFromWindow(holder: VH) {

}


}
      
​package org.devio.`as`.hi.hiitem.hiitem2

import android.content.Context
import android.util.SparseArray
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.StaggeredGridLayoutManager
import java.lang.ref.WeakReference
import java.lang.reflect.ParameterizedType

class HiAdapter(context: Context) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {

private val mRecylerViewRef: WeakReference<RecyclerView>? = null
private var mContext: Context
private var mLayoutInflater: LayoutInflater? = null
private var mDataSet = java.util.ArrayList<HiDataItem<*, out RecyclerView.ViewHolder>>()
private var mTypeArrays = SparseArray<HiDataItem<*, out RecyclerView.ViewHolder>>()

init {
mContext = context
mLayoutInflater = LayoutInflater.from(mContext)
}

/**
* 在指定索引处添加hidataitem
*/
fun addItemAt(index: Int, dataItem: HiDataItem<*, out RecyclerView.ViewHolder>, notify: Boolean) {
if (index > 0) {
mDataSet.add(index, dataItem)
} else {
mDataSet.add(dataItem)
}

val notifyPos = if (index > 0) index else mDataSet.size - 1
if (notify) {
notifyItemInserted(notifyPos)
}

}

/**
* 往现有集合末加mDataSet
*/
fun addItems(items: ArrayList<HiDataItem<*, out RecyclerView.ViewHolder>>, notify: Boolean) {
val start = items.size

for (item in items) {
mDataSet.add(item)
}

if (notify) {
notifyItemRangeChanged(start, items.size)
}
}

/**
* 删除指定索引处的item
*/
fun removeItemAt(index: Int): HiDataItem<*, out RecyclerView.ViewHolder>? {
if (index > 0 && index < mDataSet.size) {
val remove = mDataSet.removeAt(index)
notifyItemRemoved(index)
return remove
} else {
return null
}
}

/**
* 删除指定item
*/
fun removeItem(item: HiDataItem<*, out RecyclerView.ViewHolder>) {
val index = mDataSet.indexOf(item)
removeItemAt(index)
}

/**
* 刷新指定的item
*/
fun refreshItem(item: HiDataItem<*, out RecyclerView.ViewHolder>) {
val indexOf = mDataSet.indexOf(item)
notifyItemChanged(indexOf)
}

//将每一种item class hashcode 作为此item的type
override fun getItemViewType(position: Int): Int {
val item = mDataSet.get(position)
val type = item.javaClass.hashCode()
if (mTypeArrays.indexOfKey(type) < 0) {
mTypeArrays.put(type, item)
}
return type
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val dataItem = mTypeArrays.get(viewType);
var view = dataItem.getItemView(parent)
if (view == null) {
val layoutRes = dataItem.getLayoutRes()
if (layoutRes < 0) {
RuntimeException("dataItem : " + dataItem.javaClass.simpleName + " must override getItemView or getLayoutRes")
}
view = mLayoutInflater!!.inflate(layoutRes, parent, false)
}

return createViewHolderInternal(dataItem.javaClass, view!!)
}

override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {

val dataItem = getItem(position)
if (dataItem != null) {
dataItem.onBindData(holder, position)//会不会强转???
}
}

fun getItem(position: Int): HiDataItem<*, RecyclerView.ViewHolder>? {
if (position < 0 || position >= mDataSet.size) {
return null
}

return mDataSet[position] as HiDataItem<*, RecyclerView.ViewHolder>
}

override fun getItemCount(): Int {
return mDataSet.size
}

private fun createViewHolderInternal(javaClass: Class<HiDataItem<*, out RecyclerView.ViewHolder>>, view: View): RecyclerView.ViewHolder {
//判断是不是参数泛型
val superClass = javaClass.genericSuperclass
if (superClass is ParameterizedType) {
//得到泛型参数数组
val arguments = superClass.actualTypeArguments
for (argument in arguments) {
if (argument is Class<*> && RecyclerView.ViewHolder::class.java.isAssignableFrom(argument)) {
try {
argument.getConstructor(View::class.java).newInstance(view) as RecyclerView.ViewHolder
} catch (e: Throwable) {
e.printStackTrace()
}
}
}
}

return object : RecyclerView.ViewHolder(view) {}
}

//???
/**
* 为列表上的部分Item,适配网格布局
*/
override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {
super.onAttachedToRecyclerView(recyclerView)

val layoutManager = recyclerView.layoutManager
if (layoutManager is GridLayoutManager) {
val spanCount = layoutManager.spanCount
layoutManager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
//行数 每行Item数=spanCount/spanSize
override fun getSpanSize(position: Int): Int {
if (position < mDataSet.size) {
val dataItem = getItem(position)
if (dataItem != null) {
val spanSize = dataItem.getSpanSize()//???
return if (spanSize <= 0) spanCount else spanSize //只有1行或多行的处理???
}
}

return spanCount
}
}
}
}

override fun onDetachedFromRecyclerView(recyclerView: RecyclerView) {
super.onDetachedFromRecyclerView(recyclerView)
if (mRecylerViewRef != null) {
mRecylerViewRef.clear()
}
}

/**
* 当view滑入屏幕时 ???
*/
override fun onViewAttachedToWindow(holder: RecyclerView.ViewHolder) {
val recyclerView = getAttachRecyclerView()
if (recyclerView != null) {
val position = recyclerView!!.getChildAdapterPosition(holder.itemView)
val dataItem = getItem(position)
if (dataItem == null) return
val lp = holder.itemView.layoutParams
if (lp != null && lp is StaggeredGridLayoutManager.LayoutParams) {
val manager = recyclerView.layoutManager as StaggeredGridLayoutManager
val spanSize = dataItem.getSpanSize()//???
if (spanSize == manager!!.spanCount) {
lp.isFullSpan = true
}
}

//添加item自定义处理
dataItem.onViewAttachedToWindow(holder)
}
}

private fun getAttachRecyclerView(): RecyclerView? {
return if (mRecylerViewRef != null) mRecylerViewRef.get() else null
}


/**
* 当view滑出屏幕
*/
override fun onViewDetachedFromWindow(holder: RecyclerView.ViewHolder) {
val dataItem = getItem(holder.adapterPosition)
if (dataItem == null) return
dataItem.onViewDetachedFromWindow(holder)
}


}

子类的item用的是你写的

尝试过的解决方式:

通过打断点和日志发现,adpater onbindata没有判断当item是grid item时,将holder强转为自定义holder,这个应该是要加上的吧?我不确定。但项目中没有加。

写回答

1回答

LovelyChubby

2021-09-07

没有道理呀⊙∀⊙!,同过layout  inspct看下布局呢

0
hovelyChubby
hp dir="ltr">这块可参考下课程master最新代码,这块后来有小的调整

h022-03-09
共2条回复

移动端架构师

亲历日活千万级APP全流程落地,成为技术强+思维深+视野广 的P7级移动端架构师

577 学习 · 452 问题

查看课程