Flip Animation in Android Listview item

2019-04-10 21:34发布

问题:

I'm trying to show front and back face of each of my listview item with Flip animation. Animation works well, but the result of anim is being applied to other items also. And furthermore, the position of my items change when I scroll up and down. My code is as below:

public View getView(final int position, final View convertView, ViewGroup parent) {
    ArtItemHolder holder;
    View view = convertView;

    if (view == null) {
        LayoutInflater inflater = ((Activity) this.context).getLayoutInflater();
        holder = new ArtItemHolder();
        view = inflater.inflate(R.layout.feed_list_item, parent, false);

        holder.image = (ImageView) view.findViewById(R.id.img_Image);
        holder.pubDate = (TextView) view.findViewById(R.id.txt_puslishDate);
        holder.arTitle = (TextView) view.findViewById(R.id.txt_arTitle);
        holder.commentCount = (TextView) view.findViewById(R.id.txt_commentCount);
        holder.rotator  = (ImageView) view.findViewById(R.id.card_roretor);
        holder.cardFace = view.findViewById(R.id.card_face);// first of 2 child parent layout of feed_list_item.xml
        holder.cardBack = view.findViewById(R.id.card_back);// second of 2 child parent layout of feed_list_item.xml
        view.setTag(holder);
    } else {
        holder = (AdvItemHolder) view.getTag();
    }

    holder.rotator.setOnClickListener(new MyFlipperListener(view, holder.cardFace, holder.cardBack));

    return view;
}


private class MyFlipperListener implements OnClickListener{
    View parent, frontFace, backFace;

    public MyFlipperListener(View parent, View frontFace, View backFace) {
        this.parent = parent;
        this.frontFace = frontFace;
        this.backFace = backFace;
    }

    public void onClick(View v) {
        FlipAnimation flipAnimation = new FlipAnimation(frontFace, backFace);
        if (frontFace.getVisibility() == View.GONE)
        {
            flipAnimation.reverse();
        }

        parent.startAnimation(flipAnimation);
    }

}

private static class ArtItemHolder{
    ImageView image;
    TextView pubDate;
    TextView arTitle;
    TextView commentCount;
    ImageView rotator;
    View cardFace, cardBack;
}

My layout xml for items in listview

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" 
    android:gravity="center">

    <LinearLayout
        android:id="@+id/card_face"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" 
        android:background="@drawable/feed_item_selector"
        android:layout_margin="8dip"
        android:padding="2dip">

     ########## MAIN CONTENT HERE ###########

    </LinearLayout>
    <LinearLayout
        android:id="@+id/card_back"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" 
        android:background="@drawable/feed_item_selector"
        android:layout_margin="8dip"
        android:padding="2dip"
        android:visibility="gone">

     ########## SOME INFO ABOUT MAIN CONTENT HERE ###########

    </LinearLayout>
</LinearLayout>

UPDATE

FlipAnimation flipAnimation = new FlipAnimation(holder.cardFace, holder.cardBack);
holder.rotator.setOnClickListener(new MyFlipperListener(view, holder.cardFace, flipAnimation));

private class MyFlipperListener implements OnClickListener{
        View parent, frontFace;
        FlipAnimation flipAnimation;
        public MyFlipperListener(View parent, View frontFace, FlipAnimation flip) {
            this.parent = parent;
            this.frontFace = frontFace;
            this.flipAnimation = flip;
        }

        public void onClick(View v) {
            if (frontFace.getVisibility() == View.GONE){
                flipAnimation.reverse();
            }
            parent.startAnimation(flipAnimation);
        }
    }

回答1:

Your problems are these lines:

FlipAnimation flipAnimation = new 
FlipAnimation(holder.cardFace, holder.cardBack);
holder.rotator.setOnClickListener(new MyFlipperListener(view, holder.cardFace, flipAnimation ));

Your animation is also applied to other items because the adapter reuses views! You could also get problems by setting the onClickListener in the getView. Better approach is to set it outside for example with yourListView.setOnItemClickListener. Hope it helps :)



回答2:

ayt check my solution...

public View getView(final int position, final View convertView, ViewGroup parent) {
ArtItemHolder holder;
View view = convertView;

if (view == null) {
    LayoutInflater inflater = ((Activity)context).getLayoutInflater();
    holder = new ArtItemHolder();
    view = inflater.inflate(R.layout.feed_list_item, parent, false);

    holder.image = (ImageView) view.findViewById(R.id.img_Image);
    holder.pubDate = (TextView) view.findViewById(R.id.txt_puslishDate);
    holder.arTitle = (TextView) view.findViewById(R.id.txt_arTitle);
    holder.commentCount = (TextView) view.findViewById(R.id.txt_commentCount);
    holder.rotator  = (ImageView) view.findViewById(R.id.card_roretor);
    holder.rotator.setTag(false); // put a boolean here..
    holder.cardFace = view.findViewById(R.id.card_face);// first of 2 child parent layout of feed_list_item.xml
    holder.cardBack = view.findViewById(R.id.card_back);// second of 2 child parent layout of feed_list_item.xml
    holder.flipAnimation = new FlipAnimation(holder.cardFace, holder.cardBack);
    view.setTag(holder);
} else {
    holder = (AdvItemHolder) view.getTag();
}

holder.rotator.setOnClickListener(new OnClickListener() {

   @Override
   public void onClick(View v) {
     // TODO Auto-generated method stub
     if (!((Boolean) v.getTag()).booleanValue()){
     v.setTag(true); // switch boolean
     // you can either call notifydatasetchanged to show changes by the change function or put the change function here
     }else{v.setTag(false); // switch boolean again if it has already been clicked}
      }
 }));
 // i am putting the changes here-(change function) so intend i call notifydatasetchanged in the onclick
 // but it depends on your preference
 // check the boolean instead of view being visible..
        if (((Boolean) view.findViewById(R.id.card_roretor).getTag()).booleanValue()){ 
            flipAnimation.reverse();
            view.findViewById(R.id.card_roretor).startAnimation(holder.flipAnimation);
        }
 // end of the change function
return view;
}

...............................

private static class ArtItemHolder{
 ImageView image;
 TextView pubDate;
 TextView arTitle;
 TextView commentCount;
 ImageView rotator;
 View cardFace, cardBack;
 FlipAnimation flipAnimation;
}