ItemTouchHelper未应用于适配器中的每个View

时间:2018-03-06 23:29:05

标签: java android android-recyclerview recycler-adapter itemtouchhelper

在实现滑动到删除功能时,我不小心让我对视图的前视图透明。在这样做的过程中,我发现了我的ItemTouchHandler的一个错误,它没有改变背景或隐藏文本。

在我看来,我的ItemTouchHelper没有被应用到我的ReycleViewAdapter中的每个视图和/或视图没有被更新,或者它们都经过多个小时的尝试调试后共享某种单亲。在我的智慧结束时,我已经包含了一个方便的GIF问题。

将ItemTouchHelper的onDrawChild()和onDrawChildOver()方法传递给我的片段以处理操作

bug example

代码

AllLists_fragment.java:

public class showAllLists_fragment extends android.support.v4.app.Fragment implements RecycleItemTouchHelper.RecyclerItemTouchHelperListener {

    private static final String TAG = "showAllLists";


    private RecyclerView mAllItemsView = null;
    private DataCommunication mData = null;
    private ItemTouchHelper.SimpleCallback itemTouchHelper = null;;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
        super.onCreateView(inflater, container, savedInstanceState);
        View view = inflater.inflate(R.layout.show_all_lists_frag, container, false);
        this.mAllItemsView = (RecyclerView) view.findViewById(R.id.allItems);
        this.itemTouchHelper = new RecycleItemTouchHelper(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT, this);
        new ItemTouchHelper(this.itemTouchHelper).attachToRecyclerView(this.mAllItemsView);
        this.mAllItemsView.setAdapter(this.mData.getAdapter());
        this.mAllItemsView.setLayoutManager(new LinearLayoutManager(getActivity()){
            //
            @Override
            public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
                try {
                    super.onLayoutChildren(recycler, state);
                } catch (IndexOutOfBoundsException e) {
                    Log.d(TAG, "Inconsistent Exception Caught -See stack trace");
                    e.printStackTrace();
                }
            }
        });
        viewShadow();

        return view;
    }

    @TargetApi(21)
    public void viewShadow(){
        this.mAllItemsView.setTranslationZ(100);
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        try {
            this.mData = (DataCommunication) context;
        } catch (ClassCastException e) {
            throw new ClassCastException(context.toString()
                    + " must implement DataCommunication");
        }
    }



    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if(isVisibleToUser){
            this.mData.getAdapter().notifyDataSetChanged();
            this.mData.refresh();

        }
    }

    @Override
    public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction, int position) {
        int noSwipeSize = mData.getAllToDo().size();
        if (direction == ItemTouchHelper.LEFT) {

            mData.deleteTask(mData.getAdapter().getResults().get(viewHolder.getAdapterPosition()));
            mData.getAdapter().notifyItemRangeRemoved(viewHolder.getAdapterPosition(), noSwipeSize);


        } else if (direction == ItemTouchHelper.RIGHT) {
            mData.completeTask(mData.getAdapter().getResults().get(viewHolder.getAdapterPosition()));
            mData.getAdapter().notifyItemRangeRemoved(viewHolder.getAdapterPosition(), noSwipeSize);

        }
    }

    @Override
    public void onChildDraw(Canvas c, RecyclerView recyclerView, ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
        final View foregroundView = ((com.lab1.ac01220.bloomv2.ViewHolder) viewHolder).getForeground();
        if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) {
            if(dX < 0){
                this.mData.getViewHolder().getDeleteText().setVisibility(View.VISIBLE);
                this.mData.getViewHolder().getCompleteText().setVisibility(View.INVISIBLE);
                this.mData.getViewHolder().getBackground().setBackgroundColor(getResources().getColor(R.color.colorAccent));
            } else if(dX >0){
                this.mData.getViewHolder().getCompleteText().setVisibility(View.VISIBLE);
                this.mData.getViewHolder().getDeleteText().setVisibility(View.INVISIBLE);
                this.mData.getViewHolder().getBackground().setBackgroundColor(getResources().getColor(R.color.colorComplete));
            }
        }
        ItemTouchHelper.SimpleCallback.getDefaultUIUtil().onDraw(c, recyclerView, foregroundView, dX, dY,actionState, isCurrentlyActive);
    }

    @Override
    public void onChildDrawOver(Canvas c, RecyclerView recyclerView, ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
        final View foregroundView = ((com.lab1.ac01220.bloomv2.ViewHolder) viewHolder).getForeground();

        ItemTouchHelper.SimpleCallback.getDefaultUIUtil().onDrawOver(c, recyclerView, foregroundView, dX, dY,actionState, isCurrentlyActive);
        }



    }

RecycleitemTouchHelper.java

    public RecycleItemTouchHelper(int dragDirs, int swipeDirs, RecyclerItemTouchHelperListener listener) {
        super(dragDirs, swipeDirs);
        this.listener = listener;
    }

    @Override
    public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
        return false;
    }

    @Override
    public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
        this.listener.onSwiped(viewHolder, direction, viewHolder.getAdapterPosition());
    }

    @Override
    public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {

        this.listener.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);


    }

    @Override
    public void onChildDrawOver(Canvas c, RecyclerView recyclerView,
                                RecyclerView.ViewHolder viewHolder, float dX, float dY,
                                int actionState, boolean isCurrentlyActive) {
        this.listener.onChildDrawOver(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
    }

    @Override
    public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
        final View foregroundView = ((ViewHolder) viewHolder).getForeground();
        getDefaultUIUtil().clearView(foregroundView);
    }

    @Override
    public int convertToAbsoluteDirection(int flags, int layoutDirection) {
        return super.convertToAbsoluteDirection(flags, layoutDirection);
    }


    public interface RecyclerItemTouchHelperListener {
        void onSwiped(RecyclerView.ViewHolder viewHolder, int direction, int position);

        void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive);
        void onChildDrawOver(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive);
    }
}

RecycleViewAdapter.java:

public class RecycleViewAdapter extends RecyclerView.Adapter<ViewHolder>{

    private LayoutInflater inflater = null;
    private List<GlobalLists> results = null;
    private DataCommunication mData = null;
    public RecycleViewAdapter(Context context, List<GlobalLists> results){
        this.inflater = LayoutInflater.from(context);
        this.results = results;
        this.mData = (DataCommunication)context;
    }



    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = inflater.inflate(R.layout.custom_row, parent, false);
        ViewHolder holder = new ViewHolder(view);
        this.mData.setViewHolder(holder);
        return holder;
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        GlobalLists item = this.results.get(position);
        holder.setRowTitle(item.getTitle());
        //Grab the first 14 characters of the contents if the row is not null
        if(item.getContents() != null){
            StringBuffer currentContent = new StringBuffer(item.getContents().substring(0, Math.min(item.getContents().length(),28)));
            if(item.getContents().length() > 28) currentContent.append("...");
            holder.setRowContent(currentContent.toString());
        }


    }

    public void reloadAdapterData(List<GlobalLists> refresh){
        this.results = refresh;
    }

    @Override
    public int getItemCount() {
        return this.results == null || this.results.isEmpty() ? 0 : this.results.size();
    }

    public  List<GlobalLists> getResults(){
        return this.results;
    }



}

1 个答案:

答案 0 :(得分:0)

问题在于我只是将第一个ViewHolder设置为全局变量,并且仅对该变量进行了更改。相反,我应该在onChildDraw中获取当前的View并在其上执行函数:

当时:

 @Override
    public void onChildDraw(Canvas c, RecyclerView recyclerView, ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
        final View foregroundView = ((com.lab1.ac01220.bloomv2.ViewHolder) viewHolder).getForeground();
        if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) {
            if(dX < 0){
                this.mData.getViewHolder().getDeleteText().setVisibility(View.VISIBLE);
                this.mData.getViewHolder().getCompleteText().setVisibility(View.INVISIBLE);
                this.mData.getViewHolder().getBackground().setBackgroundColor(getResources().getColor(R.color.colorAccent));
            } else if(dX >0){
                this.mData.getViewHolder().getCompleteText().setVisibility(View.VISIBLE);
                this.mData.getViewHolder().getDeleteText().setVisibility(View.INVISIBLE);
                this.mData.getViewHolder().getBackground().setBackgroundColor(getResources().getColor(R.color.colorComplete));
            }
        }
        ItemTouchHelper.SimpleCallback.getDefaultUIUtil().onDraw(c, recyclerView, foregroundView, dX, dY,actionState, isCurrentlyActive);
    }

应该是:

@Override
    public void onChildDraw(Canvas c, RecyclerView recyclerView, ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
        com.lab1.ac01220.bloomv2.ViewHolder current = (com.lab1.ac01220.bloomv2.ViewHolder) viewHolder;
        final View foregroundView = ((com.lab1.ac01220.bloomv2.ViewHolder) viewHolder).getForeground();
        if (isCurrentlyActive) {
            if(dX < 0){
                current.getDeleteText().setVisibility(View.VISIBLE);
                current.getCompleteText().setVisibility(View.INVISIBLE);
                current.getBackground().setBackground(getResources().getDrawable(R.drawable.ic_rounded_rectangle_accent));
            } else if(dX >0){
                current.getCompleteText().setVisibility(View.VISIBLE);
                current.getDeleteText().setVisibility(View.INVISIBLE);
                current.getBackground().setBackground(getResources().getDrawable(R.drawable.ic_rounded_rectangle_complete));
            }
        }
        ItemTouchHelper.SimpleCallback.getDefaultUIUtil().onDraw(c, recyclerView, foregroundView, dX, dY,actionState, isCurrentlyActive);
    }