我正在使用Recycler视图来创建列表视图。在列表视图中,每个项目都有水平滚动条。在水平滚动条中,我根据特定的业务逻辑显示一个项目或3个项目。列出时,前两个卷轴显示我想要的内容。但是对于进一步的滚动,我在水平滚动视图中显示的项目有问题。它显示多个项目,其中只有一个项目。经过调查,我开始知道它的原因是,视图没有被回收。
搜索之后,我重写了这个函数onViewRecycled。问题开始时会调用此函数(第三个以及滚动时)。我不知道如何解决这个问题。我正在将历史列表传递给适配器。
请帮我解决这个问题。
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))
答案 0 :(得分:1)
我不知道你期望什么样的“回收”,但RecyclerView做的是它会调用onCreateViewHolder()
,直到它有足够的视图来覆盖比屏幕上可见的更多的视图。 。
然后,它将调用onBindViewHolder()
来填充创建的视图中的数据。
当您开始滚动时,它会抓取一个已创建的视图,并使用新的onBindViewHolder()
将其反馈回position
。它不会对视图符号进行任何魔术重置。
在您的情况下,您永远不会重置readingsView
,因此适配器会不断向其添加子项(这就是为什么当您在数据中进一步滚动时,它包含的子项数比预期的多)。在onBindViewHolder()
中,您需要先从readingsView
删除所有现有的子项,然后再开始添加新的子项。