我的recyclerview的适配器不断调用getItemViewType()
,似乎没有停止的迹象。
我还在onBindViewHolder()
、onCreateViewHolder()
和viewHolder绑定函数中打印日志,但只有getItemViewType被无限调用。
我怎样才能解决这个问题?
我的片段:
我在每个函数中添加了log,并没有看到任何函数被连续调用。
public class Fragment{
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (presenter == null) {
presenter = new Presenter(this);
}
initViewModel();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
setRecyclerView();
//this will modify adapter
loadData();
return rootView;
}
void initViewModel(){
messageViewModel = new ViewModelProvider(this).get(messageViewModel.class);
final Observer<ArrayList<WallPost>> wallPostObserver = wallPostList -> {
//this will modify adapter
updateRecyclerView(wallPostList);
};
messageViewModel.getWallPostsLiveData().observe(this, wallPostObserver);
}
public void setRecyclerView() {
layoutManager = new LinearLayoutManager(getContext());
recyclerView.setLayoutManager(layoutManager);
adapter = new Adapter(getContext(), new ArrayList<>(), Repository.getInstance().getMemberData().getValue(), getType());
recyclerView.setAdapter(adapter);
recyclerView.addOnScrollListener(scrollListener);
}
}
我的适配器getItemViewType(int position)
功能:
适配器getItemCount()
可以像getItemViewType(int position)
一样连续调用。
@Override
public int getItemViewType(int position) {
if (wallPostList.size() == 0) {
return VIEW1;
}else if(position >= wallPostList.size()){
return VIEW7;
}
WallPost wallPost = wallPostList.get(position);
Log.d("Adapter","position:"+position);
if(wallPost.getStatus().equals(POST_STATUS_REVOKE)){
return VIEW8;
}
switch (wallPost.getType()) {
case azz:
return VIEW5;
case axx:
return VIEW6;
case ayy:
default:
if(wallPost.getMsgItemList().size() > 0){
return VIEW4;
}else if(StringUtils.checkHasLink(wallPost.getContent())){
return VIEW3;
}else {
return VIEW2;
}
}
}
更新:导致问题的代码
我发现了导致此问题的原因,我通过在自定义视图中添加一个标志来限制不重复onMeansure来解决此问题,但我不知道为什么这会使适配器重复调用getItemViewType(int position)
和getItemCount()
。
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if(type.equals(SINGLE)){
info.post(()->{
halfWidth = (info.getMeasuredWidth()- arrowImageView.getMeasuredWidth())/2;
name.setMaxWidth(halfWidth-image.getMeasuredWidth());
tvNoticeTime.setMaxWidth(halfWidth-image.getMeasuredWidth());
});
}
else if(type.equals(MULTI)){
info.post(()->{
name.setMaxWidth(info.getMeasuredWidth()-image.getMeasuredWidth() - (int)PixelUtil.convertDpToPixel(8,context));
});
}
else{
int dis = (int)PixelUtil.convertDpToPixel(8,context);
info.post(()->{
name.setMaxWidth(info.getMeasuredWidth()-image.getMeasuredWidth()-dis-
infoImageView.getMeasuredWidth()-dis);
});
}
}
1条答案
按热度按时间huus2vyu1#
您所面临的问题是,您根据
wallPostObserver
更新RecyclerView,该wallPostObserver
会查找wallPostList
中的更改。由于如果List发生更改,则回收程序视图中会发生更改,并且会调用getItemViewType
方法,因此可能会出现问题。如果您设置为仅在用户选择更新时或在固定间隔内更新recyclerView,则您将“你可以通过创建一个方法来解决这个问题,如果列表发生变化,这个方法就会触发(不使用Observer
),你可以定义最大更新间隔,这样你就不会总是丢弃整个列表。