Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CoverFlow which extends Gallery (deprecated isn't working correctly in >4.0 devices)

I'm using this class to achieve a CoverFlow in my app:

public class CoverFlow extends Gallery {

/**
 * Graphics Camera used for transforming the matrix of ImageViews
 */
private Camera mCamera = new Camera();

/**
 * The maximum angle the Child ImageView will be rotated by
 */    
private int mMaxRotationAngle = 60;

/**
 * The maximum zoom on the centre Child
 */
private int mMaxZoom = -175;

/**
 * The Centre of the Coverflow 
 */   
private int mCoveflowCenter;



public CoverFlow(Context context) {
  super(context);
  this.setStaticTransformationsEnabled(true);
 }

 public CoverFlow(Context context, AttributeSet attrs) {
  super(context, attrs);
        this.setStaticTransformationsEnabled(true);
 }

  public CoverFlow(Context context, AttributeSet attrs, int defStyle) {
   super(context, attrs, defStyle);
   this.setStaticTransformationsEnabled(true);   
  }

    /**
     * Get the max rotational angle of the image
  * @return the mMaxRotationAngle
  */
 public int getMaxRotationAngle() {
  return mMaxRotationAngle;
 }

 /**
  * Set the max rotational angle of each image
  * @param maxRotationAngle the mMaxRotationAngle to set
  */
 public void setMaxRotationAngle(int maxRotationAngle) {
  mMaxRotationAngle = maxRotationAngle;
 }

 /**
  * Get the Max zoom of the centre image
  * @return the mMaxZoom
  */
 public int getMaxZoom() {
  return mMaxZoom;
 }

 /**
  * Set the max zoom of the centre image
  * @param maxZoom the mMaxZoom to set
  */
 public void setMaxZoom(int maxZoom) {
  mMaxZoom = maxZoom;
 }

 /**
     * Get the Centre of the Coverflow
     * @return The centre of this Coverflow.
     */
    private int getCenterOfCoverflow() {
        return (getWidth() - getPaddingLeft() - getPaddingRight()) / 2 + getPaddingLeft();
    }

    /**
     * Get the Centre of the View
     * @return The centre of the given view.
     */
    private static int getCenterOfView(View view) {
        return view.getLeft() + view.getWidth() / 2;
    }  
    /**
  * {@inheritDoc}
  *
  * @see #setStaticTransformationsEnabled(boolean) 
  */ 
    protected boolean getChildStaticTransformation(View child, Transformation t) {

  final int childCenter = getCenterOfView(child);
  final int childWidth = child.getWidth() ;
  int rotationAngle = 0;

  t.clear();
  t.setTransformationType(Transformation.TYPE_MATRIX);

        if (childCenter == mCoveflowCenter) {
            //PARCHE!!! 4.1
            if (Build.VERSION.SDK_INT > Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1){

            } else {
                transformImageBitmap((ImageView) child, t, 0);
            }

        } else {  

            rotationAngle = (int) (((float) (mCoveflowCenter - childCenter)/ childWidth) *  mMaxRotationAngle);
            if (Math.abs(rotationAngle) > mMaxRotationAngle) {
             rotationAngle = (rotationAngle < 0) ? -mMaxRotationAngle : mMaxRotationAngle;   
            }
            //PARCHE!!! 4.1
            if (Build.VERSION.SDK_INT > Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1){
                //no apliquem transformacio.
            } else {
                transformImageBitmap((ImageView) child, t, rotationAngle); 
            }    
        }    

  return true;
 }

 /**
  * This is called during layout when the size of this view has changed. If
  * you were just added to the view hierarchy, you're called with the old
  * values of 0.
  *
  * @param w Current width of this view.
  * @param h Current height of this view.
  * @param oldw Old width of this view.
  * @param oldh Old height of this view.
     */
     protected void onSizeChanged(int w, int h, int oldw, int oldh) {
      mCoveflowCenter = getCenterOfCoverflow();
      super.onSizeChanged(w, h, oldw, oldh);
     }

     /**
      * Transform the Image Bitmap by the Angle passed 
      * 
      * @param imageView ImageView the ImageView whose bitmap we want to rotate
      * @param t transformation 
      * @param rotationAngle the Angle by which to rotate the Bitmap
      */
     private void transformImageBitmap(ImageView child, Transformation t, int rotationAngle) {            
      mCamera.save();
      final Matrix imageMatrix = t.getMatrix();;
      final int imageHeight = child.getLayoutParams().height;
      final int imageWidth = child.getLayoutParams().width;
      final int rotation = Math.abs(rotationAngle);

      mCamera.translate(0.0f, 0.0f, 100.0f);

      //As the angle of the view gets less, zoom in     
      if ( rotation < mMaxRotationAngle ) {
       float zoomAmount = (float) (mMaxZoom +  (rotation * 2.9));
       mCamera.translate(0.0f, 0.0f, zoomAmount);          
      } 

      mCamera.rotateY(rotationAngle);
      mCamera.getMatrix(imageMatrix);               
      imageMatrix.preTranslate(-(imageWidth/2), -(imageHeight/2)); 
      imageMatrix.postTranslate((imageWidth/2), (imageHeight/2));
      mCamera.restore();
 }
}

But this code, after 4.0 device like 4.1 or 4.2 isnt working well anymore.

I've done some debugging, so I modified this part:

//As the angle of the view gets less, zoom in     
  if ( rotation < mMaxRotationAngle ) {
      Log.d("sergi",""+rotation);
   float zoomAmount = (float) (mMaxZoom +  (rotation * 2.9));
   mCamera.translate(0.0f, 0.0f, zoomAmount);          
  } 

And this returned this on a 4.0.4 device while swipping one image from right to left:

03-20 11:11:43.145: D/debugging(15987): 1
03-20 11:11:43.160: D/debugging(15987): 54
03-20 11:11:43.160: D/debugging(15987): 59
03-20 11:11:43.160: D/debugging(15987): 2
03-20 11:11:43.176: D/debugging(15987): 53
03-20 11:11:43.176: D/debugging(15987): 3
03-20 11:11:43.192: D/debugging(15987): 52
03-20 11:11:43.192: D/debugging(15987): 4
03-20 11:11:43.207: D/debugging(15987): 51
03-20 11:11:43.207: D/debugging(15987): 5
03-20 11:11:43.223: D/debugging(15987): 50
03-20 11:11:43.223: D/debugging(15987): 6
03-20 11:11:43.239: D/debugging(15987): 48
03-20 11:11:43.239: D/debugging(15987): 8
03-20 11:11:43.254: D/debugging(15987): 47
03-20 11:11:43.254: D/debugging(15987): 9

And on a 4.1 device it returned:

03-20 11:11:49.239: D/debugging(15987): 35
03-20 11:11:49.254: D/debugging(15987): 35

As you can see, basically what is happening, is that the same method, isn't being used the same way between two different apis.

As you can see, CoverFlow extends Gallery which is deprecated, but not removed, so I don't understand whats the difference. I'd appreciate if we can get to a workaround.

Thanks.

like image 436
Reinherd Avatar asked Mar 20 '13 10:03

Reinherd


1 Answers

Maybe this will help:

protected boolean getChildStaticTransformation(View child, Transformation t)
{
              .....

    if (Build.VERSION.SDK_INT >= 16) child.invalidate();

    return true;
}

This will invalidate the child and make it apply the animation.

like image 139
RealityStalker Avatar answered Nov 06 '22 17:11

RealityStalker