Paulius Vindzigelskis
Paulius Vindzigelskis

Reputation: 2191

Android: fadeIn selected row

I have listview similar to this:enter image description here

Add code, it isn't much, but maybe helpful:

CustomAdapter:

public class MyAdapter extends BaseAdapter{

private LayoutInflater mInflater;
private Animation fadeIn;
private Animation fadeOut;



public MyAdapter(Activity c) {
    mInflater = c.getLayoutInflater();
    fadeIn = AnimationUtils.loadAnimation(c.getApplicationContext(), R.anim.alpha_show);
    fadeIn.setFillAfter(true);
    fadeOut = AnimationUtils.loadAnimation(c.getApplicationContext(), R.anim.alpha_dissappear);
    fadeOut.setFillAfter(true);
}

public int getCount() {
    return MainButtonsList.getList().getSize() + 
            GlobalPrefs.getEmptyRowsAtEnd() + 
            GlobalPrefs.getEmptyRowsAtStart();
}


public View getView(int position, View v, ViewGroup parent) {
    View convertView = v;
    if (convertView == null) {
        convertView = mInflater.inflate(R.layout.main_list_item, null);
    }
    ImageView iv = (ImageView) convertView.findViewById(R.id.image);
    if ((position > GlobalPrefs.getEmptyRowsAtStart() - 1) && (position < getCount() - GlobalPrefs.getEmptyRowsAtEnd())) {
        iv.setImageResource(MainButtonsList.getList().getListImageResource(position - GlobalPrefs.getEmptyRowsAtStart()));
        iv.setAlpha(255);
        iv.setTag(MainButtonsList.UNPRESSED_BUTTON_TAG);
    } else {
        iv.setTag(MainButtonsList.UNUSED_BUTTON_TAG);
        iv.setAlpha(0);
        iv.setVisibility(0);
        iv.setClickable(false);
        iv.setImageResource(R.drawable.logo_list_null);

    }
    iv.setMaxHeight(GlobalPrefs.getRowHeight());
    iv.setMaxWidth(GlobalPrefs.getRowWidth());
    iv.setBackgroundResource(0);





    return convertView;
}

public Object getItem(int position) {
    return MainButtonsList.getList().getObject(position);
}

public long getItemId(int position) {
    return position;
}

}

Custom ListView:

public class CopyOfListView3d extends ListView{
private final Camera mCamera = new Camera();
private final Matrix mMatrix = new Matrix();
private Context context;
private Paint mPaint;


public CopyOfListView3d(Context context, AttributeSet attrs) {
    super(context, attrs);
    this.context = context;
    this.setChildrenDrawingOrderEnabled(true);

}

@Override
protected int getChildDrawingOrder (int childCount, int i) {
      //sets order number to each child, so makes overlap and center is always on top
    }

@Override
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
    // get top left coordinates
    boolean isCenter = false;
    final int top = child.getTop();
    final int bottom = child.getBottom();
    Bitmap bitmap = child.getDrawingCache();
    if (bitmap == null) {
        child.setDrawingCacheEnabled(true);
        child.buildDrawingCache();
        bitmap = child.getDrawingCache();
    }

    final int centerY = child.getHeight() / 2;
    final int centerX = child.getWidth() / 2;
    final int radius = getHeight() / 2;
    final int absParentCenterY = getTop() + getHeight() / 2;
    final int absChildCenterY = child.getTop() + centerY;
    final int distanceY = (absParentCenterY - absChildCenterY) / 2;
    final int absDistance = Math.min(radius, Math.abs(distanceY));

    final float translateZ = (float) Math.sqrt((radius * radius) - (absDistance * absDistance));
    mCamera.save();
    float myTranslateX = (float) (translateZ * (1.5f));

    int density = GlobalPrefs.getDensity();
    if (density < DisplayMetrics.DENSITY_LOW) {
        myTranslateX = (float) myTranslateX - 80;
    } else if (density == DisplayMetrics.DENSITY_LOW) {
        myTranslateX = (float) myTranslateX - GlobalPrefs.getScreenWidth() + density + 40;
    } else if (density <= DisplayMetrics.DENSITY_MEDIUM) {
            myTranslateX = (float) myTranslateX - ((float)(GlobalPrefs.getScreenWidth()*0.75)) + density/2;
    } else
        if (density <= DisplayMetrics.DENSITY_HIGH) {
            myTranslateX = (float) myTranslateX - 320;
        } else
            if (density > DisplayMetrics.DENSITY_HIGH) {
                //Log.i("density", "this is more than high");
                myTranslateX = (float) myTranslateX;
            }
    if ((top < absParentCenterY) && (bottom > absParentCenterY)) {
        //make center row bigger
        isCenter = true;
        mCamera.translate((float) myTranslateX, 0, (float) -160);//130
        child.setPressed(true);
        child.setTag(MainButtonsList.PRESSED_BUTTON_TAG);
    }  
    else {
        //top
        child.setTag(MainButtonsList.UNPRESSED_BUTTON_TAG);
        child.setPressed(false);
        mCamera.translate((float) myTranslateX, 0, -150);//120;
    };
    mCamera.getMatrix(mMatrix);
    mCamera.restore();

    // create and initialize the paint object
    if (mPaint == null) {
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setFilterBitmap(true);
    }
    //calculates alpha for each row, so far from center, rows are barely visible
    mPaint.setAlpha(calculateAlpha(absChildCenterY));

    mMatrix.postTranslate((float) (-centerX * 1.5f), top);
    canvas.drawBitmap(bitmap, mMatrix, mPaint);
    return false;
}



}

They are made of ImageViews where white color is selected state and blue color is unselected state and I change selected/unselected by screen coordinates, so center always is selected.

I have custom 3dListView which extends ListView and made custom adapter, where i set imageviews to rows. Code is too much to show, but there are pretty simple

One of these could be helpfull:

1) How can I make fade in (maybe also fade out) for center row (I can find which row is center when giving parent or childCount)? (Better)

2) It also could be helpfull if there is any OnStateChange listener, which listens to view's presses. Then I could fade in anytime when view becomes pressed and fadeout, when looses press.

Upvotes: 0

Views: 2800

Answers (2)

Paulius Vindzigelskis
Paulius Vindzigelskis

Reputation: 2191

I found an answer myself. Added this code piece to my custom ListView in drawChild method end:

final ImageView iv = (ImageView) child.findViewById(R.id.image);
            child.setTag(MainButtonsList.PRESSED_BUTTON_TAG);

            Animation anim = fadeOut();
            anim.setAnimationListener(new Animation.AnimationListener() {

                public void onAnimationStart(Animation animation) {
                    // TODO Auto-generated method stub

                }

                public void onAnimationRepeat(Animation animation) {
                    // TODO Auto-generated method stub

                }

                public void onAnimationEnd(Animation animation) {
                    child.setPressed(true);
                    iv.startAnimation(fadeIn());
                }
            });

            iv.clearAnimation();
            iv.startAnimation(anim);

In list item layout, added another image, which put under item and now it looks prety nice.

Upvotes: 4

Blundell
Blundell

Reputation: 76564

You'll want to do the fading in the adapter for the listview.

In your adapter

private List<YourListObject> deleteItems;

// Constructor to init list and other vars

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    // Draw stuff
    // including your object


    for(YourListObject obj : deleteItems){
            if(currentObj.equals(obj)){
                Animation fadeOutAnimation = new AlphaAnimation(1.0f, 0.0f);
                fadeOutAnimation.setDuration(300);
                DeleteAnimationListener listener = new DeleteAnimationListener(currentObj);
                fadeOutAnimation.setAnimationListener(listener);
                someView.startAnimation(fadeOutAnimation);
            }
        }

    return someView;
}


   public void remove(YourListObject obj){
        deleteItems.add(obj);
        notifyDataSetChanged();
    }

   protected class DeleteAnimationListener extends EndAnimationListener {

        private final YourListObject obj;

        public DeleteAnimationListener(YourListObject obj) {
            this.obj = obj;
        }

        @Override
        public void onAnimationEnd(Animation animation) {
            yourObjects.remove(obj);
            deleteItems.remove(obj);
            notifyDataSetChanged();
        }
    };

currentObj is the view in the list your currently manipulating

yourObjects is the list you are storing the data in.

deleteItems is a new list.

You call .remove(obj) on your adapter to remove one. The getView will then remove it from the list (with a fade out animation) once this animation is finished the AnimationListener will remove the actual object from your dataset.

Upvotes: 3

Related Questions