我有一个RecyclerView
,其中每个元素都有一个onClickEventListener()
来改变外观。它可以正常工作,但是我实际上需要更改所有其他元素的外观。具体来说,我需要在clicked元素中填充颜色,而其他元素只能带有笔触。我认为,比遍历RecyclerView
的所有元素的数组,还有一种更为优雅的方法。
我当前的代码如下:
vh.mImageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
GradientDrawable typeShape = (GradientDrawable) vh.mImageView.getDrawable();
if (vh.clicked) {
typeShape.setColor(Color.parseColor("#00ff5800"));
} else {
typeShape.setColor(Color.parseColor("#ff5800"));
}
vh.clicked = !vh.clicked;
}
});
答案 0 :(得分:1)
我认为,“最佳”方法是使用大多数人不熟悉的RecyclerView API的一部分: notifyItemRangeChanged()
接受有效载荷对象。
传递有效负载对象时,将调用onBindViewHolder()
的特殊版本,并将该有效负载传递给此方法。
这一切使您可以高效地重新绑定任何显示的ViewHolder对象,并且仅更新您知道已更改的视图部分。
在您的特定示例中,您可以让适配器跟踪selectedPosition
,并让onBindViewHolder()
方法根据项目的位置是否等于当前所选位置来设置项目的背景:
private void updateBackground(ViewHolder holder, int position) {
holder.itemView.setBackgroundResource(
(position == selectedPosition) ? R.drawable.highlight : R.drawable.stroke);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
updateBackground(holder, position);
// other view binding stuff
}
然后,您可以也具有特殊的onBindViewHolder()
调用的实现,以进行部分更新:
@Override
public void onBindViewHolder(ViewHolder holder, int position, List<Object> payloads) {
if (payloads != null && payloads.contains("BACKGROUND")) {
updateBackground(holder, position);
}
}
同时设置了这两种设置后,只要更改所选位置,就可以致电:
adapter.selectedPosition = 23; // or whatever else
adapter.notifyItemRangeChanged(0, adapter.getItemCount(), "BACKGROUND");
调用此特殊版本的notifyItemRangeChanged()
时,系统将调用特殊的onBindViewHolder()
,您将有机会重新绘制所有当前可见视图的背景。但是,您不会浪费时间来更新任何当前不可见的视图,也不会浪费时间来绑定完全没有改变的数据(规范onBindViewHolder()
实现中的所有“其他视图绑定内容”)
答案 1 :(得分:1)
创建一个变量以保存选择:
add_filter( 'pre_get_document_title', function( $title ) {
global $post;
if ( ! $post || ! $post->post_content ) {
return $title;
}
if ( preg_match( '#\[mc_set_title.*\]#', $post->post_content, $matches ) !== 1 ) {
return '';
}
return do_shortcode( $matches[0] );
} );
add_shortcode( 'mc_set_title', function( $atts ) {
if ( ! doing_filter( 'pre_get_document_title' ) ) {
# just remove the shortcode from post content in normal shortcode processing
return '';
}
# in filter 'pre_get_document_title' - you can use $atts and global $post to compute the title
return 'MC TITLE';
} );
在您的onClickListener内部:
int selectedItem = -1;// -1 means no selected item by default.
最后,无论是在ViewHolder还是onBindViewHolder中:
int position = getAdapterPosition();
// Make sure your position is available on your list.
if (position != RecyclerView.NO_POSITION) {
if (position == selectedItem) {
return;// Here, I don't want to generate a click event on an already selected item.
}
int currentSelected = selectedItem;// Create a temp var to deselect an existing one, if any.
selectedItem = position;// Check item.
if (currentSelected != -1) {
notifiyItemChanged(currentSelected);// Deselected the previous item.
}
notifyItemChanged(selectedItem);// Select the current item.
}