我有RecyclerView
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swipe_task_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/toolbar">
<android.support.v4.widget.NestedScrollView
android:id="@+id/scroll_task_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fillViewport="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusableInTouchMode="true"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/rv_task_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/background_task_list" />
<android.support.v4.widget.Space
android:layout_width="match_parent"
android:layout_height="80dp" />
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
</android.support.v4.widget.SwipeRefreshLayout>
初始化:
rv_task_list.layoutManager = LinearLayoutManager(context)
rv_task_list.layoutManager.setAutoMeasureEnabled(true)
rv_task_list.isNestedScrollingEnabled = false
rv_task_list.adapter = adapter
在适配器中设置数据:
data.addAll(tasksToAdapter)
notifyDataSetChanged()
(UPD)适配器:
class TaskAdapter(private val view: ITaskList) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
val data: MutableList<ITaskItem> = mutableListOf()
lateinit var context: Context
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
Log.e("TaskAdapter", "onCreateViewHolder")
context = parent.context
if (viewType == TITLE_TYPE) {
val view = LayoutInflater.from(context).inflate(R.layout.card_title, parent, false);
return TaskTitleViewHolder(view);
} else {
val view = LayoutInflater.from(context).inflate(R.layout.card_task, parent, false);
return TaskViewHolder(view);
}
}
override fun getItemViewType(position: Int): Int {
return data[position].getTaskType()
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int)
{
Log.e("TaskAdapter", "onBindViewHolder(${position})")
if (getItemViewType(position) == TITLE_TYPE) {
(holder as TaskTitleViewHolder).bind(data[position] as TaskTitle)
}
else {
val task = data[position] as Task
(holder as TaskViewHolder).bind(task)
holder.itemView.setOnClickListener {
view.onSelectTask(task.id)
}
}
}
fun setData(tasks: List<Task>, showAllTasks: Boolean = false) {
data.clear()
val tasksToAdapter: MutableList<ITaskItem> = mutableListOf()
// List creating
data.addAll(tasksToAdapter)
notifyDataSetChanged()
}
override fun getItemCount(): Int = data.size
// ViewHolders
class TaskViewHolder(view: View) : RecyclerView.ViewHolder(view) {
private val tvTaskInfo: TextView = view.findViewById(R.id.tv_task_info)
private val tvTaskComments: TextView = view.findViewById(R.id.tv_task_comments)
private val tvTaskTitle: TextView = view.findViewById(R.id.tv_task_title)
private val viewHeader: View = view.findViewById(R.id.view_header)
private val tvEstimate: TextView = view.findViewById(R.id.tv_estimate)
private val layoutExpectedDate: LinearLayout = view.findViewById(R.id.layout_expected_date)
private val tvExpectedDate: TextView = view.findViewById(R.id.tv_expected_date)
private val ivIconComments: ImageView = view.findViewById(R.id.iv_comments_icon)
private val ivFlagComments: ImageView = view.findViewById(R.id.iv_flag_icon)
private val ivIconClock: ImageView = view.findViewById(R.id.iv_clock_icon)
private val layoutDateInformation: LinearLayout = view.findViewById(R.id.layout_date_information)
fun bind(task: Task) {
tvTaskInfo.text = "${task.projectName} ${task.id} (${task.type.localization})"
if (task.commentsUnread == 0) {
tvTaskComments.setTextColor(getColor(R.color.task_list_font_color_alpha))
ivIconComments.setImageDrawable(ContextCompat.getDrawable(App.get(), R.drawable.ic_with_readed_message))
} else {
tvTaskComments.setTextColor(getColor(R.color.task_list_font_color))
ivIconComments.setImageDrawable(ContextCompat.getDrawable(App.get(), R.drawable.ic_with_unreaded_message))
}
tvTaskComments.text = "${task.commentsUnread}/${task.commentsAll}"
tvTaskTitle.text = Html.fromHtml(task.title)
viewHeader.setBackgroundColor(getColorToTaskState(task.status))
layoutDateInformation.visibility = View.GONE
if (!(task.status == TaskState.InWork || task.status == TaskState.Negotiation)) {
return
}
if (task.getFormattedExpectedDate().isNotBlank()) {
tvExpectedDate.text = task.getFormattedExpectedDate()
layoutExpectedDate.visibility = View.VISIBLE
}
else {
layoutExpectedDate.visibility = View.GONE
}
layoutDateInformation.visibility = View.VISIBLE
ivIconClock.visibility = View.GONE
if (task.type == TaskType.EstimateRework || task.type == TaskType.Design) {
with (task.getFormattedEstimateTime()) {
if (isNotBlank()) {
tvEstimate.text = "${App.get().getString(R.string.estimated)} ${task.getFormattedEstimateTime()}"
tvEstimate.visibility = View.VISIBLE
}
else
tvEstimate.visibility = View.GONE
}
ivIconClock.visibility = View.VISIBLE
ivIconClock.setImageDrawable(getImage(R.drawable.ic_clock))
ivIconClock.setColorFilter(getColor(R.color.task_list_clock_estimated), PorterDuff.Mode.SRC_ATOP)
ivFlagComments.setImageDrawable(null)
} else {
tvEstimate.text = task.roughEstimate ?: ""
ivIconClock.visibility = View.VISIBLE
ivIconClock.setImageDrawable(getImage(R.drawable.ic_clock))
ivFlagComments.setImageDrawable(getImage(R.drawable.ic_flag))
}
}
}
class TaskTitleViewHolder(view: View) : RecyclerView.ViewHolder(view) {
private val tvTaskTitle: TextView = view.findViewById(R.id.tv_tasks_title)
private val layoutCircle: FrameLayout = view.findViewById(R.id.layout_title_circle)
private val layoutCircleAdditional: FrameLayout = view.findViewById(R.id.layout_title_circle_additional)
fun bind(taskTitle: TaskTitle) {
tvTaskTitle.text = taskTitle.content.toUpperCase()
setCircle(layoutCircle, taskTitle.taskState)
if (taskTitle.additionalTaskState != null) {
layoutCircleAdditional.visibility = View.VISIBLE
setCircle(layoutCircleAdditional, taskTitle.additionalTaskState!!)
}
}
private fun setCircle(layout: FrameLayout, state: TaskState) {
if (state == TaskState.WaitToWork) {
layout.background = getImage(R.drawable.ic_waiting)
} else {
val drawable = ContextCompat.getDrawable(App.get(), R.drawable.task_header_circle)
drawable.setColorFilter(getColorToTaskState(state), PorterDuff.Mode.SRC_ATOP)
layout.background = drawable
}
}
}
我有两种类型的View Holder。当我在适配器中设置数据时,所有ViewHolders(超过90个)都是同时创建的。 onCreateViewHolder
和onBindViewHolder
被逐个调用90次。
为什么会发生?
答案 0 :(得分:3)
我认为您的问题是在RecyclerView
内使用NestedScrollView
。 NestedScrollView
扩展为包含所有内部子项(在这种情况下为RecyclerView
)
您可以尝试使用app:layout_behavior="@string/appbar_scrolling_view_behavior"
但正如官方文档所述
切勿向滚动视图添加
RecyclerView
或ListView
。这样做会导致用户界面性能下降和用户体验不佳。
答案 1 :(得分:0)
因为您的RecyclerView上有android:layout_height="wrap_content"
。
你应该给它一个尺寸。 wrap_content
将围绕所有90个项目进行包装,尝试创建所有这些视图。使用match_parent
或其他一些设定高度。
答案 2 :(得分:0)
我有类似的问题。我认为我的案例中的解决方案是禁用QuerySet
的自定义LayoutManager。我的代码在Kotlin中,但应该很容易适应Java:
supportsPredictiveItemAnimations