androidandroid-layoutviewflipperandroid-viewflipper

ViewFlipper inside RecyclerView ViewHolder


I am using viewFlipper in RecyclerView Adapter Item but it is working in an abnormal way like if I flip a view and then scroll, the other view in the recyclerView also gets flipped. Please help me in resolving this issue..

Code For RecyclerView Adapter :

public class SelfStudyAdapter extends RecyclerView.Adapter<SelfStudyAdapter.ViewHolder> {
    private BaseActivity context;
    private LayoutInflater inflater;
    private List<SelfStudyModel> dataList = new ArrayList<>();
    private AdapterClickListener adapterClickListener;

    public SelfStudyAdapter(BaseActivity context, List<SelfStudyModel> dataList) {
        this.context = context;
        this.dataList = dataList;
        inflater = LayoutInflater.from(context);
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = inflater.inflate(R.layout.item_new_learning_path, parent, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        SelfStudyModel data = dataList.get(position);

        int getLastPercentage = Math.round(data.getLastTestPercentage());
        holder.txtChapter.setText(data.getChapter().getName());
        holder.txtChapterNo.setText(context.getResources().getString(R.string.chapter) + " " + data.getChapter().getNumber());
        holder.txtChapter2.setText(data.getChapter().getName());
        holder.txtChapterNo2.setText(context.getResources().getString(R.string.chapter) + " " + data.getChapter().getNumber());
        if (getLastPercentage > 0) {
            holder.txtMarksPercentage2.setText(String.valueOf(getLastPercentage));
            holder.progressMarksPercentage2.setProgress(getLastPercentage);
            holder.flProgressBar2.setVisibility(View.VISIBLE);
            holder.txtLastPercentage2.setVisibility(View.VISIBLE);
            holder.txtMarksPercentage2.setVisibility(View.VISIBLE);
            holder.progressMarksPercentage2.setVisibility(View.VISIBLE);
        } else {
            holder.flProgressBar2.setVisibility(View.INVISIBLE);
            holder.txtLastPercentage2.setVisibility(View.INVISIBLE);
            holder.txtMarksPercentage2.setVisibility(View.INVISIBLE);
            holder.progressMarksPercentage2.setVisibility(View.INVISIBLE);
        }

        holder.btnLearning2.setText(data.getLqViewed() + "/" + data.getLqTotal());
        holder.txtPqViewed.setText(String.valueOf(data.getWqViewed()));
        holder.txtPqTotal.setText("/" + data.getWqTotal());
        holder.btnSummary2.setText(data.getSummaryTimeSpent() + " min");
        holder.txtPqUp.setText(String.valueOf(data.getFlaggedWqTotal()));
        holder.txtPqDown.setText(String.valueOf(data.getNeedHelpWqTotal()));
    }

    @Override
    public int getItemCount() {
        return dataList.size();
    }

    public AdapterClickListener getAdapterClickListener() {
        return adapterClickListener;
    }

    public void setAdapterClickListener(AdapterClickListener adapterClickListener) {
        this.adapterClickListener = adapterClickListener;
    }

    public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

        protected ViewFlipper viewFlipper;
        protected TextView txtChapterNo, txtChapter;
        protected Button btnSummary, btnLearning, btnPractise;

        protected TextView txtChapterNo2, txtChapter2;
        protected Button btnSummary2, btnLearning2;
        protected LinearLayout llPractise2;
        protected TextView txtPqViewed, txtPqTotal, txtPqUp, txtPqDown;
        protected TextView txtLastPercentage2;
        protected ProgressBar progressMarksPercentage2;
        protected TextView txtMarksPercentage2;
        protected FrameLayout flProgressBar2;

        public ViewHolder(View itemView) {
            super(itemView);
            viewFlipper = (ViewFlipper) itemView.findViewById(R.id.view_flipper);
            txtChapterNo = (TextView) itemView.findViewById(R.id.txt_chapter_no);
            txtChapter = (TextView) itemView.findViewById(R.id.txt_chapter);
            btnSummary = (Button) itemView.findViewById(R.id.btn_summary);
            btnLearning = (Button) itemView.findViewById(R.id.btn_learning);
            btnPractise = (Button) itemView.findViewById(R.id.btn_practise);

            txtChapterNo2 = (TextView) itemView.findViewById(R.id.txt_chapter_no2);
            txtChapter2 = (TextView) itemView.findViewById(R.id.txt_chapter2);
            btnSummary2 = (Button) itemView.findViewById(R.id.btn_summary2);
            btnLearning2 = (Button) itemView.findViewById(R.id.btn_learning2);
            llPractise2 = (LinearLayout) itemView.findViewById(R.id.ll_practice2);
            txtPqViewed = (TextView) itemView.findViewById(R.id.txt_pq_viewed);
            txtPqTotal = (TextView) itemView.findViewById(R.id.txt_pq_total);
            txtPqUp = (TextView) itemView.findViewById(R.id.txt_pq_up);
            txtPqDown = (TextView) itemView.findViewById(R.id.txt_pq_down);
            txtMarksPercentage2 = (TextView) itemView.findViewById(R.id.txt_marks_percentage2);
            txtLastPercentage2 = (TextView) itemView.findViewById(R.id.txt_last_percentage2);
            progressMarksPercentage2 = (ProgressBar) itemView.findViewById(R.id.progress_marks_percentage2);
            flProgressBar2 = (FrameLayout) itemView.findViewById(R.id.fl_progress_bar2);

            btnSummary.setOnClickListener(this);
            btnLearning.setOnClickListener(this);
            btnPractise.setOnClickListener(this);

            btnSummary2.setOnClickListener(this);
            btnLearning2.setOnClickListener(this);
            llPractise2.setOnClickListener(this);

            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    AnimationFactory.flipTransition(viewFlipper, AnimationFactory.FlipDirection.TOP_BOTTOM);
                }
            });
        }

        @Override
        public void onClick(View v) {
            if (getAdapterClickListener() != null) {
                getAdapterClickListener().onClick(getAdapterPosition(), v);
            }
        }
    }
}

Layout of Adapter Item :

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <ViewFlipper
        android:id="@+id/view_flipper"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

         <include layout="@layout/layout1"/>

        <include layout="@layout/layout2"/>

    </ViewFlipper>

    <View
        android:layout_width="match_parent"
        android:layout_height="@dimen/line_dimen"
        android:layout_alignParentBottom="true"
        android:background="@color/gray_700" />

</RelativeLayout>

Solution

  • I had a similar issue using ViewSwitcher. If you want it to always recycle to the first child view, you can set this in your onBindViewHolder:

    resetFlipper(holder.viewFlipper);
    

    Then create a helper function to set the child without triggering the animation:

    private void resetFlipper(ViewFlipper vf){
        Animation inAnimation = vf.getInAnimation();
        Animation outAnimation = vf.getOutAnimation();
        vf.setInAnimation(null);
        vf.setOutAnimation(null);
        vf.setDisplayedChild(0);
        vf.setInAnimation(inAnimation);
        vf.setOutAnimation(outAnimation);
    }