Android Studio循环视图适配器循环getItemViewType()

pexxcrt2  于 2022-11-25  发布在  Android
关注(0)|答案(1)|浏览(281)

我的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);
            });
        }
    }
huus2vyu

huus2vyu1#

您所面临的问题是,您根据wallPostObserver更新RecyclerView,该wallPostObserver会查找wallPostList中的更改。由于如果List发生更改,则回收程序视图中会发生更改,并且会调用getItemViewType方法,因此可能会出现问题。如果您设置为仅在用户选择更新时或在固定间隔内更新recyclerView,则您将“你可以通过创建一个方法来解决这个问题,如果列表发生变化,这个方法就会触发(不使用Observer),你可以定义最大更新间隔,这样你就不会总是丢弃整个列表。

相关问题