简介
现在很多社交交友类的APP
首页都会有一个类似于卡片式切换的交互页,提高和用户的互动性。下面我们也做一个类似于这样的效果,它实现了用户的左右滑动和点击交互监听功能,同时也可设置其剩下多少内容时加载更多,简单的代码实现炫酷的操作,定会为你的应用增色不少。
使用
1、Layout
布局
<com.wiggins.cardcontainer.widget.CardContainerView
android:id="@+id/card_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
2、添加卡片View
@Override
public void addView(View card) {
if (isLoadMore) {
this.mCardList.add(ListUtil.getSize(mCardList), card);
} else {
this.mCardList.add(card);
}
LayoutParams layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
layoutParams.addRule(RelativeLayout.CENTER_VERTICAL);
this.addView(card, 0, layoutParams);
card.setOnTouchListener(onTouchListener);
if (!isLoadMore) {
this.setLayoutParams(card, mCardList.size());
}
}
3、设置卡片相对位置
private void setLayoutParams(View card, int index) {
LayoutParams params = new LayoutParams(card.getLayoutParams());
params.topMargin = dip2px(marginTop) + getResources().getDimensionPixelSize(R.dimen.margin_tiny) * index;
params.bottomMargin = dip2px(marginBottom) - getResources().getDimensionPixelSize(R.dimen.margin_tiny) * index;
params.leftMargin = dip2px(marginLeft);
params.rightMargin = dip2px(marginRight);
card.setLayoutParams(params);
}
4、触摸拖拽监听
private OnTouchListener onTouchListener = new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (mOnTouch && v.equals(mCardList.get(0))) {
int rawY = (int) event.getRawY();
int rawX = (int) event.getRawX();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
getLayout();
mLastY = (int) event.getRawY();
mLastX = (int) event.getRawX();
break;
case MotionEvent.ACTION_MOVE:
int offsetY = rawY - mLastY;
int offsetX = rawX - mLastX;
mCardList.get(0).layout(mCardList.get(0).getLeft() + offsetX, mCardList.get(0).getTop() + offsetY, mCardList.get(0).getRight() + offsetX, mCardList.get(0).getBottom() + offsetY);
mRightOut = mCardList.get(0).getLeft() > getDisplayMetrics(mContext).widthPixels / 2;
mLeftOut = mCardList.get(0).getRight() < getDisplayMetrics(mContext).widthPixels / 2;
mLastY = rawY;
mLastX = rawX;
break;
case MotionEvent.ACTION_UP:
change();
break;
}
}
return true;
}
};
5、滑出及复位
private void change() {
if (mLeftOut) {
// 向左边滑出
out(true);
} else if (mRightOut) {
// 向右边滑出
out(false);
} else {
// 复位
reset();
}
}
6、加载及滑动接口
public interface LoadMore {
void load();
}
public interface LeftOrRight {
void leftOrRight(boolean left);
}
7、滑动动画
private void animator(CardIndex newCard, CardIndex oldCard) {
ValueAnimator animator = ValueAnimator.ofObject(new PointEvaluator(), newCard, oldCard);
animator.setDuration(200);
animator.setInterpolator(new AccelerateDecelerateInterpolator());
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mOnTouch = false;
CardIndex value = (CardIndex) animation.getAnimatedValue();
mCardList.get(0).layout(value.left, value.top, value.right, value.bottom);
}
});
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
if (mRightOut || mLeftOut) {
removeTopCard();
if (mLeftOrRight != null) {
mLeftOrRight.leftOrRight(mLeftOut);
}
}
mOnTouch = true;
}
});
animator.start();
}
8、调用代码实现
public class MainActivity extends BaseActivity {
private TitleView titleView;
private CardContainerView mCardContainerView;
private int[] imageIcon = {R.drawable.pic1, R.drawable.pic2, R.drawable.pic3, R.drawable.pic4,
R.drawable.pic5, R.drawable.pic6, R.drawable.pic7, R.drawable.pic8,
R.drawable.pic9, R.drawable.pic10, R.drawable.pic11, R.drawable.pic12};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
setListener();
addCard(6);
}
private void initView() {
titleView = (TitleView) findViewById(R.id.titleView);
titleView.setAppTitle(UIUtils.getString(R.string.title));
titleView.setLeftImageVisibility(View.GONE);
mCardContainerView = (CardContainerView) findViewById(R.id.card_container);
mCardContainerView.setLoadSize(3);
}
private void setListener() {
mCardContainerView.setLoadMoreListener(new CardContainerView.LoadMore() {
@Override
public void load() {
addCard(3);
}
});
mCardContainerView.setLeftOrRightListener(new CardContainerView.LeftOrRight() {
@Override
public void leftOrRight(boolean left) {
if (left) {
ToastUtil.showText(UIUtils.getString(R.string.like));
} else {
ToastUtil.showText(UIUtils.getString(R.string.dislike));
}
}
});
}
private void addCard(int size) {
for (int i = 0; i < size; i++) {
mCardContainerView.addView(getCard(getImageIcon(), getNickName(), getSignature()));
}
}
private int getImageIcon() {
int indexImageIcon = new Random().nextInt(imageIcon.length);
return imageIcon[indexImageIcon];
}
private String getNickName() {
String[] nickName = UIUtils.getResources().getStringArray(R.array.nickName);
int indexNickName = new Random().nextInt(nickName.length);
return nickName[indexNickName];
}
private String getSignature() {
String[] signature = UIUtils.getResources().getStringArray(R.array.signature);
int indexSignature = new Random().nextInt(signature.length);
return signature[indexSignature];
}
private View getCard(int imageIcon, String nickName, String signature) {
View card = LayoutInflater.from(this).inflate(R.layout.activity_card, null);
RoundImageView mIvIcon = (RoundImageView) card.findViewById(R.id.iv_icon);
TextView mNickName = (TextView) card.findViewById(R.id.tv_nickName);
TextView mSignature = (TextView) card.findViewById(R.id.tv_signature);
ImageView mIvLike = (ImageView) card.findViewById(R.id.iv_like);
ImageView mIvDisLike = (ImageView) card.findViewById(R.id.iv_disLike);
mIvIcon.setImageResource(imageIcon);
mNickName.setText(nickName);
mSignature.setText(signature);
mIvLike.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mCardContainerView.removeTopCard(true);
}
});
mIvDisLike.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mCardContainerView.removeTopCard(false);
}
});
return card;
}
}
项目地址 ☞ 传送门