我希望在显示数据时更新RecyclerView
,在我的情况下,我会显示带或不带标签的图片。
默认情况下,我在创建视图持有者时设置标签的可见性,这很好,但我希望用户在显示RecyclerView
时通过菜单更改标签可见性,所以我想手动更新RecyclerView
中所有现有视图的可见性。
我可以以某种方式获得所有现有的Views
吗?我需要所有,不仅仅是可见的,我不希望以后回收的View
没有更新......
答案 0 :(得分:56)
首先,你需要获得所有观点'显示的索引,然后你需要遍历每个索引,并使用每个视图的viewHolder:
final int firstVisibleItemPosition = layoutManager.findFirstVisibleItemPosition();
final int lastVisibleItemPosition = layoutManager.findLastVisibleItemPosition();
for (int i = firstVisibleItemPosition; i <= lastVisibleItemPosition; ++i) {
ViewHolder holder = (ViewHolder) mRecyclerView.findViewHolderForAdapterPosition(i);
...
}
编辑:似乎它并不总是返回您可能想要处理的所有ViewHolders。这似乎是一个更稳定的解决方案:
for (int childCount = recyclerView.getChildCount(), i = 0; i < childCount; ++i) {
final ViewHolder holder = recyclerView.getChildViewHolder(recyclerView.getChildAt(i));
...
}
答案 1 :(得分:17)
notifyDataSetChanged()
更新整个适配器列表大小并不方便。我只是尝试观察我放的日志,RV绑定了更多不可见的项目,实际上我找不到检索它们的方法。我最终在Set
或List
onBindViewHolder()
中的onViewRecycled()
ViewHolders以及private Set<AbstractViewHolder> mBoundViewHolders = new HashSet<>();
private int mVisibility = View.VISIBILE;
// So you can have access from the Activity/Fragment
public Set<AbstractViewHolder> getAllBoundViewHolders() {
return Collections.unmodifiableSet(mBoundViewHolders);
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position, List payloads) {
// Binding code
...
holder.view.setVisibility(mVisibility);
// Caching VH
mBoundViewHolders.add((AbstractViewHolder) holder);
}
@Override
public void onViewRecycled(RecyclerView.ViewHolder holder) {
// Uncaching VH
mBoundViewHolders.remove(holder);
}
// Your method becomes
public void updateVisibility(int visibility) {
mVisibility = visibility;
for (AbstractViewHolder holder : mBoundViewHolders) {
holder.updateVisibility(visibility);
}
}
中取消隐藏的缓存 :
notifyItemRangeChanged()
实现您的界面或抽象ViewHolder,以便您可以调用您的方法。 通过这种方式,您可以访问ViewHolder内容。
这就是我在FlexibleAdapter中取消选择而不是来调用toggleActivation()
的内容。如果用户有动画,则会执行所有操作,并且当我调用方法listagg()
时,背景也会更改。
如果您知道更好的方法来检索所有绑定的VH,请告诉我。
答案 2 :(得分:13)
在适配器类中:
Boolean isVisible = false;
public CustomAdapter(boolean isVisible) {
this.isVisible= isVisible;
}
@Override
public void onBindViewHolder(ViewHolder holder, final int position) {
...
if (isVisible){
//setVisibility(View.VISIBLE)
}else{
//setVisibility(View.INVISIBLE
}
}
public void updateVisibility(boolean newValue){
isVisible= newValue;
}
在Activity
中要更新实例化适配器的值:
adapter.updateVisibility(false);
adapter.notifydataSetChanged();
答案 3 :(得分:6)
所有现有视图都是可见的,加上RecyclerView
缓存的一些视图。您可以访问所有可见的View
:
View child;
for (int i = 0; i < mRecycler.getChildCount(); i++) {
child = mRecycler.getChildAt(i);
//In case you need to access ViewHolder:
mRecycler.getChildViewHolder(child);
}
即使您访问了缓存的View
,他们还没有绑定数据,因此您不知道标签是否可见。只需在Views
中设置剩余onBindViewHolder
的标签可见性。
View
的其余部分尚不存在,因此您无法对其进行任何更改,即使它们对所有这些都有相同的标签可见性状态
答案 4 :(得分:0)
以上所有解决方案仅提供可见的持有者,但实际上还有2-3个其他持有者受约束但不可见。为了得到那些, 我想到的最简单和准确的方法是让所有持有者:
int lastBoundHolderPosition = -1;
int lastDetachedHolderPosition = -1;
public void onBindViewHolder(final MyViewHolder holder, int position) {
lastBoundHolderPosition = position;
//Your implementation
}
public void onViewDetachedFromWindow(MyViewHolder holder){
lastDetachedHolderPosition = holder.holder.getAdapterPosition();
}
如果希望所有适配器都可见(加上绑定但不可见):
if(lastDetachedHolderPosition == -1){
for(pos = 0; pos <= lastDetachedHolderPosition; pos++){
ViewHolder holder = (ViewHolder) mRecyclerView.findViewHolderForAdapterPosition(pos);
}
}else{
if(lastBoundHolderPosition > lastDetachedHolderPosition){ //Scroll down
//get all the bound holders
for(int pos = lastDetachedHolderPosition + 1; pos <= lastBoundHolderPosition; pos++){
ViewHolder holder = (ViewHolder) mRecyclerView.findViewHolderForAdapterPosition(pos);
}
}else{ //Scroll up
//get all the bound holders
for(int pos = lastBoundHolderPosition ; pos <= lastDetachedHolderPosition-1; pos++){
ViewHolder holder = (ViewHolder) mRecyclerView.findViewHolderForAdapterPosition(pos);
}
}
}