package com.cooltechworks.creditcarddesign;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.content.Context;
import android.content.res.TypedArray;
import android.os.Build;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.OvershootInterpolator;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import io.codetail.animation.SupportAnimator;
import io.codetail.animation.ViewAnimationUtils;
/**
* Created by Harish on 03/01/16.
*/
public class CreditCardView extends FrameLayout {
private static final int TEXTVIEW_CARD_HOLDER_ID = R.id.front_card_holder_name;
private static final int TEXTVIEW_CARD_EXPIRY_ID = R.id.front_card_expiry;
private static final int TEXTVIEW_CARD_NUMBER_ID = R.id.front_card_number;
private static final int TEXTVIEW_CARD_CVV_ID = R.id.back_card_cvv;
private static final int FRONT_CARD_ID = R.id.front_card_container;
private static final int BACK_CARD_ID = R.id.back_card_container;
private static final int FRONT_CARD_OUTLINE_ID = R.id.front_card_outline;
private static final int BACK_CARD_OUTLINE_ID = R.id.back_card_outline;
private int mCurrentDrawable;
private String mRawCardNumber;
private ICustomCardSelector mSelectorLogic;
private String mCardHolderName, mCVV, mExpiry;
public CreditCardView(Context context) {
super(context);
init();
}
public CreditCardView(Context context, AttributeSet attrs) {
super(context, attrs);
init(attrs);
}
public CreditCardView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(attrs);
}
public String getCardHolderName() {
return mCardHolderName;
}
public String getCVV() {
return mCVV;
}
public String getExpiry() {
return mExpiry;
}
interface ICustomCardSelector {
CardSelector getCardSelector(String cardNumber);
}
private void init() {
mCurrentDrawable = R.drawable.card_color_round_rect_default;
mRawCardNumber = "";
LayoutInflater inflater = (LayoutInflater) getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.view_creditcard, this, true);
}
private void init(AttributeSet attrs) {
init();
TypedArray a = getContext().obtainStyledAttributes(attrs,
R.styleable.creditcard, 0, 0);
String cardHolderName = a.getString(R.styleable.creditcard_card_holder_name);
String expiry = a.getString(R.styleable.creditcard_card_expiration);
String cardNumber = a.getString(R.styleable.creditcard_card_number);
int cvv = a.getInt(R.styleable.creditcard_cvv, 0);
int cardSide = a.getInt(R.styleable.creditcard_card_side,CreditCardUtils.CARD_SIDE_FRONT);
setCardNumber(cardNumber);
setCVV(cvv);
setCardExpiry(expiry);
setCardHolderName(cardHolderName);
if(cardSide == CreditCardUtils.CARD_SIDE_BACK) {
showBackImmediate();
}
paintCard();
a.recycle();
}
private void flip(final boolean ltr, boolean isImmediate) {
View layoutContainer = findViewById(R.id.card_outline_container);
View frontView = findViewById(FRONT_CARD_OUTLINE_ID);
View backView = findViewById(BACK_CARD_OUTLINE_ID);
final View frontContentView = findViewById(FRONT_CARD_ID);
final View backContentView = findViewById(BACK_CARD_ID);
View layoutContentContainer = findViewById(R.id.card_container);
if(isImmediate) {
frontContentView.setVisibility(ltr?VISIBLE:GONE);
backContentView.setVisibility(ltr?GONE:VISIBLE);
}
else {
int duration = 600;
FlipAnimator flipAnimator = new FlipAnimator(frontView, backView, frontView.getWidth() / 2, backView.getHeight() / 2);
flipAnimator.setInterpolator(new OvershootInterpolator(0.5f));
flipAnimator.setDuration(duration);
if (ltr) {
flipAnimator.reverse();
}
flipAnimator.setTranslateDirection(FlipAnimator.DIRECTION_Z);
flipAnimator.setRotationDirection(FlipAnimator.DIRECTION_Y);
layoutContainer.startAnimation(flipAnimator);
FlipAnimator flipAnimator1 = new FlipAnimator(frontContentView, backContentView, frontContentView.getWidth() / 2, backContentView.getHeight() / 2);
flipAnimator1.setInterpolator(new OvershootInterpolator(0.5f));
flipAnimator1.setDuration(duration);
if (ltr) {
flipAnimator1.reverse();
}
flipAnimator1.setTranslateDirection(FlipAnimator.DIRECTION_Z);
flipAnimator1.setRotationDirection(FlipAnimator.DIRECTION_Y);
layoutContentContainer.startAnimation(flipAnimator1);
}
}
public void setCardNumber(String rawCardNumber) {
this.mRawCardNumber = rawCardNumber == null ? "" : rawCardNumber;
String newCardNumber = mRawCardNumber;
for(int i=mRawCardNumber.length();i<16;i++) {
newCardNumber +=CreditCardUtils.CHAR_X;
}
String cardNumber = CreditCardUtils.handleCardNumber(newCardNumber, CreditCardUtils.DOUBLE_SPACE_SEPERATOR);
((TextView)findViewById(TEXTVIEW_CARD_NUMBER_ID)).setText(cardNumber);
if(mRawCardNumber.length() == 3) {
revealCardAnimation();
}
else {
paintCard();
}
}
public void setCVV(int cvvInt) {
if(cvvInt == 0) {
setCVV("");
}
else {
String cvv = String.valueOf(cvvInt);
setCVV(cvv);
}
}
public void showFront() {
flip(true,false);
}
public void showFrontImmediate() {
flip(true,true);
}
public void showBack() {
flip(false,false);
}
public void showBackImmediate() {
flip(false,true);
}
public void setCVV(String cvv) {
if(cvv == null) {
cvv = "";
}
this.mCVV = cvv;
((TextView)findViewById(TEXTVIEW_CARD_CVV_ID)).setText(cvv);
}
public void setCardExpiry(String dateYear) {
dateYear = dateYear == null ? "": CreditCardUtils.handleExpiration(dateYear);
this.mExpiry = dateYear;
((TextView) findViewById(TEXTVIEW_CARD_EXPIRY_ID)).setText(dateYear);
}
public void setCardHolderName(String cardHolderName) {
cardHolderName = cardHolderName == null ? "" : cardHolderName;
if(cardHolderName.length() > 16) {
cardHolderName = cardHolderName.substring(0,16);
}
this.mCardHolderName = cardHolderName;
((TextView)findViewById(TEXTVIEW_CARD_HOLDER_ID)).setText(cardHolderName);
}
public void paintCard() {
CardSelector card = selectCard();
View cardContainer = findViewById(R.id.card_outline_container);
View chipContainer = findViewById(R.id.chip_container);
View chipInner = findViewById(R.id.chip_inner_view);
View cardBack = findViewById(BACK_CARD_OUTLINE_ID);
View cardFront = findViewById(FRONT_CARD_OUTLINE_ID);
chipContainer.setBackgroundResource(card.getResChipOuterId());
chipInner.setBackgroundResource(card.getResChipInnerId());
ImageView frontLogoImageView = (ImageView) cardContainer.findViewById(R.id.logo_img);
frontLogoImageView.setImageResource(card.getResLogoId());
ImageView centerImageView = (ImageView) cardContainer.findViewById(R.id.logo_center_img);
centerImageView.setImageResource(card.getResCenterImageId());
ImageView backLogoImageView = (ImageView) findViewById(BACK_CARD_ID).findViewById(R.id.logo_img);
backLogoImageView.setImageResource(card.getResLogoId());
cardBack.setBackgroundResource(card.getResCardId());
cardFront.setBackgroundResource(card.getResCardId());
}
public void revealCardAnimation() {
CardSelector card = selectCard();
View cardFront = findViewById(FRONT_CARD_OUTLINE_ID);
View cardContainer = findViewById(R.id.card_outline_container);
paintCard();
animateChange(cardContainer, cardFront, card.getResCardId());
}
public CardSelector selectCard() {
if(mSelectorLogic != null) {
return mSelectorLogic.getCardSelector(mRawCardNumber);
}
return CardSelector.selectCard(mRawCardNumber);
}
public void animateChange(final View cardContainer, final View v, final int drawableId) {
showAnimation(cardContainer, v, drawableId);
}
public void showAnimation(final View cardContainer, final View v, final int drawableId) {
final View mRevealView = v;
mRevealView.setBackgroundResource(drawableId);
if (mCurrentDrawable == drawableId) {
return;
}
int duration = 1000;
int cx = mRevealView.getLeft();
int cy = mRevealView.getTop();
int radius = Math.max(mRevealView.getWidth(), mRevealView.getHeight()) * 4;
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
SupportAnimator animator =
ViewAnimationUtils.createCircularReveal(mRevealView, cx, cy, 0, radius);
animator.setInterpolator(new AccelerateDecelerateInterpolator());
animator.setDuration(duration);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
cardContainer.setBackgroundResource(drawableId);
}
}, duration);
mRevealView.setVisibility(View.VISIBLE);
animator.start();
mCurrentDrawable = drawableId;
} else {
Animator anim = android.view.ViewAnimationUtils.createCircularReveal(mRevealView, cx, cy, 0, radius);
mRevealView.setVisibility(View.VISIBLE);
anim.setDuration(duration);
anim.start();
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
cardContainer.setBackgroundResource(drawableId);
}
});
mCurrentDrawable = drawableId;
}
}
public void setSelectorLogic(ICustomCardSelector mSelectorLogic) {
this.mSelectorLogic = mSelectorLogic;
}
public String getCardNumber() {
return mRawCardNumber;
}
}