diff --git a/app/src/main/java/com/yuqirong/cardswipeview/MainActivity.java b/app/src/main/java/com/yuqirong/cardswipeview/MainActivity.java index d37d99e..dfd833f 100644 --- a/app/src/main/java/com/yuqirong/cardswipeview/MainActivity.java +++ b/app/src/main/java/com/yuqirong/cardswipeview/MainActivity.java @@ -8,6 +8,7 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.ImageButton; import android.widget.ImageView; import android.widget.Toast; @@ -17,12 +18,15 @@ import me.yuqirong.cardswipelayout.CardConfig; import me.yuqirong.cardswipelayout.CardItemTouchHelperCallback; import me.yuqirong.cardswipelayout.CardLayoutManager; +import me.yuqirong.cardswipelayout.CardRecyclerView; import me.yuqirong.cardswipelayout.OnSwipeListener; -public class MainActivity extends AppCompatActivity { +public class MainActivity extends AppCompatActivity implements View.OnClickListener { private List list = new ArrayList<>(); + private CardItemTouchHelperCallback cardCallback; + private CardRecyclerView recyclerView; @Override protected void onCreate(Bundle savedInstanceState) { @@ -33,10 +37,17 @@ protected void onCreate(Bundle savedInstanceState) { } private void initView() { - final RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView); + ImageButton likeButton = (ImageButton) findViewById(R.id.like_button); + ImageButton hateButton = (ImageButton) findViewById(R.id.hate_button); + ImageButton backButton = (ImageButton) findViewById(R.id.back_button); + likeButton.setOnClickListener(this); + hateButton.setOnClickListener(this); + backButton.setOnClickListener(this); + + recyclerView = (CardRecyclerView) findViewById(R.id.recyclerView); recyclerView.setItemAnimator(new DefaultItemAnimator()); recyclerView.setAdapter(new MyAdapter()); - CardItemTouchHelperCallback cardCallback = new CardItemTouchHelperCallback(recyclerView.getAdapter(), list); + cardCallback = new CardItemTouchHelperCallback(recyclerView, recyclerView.getAdapter(), list); cardCallback.setOnSwipedListener(new OnSwipeListener() { @Override @@ -91,6 +102,21 @@ private void initData() { list.add(R.drawable.img_avatar_07); } + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.like_button: + cardCallback.handleCardSwipe(CardConfig.SWIPING_RIGHT, 300L); + break; + case R.id.hate_button: + cardCallback.handleCardSwipe(CardConfig.SWIPING_LEFT, 300L); + break; + case R.id.back_button: + cardCallback.handlerCardBack(300L); + break; + } + } + private class MyAdapter extends RecyclerView.Adapter { @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { diff --git a/app/src/main/res/drawable-xhdpi/img_buttons_hate_normal.png b/app/src/main/res/drawable-xhdpi/img_buttons_hate_normal.png new file mode 100644 index 0000000..8a4fcd2 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/img_buttons_hate_normal.png differ diff --git a/app/src/main/res/drawable-xhdpi/img_buttons_hate_pressed.png b/app/src/main/res/drawable-xhdpi/img_buttons_hate_pressed.png new file mode 100644 index 0000000..5110c56 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/img_buttons_hate_pressed.png differ diff --git a/app/src/main/res/drawable-xhdpi/img_buttons_like_normal.png b/app/src/main/res/drawable-xhdpi/img_buttons_like_normal.png new file mode 100644 index 0000000..953cc6e Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/img_buttons_like_normal.png differ diff --git a/app/src/main/res/drawable-xhdpi/img_buttons_like_pressed.png b/app/src/main/res/drawable-xhdpi/img_buttons_like_pressed.png new file mode 100644 index 0000000..eff6e4f Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/img_buttons_like_pressed.png differ diff --git a/app/src/main/res/drawable/ic_reply_black_24dp.xml b/app/src/main/res/drawable/ic_reply_black_24dp.xml new file mode 100644 index 0000000..46b19a0 --- /dev/null +++ b/app/src/main/res/drawable/ic_reply_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/img_buttons_hate_selector.xml b/app/src/main/res/drawable/img_buttons_hate_selector.xml new file mode 100644 index 0000000..355cbb4 --- /dev/null +++ b/app/src/main/res/drawable/img_buttons_hate_selector.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/img_buttons_like_selector.xml b/app/src/main/res/drawable/img_buttons_like_selector.xml new file mode 100644 index 0000000..3867936 --- /dev/null +++ b/app/src/main/res/drawable/img_buttons_like_selector.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index a9ea790..d97d1bf 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -6,9 +6,51 @@ android:orientation="vertical" tools:context="com.yuqirong.cardswipeview.MainActivity"> - + android:layout_height="0dp" + android:layout_weight="1" /> + + + + + + + + + + + + + diff --git a/lib/src/main/java/me/yuqirong/cardswipelayout/CardItemTouchHelperCallback.java b/lib/src/main/java/me/yuqirong/cardswipelayout/CardItemTouchHelperCallback.java index 0742755..597d4b8 100644 --- a/lib/src/main/java/me/yuqirong/cardswipelayout/CardItemTouchHelperCallback.java +++ b/lib/src/main/java/me/yuqirong/cardswipelayout/CardItemTouchHelperCallback.java @@ -1,11 +1,17 @@ package me.yuqirong.cardswipelayout; +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.ValueAnimator; import android.graphics.Canvas; import android.support.annotation.NonNull; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.helper.ItemTouchHelper; import android.view.View; +import android.view.animation.Interpolator; +import android.widget.Toast; +import java.util.ArrayList; import java.util.List; /** @@ -17,13 +23,42 @@ public class CardItemTouchHelperCallback extends ItemTouchHelper.Callback { private final RecyclerView.Adapter adapter; private List dataList; private OnSwipeListener mListener; + private CardRecyclerView recyclerView; + ValueAnimator swipeAnimator; + //需要撤回的View列表 + List mLastReturnList = new ArrayList<>(); + //需要添加道卡片的列表 + List needAddLastList = new ArrayList<>(); - public CardItemTouchHelperCallback(@NonNull RecyclerView.Adapter adapter, @NonNull List dataList) { - this.adapter = checkIsNull(adapter); - this.dataList = checkIsNull(dataList); + public int getReturnSize(){ + return mLastReturnList.size(); + } + + public void addData(T data) { + needAddLastList.add(data); + } + + public static class ReturnView { + + RecyclerView.ViewHolder viewHolder; + Integer direction; + T curData; + + public ReturnView(RecyclerView.ViewHolder viewHolder, Integer direction, T data) { + this.viewHolder = viewHolder; + this.direction = direction; + this.curData = data; + } + + } + + public CardItemTouchHelperCallback(@NonNull CardRecyclerView recyclerView, @NonNull RecyclerView.Adapter adapter, @NonNull List dataList) { + this(recyclerView, adapter, dataList, null); } - public CardItemTouchHelperCallback(@NonNull RecyclerView.Adapter adapter, @NonNull List dataList, OnSwipeListener listener) { + public CardItemTouchHelperCallback(@NonNull CardRecyclerView recyclerView, @NonNull RecyclerView.Adapter adapter, + @NonNull List dataList, OnSwipeListener listener) { + this.recyclerView = checkIsNull(recyclerView); this.adapter = checkIsNull(adapter); this.dataList = checkIsNull(dataList); this.mListener = listener; @@ -63,12 +98,20 @@ public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) { int layoutPosition = viewHolder.getLayoutPosition(); T remove = dataList.remove(layoutPosition); adapter.notifyDataSetChanged(); + + mLastReturnList.add(new ReturnView(viewHolder,direction,remove)); if (mListener != null) { mListener.onSwiped(viewHolder, remove, direction == ItemTouchHelper.LEFT ? CardConfig.SWIPED_LEFT : CardConfig.SWIPED_RIGHT); } + // 当没有数据时回调 mListener if (adapter.getItemCount() == 0) { - if (mListener != null) { + if(needAddLastList.size() > 0) { + dataList.addAll(needAddLastList); + needAddLastList.clear(); + mLastReturnList.clear(); + adapter.notifyDataSetChanged(); + }else if (mListener != null) { mListener.onSwipedClear(); } } @@ -133,4 +176,101 @@ private float getThreshold(RecyclerView recyclerView, RecyclerView.ViewHolder vi return recyclerView.getWidth() * getSwipeThreshold(viewHolder); } + public T handlerCardBack(long duration) { + if(mLastReturnList.isEmpty()) { + Toast.makeText(recyclerView.getContext(),"当前不可返回",Toast.LENGTH_SHORT).show(); + return null; + } + + final ReturnView returnView = mLastReturnList.remove(mLastReturnList.size()-1); + + // 移除 onTouchListener,否则触摸滑动会乱了 + RecyclerView.ViewHolder topHolder = recyclerView.findViewHolderForAdapterPosition(0); + if(topHolder != null&&topHolder.itemView != null) { + topHolder.itemView.setOnTouchListener(null); + } + + dataList.add(0, (T) returnView.curData); + adapter.notifyDataSetChanged(); + + if (swipeAnimator != null && swipeAnimator.isStarted()) { + return null; + } + final CardRecyclerView recyclerView = checkIsNull(this.recyclerView); + final Canvas canvas = checkIsNull(this.recyclerView.getCanvas()); + if (returnView.viewHolder == null) { + return null; + } + if (returnView.direction == CardConfig.SWIPING_LEFT) { + swipeAnimator = ValueAnimator.ofFloat(-recyclerView.getWidth() / 2, 0); + } else if (returnView.direction == CardConfig.SWIPING_RIGHT) { + swipeAnimator = ValueAnimator.ofFloat(recyclerView.getWidth() / 2, 0); + } else { + throw new IllegalStateException("flag must be one of SWIPING_LEFT or SWIPING_RIGHT"); + } + swipeAnimator.setDuration(duration); + swipeAnimator.setInterpolator(null); + swipeAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + + float value = (float) animation.getAnimatedValue(); + onChildDraw(canvas, recyclerView, returnView.viewHolder, value, 0, ItemTouchHelper.ACTION_STATE_SWIPE, false); + } + }); + swipeAnimator.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + super.onAnimationEnd(animation); +// onSwiped(returnView.viewHolder, returnView.direction == CardConfig.SWIPING_LEFT ? ItemTouchHelper.LEFT : ItemTouchHelper.RIGHT); + } + }); + swipeAnimator.start(); + + return (T) returnView.curData; + + } + + public void handleCardSwipe(int flag, long duration) { + handleCardSwipe(flag, duration, null); + } + + public void handleCardSwipe(final int flag, long duration, Interpolator interpolator) { + if (swipeAnimator != null && swipeAnimator.isStarted()) { + return; + } + final CardRecyclerView recyclerView = checkIsNull(this.recyclerView); + final Canvas canvas = checkIsNull(this.recyclerView.getCanvas()); + final RecyclerView.ViewHolder viewHolder = recyclerView.findViewHolderForAdapterPosition(0); + if (viewHolder == null) { + return; + } + if (flag == CardConfig.SWIPING_LEFT) { + swipeAnimator = ValueAnimator.ofFloat(0, -recyclerView.getWidth() / 2); + } else if (flag == CardConfig.SWIPING_RIGHT) { + swipeAnimator = ValueAnimator.ofFloat(0, recyclerView.getWidth() / 2); + } else { + throw new IllegalStateException("flag must be one of SWIPING_LEFT or SWIPING_RIGHT"); + } + swipeAnimator.setDuration(duration); + swipeAnimator.setInterpolator(interpolator); + swipeAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + + float value = (float) animation.getAnimatedValue(); + onChildDraw(canvas, recyclerView, viewHolder, value, 0, ItemTouchHelper.ACTION_STATE_SWIPE, true); + } + }); + swipeAnimator.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + super.onAnimationEnd(animation); + onSwiped(viewHolder, flag == CardConfig.SWIPING_LEFT ? ItemTouchHelper.LEFT : ItemTouchHelper.RIGHT); + clearView(recyclerView, viewHolder); + } + }); + swipeAnimator.start(); + } + } diff --git a/lib/src/main/java/me/yuqirong/cardswipelayout/CardRecyclerView.java b/lib/src/main/java/me/yuqirong/cardswipelayout/CardRecyclerView.java new file mode 100644 index 0000000..01d5f98 --- /dev/null +++ b/lib/src/main/java/me/yuqirong/cardswipelayout/CardRecyclerView.java @@ -0,0 +1,34 @@ +package me.yuqirong.cardswipelayout; + +import android.content.Context; +import android.graphics.Canvas; +import android.support.annotation.Nullable; +import android.support.v7.widget.RecyclerView; +import android.util.AttributeSet; + +public class CardRecyclerView extends RecyclerView { + + private Canvas canvas; + + public CardRecyclerView(Context context) { + super(context); + } + + public CardRecyclerView(Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + } + + public CardRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + } + + @Override + public void onDraw(Canvas c) { + this.canvas = c; + super.onDraw(c); + } + + public Canvas getCanvas() { + return canvas; + } +}