0

我正在使用本教程为我的 RecyclerView 构建一个 itemTouchListener。recyclerview 中的项目比屏幕显示的要多(超过 10 个),因此回收开始行动。itemtouchHelper 处理上下和左右移动。经过 2 天的挣扎(将 setStableIds 设置为 true,这会在上下移动时导致查看器视图闪烁),我终于得到了更好的行为。我的关键功能代码:

  @Override
    public int getItemCount() {
        return questionlist.size();
    }

    @Override
    public void onViewMoved(int oldPosition, int newPosition) {
        targetqueobj = questionlist.get(oldPosition);

        this.fromPosition = oldPosition;
        this.toPosition = newPosition;
        questionlist.remove(targetqueobj);
        questionlist.add(newPosition, targetqueobj);

        //    targetqueobj.setinturn(toPosition+1);
    }



    @Override
    public void onViewSwiped(final RecyclerView.ViewHolder thisviewholder,final int position, int direction) {
        targetqueobj = questionlist.get(position);
        if (direction == ItemTouchHelper.LEFT){
            // saveqset();
            Intent intent = new Intent(context, QuestionEditActivity.class);
            intent.putExtra("com.logictop.mqapp.QuestionObjParcelable",targetqueobj);
            context.startActivity(intent);
        }
        if (direction == ItemTouchHelper.RIGHT) {
            // DIALOG
            AlertDialog.Builder builder = new AlertDialog.Builder(context);
            builder.setMessage(R.string.remove_question);
            builder.setNegativeButton(R.string.No, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface arg0, int arg1) {
             //       thisviewholder.itemView.setAlpha(1);
                    notifyDataSetChanged();
                }
            });

            builder.setPositiveButton(R.string.Yes, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface arg0, int arg1) {
                    questionlist.remove(position);
                    notifyItemRemoved(position);
                    notifyItemRangeChanged(position, getItemCount()-position);
                }
            });
            Dialog dialog = builder.create();
            dialog.setCancelable(false);
            dialog.setCanceledOnTouchOutside(false);
            dialog.show();

        }
    }
    if (direction == ItemTouchHelper.RIGHT) {
        // DIALOG
        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        builder.setMessage(R.string.remove_question);
        builder.setNegativeButton(R.string.No, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface arg0, int arg1) {
                thisviewholder.itemView.setAlpha(1);
                notifyDataSetChanged();
            }
        });

        builder.setPositiveButton(R.string.Yes, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface arg0, int arg1) {
                questionlist.remove(position);
                notifyItemRemoved(position);
                notifyItemRangeChanged(position, getItemCount()-position);
            }
        });
        Dialog dialog = builder.create();
        dialog.setCancelable(false);
        dialog.setCanceledOnTouchOutside(false);
        dialog.show();

    }
}

问题是这样的。尽管 recyclerview 运行平稳,项目很好地改变了位置,但是当一个项目被滑开时,有时当 recyclerview 向下滚动时另一个项目看起来也被删除了(所以看起来被删除的另一个项目填充了相同的“屏幕”位置滚动后在回收站视图中)。它不会每次都发生,它主要发生在某些特定位置的视图被滑动时。如果我向上或向下移动邻居视图,则可以弥补“差距”。

抱歉,在我第二次删除视图并向下滚动后,您必须稍等片刻才能看到发生的事情

我已经尝试了在这里找到的所有解决方案(notifyDataChanged、notifyItemRangeChanged(每个参数组合)。但是没有什么能让我有一个稳定的行为。在大量的stackoverflow搜索之后,我决定遵循 holder.setIsRecyclable(false) 即使我不想的建议这样做(因为它毕竟消除了拥有recyclerview的意义)。但在这种情况下,会出现其他问题。你会在下面看到当大部分视图被刷掉时,它们较低的视图不会离开屏幕,即使他们显然已经“离开了适配器”(不能将它们刷掉)。最后,最后一个视图仍然卡住了。

您也必须在这里稍等片刻,最后您会看到卡住的视图

我已经在一个全新的项目中测试了这两种方式,没有任何外部影响。我曾尝试放入notifyDataChanged()clearView 的覆盖功能。似乎没有什么能提供一个坚如磐石的稳定回收者视图,它本身不会在某个时候出现差距。

现在的问题是:有没有办法让回收工作的回收工作表现得像它应该表现的那样,还是我应该接受这种情况?非常感谢您的关注!

更新 1---------------------------------------- 正如我被告知可能存在问题,thisviewholder.itemView.setAlpha(1);我将其与相应的覆盖一起注释掉onChildDraw(它的整体),用于在滑出视图时淡出视图。所以现在什么都看不见了。问题仍然存在。

更新 2---------------------------- 我已强制执行 stableIds(已经执行过一次但没有成功)

@Override
public long getItemId(int position){
    return questionlist.get(position).getquestionid();
}

和适配器构造器

public QSetEditAdapter(ArrayList<QuestionObj_prcl> questionlist, Context context) {
        this.context = context;
        this.questionlist = questionlist;
        setHasStableIds(true);
    }

问题仍然存在。

更新 3---------------------------- 我最终使用了不同的教程,现在一切都按预期工作。非常感谢!

4

2 回答 2

2

以这种方式更改您的适配器

于 2017-11-21T21:40:13.203 回答
-1

我不知道为什么会发生这种情况 正是在列表下方的方法中,它保留了您第一次给它的值并且不会更新此值!

公共无效 onViewSwiped (int 位置)

但是解决办法是什么???解决方案是使用 -> touchHelper.startSwipe(holder) 方法例如:

holder.itemView.setOnTouchListener (new View.OnTouchListener () { VerOverride public boolean onTouch (View view, MotionEvent event) { if (event.getAction () == MotionEvent.ACTION_DOWN) { Update = false; touchHelper.startSwipe (holder); } 返回真; } });

此方法的工作是重新加载已删除的动画和视图 祝你好运

于 2020-07-05T10:06:02.237 回答