iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 19
0
自我挑戰組

Android的學習歷程系列 第 19

[Day 19]Android-在RecyclerView上使用ObjectAnimator(六)

  • 分享至 

  • xImage
  •  

今天要來研究自己搞出的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的部分來做資料的儲存。


上一篇
[Day 18]Android-在RecyclerView上使用ObjectAnimator(五)
下一篇
[Day 20]Android-SharedPreferences的基本使用方式
系列文
Android的學習歷程30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言