【问题标题】:java.lang.IllegalStateException: Cannot call this method while RecyclerView is computing a layout or scrolling when notifydatasetChanged()java.lang.IllegalStateException:当 RecyclerView 正在计算布局或在 notifydatasetChanged() 滚动时无法调用此方法
【发布时间】:2017-06-21 08:50:53
【问题描述】:

为了在创建activity后调用API,我需要对索引为“0”的RecyclerView项执行点击事件。

为此,我在 onBindviewHolder 调用 holder.view.performClick 事件。但问题是我需要在 onClick 事件中调用 notifydataSetChanged() 方法来更新适配器。最初,它将自动单击位置“0”并调用 notifydataSetChanged() 方法并崩溃。 这个问题的解决方案是什么?请帮忙。

public void onBindViewHolder(ViewHolder holder, int position) {
    if (position==0){
        holder.itemView.performClick();
    }

我在 MainActivity.class 中调用了这个接口

public void onRecyclerViewItemClick(@NonNull View view, @NonNull CalendarDTO calendarDTO, int position) {
    isClickedPosition=position;
    adapter.notifyDataSetChanged();
    Toast.makeText(this, calendarDTO.getDate(), Toast.LENGTH_SHORT).show();
}

请检查错误:-

FATAL EXCEPTION: main
Process: in.playin.calendarrecyclerview, PID: 4063
java.lang.IllegalStateException: Cannot call this method while RecyclerView is computing a layout or scrolling
    at android.support.v7.widget.RecyclerView.assertNotInLayoutOrScroll(RecyclerView.java:2575)
    at android.support.v7.widget.RecyclerView$RecyclerViewDataObserver.onChanged(RecyclerView.java:4932)
    at android.support.v7.widget.RecyclerView$AdapterDataObservable.notifyChanged(RecyclerView.java:11359)
    at android.support.v7.widget.RecyclerView$Adapter.notifyDataSetChanged(RecyclerView.java:6636)
    at in.playin.calendarrecyclerview.CalendarRecyclerViewAdapter$ViewHolder$1.onClick(CalendarRecyclerViewAdapter.java:115)
    at android.view.View.performClick(View.java:5207)
    at in.playin.calendarrecyclerview.CalendarRecyclerViewAdapter.onBindViewHolder(CalendarRecyclerViewAdapter.java:59)
    at in.playin.calendarrecyclerview.CalendarRecyclerViewAdapter.onBindViewHolder(CalendarRecyclerViewAdapter.java:22)
    at android.support.v7.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:6356)
    at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:6389)
    at android.support.v7.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:5335)
    at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5598)
    at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5440)
    at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5436)
    at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2224)
    at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1551)
    at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1511)
    at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:595)
    at android.support.v7.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3583)
    at android.support.v7.widget.RecyclerView.onMeasure(RecyclerView.java:3025)
    at android.view.View.measure(View.java:18809)
    at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:715)
    at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:461)
    at android.view.View.measure(View.java:18809)
    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5955)
    at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
    at android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:139)
    at android.view.View.measure(View.java:18809)
    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5955)
    at android.support.v7.widget.ActionBarOverlayLayout.onMeasure(ActionBarOverlayLayout.java:393)
    at android.view.View.measure(View.java:18809)
    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5955)
    at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
    at android.view.View.measure(View.java:18809)
    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5955)
    at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1465)
    at android.widget.LinearLayout.measureVertical(LinearLayout.java:748)
    at android.widget.LinearLayout.onMeasure(LinearLayout.java:630)
    at android.view.View.measure(View.java:18809)
    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5955)
    at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
    at com.android.internal.policy.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2643)
    at android.view.View.measure(View.java:18809)
    at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2112)
    at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1228)
    at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1464)
    at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1119)
    at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6060)
    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:858)

【问题讨论】:

  • 请跟踪堆栈。
  • 请检查错误跟踪

标签: android android-recyclerview notifydatasetchanged


【解决方案1】:

试试这个

在 OnBindViewHolder 中

public static  boolean isPerformClicked;
int performClickCount;

 @Override
public void onBindViewHolder(ViewHolder viewHolder, int i) {
    if (i==0){
        viewHolder.tv_android.setBackgroundColor(Color.RED);
        if (performClickCount==0){
            isPerformClicked = true;
            viewHolder.itemView.performClick();
        }else{
            viewHolder.tv_android.setBackgroundColor(Color.RED);
        }

    }else{
        isPerformClicked=false;
        performClickCount = performClickCount+1;
        viewHolder.tv_android.setBackgroundColor(Color.YELLOW);

    }
    if (i!=BlankFragment.selectedPosition){
        viewHolder.tv_android.setBackgroundColor(Color.YELLOW);
    }else{
        viewHolder.tv_android.setBackgroundColor(Color.RED);
    }

    viewHolder.tv_android.setText(android_versions.get(i).getAndroid_version_name());
    Picasso.with(context).load(android_versions.get(i).getAndroid_image_url()).resize(120, 60).into(viewHolder.img_android);
}

在持有人项目点击或项目

  @Override
public void onRecyclerViewItemClick(@NonNull View view, @NonNull AndroidVersion calendarDTO, int position) {
    selectedPosition=position;
    Toast.makeText(getContext(),String.valueOf(position), Toast.LENGTH_SHORT).show();
    if (!isPerformClicked){
        adapter.notifyDataSetChanged();
    }
}

【讨论】:

  • 请避免使用public static
【解决方案2】:
public void onBindViewHolder(ViewHolder holder, int position) {
    holder.itemView.setOnClickListener(null);
    if (position == 0) {
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                 holder.itemView.performClick();
            }
        });
    }
}

【讨论】:

  • 我在不同的活动中使用界面..!
  • 试试这个代码,我已经编辑过了。为 holder.itemview.setOnClickListener 更改您自己的布局点击事件
  • 我们需要自己执行自动点击,您的代码声明首先手动点击然后执行自动点击..!
  • 是的..!它没有执行点击事件..!
【解决方案3】:

根据您的描述,您必须以适当的方式编写 toast 的上下文,如果您在适配器中,则使用 context,如果您处于片段或活动中,则根据您的上下文记下它.

谢谢...

【讨论】:

  • 界面处于不同的活动状态。所以我使用“this”,但问题不同。
  • 然后将 context 设置为 perameter 并使用它而不是 this.. 它会给你错误。\
  • java.lang.IllegalStateException: 当上面的 notifydatasetChanged() 出现错误时,RecyclerView 正在计算布局或滚动时无法调用此方法..!它与上下文或吐司无关..!
  • 由于 notifydatasetChanged() 方法导致的错误,因为它在 recyclerview 完成放置项目之前调用..!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-14
  • 1970-01-01
  • 1970-01-01
  • 2017-04-12
  • 2016-02-10
  • 1970-01-01
相关资源
最近更新 更多