使用ItemTouchHelper.SimpleCallback

时间:2019-03-17 01:51:11

标签: android android-recyclerview

我正在使用ItemTouchHelper.SimpleCallback向我的RecyclerView添加拖放功能,但是在周围拖动物品后它会随机崩溃。有时会在前几次拖动项目后发生,但是有时我会坐在那里几分钟,只是移动项目以尝试在没有运气的情况下进行复制。列表项布局xml使用ConstraintLayout作为根视图。 RecyclerView是我使用TabLayout导航到的片段。我尝试查找错误,但找不到太多信息。

这是错误

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: ferox.bracket, PID: 12379
    java.lang.IllegalArgumentException: view is not a child, cannot hide android.support.constraint.ConstraintLayout{45c7cc V.E...... ......ID 0,-231-1080,-81 #7f0900a8 app:id/participant_parent_layout}
        at android.support.v7.widget.ChildHelper.unhide(ChildHelper.java:352)
        at android.support.v7.widget.RecyclerView$Recycler.getScrapOrHiddenOrCachedHolderForPosition(RecyclerView.java:6393)
        at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5896)
        at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5858)
        at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5854)
        at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2230)
        at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1557) 
        at ...

我的ItemTouchHelper:

this.helper = new ItemTouchHelper(new ItemTouchHelper
.SimpleCallback(ItemTouchHelper.UP | ItemTouchHelper.DOWN, ItemTouchHelper.START) {

    @Override
    public boolean onMove(@NonNull RecyclerView recyclerView, 
        @NonNull RecyclerView.ViewHolder viewHolder, 
        @NonNull RecyclerView.ViewHolder target) {

    int movedPosition = viewHolder.getAdapterPosition();
    int targetPostition = target.getAdapterPosition();

    swapSeed(players.get(movedPosition), players.get(targetPostition));
    Collections.swap(players, movedPosition, targetPostition);

    notifyItemMoved(movedPosition, targetPostition);
    notifyItemChanged(targetPostition);
    notifyItemChanged(movedPosition);

    return true;
    }

    @Override
    public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
    int position = viewHolder.getAdapterPosition();

    new AlertDialog.Builder(viewHolder.itemView.getContext()).setMessage("Delete participant?")
            .setPositiveButton("Yes", (dialog, which) -> {
                players.remove(position);
                notifyItemRemoved(position);
            })
            .setNegativeButton("No", (dialog, which) -> {
                defaultItemAnimator.setSupportsChangeAnimations(true);
                notifyItemChanged(position, null);
            })
            .create().show();
    }


    @Override
    public float getSwipeThreshold(@NonNull RecyclerView.ViewHolder viewHolder) {
    return .7f;
    }

    @Override
    public float getSwipeEscapeVelocity(float defaultValue) {
    return super.getSwipeEscapeVelocity(5f * defaultValue);
    }

    @Override
    public boolean isLongPressDragEnabled() {
    return false;
    }

});

我的片段的OnCreate:

    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    Intent intent = getActivity().getIntent();
    View v = inflater.inflate(R.layout.fragment_participants, container, false);
    CustomLinearLayoutManager linearLayoutManager = new CustomLinearLayoutManager(getContext(), RecyclerView.VERTICAL, false);

    DefaultItemAnimator defaultItemAnimator = new DefaultItemAnimator();
    defaultItemAnimator.setSupportsChangeAnimations(false);

    adapter = new RecyclerViewAdapter(getContext(), players, linearLayoutManager, defaultItemAnimator);

    recyclerView = v.findViewById(R.id.participant_list);
    recyclerView.setLayoutManager(linearLayoutManager);
    recyclerView.setItemAnimator(defaultItemAnimator);
    recyclerView.addItemDecoration(new DividerItemDecoration(getContext(), LinearLayoutManager.VERTICAL));
    recyclerView.setAdapter(adapter);
    adapter.getHelper().attachToRecyclerView(recyclerView);

    url = intent.getStringExtra("tournamentURL");
    ChallongeRequests.sendGet(response -> initPlayerList(response), ChallongeRequests.participantIndex(url));
    return v;
}

编辑:这似乎只有在滚动一些不确定的数量并同时拖动一个视口支架之后才会发生。我已经将DefaultItemAnimator.setSupportsChangeAnimations()设置为false,并且停止了该错误。但是,这又产生了一个问题,即在滑动后要求删除列表项时,如果单击“否”,则notifyItemChanged不会将视图滑回地点。我可以通过根据需要在我的代码中打开和关闭setSupportsChangeAnimations()来解决此问题,但是我觉得好像recyclerview的默认行为不应引起此错误。我不确定是否应该使用我尚未做过的itemanimator做某事,或者做什么。

0 个答案:

没有答案