[英]how to recycle view in Recycler View
I am using Recycler view to create List View. 我正在使用Recycler视图创建列表视图。 With in the List View, Each of the item has Horizontal Scroll bar.
在列表视图中,每个项目都有水平滚动条。 In the horizontal scroll bar, I display either one item or 3 items based on particular business logic.
在水平滚动条中,我根据特定的业务逻辑显示一项或三项。 When listed, the first 2 scrolls display exactly what I wanted.
列出后,前2个滚动条完全显示我想要的内容。 But for further scrolls, I am having problem with the items that I display in the Horizontal Scroll view.
但是对于进一步的滚动,我在“水平滚动”视图中显示的项目有问题。 It displays multiple items where only one item should be there.
它显示多个项目,其中仅应有一个项目。 When investigated, I came to know that its because, the view is not recycled.
经过调查,我知道这是因为,视图未被回收。
After searching, I override this function, onViewRecycled. 搜索后,我重写了onViewRecycled这个函数。 This function is called when the issue starts (third and further on scrolls).
当问题开始时(滚动第三和更远),将调用此函数。 I don't know how to fix this issue.
我不知道如何解决此问题。 I am passing List of History to adapter at the beginning itself.
我一开始就将历史列表传递给适配器。
Kindly help me to resolve this. 请帮助我解决这个问题。
public class HistoryAdapter(users:List<HistoryItem>): RecyclerView.Adapter<HistoryAdapter.ViewHolder>() {
val TAG = "HistoryAdapter"
var historyList:List<HistoryItem>? =null
var context: Context? =null
init {
historyList = users
}
override fun onViewRecycled(holder: ViewHolder?) {
super.onViewRecycled(holder)
Log.d(TAG,"********************************************************************************************************************************Views are recycled****************************")
if (holder is HistoryAdapter.ViewHolder) {
val handler = Handler()
handler.post(Runnable { () -> notifyItemRemoved(holder.getOldPosition()) })
//notifyItemRangeChanged(holder.getAdapterPosition(),historyList!!.size())
}
}
override fun getItemId(position: Int): Long {
return super.getItemId(position)
}
override fun onBindViewHolder(holder: ViewHolder?, position: Int) {
var lung: Boolean? = false
var tag: String? = null
val historyItem: HistoryItem = historyList!!.get(position)
holder!!.profileImg.setImageBitmap(BitmapFactory.decodeFile(File(Environment.getDataDirectory().getAbsolutePath(), "data/" + context!!.getPackageName() + "/files/users/" + historyItem.uuidVal + "/portrait.png").getAbsolutePath()))
holder!!.notesTxt.setText(historyItem.sessionVal!!.getNote())
val date = historyItem.sessionVal!!.getDate()
var formatDayOfMonth = SimpleDateFormat("dd");
val day = Integer.parseInt(formatDayOfMonth.format(date));
val dayStr = day.toString();
formatDayOfMonth = SimpleDateFormat("MMM")
val month = formatDayOfMonth.format(date)
formatDayOfMonth = SimpleDateFormat("yyyy")
val year = formatDayOfMonth.format(date)
formatDayOfMonth = SimpleDateFormat("hh:mm a")
val currentTime = formatDayOfMonth.format(date)
val dateStr = month+" "+dayStr+", "+year
holder!!.dateTxt.setText(dateStr)
holder!!.timeTxt.setText(currentTime)
Log.d(TAG,"********************************************************************************************************************************************user =>"+historyItem.uuidVal);
Log.d(TAG,"********************************************************************************************************************************************current time =>"+currentTime);
var ambientTemp: Double? = null
var surfaceTemp: Double? = null
var coreBodyTemp: Double? = null
var heartRate: Int? = null
var lungAvailable: Boolean = false
var heartAvailable: Boolean = false
var tempAvailable: Boolean = false
try {
val tempRecording:TemperatureRecording = checkNotNull(historyItem.sessionVal!!.getTemperature())
tempAvailable = true
ambientTemp = tempRecording.getAmbientTemp()
surfaceTemp = tempRecording.getSurfaceTemp()
coreBodyTemp = TemperatureRecording.CalculateCoreBodyTemperature.getCoreBodyTemp(ambientTemp,surfaceTemp)
} catch(i: IllegalStateException) {
Log.w(TAG,"Temperature not available for user session")
tempAvailable = false
}
try {
val heartRecording:HeartRecording = checkNotNull(historyItem.sessionVal!!.getHeart())
heartAvailable = true
heartRate = heartRecording.getHeartRate()
} catch(i: IllegalStateException) {
Log.w(TAG,"Heart not available for user session")
heartAvailable = false
}
try {
val lungRecording:LungsRecording = checkNotNull(historyItem.sessionVal!!.getLungs())
lungAvailable = true
} catch(i: IllegalStateException) {
Log.w(TAG,"Lung not available for user session")
lungAvailable = false
}
Log.d(TAG,"********************************************************************************************************************************************temperature =>"+tempAvailable)
Log.d(TAG,"********************************************************************************************************************************************heart =>"+heartAvailable)
Log.d(TAG,"********************************************************************************************************************************************lung =>"+lungAvailable)
//Log.d(TAG,"********************************************************************************************************************************************ambient temp val =>"+ambientTemp)
//Log.d(TAG,"********************************************************************************************************************************************surface temp val =>"+surfaceTemp)
//Log.d(TAG,"********************************************************************************************************************************************heart val =>"+heartRate)
//Log.d(TAG,"********************************************************************************************************************************************lung val =>"+historyItem.sessionVal!!.getLungs())
val parentLinearLayout = holder!!.readingsView
//createLayout(holder!!.readingsView,tag,coreBodyTemp,heartRate)
var childLinearLayout: LinearLayout? = null
if(tempAvailable == true && heartAvailable == true && lungAvailable == true) {
for(i in 1..3) {
if(i == 1) {
val df = DecimalFormat("#.##");
childLinearLayout = createChildView(BitmapFactory.decodeResource(context!!.getResources(),R.drawable.temperature), df.format(coreBodyTemp).toString(), context!!.getString(R.string.temperatureStr))
parentLinearLayout.addView(childLinearLayout)
childLinearLayout = null
} else if(i == 2) {
childLinearLayout = createChildView(BitmapFactory.decodeResource(context!!.getResources(),R.drawable.heart), heartRate.toString(), context!!.getString(R.string.heartRate))
parentLinearLayout.addView(childLinearLayout)
childLinearLayout = null
} else if(i == 3) {
childLinearLayout = createChildView(BitmapFactory.decodeResource(context!!.getResources(),R.drawable.lung), "", "")
parentLinearLayout.addView(childLinearLayout)
childLinearLayout = null
}
}
} else if (tempAvailable) {
val df = DecimalFormat("#.##");
childLinearLayout = createChildView(BitmapFactory.decodeResource(context!!.getResources(),R.drawable.temperature), df.format(coreBodyTemp).toString(), context!!.getString(R.string.temperatureStr))
parentLinearLayout.addView(childLinearLayout)
childLinearLayout = null
} else if (heartAvailable) {
childLinearLayout = createChildView(BitmapFactory.decodeResource(context!!.getResources(),R.drawable.heart), heartRate.toString(), context!!.getString(R.string.heartRate))
parentLinearLayout.addView(childLinearLayout)
childLinearLayout = null
} else if (lungAvailable) {
childLinearLayout = createChildView(BitmapFactory.decodeResource(context!!.getResources(),R.drawable.lung), "", "")
parentLinearLayout.addView(childLinearLayout)
childLinearLayout = null
}
}
fun createChildView(icon: Bitmap,readingVal: String, readingTag: String) : LinearLayout {
val lp = LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT)
lp.weight = 1f
val parent: LinearLayout = LinearLayout(context!!)
parent.setOrientation(LinearLayout.HORIZONTAL)
parent.setLayoutParams(lp)
val imageView = ImageView(context!!)
val layoutParams = LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT)
layoutParams.weight = 0.4f
layoutParams.leftMargin = 10
layoutParams.rightMargin = 10
layoutParams.topMargin = 10
layoutParams.bottomMargin =10
imageView.setLayoutParams(layoutParams)
imageView.setImageBitmap(icon)
parent.addView(imageView)
val readingLayout = LinearLayout(context!!)
readingLayout.setOrientation(LinearLayout.VERTICAL)
val lp1 = LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT)
lp1.weight = 0.6f
lp1.topMargin = 10
readingLayout.setLayoutParams(lp)
val displayValue = TextView(context!!)
val layoutParams1 = LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, 0)
layoutParams1.weight = 0.7f
displayValue.setLayoutParams(layoutParams1)
displayValue.setText(readingVal)
readingLayout.addView(displayValue)
val displayTag = TextView(context!!)
layoutParams1.weight = 0.3f
displayTag.setLayoutParams(layoutParams1)
displayTag.setText(readingTag)
readingLayout.addView(displayTag)
parent.addView(readingLayout)
return parent
}
override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): ViewHolder? {
context = parent!!.getContext()
// create a new view
val v: View = LayoutInflater.from(parent!!.getContext())
.inflate(R.layout.layout_history_row, parent, false);
return ViewHolder(v)
}
override fun getItemCount(): Int {
return historyList!!.size()
}
public class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
public var profileImg: ImageView
public var dateTxt: TextView
public var timeTxt: TextView
public var locationTxt: TextView
public var notesTxt: TextView
//public var icon: ImageView
//public var readingTxt: TextView
//public var readingDescTxt: TextView
public var readingsView: LinearLayout
init {
profileImg = itemView.findViewById(R.id.profileImage) as ImageView
dateTxt = itemView.findViewById(R.id.date) as TextView
timeTxt = itemView.findViewById(R.id.time) as TextView
locationTxt = itemView.findViewById(R.id.location) as TextView
notesTxt = itemView.findViewById(R.id.notes) as TextView
//readingTxt = itemView.findViewById(R.id.readings) as TextView
//readingDescTxt = itemView.findViewById(R.id.readingsDesc) as TextView
// icon = itemView.findViewById(R.id.icon) as ImageView
readingsView = itemView.findViewById(R.id.readingsView) as LinearLayout
}
}
}
val history = findViewById(R.id.history) as RecyclerView
for(user in allUsers) {
val uuid: String? = user.getId()
Log.d(TAG,"*****************************************************************************************************************UUID=>"+uuid+"FirstName=>"+user.getFirstName()+",sessions size =>"+user.getSessions().size())
for(session in user.getSessions()) {
historyItems.add(HistoryItem(user.getId(),session))
}
}
history.setHasFixedSize(true);
history.setAdapter(HistoryAdapter(historyItems))
history.setLayoutManager(LinearLayoutManager(this))
I don't know what kind of "recycling" you're expecting, but what the RecyclerView does is that it will call onCreateViewHolder()
until it has enough viewholders to cover slightly more than what is visible on the screen. 我不知道您期望什么样的“回收”,但是RecyclerView的作用是它将调用
onCreateViewHolder()
直到它具有足够的视口以覆盖屏幕上可见的内容为止。 It will then call onBindViewHolder()
to populate the data in the created viewholders. 然后,它将调用
onBindViewHolder()
来填充创建的视图持有人中的数据。
When you start scrolling, it will grab one of the already created viewholders and feed it back into onBindViewHolder()
with a new position
. 当您开始滚动时,它将抓取一个已经创建的viewholder,并将其以新
position
反馈到onBindViewHolder()
。 It doesn't do any magic resetting of the viewholder. 它不会对视点保持器进行任何神奇的重置。
In your case, you're never resetting the readingsView
, so the adapter keeps adding children to it (which is why it contains more children than expected as you scroll further through the data). 在您的情况下,您永远不会重置
readingsView
,因此适配器会继续向其添加子项(这就是为什么当您进一步滚动数据时它包含比预期更多的子项的原因)。 In onBindViewHolder()
you'll need to remove all existing children from readingsView
before you start adding new ones. 在
onBindViewHolder()
,在开始添加新的子级之前,您需要从readingsView
删除所有现有的子级。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.