5

I am implementing a BaseAdapter and I have TranslateAnimation for a single list item.

The problem is that when scrolling down other views have the same offset.

Here is my implementation of the getView() method:

        @Override
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder viewHolder;
    if (convertView == null) {
            //initialization code
            convertView.setTag(viewHolder);
    } else {
         viewHolder =(ViewHolder) convertView.getTag();
    }

        Animation animation;
        switch (item.getAnimationDirection()) {
        case AnimationDirection.HIDE:
            animation = new TranslateAnimation(itemOffset, 0, 0, 0);
            animation.setDuration(200);
            animation.setFillAfter(true);
            viewHolder.layoutToAnimate.setAnimation(animation);
            item.setAnimationDirection(AnimationDirection.HIDDEN);
            break;
        case AnimationDirection.REVEAL:
            itemOffset = viewHolder.remove.getWidth() + 20;
            animation = new TranslateAnimation(0, itemOffset, 0, 0);
            animation.setDuration(200);
            animation.setFillAfter(true);
            viewHolder.layoutToAnimate.setAnimation(animation);
            item.setAnimationDirection(AnimationDirection.SHOWING);
            break;
        }

        viewHolder.remove.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                if (item.getAnimationDirection() == AnimationDirection.HIDDEN) {
                    item.setAnimationDirection(AnimationDirection.REVEAL);
                    notifyDataSetChanged();
                }
            }
        });
        convertView.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                if (item.getAnimationDirection() == AnimationDirection.SHOWING) {
                    item.setAnimationDirection(AnimationDirection.HIDE);
                    notifyDataSetChanged();
                }
            }
        });
        return convertView;
  }

My question is::

How can I keep the View offset state for every ListView item?

user1940676
  • 4,348
  • 9
  • 44
  • 73

3 Answers3

4

The Android framework provides hooks to preserve and restore view properties, so all you need to do is to ensure that your view code implements onSaveInstanceState() and onRestoreInstanceState(Parcelable state) and when invoked, invokes the same for its child views and invokes the parent class' methods e.g. super.onSaveInstanceState().

I posted an answer here which in response to a question about retaining the data used within a ListView but also discusses how to preserve other view properties such as scroll position in the comments.

Community
  • 1
  • 1
Phil Haigh
  • 4,522
  • 1
  • 25
  • 29
  • I can save the offset for each item, but how can I set the offset inside the getView() method? – user1940676 May 12 '14 at 12:24
  • You shouldn't need to set the offset. The parent class of your view will do that when `onRestoreInstanceState` is called. If you want to explictly set a horizontal position initially, then your view must be a subclass of (or inside) a view that supports horizontal scrolling - on which you can set the scroll position programatically - see http://developer.android.com/reference/android/widget/HorizontalScrollView.html – Phil Haigh May 12 '14 at 12:28
1

Use a Map<Integer, Integer> for this. Something like

map.put(position, offset);

and

int offset = map.get(position);

Don't forget to set this every time a call to getView is made.

nhaarman
  • 98,571
  • 55
  • 246
  • 278
  • where should I store the view offset? right after I start the animation? – user1940676 May 12 '14 at 12:09
  • Whenever it changes for a particular position. You could use a `AnimatorUpdateListener`. – nhaarman May 12 '14 at 12:10
  • and how can I restore the offset? when I call setX() inside the adapter it doesn't seem to work, I mean is there a way to achieve it inside the adapter without using a custom listview implementation ? – user1940676 May 12 '14 at 12:15
0

I was facing similar problem but mine was with colors and had 2 listview positioned side by side. I was setting red color to the item on the list that was touched on the same position on another list. The correct entry was highlighted but another item on the list was too at arbitary position. The way I solved it was by using if-else statement(I was using only if before). My code in getview() is like this:

if(position == highLightPosition){
holder.layout.setBackgroundColor(getResources().getColor(R.color.high_red));
}else{
//I set default color here that solved my problem
holder.layout.setBackgroundColor(getResources().getColor(R.color.white));
}

try something like this I know switch and if looks the same but this worked for me.

Illegal Argument
  • 10,090
  • 2
  • 44
  • 61