今天要來研究自己搞出的bug,檢查了一下發現主要的問題應該是在延遲的部分造成資料處理出現問題。
想了想還真沒想到好的解決方式,這個部分過去是使用比較強硬的方式,在蓋回前都不能再翻開其他牌來達成。
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView myTextView;
ImageView mImageView;
ImageView cardView;
ObjectAnimator animator = ObjectAnimator.ofFloat(itemView, "rotationY", 0, 180);
ObjectAnimator animatorBack = ObjectAnimator.ofFloat(itemView, "rotationY", 180, 360);
ViewHolder(View itemView) {
super(itemView);
myTextView = itemView.findViewById(R.id.info_text);
mImageView = itemView.findViewById(R.id.photo_item);
cardView = itemView.findViewById(R.id.photo_stroke);
//mImageView.setRotation(90);
itemView.setOnClickListener(this);
private void flipAnimation() {
if (selectCard == 2) {
animator.setDuration(750);
animator.start();
if (selectList.get(0).equals(selectList.get(1))) {
animatorBack.setDuration(750);
animatorBack.start();
} else {
animator.setDuration(750);
animator.start();
handler.postDelayed(new Runnable() {
@Override
public void run() {
if (selectCard < 2) {
startEvent();
}, 750);
handler.postDelayed(new Runnable() {
int position = getAdapterPosition();
@Override
public void run() {
switchCard(position);
}, 375);
private void switchCard(int pos) {
int getSeclectRegister = mSelectRegister[pos];
if (getSeclectRegister == 1) {
mImageView.setVisibility(View.VISIBLE);
} else {
mImageView.setVisibility(View.INVISIBLE);
mSelectRegister[pos] = mSelectRegister[pos] * -1;
private void startEvent() {
handler.postDelayed(new Runnable() {
@Override
public void run() {
checkEvent = 0;
}, 750);
private void selectView(int pos) {
selectCard += 1;
selectList.add(pos);
itemViewList.add(itemView);
ivNumberList.add(mImageView);
private void clearList() {
selectList.clear();
itemViewList.clear();
ivNumberList.clear();
selectCard = 0;
private void selectSamePosition() {
clearList();
handler.postDelayed(new Runnable() {
@Override
public void run() {
startEvent();
}, 750);
private void selectSameImage() {
handler.postDelayed(new Runnable() {
@Override
public void run() {
for (int i = 0; i <= 1; i++) {
itemViewList.get(i).setVisibility(View.INVISIBLE);
itemViewList.get(i).setOnClickListener(null);
clearList();
startEvent();
score += 2;
if (score == mData.length) {
Log.i("TAG", "pass");
mClickListener.onItemClick(itemView, getAdapterPosition(), score);
}, 750);
private void selectDifferentImage() {
handler.postDelayed(new Runnable() {
@Override
public void run() {
for (int i = 0; i <= 1; i++) {
ObjectAnimator resetAnimator = ObjectAnimator.ofFloat(itemViewList.get(i), "rotationY", 180, 0);
resetAnimator.setDuration(750);
resetAnimator.start();
handler.postDelayed(new Runnable() {
@Override
public void run() {
for (int i = 0; i <= 1; i++) {
ivNumberList.get(i).setVisibility(View.INVISIBLE);
mSelectRegister[selectList.get(i)] = 1;
}, 375);
handler.postDelayed(new Runnable() {
@Override
public void run() {
clearList();
startEvent();
}, 751);
}, 750);
@Override
public void onClick(View view) {
int position = getAdapterPosition();
if (checkEvent == 0) {
checkEvent = 1;
selectView(position);
flipAnimation();
if (selectCard == 2) {
if (selectList.get(0).equals(selectList.get(1))) {
selectSamePosition();
} else if (mData[selectList.get(0)].equals(mData[selectList.get(1)])) {
selectSameImage();
} else {
selectDifferentImage();
使用這個做法的話,整個過程都會有很大的延遲時間,體驗上較差,所以這次就以不延遲的情況下來重寫這個部分,最後沒想到什麼好方法來解決這個問題,只能盡量不在handler的地方清除資料。
MyRecyclerViewAdapter
public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewAdapter.ViewHolder> {
private String[] mData = new String[0];
private LayoutInflater mInflater;
private ItemClickListener mClickListener;
private Integer[] imageResource = {R.drawable.red_card, R.drawable.orange_card, R.drawable.yellow_card,
R.drawable.green_card, R.drawable.blue_card, R.drawable.indigo_card, R.drawable.purple_card};
private Handler handler;
private ArrayList<Integer> selectPosStack;
private ArrayList<View> selectViewStack;
private ArrayList<ImageView> selectFrontStack;
private ArrayList<ImageView> selectBackStack;
//選取狀態
private int[] mSelectStatus;
private int[] mSelectWork;
MyRecyclerViewAdapter(Context context, String[] data, int[] selectStatus, int[] selectWork) {
handler = new Handler();
this.mInflater = LayoutInflater.from(context);
this.mData = data;
this.mSelectStatus = selectStatus;
this.mSelectWork = selectWork;
selectPosStack = new ArrayList<>();
selectViewStack = new ArrayList<>();
selectFrontStack = new ArrayList<>();
selectBackStack = new ArrayList<>();
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = mInflater.inflate(R.layout.card_item, parent, false);
return new ViewHolder(view);
@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
holder.mImageView.setImageResource(imageResource[Integer.parseInt(mData[position]) - 1]);
//開頭動畫
View seeView = holder.itemView;
ObjectAnimator animatorBack = ObjectAnimator.ofFloat(seeView, "rotationY", 180, 360);
holder.mImageView.setVisibility(View.VISIBLE);
animatorBack.setDuration(1000);
animatorBack.start();
handler.postDelayed(new Runnable() {
@Override
public void run() {
holder.mImageView.setVisibility(View.INVISIBLE);
}, 500);
@Override
public int getItemCount() {
return mData.length;
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
ImageView mImageView;
ImageView cardView;
ViewHolder(View itemView) {
super(itemView);
mImageView = itemView.findViewById(R.id.photo_item);
cardView = itemView.findViewById(R.id.photo_stroke);
itemView.setOnClickListener(this);
//翻牌動畫
ObjectAnimator animator = ObjectAnimator.ofFloat(itemView, "rotationY", 0, 180);
ObjectAnimator animatorBack = ObjectAnimator.ofFloat(itemView, "rotationY", 180, 360);
@Override
public void onClick(View view) {
int position = getAdapterPosition();
selectCard(position, animator, animatorBack, mImageView, cardView, itemView);
private void selectCard(final int pos, ObjectAnimator animator, ObjectAnimator animatorBack, final ImageView mImageView, final ImageView cardView, final View itemView) {
if (mSelectWork[pos] == 1) {
//切換選取狀態 -1選取 1未選取
mSelectStatus[pos] *= -1;
if (mSelectStatus[pos] == -1) {
//正面動畫
animator.setDuration(750);
animator.start();
//切換工作狀態 -1運行 1閒置
mSelectWork[pos] *= -1;
//顯示卡面,隱藏卡背
handler.postDelayed(new Runnable() {
@Override
public void run() {
mImageView.setVisibility(View.VISIBLE);
cardView.setVisibility(View.INVISIBLE);
}, 375);
//翻牌結束動作
handler.postDelayed(new Runnable() {
@Override
public void run() {
mSelectWork[pos] *= -1;
selectPosStack.add(pos);
selectViewStack.add(itemView);
selectFrontStack.add(mImageView);
selectBackStack.add(cardView);
//判斷是否選擇相同圖示
Log.e("selectList", "" + selectPosStack);
if (selectPosStack.size() >= 2) {
if (mData[selectPosStack.get(0)].equals(mData[selectPosStack.get(1)])) {
selectViewStack.get(0).setVisibility(View.INVISIBLE);
selectViewStack.get(1).setVisibility(View.INVISIBLE);
selectPosStack.remove(0);
selectPosStack.remove(0);
selectViewStack.remove(0);
selectViewStack.remove(0);
selectFrontStack.remove(0);
selectFrontStack.remove(0);
selectBackStack.remove(0);
selectBackStack.remove(0);
} else {
final ArrayList<Integer> regSelectPosStack = new ArrayList<>();
ArrayList<View> regSelectViewStack = new ArrayList<>();
final ArrayList<View> regSelectFrontStack = new ArrayList<>();
final ArrayList<View> regSelectBackStack = new ArrayList<>();
if (selectPosStack.size() == 2) {
regSelectPosStack.add(0,selectPosStack.get(0));
regSelectPosStack.add(0,selectPosStack.get(1));
selectPosStack.remove(0);
selectPosStack.remove(0);
regSelectViewStack.add(0,selectViewStack.get(0));
regSelectViewStack.add(0,selectViewStack.get(1));
selectViewStack.remove(0);
selectViewStack.remove(0);
regSelectFrontStack.add(0,selectFrontStack.get(0));
regSelectFrontStack.add(0,selectFrontStack.get(1));
selectFrontStack.remove(0);
selectFrontStack.remove(0);
regSelectBackStack.add(0,selectBackStack.get(0));
regSelectBackStack.add(0,selectBackStack.get(1));
selectBackStack.remove(0);
selectBackStack.remove(0);
ObjectAnimator firstItemBack = ObjectAnimator.ofFloat(regSelectViewStack.get(0), "rotationY", 180, 360);
ObjectAnimator secondItemBack = ObjectAnimator.ofFloat(regSelectViewStack.get(1), "rotationY", 180, 360);
mSelectStatus[regSelectPosStack.get(0)] *= -1;
mSelectStatus[regSelectPosStack.get(1)] *= -1;
mSelectWork[regSelectPosStack.get(0)] *= -1;
mSelectWork[regSelectPosStack.get(1)] *= -1;
firstItemBack.setDuration(750);
secondItemBack.setDuration(750);
firstItemBack.start();
secondItemBack.start();
handler.postDelayed(new Runnable() {
@Override
public void run() {
regSelectFrontStack.get(0).setVisibility(View.INVISIBLE);
regSelectFrontStack.get(1).setVisibility(View.INVISIBLE);
regSelectBackStack.get(0).setVisibility(View.VISIBLE);
regSelectBackStack.get(1).setVisibility(View.VISIBLE);
}, 375);
handler.postDelayed(new Runnable() {
@Override
public void run() {
mSelectWork[regSelectPosStack.get(0)] *= -1;
mSelectWork[regSelectPosStack.get(1)] *= -1;
}, 750);
}, 750);
} else {
//覆蓋動畫
animatorBack.setDuration(750);
animatorBack.start();
mSelectWork[pos] *= -1;
if (selectPosStack.contains(pos)) {
for (int i = 0; i < selectPosStack.size(); i++) {
if (selectPosStack.get(i) == pos) {
selectPosStack.remove(i);
selectViewStack.remove(i);
selectBackStack.remove(i);
selectFrontStack.remove(i);
//顯示卡背,隱藏卡面
handler.postDelayed(new Runnable() {
@Override
public void run() {
mImageView.setVisibility(View.INVISIBLE);
cardView.setVisibility(View.VISIBLE);
}, 375);
//翻牌結束
handler.postDelayed(new Runnable() {
@Override
public void run() {
mSelectWork[pos] *= -1;
Log.e("selectList", "" + selectPosStack);
}, 750);
void setClickListener(ItemClickListener itemClickListener) {
this.mClickListener = itemClickListener;
public interface ItemClickListener {
void onItemClick(View view, int position, int score);
之後會先進到sharedpreferences的部分來做資料的儲存。