我是Android开发人员中的新手,现在正在移植我的iOS应用程序。 试图使RecyclerView变得非常复杂,但是有时在notifyDataSetChanged()方法之后,特定行的行为会在另一行上重复。
There are three rows with same ViewType in first part of RecyclerView
它们每个都有TextView和EditText小部件,我在CustomViewHolder类中进行填充。
第一行和第二行应该像往常一样工作:当我单击EditText时,键盘将打开。但是第三行EditText的焦点应该启动对话框警报。在重新加载适配器的DataSet之前,一切工作正常。重新加载DataSet之后,第一行的EditText也开始打开对话框警报,而不是正常打开键盘。
自定义行时,看起来好像缺少了某些东西,并以某种方式引用了同一对象。这是我的适配器代码(简体):
class NewRequestsRecyclerAdapter(val context: Context, val parameters:ArrayList<NewRequestsFragment.ParameterCell>,val delegate:NewRequestProtocol?): RecyclerView.Adapter<NewRequestsRecyclerAdapter.CustomViewHolder>() {
enum class RowType {
Header,Parameter
}
override fun getItemCount(): Int {
// count logic
}
override fun onCreateViewHolder(parent : ViewGroup, viewType: Int): CustomViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
val cellForRow = when (RowType.values()[viewType]) {
RowType.Header -> layoutInflater.inflate(R.layout.cell_header,parent,false)
RowType.Parameter -> layoutInflater.inflate(R.layout.cell_parameter_new_requests,parent,false)
}
return CustomViewHolder(cellForRow, RowType.values()[viewType])
}
override fun getItemViewType(position: Int): Int {
// Here's ItemViewType logic ...
}
override fun onBindViewHolder(holder: CustomViewHolder, position: Int) {
holder.bindMenu(position)
}
inner class CustomViewHolder(val cellView: View, val type:RowType): RecyclerView.ViewHolder(cellView) {
fun bindMenu(row:Int) {
when (type) {
RowType.Header -> {
val nameView = cellView.findViewById<TextView>(R.id.headerName)
// other logic to populate Header views
}
RowType.Parameter -> {
val nameView = cellView.findViewById<TextView>(R.id.paramName)
val editText = cellView.findViewById<EditText(R.id.paramEditText)
nameView.text = parameters[row-1].name
editText.apply {
hint = parameters[row-1].placeholder
when (parameters[row-1].type) {
NewRequestsFragment.PartsCellType.Name -> {
setText(delegate?.currentItem?.name)
}
NewRequestsFragment.PartsCellType.Number -> {
setText(delegate?.currentItem?.number)
}
NewRequestsFragment.PartsCellType.StateType-> {
setText(delegate?.currentItem?.state)
showSoftInputOnFocus = false
setOnFocusChangeListener { view, changed ->
if (changed) {
inputType = InputType.TYPE_NULL
delegate?.showStateDialog()
}
}
}
}
}
}
我知道可以解决此问题,我可以通过按钮显示警报,但是我想知道为什么我的代码会导致这种情况。
你能指导我我所缺少的吗?
答案 0 :(得分:0)
RecyclerView
这类问题,其中一个项目神秘地具有另一项目的属性或行为,通常是由于未重置视图所有者。
您正在定义视图持有者在创建时的行为,因此,第一次创建所有视图持有者并使其行为适当。当事情发生变化时,视图所有者将被重用,而不是重新创建。结果,事情可能会变得混乱,例如在键盘应该显示时打开对话框。
要更正此问题,请在绑定视图支架时使其重置为您想要的方式。