RecyclerView之item左滑喜欢右滑不喜欢~

话不多说,直接上图,看看是不是你的菜~

列表左右滑

参考:https://github.com/ehanxuan/Android-ItemTouchHelper-Demo

ItemTouchHelper

了解RecyclerView的同学都知道,item的操作都是通过ItemTouchHelper来处理的。
ItemTouchHelper用法很简单,初始化,然后绑定RecyclerView即可

        ItemTouchHelper mItemTouchHelper = new ItemTouchHelper(callback);
        mItemTouchHelper.attachToRecyclerView(like_me_list);

注意到ItemTouchHelper初始化时的参数了吗?
其实这个callback就是ItemTouchHelper.Callback,ItemTouchHelper.Callback是对item操作的回调类,比如item的move swipe等。

要想定制化我们的左右滑,最重要的就是重写ItemTouchHelper.Callback

ItemTouchHelper.Callback

实现如上GIF的效果

  1. 点击时,所点击的view要提到顶部(不然会被其他的item遮盖)
  2. 根据滑动的轨迹,让item按照需要的轨迹移动
  3. 移动的参数,移动后的处理

点击时,所点击的view要提到顶部

参考了源码,长按拖动时,item就是提到顶部的。

    public static void takeViewTopInRec(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, boolean isCurrentlyActive) {
        if (Build.VERSION.SDK_INT >= 21 && isCurrentlyActive) {
            Object originalElevation = viewHolder.itemView.getTag(android.support.v7.recyclerview.R.id.item_touch_helper_previous_elevation);
            if (originalElevation == null) {
                originalElevation = ViewCompat.getElevation(viewHolder.itemView);
                float newElevation = 1.0F + findMaxElevation(recyclerView, viewHolder.itemView);
                ViewCompat.setElevation(viewHolder.itemView, newElevation);
                viewHolder.itemView.setTag(android.support.v7.recyclerview.R.id.item_touch_helper_previous_elevation, originalElevation);
            }
        }
    }

    private static float findMaxElevation(RecyclerView recyclerView, View itemView) {
        int childCount = recyclerView.getChildCount();
        float max = 0.0F;

        for (int i = 0; i < childCount; ++i) {
            View child = recyclerView.getChildAt(i);
            if (child != itemView) {
                float elevation = ViewCompat.getElevation(child);
                if (elevation > max) {
                    max = elevation;
                }
            }
        }

        return max;
    }

根据滑动的轨迹,让item按照需要的轨迹移动

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

            //为了把view提到顶部
            takeViewTopInRec(recyclerView, viewHolder, isCurrentlyActive);

            final int width = viewHolder.itemView.getWidth();
            final int height = viewHolder.itemView.getHeight();
            // Fade out the view as it is swiped out of the parent's bounds
            final float r = Math.abs(dX) / (float) width;

            final float alpha = ALPHA_FULL - r;

            viewHolder.itemView.setTranslationX(dX * 1.1f);

            if (r < 0.3) {
                viewHolder.itemView.setScaleX(1 + r * 0.2f);
                viewHolder.itemView.setScaleY(1 + r * 0.2f);
            }

            viewHolder.itemView.setTranslationY(r * height * 0.2f);
            if (dX >= 0) {
                swipeAction = MatchPairConstant.LIKE_ACTION;
                viewHolder.itemView.setRotation(10 * r);
                ((RecyclerGridSlipAdapter.ItemViewHolder) viewHolder).like.setAlpha(r * 4f > 1 ? 1f : r * 4f);
                ((RecyclerGridSlipAdapter.ItemViewHolder) viewHolder).dislike.setAlpha(0f);

            } else {
                swipeAction = MatchPairConstant.DIS_LIKE_ACTION;
                viewHolder.itemView.setRotation(-10 * r);

                ((RecyclerGridSlipAdapter.ItemViewHolder) viewHolder).dislike.setAlpha(r * 4f > 1 ? 1f : r * 4f);
                ((RecyclerGridSlipAdapter.ItemViewHolder) viewHolder).like.setAlpha(0f);
            }
            /*if (r > 0.5) {
                viewHolder.itemView.setAlpha(alpha * 2f);
            }*/

        } else {
            super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
        }
    }

移动的参数,移动后的处理

//滑动到删除的速度
    @Override
    public float getSwipeEscapeVelocity(float defaultValue) {
        return super.getSwipeEscapeVelocity(defaultValue);
    }

    @Override
    public long getAnimationDuration(@NonNull RecyclerView recyclerView, int animationType, float animateDx, float animateDy) {
        return 400;
        //return super.getAnimationDuration(recyclerView, animationType, animateDx, animateDy);
    }

    //滑动到删除的距离
    @Override
    public float getSwipeThreshold(@NonNull RecyclerView.ViewHolder viewHolder) {
        //return super.getSwipeThreshold(viewHolder);
        return 0.30f;
    }

    @Override
    public void clearView(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
        super.clearView(recyclerView, viewHolder);
        viewHolder.itemView.setAlpha(ALPHA_FULL);
        viewHolder.itemView.setRotation(0);
        viewHolder.itemView.setTranslationX(0);
        viewHolder.itemView.setTranslationY(0);
        viewHolder.itemView.setScaleX(1);
        viewHolder.itemView.setScaleY(1);
        ((RecyclerGridSlipAdapter.ItemViewHolder) viewHolder).like.setAlpha(0f);
        ((RecyclerGridSlipAdapter.ItemViewHolder) viewHolder).dislike.setAlpha(0f);
        // Tell the view holder it's time to restore the idle state
        ItemTouchHelperViewHolder itemViewHolder = (ItemTouchHelperViewHolder) viewHolder;
        itemViewHolder.onItemClear();
    }
//支持滑动的模式(左右)
    @Override
    public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
        // Set movement flags based on the layout manager
        final int dragFlags = 0;
        final int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END;
        return makeMovementFlags(dragFlags, swipeFlags);
    }

上面的代码就是核心了,但是还不足以让程序跑起来。我们要把某些行为(选中了item/移除了item/item移除后重置等)通知业务层

ItemTouchHelperAdapter

public interface ItemTouchHelperAdapter {

    /**
     * Called when an item has been dragged far enough to trigger a move. This is called every time
     * an item is shifted, and not at the end of a "drop" event.
*
* Implementations should call {@link RecyclerView.Adapter#notifyItemMoved(int, int)} after * adjusting the underlying data to reflect this move. * * @param fromPosition The start position of the moved item. * @param toPosition Then resolved position of the moved item. * @return True if the item was moved to the new adapter position. * @see RecyclerView#getAdapterPositionFor(RecyclerView.ViewHolder) * @see RecyclerView.ViewHolder#getAdapterPosition() */ boolean onItemMove(int fromPosition, int toPosition); /** * Called when an item has been dismissed by a swipe.
*
* Implementations should call {@link RecyclerView.Adapter#notifyItemRemoved(int)} after * adjusting the underlying data to reflect this removal. * * @param position The position of the item dismissed. * @see RecyclerView#getAdapterPositionFor(RecyclerView.ViewHolder) * @see RecyclerView.ViewHolder#getAdapterPosition() */ void onItemDismiss(String action, int position); void onItemReset(@NonNull RecyclerView.ViewHolder viewHolder, int position); }
public interface ItemTouchHelperViewHolder {

    /**
     * Called when the {@link ItemTouchHelper} first registers an item as being moved or swiped.
     * Implementations should update the item view to indicate it's active state.
     */
    void onItemSelected();


    /**
     * Called when the {@link ItemTouchHelper} has completed the move or swipe, and the active item
     * state should be cleared.
     */
    void onItemClear();
}

实现了ItemTouchHelperAdapter的自定义apapter ,重写这些方法即可

@Override
    public void onItemDismiss(String action, int position) {
        final LikeMeDetailEntity likeMeDetailEntity = mItems.get(position);
        mItems.remove(position);
        notifyItemRemoved(position);
        if (mExecuteListener != null) {
            mExecuteListener.onLikeActionCallback(position, likeMeDetailEntity, action);
        }
    }

    @Override
    public boolean onItemMove(int fromPosition, int toPosition) {
        Collections.swap(mItems, fromPosition, toPosition);
        notifyItemMoved(fromPosition, toPosition);
        return true;
    }

    @Override
    public void onItemReset(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
        //notifyDataSetChanged();
        ToastUtils.showToast(GlobalContext.getString(R.string.no_like_me_like_time));
        notifyItemChanged(position);
    }

当然,还要支持点击右滑

private void swipeRight(final LikeMeDetailEntity detailEntity, ItemViewHolder holder, final int position) {
        clearAnim();
        final int widthPixels = GlobalContext.getDisplayMetrics().widthPixels;
        if (mExecuteListener != null) {
            mExecuteListener.onLikeAnimExecuteListener(LikeExecuteListener.START);
        }
        LikeMeItemTouchHelperCallback.takeViewTopInRec(recyclerView, holder, true);

        final View itemView = holder.itemView;
        final View like = holder.like;
        ValueAnimator rotation = ObjectAnimator.ofPropertyValuesHolder(
                itemView, PropertyValuesHolder.ofFloat("rotation", 30f));
        rotation.setDuration(300);
        float trans = itemView.getWidth() + widthPixels;
        ValueAnimator translateX = ObjectAnimator.ofPropertyValuesHolder(
                itemView, PropertyValuesHolder.ofFloat("translationX", 0f, trans));

        ValueAnimator translateY = ObjectAnimator.ofPropertyValuesHolder(
                itemView, PropertyValuesHolder.ofFloat("translationY", 0f, DisplayUtil.dip2px(GlobalContext.getAppContext(), 265 * 0.2f)));

        translateX.setDuration(500);
        translateY.setDuration(500);
        cardAnimationSet = new AnimatorSet();
        cardAnimationSet.setInterpolator(new AccelerateInterpolator());
        cardAnimationSet.playTogether(rotation, translateX, translateY);
        cardAnimationSet.start();
        ObjectAnimator overlayAnimator = ObjectAnimator.ofFloat(like, "alpha", 0f, 1f);
        overlayAnimator.setDuration(300);

        likeActionAnimationSet = new AnimatorSet();
        likeActionAnimationSet.playTogether(overlayAnimator);
        likeActionAnimationSet.start();
        cardAnimationSet.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {

            }

            @Override
            public void onAnimationEnd(Animator animation) {
                if (position < mItems.size()) {
                    mItems.remove(position);
                    notifyItemRemoved(position);
                    if (mExecuteListener != null) {
                        mExecuteListener.onLikeAnimExecuteListener(LikeExecuteListener.END);
                        mExecuteListener.onLikeActionCallback(position, detailEntity, MatchPairConstant.LIKE_ACTION);
                    }
                } else {
                    notifyDataSetChanged();
                }
            }

            @Override
            public void onAnimationCancel(Animator animation) {

            }

            @Override
            public void onAnimationRepeat(Animator animation) {

            }
        });

        schedule = AndroidSchedulers.mainThread().createWorker()
                .schedule(new Action0() {
                    @Override
                    public void call() {
                        itemView.setRotation(0);
                        itemView.setTranslationX(0);
                        itemView.setTranslationY(0);
                        like.setAlpha(0f);
                    }
                }, 800, TimeUnit.MILLISECONDS);
    }

完整代码

完整代码掺杂了很多业务逻辑,但不影响同学们理解。看大题的用法即可

LikeMeActivity

public class LikeMeActivity extends BaseActivity implements View.OnClickListener {
    private TextView like_me_num;
    private RecyclerView like_me_list;
    private View empty_view;

    private CompositeSubscription mSubscription = new CompositeSubscription();
    private RecyclerGridSlipAdapter adapter;
    private List likeMes;
    private SwipeRefreshLayout swipe_refresh;
    private LikeMeItemTouchHelperCallback callback;
    private LikeMeModel mLikeMeModel = new LikeMeModel();

    //是不是最后一页
    private boolean is_last_page = false;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.like_me_layout);
        like_me_num = findViewById(R.id.like_me_num);
        like_me_list = findViewById(R.id.like_me_list);
        swipe_refresh = findViewById(R.id.swipe_refresh);
        empty_view = findViewById(R.id.empty_view);
        findViewById(R.id.like_me_title).setOnClickListener(this);
        findViewById(R.id.page_back).setOnClickListener(this);

        adapter = new RecyclerGridSlipAdapter();

        like_me_list.setHasFixedSize(true);
        like_me_list.setAdapter(adapter);
        like_me_list.setLayoutManager(new GridLayoutManager(this, 2));

        callback = new LikeMeItemTouchHelperCallback(adapter);
        ItemTouchHelper mItemTouchHelper = new ItemTouchHelper(callback);
        mItemTouchHelper.attachToRecyclerView(like_me_list);
        adapter.setExecuteListener(new RecyclerGridSlipAdapter.LikeExecuteListener() {
            @Override
            public void onLikeAnimExecuteListener(int status) {
                switch (status) {
                    case RecyclerGridSlipAdapter.LikeExecuteListener.START:
                        callback.setCanSwipe(false);
                        break;
                    case RecyclerGridSlipAdapter.LikeExecuteListener.END:
                        callback.setCanSwipe(true);
                        break;
                }
            }

            @Override
            public void onLikeActionCallback(int position, LikeMeDetailEntity likeDetail, String action) {
                likeAction(position, likeDetail, action);
            }
        });
        loadData(0);

        like_me_list.addOnScrollListener(new RecyclerView.OnScrollListener() {

            @Override
            public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
                if (recyclerView.getLayoutManager() == null) {
                    return;
                }
                //当前RecyclerView显示出来的最后一个的item的position
                int lastPosition = -1;

                //当前状态为停止滑动状态SCROLL_STATE_IDLE时
                if (newState == RecyclerView.SCROLL_STATE_IDLE) {
                    RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
                    if (layoutManager instanceof GridLayoutManager) {
                        //通过LayoutManager找到当前显示的最后的item的position
                        lastPosition = ((GridLayoutManager) layoutManager).findLastVisibleItemPosition();
                    }

                    //时判断界面显示的最后item的position是否等于itemCount总数-1也就是最后一个item的position
                    //如果相等则说明已经滑动到最后了
                    if (lastPosition == recyclerView.getLayoutManager().getItemCount() - 1) {
                        loadData(likeMes != null && !likeMes.isEmpty() ? likeMes.get(likeMes.size() - 1).beliked_timestamp : 0);
                    }

                }
            }
        });

        swipe_refresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                loadData(0);
                final Subscription schedule = AndroidSchedulers.mainThread()
                        .createWorker()
                        .schedule(new Action0() {
                            @Override
                            public void call() {
                                swipe_refresh.setRefreshing(false);
                            }
                        }, 300, TimeUnit.MILLISECONDS);
                mSubscription.add(schedule);
            }
        });
    }


    private void loadData(final long last_timestamp) {
        if (is_last_page && last_timestamp != 0) {
            return;
        }
        final Subscription subscribe = MatchPairNetManager.getLikeMeList(last_timestamp)
                .doOnNext(new Action1>() {
                    @Override
                    public void call(RspQueenDefault rsp) {
                        swipe_refresh.setRefreshing(false);
                        if (rsp.isSuccess() && rsp.getResultEntity() != null && rsp.getResultEntity().data != null) {
                            if (last_timestamp == 0) {
                                if (rsp.getResultEntity().data.items == null || rsp.getResultEntity().data.items.isEmpty()) {
                                    empty_view.setVisibility(View.VISIBLE);
                                } else {
                                    empty_view.setVisibility(View.GONE);
                                }
                            } else {
                                empty_view.setVisibility(View.GONE);
                            }
                            callback.setLike_num(rsp.getResultEntity().data.left_like_count);
                            adapter.setLike_num(rsp.getResultEntity().data.left_like_count);
                            final LikeMeInfoEntity data = rsp.getResultEntity().data;
                            like_me_num.setText(String.valueOf(data.beliked_num));
                            if (last_timestamp != 0) {
                                mergeListView(data.items);
                            } else {
                                likeMes = rsp.getResultEntity().data.items;
                            }
                            adapter.refreshAllDate(likeMes);

                            is_last_page = rsp.getResultEntity().data.is_last_page == 1;
                        } else {
                            if (last_timestamp == 0) {
                                empty_view.setVisibility(View.VISIBLE);
                            }
                        }
                    }
                })
                .subscribe(new DefaultSubscriber<>("refreshData"));
        mSubscription.add(subscribe);
    }


    private void likeAction(final int position, final LikeMeDetailEntity likeDetail, final String action) {
        final Subscription subscribe = mLikeMeModel.beLikeAction(likeDetail.info.uid, action)
                .doOnNext(new Action1>() {
                    @Override
                    public void call(RspQueenDefault rsp) {
                        if (!rsp.isSuccess) {
                            ToastUtils.showToast(rsp.getErrorMessage());
                            //adapter.insertDate(position, likeDetail);
                        }
                        if (rsp.isSuccess && rsp.getResultEntity() != null && rsp.getResultEntity().data != null) {
                            callback.setLike_num(rsp.getResultEntity().data.left_like_count);
                            adapter.setLike_num(rsp.getResultEntity().data.left_like_count);
                            if (TextUtils.equals(action, MatchPairConstant.LIKE_ACTION)) {
                                final AppInNotifyManager notifyManager = new AppInNotifyManager();
                                notifyManager.setActivity(LikeMeActivity.this);
                                notifyManager.showInnerNotifyView(new AppInnerEntity(likeDetail.info), AppInnerNotifyView.NOTIFY_LIKE_ME, new AppInnerNotifyView.InnerNotifyClickListener() {
                                    @Override
                                    public void onInnerNotifyClickListener() {
                                        ChatUiManager.startMessagePage(LikeMeActivity.this, likeDetail.info.uid, QueenChatConstant.FROM_NOTIFY);
                                    }
                                });
                            }
                            removeItem(likeDetail.info.uid);
                            if (likeMes == null || likeMes.isEmpty()) {
                                empty_view.setVisibility(View.VISIBLE);
                            } else {
                                empty_view.setVisibility(View.GONE);
                            }
                        }
                    }
                })
                .subscribe(new DefaultSubscriber<>("likeAction"));
        mSubscription.add(subscribe);
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (!EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().register(this);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mSubscription.clear();
        if (adapter != null) {
            adapter.release();
        }

        EventBus.getDefault().unregister(this);
    }

    @Subscribe
    public void onEventMainThread(BeLikeLikeSuccessEvent event) {
        //收到喜欢的通知,需要将此人移除
        if (event != null) {
            final int uid = event.uid;
            removeItem(uid);
            if (likeMes == null || likeMes.isEmpty()) {
                empty_view.setVisibility(View.VISIBLE);
            } else {
                empty_view.setVisibility(View.GONE);
            }
        }
    }

    private void removeItem(int uid) {
        for (int i = 0; likeMes != null && i < likeMes.size(); i++) {
            if (likeMes.get(i) != null &&
                    likeMes.get(i).info != null &&
                    likeMes.get(i).info.uid == uid) {
                likeMes.remove(i);
                if (adapter != null) {
                    adapter.refreshAllDate(likeMes);
                }
                break;
            }
        }
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.page_back:
                finish();
                break;
        }
    }

    private static final String TAG = "LikeMeActivity";

    private void mergeListView(List likeMesNow) {
        if (likeMes == null || likeMes.isEmpty()) {
            likeMes = likeMesNow;
            return;
        }

        if (likeMesNow != null && !likeMesNow.isEmpty()) {
            Iterator iterator = likeMesNow.iterator();
            while (iterator.hasNext()) {
                final LikeMeDetailEntity next = (LikeMeDetailEntity) iterator.next();
                if (likeMes.contains(next)) {
                    iterator.remove();
                }
            }
            likeMes.addAll(likeMesNow);
        }
    }
}

LikeMeItemTouchHelperCallback

/**
 * 谁喜欢我订制
 */
public class LikeMeItemTouchHelperCallback extends ItemTouchHelper.Callback {
    private static final String TAG = "SlipItemTouchHelperCall";

    private String swipeAction = "";

    public static final float ALPHA_FULL = 1.0f;

    private final ItemTouchHelperAdapter mAdapter;
    private boolean isCanSwipe = true;

    private int like_num;

    public void setLike_num(int like_num) {
        this.like_num = like_num;
    }

    public LikeMeItemTouchHelperCallback(ItemTouchHelperAdapter adapter) {
        mAdapter = adapter;
    }

    public void setCanSwipe(boolean canSwipe) {
        isCanSwipe = canSwipe;
    }

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

    @Override
    public boolean isItemViewSwipeEnabled() {
        return isCanSwipe;
    }

    @Override
    public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
        // Set movement flags based on the layout manager
        final int dragFlags = 0;
        final int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END;
        return makeMovementFlags(dragFlags, swipeFlags);
    }

    @Override
    public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder source, @NonNull RecyclerView.ViewHolder target) {
        if (source.getItemViewType() != target.getItemViewType()) {
            return false;
        }

        // Notify the adapter of the move
        mAdapter.onItemMove(source.getAdapterPosition(), target.getAdapterPosition());
        return true;
    }

    @Override
    public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int i) {
        // Notify the adapter of the dismissal
        if (like_num <= 0 && TextUtils.equals(swipeAction, MatchPairConstant.LIKE_ACTION)) {
            //如果剩余喜欢次数小于零,并且是喜欢,则反馈
            mAdapter.onItemReset(viewHolder, viewHolder.getAdapterPosition());
        } else {
            mAdapter.onItemDismiss(swipeAction, viewHolder.getAdapterPosition());
        }
        swipeAction = "";

    }

    //滑动到删除的速度
    @Override
    public float getSwipeEscapeVelocity(float defaultValue) {
        return super.getSwipeEscapeVelocity(defaultValue);
    }

    @Override
    public long getAnimationDuration(@NonNull RecyclerView recyclerView, int animationType, float animateDx, float animateDy) {
        return 400;
        //return super.getAnimationDuration(recyclerView, animationType, animateDx, animateDy);
    }

    //滑动到删除的距离
    @Override
    public float getSwipeThreshold(@NonNull RecyclerView.ViewHolder viewHolder) {
        //return super.getSwipeThreshold(viewHolder);
        return 0.30f;
    }


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

            //为了把view提到顶部
            takeViewTopInRec(recyclerView, viewHolder, isCurrentlyActive);

            final int width = viewHolder.itemView.getWidth();
            final int height = viewHolder.itemView.getHeight();
            // Fade out the view as it is swiped out of the parent's bounds
            final float r = Math.abs(dX) / (float) width;

            final float alpha = ALPHA_FULL - r;

            viewHolder.itemView.setTranslationX(dX * 1.1f);

            if (r < 0.3) {
                viewHolder.itemView.setScaleX(1 + r * 0.2f);
                viewHolder.itemView.setScaleY(1 + r * 0.2f);
            }

            viewHolder.itemView.setTranslationY(r * height * 0.2f);
            if (dX >= 0) {
                swipeAction = MatchPairConstant.LIKE_ACTION;
                viewHolder.itemView.setRotation(10 * r);
                ((RecyclerGridSlipAdapter.ItemViewHolder) viewHolder).like.setAlpha(r * 4f > 1 ? 1f : r * 4f);
                ((RecyclerGridSlipAdapter.ItemViewHolder) viewHolder).dislike.setAlpha(0f);

            } else {
                swipeAction = MatchPairConstant.DIS_LIKE_ACTION;
                viewHolder.itemView.setRotation(-10 * r);

                ((RecyclerGridSlipAdapter.ItemViewHolder) viewHolder).dislike.setAlpha(r * 4f > 1 ? 1f : r * 4f);
                ((RecyclerGridSlipAdapter.ItemViewHolder) viewHolder).like.setAlpha(0f);
            }
            /*if (r > 0.5) {
                viewHolder.itemView.setAlpha(alpha * 2f);
            }*/

        } else {
            super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
        }
    }


    @Override
    public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
        // We only want the active item to change
        if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
            if (viewHolder instanceof ItemTouchHelperViewHolder) {
                // Let the view holder know that this item is being moved or dragged
                ItemTouchHelperViewHolder itemViewHolder = (ItemTouchHelperViewHolder) viewHolder;
                itemViewHolder.onItemSelected();
            }
        }

        super.onSelectedChanged(viewHolder, actionState);
    }

    @Override
    public void clearView(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
        super.clearView(recyclerView, viewHolder);
        viewHolder.itemView.setAlpha(ALPHA_FULL);
        viewHolder.itemView.setRotation(0);
        viewHolder.itemView.setTranslationX(0);
        viewHolder.itemView.setTranslationY(0);
        viewHolder.itemView.setScaleX(1);
        viewHolder.itemView.setScaleY(1);
        ((RecyclerGridSlipAdapter.ItemViewHolder) viewHolder).like.setAlpha(0f);
        ((RecyclerGridSlipAdapter.ItemViewHolder) viewHolder).dislike.setAlpha(0f);
        // Tell the view holder it's time to restore the idle state
        ItemTouchHelperViewHolder itemViewHolder = (ItemTouchHelperViewHolder) viewHolder;
        itemViewHolder.onItemClear();
    }

    public static void takeViewTopInRec(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, boolean isCurrentlyActive) {
        if (Build.VERSION.SDK_INT >= 21 && isCurrentlyActive) {
            Object originalElevation = viewHolder.itemView.getTag(android.support.v7.recyclerview.R.id.item_touch_helper_previous_elevation);
            if (originalElevation == null) {
                originalElevation = ViewCompat.getElevation(viewHolder.itemView);
                float newElevation = 1.0F + findMaxElevation(recyclerView, viewHolder.itemView);
                ViewCompat.setElevation(viewHolder.itemView, newElevation);
                viewHolder.itemView.setTag(android.support.v7.recyclerview.R.id.item_touch_helper_previous_elevation, originalElevation);
            }
        }
    }

    private static float findMaxElevation(RecyclerView recyclerView, View itemView) {
        int childCount = recyclerView.getChildCount();
        float max = 0.0F;

        for (int i = 0; i < childCount; ++i) {
            View child = recyclerView.getChildAt(i);
            if (child != itemView) {
                float elevation = ViewCompat.getElevation(child);
                if (elevation > max) {
                    max = elevation;
                }
            }
        }

        return max;
    }

}

RecyclerGridSlipAdapter

public class RecyclerGridSlipAdapter extends RecyclerView.Adapter
        implements ItemTouchHelperAdapter {

    private final List mItems = new ArrayList<>();

    private RecyclerView recyclerView;
    private Subscription schedule;
    private AnimatorSet likeActionAnimationSet;
    private AnimatorSet cardAnimationSet;

    private int like_num;

    public RecyclerGridSlipAdapter() {
    }

    public void setLike_num(int like_num) {
        this.like_num = like_num;
    }

    public void refreshAllDate(List dates) {
        if (dates != null) {
            mItems.clear();
            mItems.addAll(dates);
            notifyDataSetChanged();
        }
    }

    public void insertDate(int position, LikeMeDetailEntity meDetail) {
        if (position <= mItems.size() && meDetail != null) {
            mItems.add(position, meDetail);
            notifyItemInserted(position);
        }
    }

    @Override
    @NonNull
    public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_like_me, parent, false);
        return new ItemViewHolder(view);
    }

    @SuppressLint("SetTextI18n")
    @Override
    public void onBindViewHolder(@NonNull final ItemViewHolder holder, int position) {
        final int adapterPosition = holder.getAdapterPosition();
        final LikeMeDetailEntity detailEntity = mItems.get(adapterPosition);
        if (detailEntity != null) {
            if (detailEntity.info != null && !TextUtils.isEmpty(detailEntity.info.nick)) {
                holder.name.setText(detailEntity.info.nick);
                holder.age.setText("," + detailEntity.info.age);
            }
            if (!TextUtils.isEmpty(detailEntity.distance)) {
                holder.distance.setText(detailEntity.distance);
            }
            if (detailEntity.info != null) {
                LoadPicUtils.loadHalfPic(detailEntity.info.portrait, holder.avatar);
            }
        }

        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (ClickUtils.isCommonClick(v) && detailEntity != null && detailEntity.info != null) {
                    ProfileUiManager.openHomePageActivity(v.getContext(), detailEntity.info.uid, HomePageActivity.BE_LIKE_ME,5);
                }
            }
        });


        holder.to_like.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (ClickUtils.isCommonClick(v)) {
                    if (like_num <= 0) {
                        ToastUtils.showToast(GlobalContext.getString(R.string.no_like_me_like_time));
                        return;
                    }
                    swipeRight(detailEntity, holder, adapterPosition);
                }
            }
        });
    }

    @Override
    public void onItemDismiss(String action, int position) {
        final LikeMeDetailEntity likeMeDetailEntity = mItems.get(position);
        mItems.remove(position);
        notifyItemRemoved(position);
        if (mExecuteListener != null) {
            mExecuteListener.onLikeActionCallback(position, likeMeDetailEntity, action);
        }
    }

    @Override
    public boolean onItemMove(int fromPosition, int toPosition) {
        Collections.swap(mItems, fromPosition, toPosition);
        notifyItemMoved(fromPosition, toPosition);
        return true;
    }

    @Override
    public void onItemReset(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
        //notifyDataSetChanged();
        ToastUtils.showToast(GlobalContext.getString(R.string.no_like_me_like_time));
        notifyItemChanged(position);
    }

    @Override
    public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
        this.recyclerView = recyclerView;
        super.onAttachedToRecyclerView(recyclerView);
    }

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

    private static final String TAG = "RecyclerGridSlipAdapter";

    /**
     * Simple example of a view holder that implements {@link ItemTouchHelperViewHolder} and has a
     * "handle" view that initiates a drag event when touched.
     */
    public static class ItemViewHolder extends RecyclerView.ViewHolder implements
            ItemTouchHelperViewHolder {
        public SimpleDraweeView avatar;
        public ImageView like;
        public ImageView dislike;
        public ImageView to_like;
        public TextView name;
        public TextView age;
        public TextView distance;

        ItemViewHolder(View itemView) {
            super(itemView);
            like = itemView.findViewById(R.id.like);
            like.setAlpha(0f);

            dislike = itemView.findViewById(R.id.dislike);
            dislike.setAlpha(0f);
            to_like = itemView.findViewById(R.id.to_like);
            distance = itemView.findViewById(R.id.distance);
            name = itemView.findViewById(R.id.name);
            age = itemView.findViewById(R.id.age);
            avatar = itemView.findViewById(R.id.avatar);
        }

        @Override
        public void onItemSelected() {
            Log.i(TAG, "onItemSelected: ");
        }

        @Override
        public void onItemClear() {
        }
    }

    private LikeExecuteListener mExecuteListener;

    public void setExecuteListener(LikeExecuteListener executeListener) {
        mExecuteListener = executeListener;
    }

    private void swipeRight(final LikeMeDetailEntity detailEntity, ItemViewHolder holder, final int position) {
        clearAnim();
        final int widthPixels = GlobalContext.getDisplayMetrics().widthPixels;
        if (mExecuteListener != null) {
            mExecuteListener.onLikeAnimExecuteListener(LikeExecuteListener.START);
        }
        LikeMeItemTouchHelperCallback.takeViewTopInRec(recyclerView, holder, true);

        final View itemView = holder.itemView;
        final View like = holder.like;
        ValueAnimator rotation = ObjectAnimator.ofPropertyValuesHolder(
                itemView, PropertyValuesHolder.ofFloat("rotation", 30f));
        rotation.setDuration(300);
        float trans = itemView.getWidth() + widthPixels;
        ValueAnimator translateX = ObjectAnimator.ofPropertyValuesHolder(
                itemView, PropertyValuesHolder.ofFloat("translationX", 0f, trans));

        ValueAnimator translateY = ObjectAnimator.ofPropertyValuesHolder(
                itemView, PropertyValuesHolder.ofFloat("translationY", 0f, DisplayUtil.dip2px(GlobalContext.getAppContext(), 265 * 0.2f)));

        translateX.setDuration(500);
        translateY.setDuration(500);
        cardAnimationSet = new AnimatorSet();
        cardAnimationSet.setInterpolator(new AccelerateInterpolator());
        cardAnimationSet.playTogether(rotation, translateX, translateY);
        cardAnimationSet.start();
        ObjectAnimator overlayAnimator = ObjectAnimator.ofFloat(like, "alpha", 0f, 1f);
        overlayAnimator.setDuration(300);

        likeActionAnimationSet = new AnimatorSet();
        likeActionAnimationSet.playTogether(overlayAnimator);
        likeActionAnimationSet.start();
        cardAnimationSet.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {

            }

            @Override
            public void onAnimationEnd(Animator animation) {
                if (position < mItems.size()) {
                    mItems.remove(position);
                    notifyItemRemoved(position);
                    if (mExecuteListener != null) {
                        mExecuteListener.onLikeAnimExecuteListener(LikeExecuteListener.END);
                        mExecuteListener.onLikeActionCallback(position, detailEntity, MatchPairConstant.LIKE_ACTION);
                    }
                } else {
                    notifyDataSetChanged();
                }
            }

            @Override
            public void onAnimationCancel(Animator animation) {

            }

            @Override
            public void onAnimationRepeat(Animator animation) {

            }
        });

        schedule = AndroidSchedulers.mainThread().createWorker()
                .schedule(new Action0() {
                    @Override
                    public void call() {
                        itemView.setRotation(0);
                        itemView.setTranslationX(0);
                        itemView.setTranslationY(0);
                        like.setAlpha(0f);
                    }
                }, 800, TimeUnit.MILLISECONDS);
    }

    public void release() {
        if (schedule != null) {
            schedule.unsubscribe();
        }
        clearAnim();
    }

    private void clearAnim() {
        if (cardAnimationSet != null) {
            cardAnimationSet.cancel();
        }

        if (likeActionAnimationSet != null) {
            likeActionAnimationSet.cancel();
        }
    }

    public interface LikeExecuteListener {
        int START = 0;
        int END = 2;

        void onLikeAnimExecuteListener(int status);

        void onLikeActionCallback(int position, LikeMeDetailEntity likeDetail, String action);
    }
}

你可能感兴趣的:(RecyclerView之item左滑喜欢右滑不喜欢~)