Thanks for the input, like the way you've done this, looks good. :) On Jan 19, 12:05 am, Nerdrow <[email protected]> wrote: > I did a similar POC overriding the getChildStaticTransformation() > method of the Gallery. Like Taf's widget, you need to provide a > standard adapter and should probably pre-create the mirror images (if > you need them). The below runs pretty smooth on a G1 & Droid, feel > free to use and improve :) > > package com.nnm.sexyui.widget; > > import android.content.Context; > import android.graphics.Camera; > import android.graphics.Color; > import android.graphics.Matrix; > import android.util.AttributeSet; > //import android.util.Log; > import android.view.View; > import android.view.animation.Transformation; > import android.widget.Gallery; > > /** > * > */ > public class Gallery3D extends Gallery { > > //private static final String TAG = "Gallery3D"; > > private static final int DEFAULT_FADING_EDGE_LENGTH = 90; > private static final Camera mCamera = new Camera(); > > private float[] mOffsetRotateCache, mOffsetScaleCache; > private float mMaxUnselectedRotateAngle = 45.0f, > mMaxSelectedScale = 1.0f, > mMinUnselectedScale = 0.85f; > > private int mStageOffsetMin = 0, mStageOffsetMax = 0; > private int mItemWidth = 280; > > /********************************** > CONSTRUCTORS > **********************************/ > > /** > * Create a new Gallery3D instance. > * @param context > */ > public Gallery3D(Context context) { > this(context, null); > } > /** > * Create a new Gallery3D instance. > * @param context > * @param attrs > */ > public Gallery3D(Context context, AttributeSet attrs) { > this(context, attrs, 0); > } > /** > * Create a new Gallery3D instance. > * @param context > * @param attrs > * @param defStyle > */ > public Gallery3D(Context context, AttributeSet attrs, int defStyle) { > super(context, attrs, defStyle); > > setClipChildren(false); > setClipToPadding(false); > setDrawingCacheBackgroundColor(Color.BLACK); > setHorizontalFadingEdgeEnabled(true); > setFadingEdgeLength(DEFAULT_FADING_EDGE_LENGTH); > setStaticTransformationsEnabled(true); > } > > /********************************** > GETTERS/SETTERS > **********************************/ > > /** > * The width of gallery items (must be uniform) > * @param width > */ > public final void setItemWidth(int width) { > mItemWidth = width; > buildOffsetCache(); > } > /** > * The amount that non-focused items will be rotated. > * @param rotate Valid rotation value between 0.0f and 90.0f. > */ > public final void setUnselectedRotate(float rotate) { > mMaxUnselectedRotateAngle = rotate; > buildOffsetCache(); > } > /** > * The amount that non-selected items will be scaled. > * @param scale Scale value, may be greater than 1.0f. > */ > public final void setUnselectedScale(float scale) { > mMinUnselectedScale = scale; > buildOffsetCache(); > } > /** > * Optional, over-scale the selected item (ie, 1.1f) > * @param scale > */ > public final void setSelectedScale(float scale) { > mMaxSelectedScale = scale; > buildOffsetCache(); > } > > /********************************** > PRIVATE METHODS > **********************************/ > > /** > * Pre-calculate the range rotation angles and scaling factors > * for the non-static horizontal range of the Gallery. > */ > private final void buildOffsetCache() { > final int galleryWidth = getWidth(); > if(galleryWidth<1 || mItemWidth<1) return; > > final float unRotate = mMaxUnselectedRotateAngle, > unScale = mMinUnselectedScale, > maxScale = mMaxSelectedScale, > unScaleRange = > (mMaxSelectedScale-mMinUnselectedScale); > > final float centerline = galleryWidth/2; > final float itemHalfWidth = mItemWidth/2; > > final int rangeMin = mStageOffsetMin = (int)(centerline- > itemHalfWidth); > final int rangeMax = mStageOffsetMax = (int)(centerline > +itemHalfWidth); > > mOffsetRotateCache = new float[galleryWidth]; > mOffsetScaleCache = new float[galleryWidth]; > > // child is to the left of the centerline, so translating only > for(int i=0;i<rangeMin;i++) { > mOffsetRotateCache[i]=mMaxUnselectedRotateAngle; > mOffsetScaleCache[i]=unScale; > } > > // child is in range, so translating, rotating, and scaling > float rangePct = 0.0f; > for(int i=rangeMin;i<rangeMax;i++) { > rangePct = ((centerline-i)/itemHalfWidth); > mOffsetRotateCache[i]=(rangePct*unRotate); > mOffsetScaleCache[i]= > (rangePct>0)? > (maxScale-(rangePct*unScaleRange)): > (maxScale+(rangePct*unScaleRange)); > } > > // child is to the right of the range, so translating only > for(int i=rangeMax;i<galleryWidth;i++) { > mOffsetRotateCache[i]=-unRotate; > mOffsetScaleCache[i]=unScale; > } > > // this is ugly but it works :) > // smooth the rotation/scaling around the centerline by 3 pixels > in either direction > final int smoothMin = (int)(centerline-3), smoothMax = (int) > (centerline+3); > for(int i=smoothMin;i<smoothMax;i++) { > mOffsetRotateCache[i]=0.0f; > mOffsetScaleCache[i]=maxScale; > } > > // TODO: this was a quick proof-of-concept. we don't really need > to store > // the entire width, only the range between rangeMin and > rangeMax. The > // getStaticTransformation method would then need to take this > into account > // when it grabs the rotation/scale values (ie, subtract the > range lower-bound > // from the child centerline, or something like that). > } > > /********************************** > OVERRIDE METHODS > **********************************/ > > /** > * Per SDK: > * <b><i> > * Override this if your view is known to always be drawn on top of a > solid color > * background, and needs to draw fading edges. Returning a non-zero > color enables t > * he view system to optimize the drawing of the fading edges. If you > do return > * a non-zero color, the alpha should be set to 0xFF. > * </i><b> > * @return > */ > @Override public int getSolidColor() { > return Color.BLACK; > } > /** > * Be sure the static rotation/scale cache is updated > * when the overall size changes > **/ > @Override public void onSizeChanged(int w, int h, int oldw, int oldh) > { > super.onSizeChanged(w, h, oldw, oldh); > buildOffsetCache(); > } > /** > * Apply the necessary rotate and scale transformations to the > provided child. > * @param child > * @param t > * @return > */ > @Override protected boolean getChildStaticTransformation(View child, > Transformation t) { > // reset the transformation > t.clear(); > t.setTransformationType(Transformation.TYPE_BOTH); > > // the offset of the child's centerline from the center > // of the gallery > final int centerX = child.getWidth()/2, centerY = > child.getHeight()/ > 2; > final int centerChild = (child.getLeft()+centerX); > > final Camera camera = mCamera; > final Matrix matrix = t.getMatrix(); > > // left of rotating, scaling range > if(centerChild<mStageOffsetMin) { > camera.save(); > camera.rotateY(mMaxUnselectedRotateAngle); > camera.getMatrix(matrix); > camera.restore(); > > matrix.preTranslate(-centerX, -centerY); > matrix.postTranslate(centerX, centerY); > > matrix.preScale(mMinUnselectedScale, > mMinUnselectedScale, centerX, > centerY); > > // right of rotating, scaling range > } else if(centerChild>mStageOffsetMax) { > camera.save(); > camera.rotateY(-mMaxUnselectedRotateAngle); > camera.getMatrix(matrix); > camera.restore(); > > matrix.preTranslate(-centerX, -centerY); > matrix.postTranslate(centerX, centerY); > > matrix.preScale(mMinUnselectedScale, > mMinUnselectedScale, centerX, > centerY); > > // within the rotating, scaling range > } else { > camera.save(); > camera.rotateY(mOffsetRotateCache[centerChild]); > camera.getMatrix(matrix); > camera.restore(); > > matrix.preTranslate(-centerX, -centerY); > matrix.postTranslate(centerX, centerY); > > matrix.preScale(mOffsetScaleCache[centerChild], > mOffsetScaleCache > [centerChild], centerX, centerY); > > } > > return true; > } > > } > > On Jan 8, 2:41 pm, Flying Coder <[email protected]> wrote: > > > > > Wow - looks great! I'll definitely play around with it and will let > > you know if I have any feedback. > > > Cheers, > > Steve > > > On Jan 8, 3:45 am, Taf <[email protected]> wrote: > > > > Hi, > > > > I've had a go at creating a coverflow like widget. My results can be > > > found here: > > > >http://www.inter-fuser.com/2010/01/android-coverflow-widget.html > > > > If you fancy giving it a try I'd been interested in your feedback. > > > I've only tried it on a HTC G1 running Android 1.1 > > > > Thanks, > > > > Neil.
-- You received this message because you are subscribed to the Google Groups "Android Developers" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/android-developers?hl=en

