Android的照片放大/缩小照片、Android

2023-09-05 11:02:45 作者:君醉相思浓

您好我现在用的库部件,显示从互联网上下载的图片。

显示多个图像,我想有一个逐渐放大,而人上下滑动屏幕上。我知道如何实现触摸事件的唯一的事情,我不知道如何使整个画廊视图逐步发展壮大。我不希望放大一张图片我想整个画廊放大/缩小逐渐显现。

EDIT3:我设法放大画廊的可见部分,但问题是我需要找到一种方法,画廊,了解它,更新它的其他孩子了。

如果3张图片可见然后你开始缩放和画廊也变得越来越小,所以做图片,但什么样的我想在这种情况下更多的图像可见不过我还是要说什么情况是知道如何达到这个预期效果。这里就是整个code:

 公共类Gallery1扩展活动实现OnTouchListener {

私有静态最后字符串变量=GalleryTest;
私人持股量放大= 0.0;
//记住一些东西放大
的PointF开始=新的PointF();
的PointF中期=新的PointF();
图库克;
的LinearLayout布局2;
私人ImageAdapter广告;

@覆盖
公共无效的onCreate(包savedInstanceState){
    super.onCreate(savedInstanceState);
    的setContentView(R.layout.gallery_1);
    布局2 =(的LinearLayout)findViewById(R.id.layout2);

    //参考图库视图
    G =(图库论坛)findViewById(R.id.gallery);
    //适配器设置为我们的自定义适配器(如下图)
    AD =新ImageAdapter(本);
    g.setAdapter(广告);


    layout2.setOnTouchListener(本);

}


公共无效zoomList(布尔增加){
    Log.i(TAG,startig动画);


    AnimatorSet组=新AnimatorSet();
    set.playTogether(

        ObjectAnimator.ofFloat(G,将scaleX,变焦),
        ObjectAnimator.ofFloat(G的scaleY,变焦)

    );
    set.addListener(新AnimatorListener(){

        @覆盖
        公共无效onAnimationStart(动画动画){


        }

        @覆盖
        公共无效onAnimationRepeat(动画动画){
            // TODO自动生成方法存根

        }

        @覆盖
        公共无效onAnimationEnd(动画动画){

        }

        @覆盖
        公共无效onAnimationCancel(动画动画){
            // TODO自动生成方法存根

        }
    });
    set.setDuration(100)。开始();


}


公共类ImageAdapter扩展了BaseAdapter {
    私有静态最终诠释ITEM_WIDTH = 136;
    私有静态最终诠释ITEM_HEIGHT = 88;

    私人最终诠释mGalleryItemBackground;
    私人最终语境mContext;

    私人最终整数[] mImageIds = {
            R.drawable.gallery_photo_1,
            R.drawable.gallery_photo_2,
            R.drawable.gallery_photo_3,
            R.drawable.gallery_photo_4,
            R.drawable.gallery_photo_5,
            R.drawable.gallery_photo_6,
            R.drawable.gallery_photo_7,
            R.drawable.gallery_photo_8
    };

    私人最终浮动mDensity;

    公共ImageAdapter(上下文C){
        mContext = C;
        //见RES /价值/ attrs.xml为的<申报,设置样式>定义
        // Gallery1。
        TypedArray A = obtainStyledAttributes(R.styleable.Gallery1);
        mGalleryItemBackground = a.getResourceId(
                R.styleable.Gallery1_android_galleryItemBackground,1);
        a.recycle();

        mDensity = c.getResources()getDisplayMetrics()密度。
    }

    公众诠释getCount将(){
        返回mImageIds.length;
    }

    公共对象的getItem(INT位置){
        返回的位置;
    }

    众长getItemId(INT位置){
        返回的位置;
    }

    公共查看getView(INT位置,查看convertView,ViewGroup中父){
        ImageView的ImageView的;
        如果(convertView == NULL){
            convertView =新ImageView的(mContext);

            ImageView的=(ImageView的)convertView;
            imageView.setScaleType(ImageView.ScaleType.FIT_XY);
            imageView.setLayoutParams(新Gallery.LayoutParams(
                    (INT)(ITEM_WIDTH * mDensity + 0.5F)
                    (中间体)(ITEM_HEIGHT * mDensity + 0.5F)));

        } 其他 {
            ImageView的=(ImageView的)convertView;
        }

        imageView.setImageResource(mImageIds [位置]);

        返回ImageView的;
    }
}

公共布尔onTouch(视图V,MotionEvent事件){

    如果(event.getAction()== MotionEvent.ACTION_MOVE
            &功放;&安培; event.getPointerCount()> 1){
        中点(中,事件);

        如果(mid.y> start.y){

            Log.i(TAG,下乡(Math.abs(mid.y  -  start.y)=+(Mat​​h.abs(mid.y  -  start.y))+和缩放=+变焦); / /下降等方面加大
            如果((Math.abs(mid.y  -  start.y)→10)及及(变焦< 2.5F)){

                变焦=变焦+ 0.1F;
                中点(启动,事件);
                zoomList(真正的);


            }
            返回true;
        }否则如果(mid.y< start.y){

            Log.i(TAG,涨(Math.abs(mid.y  -  start.y)=+(Mat​​h.abs(mid.y  -  start.y))+和缩放=+变焦); / /小
            如果((Math.abs(mid.y  -  start.y)→10)及及(变焦> 0.1)){

                中点(启动,事件);
                变焦=放大0.1F;
                zoomList(假);

            }
            返回true;
        }

    }

    否则如果(event.getAction()== MotionEvent.ACTION_POINTER_DOWN){
        Log.e(TAG,指针去了:+ event.getPointerCount());
        返回true;
    }
    否则如果(event.getAction()== MotionEvent.ACTION_UP){
        Log.i(TAG,指针往上走);
        返回true;
    }
    否则如果(event.getAction()== MotionEvent.ACTION_DOWN){
        Log.i(TAG,指针下降);
        start.set(event.getX(),event.getY());
        返回true;
    }

     返回false;
       //表示事件已经被处理或不
   }

私人无效中点(的PointF点,MotionEvent事件){
    浮X = event.getX(0)+ event.getX(1);
    浮Y = event.getY(0)+ event.getY(1);
    point.set(X / 2,Y / 2);
 }
 

我意识到我可能要延长画廊甚至另一个视图组或创建自己的类,但我不知道从哪里开始:该方法使用一个负责定标...

EDIT4:我不知道他的问题是清楚。这是国家的一个例子:

国家之一:初始状态,我们必须考虑到3图像

状态2:我们检测纵向触摸持续了2个手指=我们必须缩小

状态3:我们开始缩放=动画在画廊或对孩子???

状态4:像册检测到它的3个孩子都是小

状态5:像册根据新的可用空间增加了1 /更多的孩子

最后更新: 感谢所有已经发布了,但我终于得出了一个结论,那就是不使用画廊都: 1.这是德precated 2.这是不够的定制我的情况

玩转Android UI篇 ZoomControls放大缩小图片

如果要进行动画处理多个图像一次,你可能要考虑使用OpenGL,我使用libgdx库: https://github.com/libgdx/libgdx

解决方案

下面的的 ScalingGallery 的的实施可能会有所帮助。 这个画廊的子类覆盖的的 getChildStaticTransformation在其中的比例进行(查看孩子,变换T)的方式。您可以进一步自定义缩放参数,以适应自己的需要。

请注意在的 ScalingGalleryItemLayout.java 的类。这是必要的,因为你已经完成缩放operationg对孩子意见后,他们的命中框不再有效,使他们必须从具有的的 getChildStaticTransformation(查看孩子,变换T)更新的方式。

这是包裹在 ScalingGalleryItemLayout 的每家画廊的项目做延伸一个的的LinearLayout 的。同样,您可以自定义此以满足自己的需要,如果一个的的LinearLayout 的不符合您的布局需要你的库项目。

  

文件:/src/com/example/ScalingGallery.java

  / **
 *它改变了大小以及基于他们在画廊位置的项目位置自定义的库组件。
 * /
公共类ScalingGallery扩展库{

    公共静态最终诠释ITEM_SPACING = -20;

    私有静态最终浮动SIZE_SCALE_MULTIPLIER = 0.25f;
    私有静态最终浮动ALPHA_SCALE_MULTIPLIER = 0.5F;
    私有静态最终浮动X_OFFSET = 20.0f;

    / **
     *实现由子以调整边界后它已被矩阵转换。
     * /
    公共接口SetHitRectInterface {
        公共无效setHitRect(RectF newRect);
    }

    / **
     * @参数方面
     *背景下,此画廊将被使用。
     * @参数ATTRS
     *属性为这个画廊(通过XML或IN  -  code)
     * /
    公共ScalingGallery(上下文的背景下,ATTRS的AttributeSet){
        超(背景下,ATTRS);
        setStaticTransformationsEnabled(真正的);
        setChildrenDrawingOrderEnabled(真正的);
    }

    / **
     * {@inheritDoc}
     *
     * @see #setStaticTransformationsEnabled(布尔)
     *
     *这是在定标发生。
     * /
    保护布尔getChildStaticTransformation(查看孩子,变换T){

        child.invalidate();

        t.clear();
        t.se​​tTransformationType(Transformation.TYPE_BOTH);

        //孩子的位置,在画廊(... +2 +1 0 -1 -2 ... 0是中间)
        最终诠释childPosition = getSelectedItemPosition() -  getPositionForView(子);
        最终诠释childPositionAbs =(INT)Math.abs(childPosition);

        最终浮动左= child.getLeft();
        最终浮动顶部= child.getTop();
        最终浮动右= child.getRight();
        最终浮动底= child.getBottom();

        字模= t.getMatrix();
        RectF modifiedHitBox =新RectF();

        //改变α,规模和翻译非中间的孩子的意见。
        如果(childPosition!= 0){

            最终诠释身高= child.getMeasuredHeight();
            最终诠释宽度= child.getMeasuredWidth();

            //缩放大小。
            浮scaledSize = 1.0F  - (childPositionAbs * SIZE_SCALE_MULTIPLIER);
            如果(scaledSize℃,){
                scaledSize = 0;
            }
            matrix.setScale(scaledSize,scaledSize);

            浮MOVEX = 0;
            浮moveY = 0;

            从右到左移动//  - 线性移动,因为缩放相对于该视图的左上角进行。
            如果(childPosition℃,){
                的Movex =((childPositionAbs  -  1)* SIZE_SCALE_MULTIPLIER *宽)+ X_OFFSET;
                MOVEX * = -1;

            }否则{//移动从左到右 - 总和的previous位置'×位移。

                // X(N)= X(0)+ X(1)+ X(2)+ ... + X(N-1)
                的for(int i = childPositionAbs; I> 0;我 - ){
                    的Movex + =(I * SIZE_SCALE_MULTIPLIER *宽);
                }
                MOVEX + = X_OFFSET;
            }

            //向下移动的y轴是线性的。
            moveY =((childPositionAbs * SIZE_SCALE_MULTIPLIER *高)/ 2);

            matrix.postTranslate(MOVEX,moveY);

            //规模alpha值。
            最终浮阿尔法=(1.0F / childPositionAbs)* ALPHA_SCALE_MULTIPLIER;
            t.se​​tAlpha(阿尔法);

            //计算新打箱。自从我们搬到了孩子,击中格不再排队的新的子位置。
            最终浮动newLeft =左+的Movex;
            最终浮动newTop =顶部+ moveY;
            最终浮动newRight = newLeft +(宽* scaledSize);
            最终浮动newBottom = newTop +(高* scaledSize);
            modifiedHitBox =新RectF(newLeft,newTop,newRight,newBottom);
        } 其他 {
            modifiedHitBox =新RectF(左,上,右,下);
        }

        //更新子打框,以便您可以在孩子的边界内挖掘
        ((SetHitRectInterface)子).setHitRect(modifiedHitBox);

        返回true;
    }

    @覆盖
    保护无效onLayout(布尔改变,诠释L,INT T,INT R,int b)在{

        //有助于在滚动过程中理顺抖动。
        //阅读更多 -  http://www.unwesen.de/2011/04/17/android-jittery-scrolling-gallery/
        最终诠释viewsOnScreen = getLastVisiblePosition() -  getFirstVisiblePosition();
        如果(viewsOnScreen&所述; = 0){
            super.onLayout(改变,L,T,R,B);
        }
    }

    私人诠释mLastDrawnPosition;

    @覆盖
    保护INT getChildDrawingOrder(INT childCount,int i)以{

        每次//重置最后一个位置的变量,我们正在开始一个新的绘图环
        如果(我== 0){
            mLastDrawnPosition = 0;
        }

        最终诠释centerPosition = getSelectedItemPosition() -  getFirstVisiblePosition();

        如果(ⅰ== childCount  -  1){
            返回centerPosition;
        }否则,如果(I> = centerPosition){
            mLastDrawnPosition ++;
            返回childCount  -  mLastDrawnPosition;
        } 其他 {
            返回我;
        }
    }
}
 

  

文件:/src/com/example/ScalingGalleryItemLayout.java

 公共类ScalingGalleryItemLayout扩展的LinearLayout实现SetHitRectInterface {

    公共ScalingGalleryItemLayout(上下文的背景下){
        超(上下文);
    }

    公共ScalingGalleryItemLayout(上下文的背景下,ATTRS的AttributeSet){
        超(背景下,ATTRS);
    }

    公共ScalingGalleryItemLayout(上下文的背景下,ATTRS的AttributeSet,诠释defStyle){
        超(背景下,ATTRS,defStyle);
    }

    私人矩形mTransformedRect;

    @覆盖
    公共无效setHitRect(RectF newRect){

        如果(newRect == NULL){
            返回;
        }

        如果(mTransformedRect == NULL){
            mTransformedRect =新的矩形();
        }

        newRect.round(mTransformedRect);
    }

    @覆盖
    公共无效getHitRect(矩形outRect){

        如果(mTransformedRect == NULL){
            super.getHitRect(outRect);
        } 其他 {
            outRect.set(mTransformedRect);
        }
    }
}
 

  

文件:/res/layout/ScaledGalleryItemLayout.xml

 < XML版本=1.0编码=UTF-8&GT?;
< com.example.ScalingGalleryItemLayout的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
    机器人:ID =@ + ID / gallery_item_layout
    机器人:layout_width =WRAP_CONTENT
    机器人:layout_height =WRAP_CONTENT
    机器人:layout_gravity =中心
    机器人:重力=中心
    机器人:方向=垂直
    机器人:填充=5DP>

    < ImageView的
        机器人:ID =@ + ID / gallery_item_image
        机器人:layout_width =为360px
        机器人:layout_height =210px
        机器人:layout_gravity =中心
        机器人:反锯齿=真
        机器人:背景=@可绘制/ gallery_item_button_selector
        机器人:cropToPadding =真
        机器人:填充=35dp
        机器人:scaleType =centerInside/>

    <的TextView
        机器人:ID =@ + ID / gallery_item_text
        机器人:layout_width =WRAP_CONTENT
        机器人:layout_height =WRAP_CONTENT
        机器人:layout_gravity =中心
        机器人:文字颜色=@可绘制/白
        机器人:TEXTSIZE =30sp/>

< /com.example.ScalingGalleryItemLayout>
 

Hi I am using the Gallery widget to show images downloaded from the internet.

to show several images and I would like to have a gradual zoom while people slide up and down on the screen. I know how to implement the touch event the only thing I don't know how to make the whole gallery view grow gradually. I don't want to zoom in on one image I want the whole gallery to zoom in/out gradually.

EDIT3: I manage to zoom the visible part of the gallery but the problem is I need to find a way for the gallery to find out about it and update it's other children too.

What happens is if 3 images are visible then you start zooming and the gallery does get smaller, so do the images but what I would like in this case is more images to be visible but I don't know how to reach this desired effect. Here's the entire code:

public class Gallery1 extends Activity implements OnTouchListener {

private static final String TAG = "GalleryTest";
private float zoom=0.0f;
// Remember some things for zooming
PointF start = new PointF();
PointF mid = new PointF();
Gallery g;
LinearLayout layout2;
private ImageAdapter ad;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.gallery_1);
    layout2=(LinearLayout) findViewById(R.id.layout2);

    // Reference the Gallery view
    g = (Gallery) findViewById(R.id.gallery);
    // Set the adapter to our custom adapter (below)
    ad=new ImageAdapter(this);
    g.setAdapter(ad);


    layout2.setOnTouchListener(this);

}


public void zoomList(boolean increase) {
    Log.i(TAG, "startig animation");


    AnimatorSet set = new AnimatorSet();
    set.playTogether(

        ObjectAnimator.ofFloat(g, "scaleX", zoom),
        ObjectAnimator.ofFloat(g, "scaleY", zoom)

    );
    set.addListener(new AnimatorListener() {

        @Override
        public void onAnimationStart(Animator animation) {


        }

        @Override
        public void onAnimationRepeat(Animator animation) {
            // TODO Auto-generated method stub

        }

        @Override
        public void onAnimationEnd(Animator animation) {

        }

        @Override
        public void onAnimationCancel(Animator animation) {
            // TODO Auto-generated method stub

        }
    });
    set.setDuration(100).start();


}


public class ImageAdapter extends BaseAdapter {
    private static final int ITEM_WIDTH = 136;
    private static final int ITEM_HEIGHT = 88;

    private final int mGalleryItemBackground;
    private final Context mContext;

    private final Integer[] mImageIds = {
            R.drawable.gallery_photo_1,
            R.drawable.gallery_photo_2,
            R.drawable.gallery_photo_3,
            R.drawable.gallery_photo_4,
            R.drawable.gallery_photo_5,
            R.drawable.gallery_photo_6,
            R.drawable.gallery_photo_7,
            R.drawable.gallery_photo_8
    };

    private final float mDensity;

    public ImageAdapter(Context c) {
        mContext = c;
        // See res/values/attrs.xml for the <declare-styleable> that defines
        // Gallery1.
        TypedArray a = obtainStyledAttributes(R.styleable.Gallery1);
        mGalleryItemBackground = a.getResourceId(
                R.styleable.Gallery1_android_galleryItemBackground, 1);
        a.recycle();

        mDensity = c.getResources().getDisplayMetrics().density;
    }

    public int getCount() {
        return mImageIds.length;
    }

    public Object getItem(int position) {
        return position;
    }

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

    public View getView(int position, View convertView, ViewGroup parent) {
        ImageView imageView;
        if (convertView == null) {
            convertView = new ImageView(mContext);

            imageView = (ImageView) convertView;
            imageView.setScaleType(ImageView.ScaleType.FIT_XY);
            imageView.setLayoutParams(new Gallery.LayoutParams(
                    (int) (ITEM_WIDTH * mDensity + 0.5f),
                    (int) (ITEM_HEIGHT * mDensity + 0.5f)));

        } else {
            imageView = (ImageView) convertView;
        }

        imageView.setImageResource(mImageIds[position]);

        return imageView;
    }
}

public boolean onTouch(View v, MotionEvent event) {

    if (event.getAction() == MotionEvent.ACTION_MOVE
            && event.getPointerCount() > 1) {
        midPoint(mid, event);

        if(mid.y > start.y){

            Log.i(TAG, "Going down (Math.abs(mid.y - start.y)= "+(Math.abs(mid.y - start.y))+" and zoom="+zoom); // going down so increase
            if ((Math.abs(mid.y - start.y) > 10) && (zoom<2.5f)){

                zoom=zoom+0.1f;
                midPoint(start, event);
                zoomList(true);


            }
            return true;
        }else if(mid.y < start.y){

            Log.i(TAG, "Going up (Math.abs(mid.y - start.y)= "+(Math.abs(mid.y - start.y))+" and zoom="+zoom); //smaller
            if ((Math.abs(mid.y - start.y) > 10) &&(zoom>0.1)){

                midPoint(start, event);
                zoom=zoom-0.1f;
                zoomList(false);

            }
            return true;
        }

    }

    else if (event.getAction() == MotionEvent.ACTION_POINTER_DOWN) {
        Log.e(TAG, "Pointer went down: " + event.getPointerCount());
        return true;
    }
    else if (event.getAction() == MotionEvent.ACTION_UP) {
        Log.i(TAG, "Pointer going up");
        return true;
    }
    else if (event.getAction() == MotionEvent.ACTION_DOWN) {
        Log.i(TAG, "Pointer going down");
        start.set(event.getX(), event.getY());
        return true;
    }

     return false;
       // indicate event was handled or not
   }

private void midPoint(PointF point, MotionEvent event) {
    float x = event.getX(0) + event.getX(1);
    float y = event.getY(0) + event.getY(1);
    point.set(x / 2, y / 2);
 }

I realise I will probably have to extend the Gallery or even another View group or create my own class but I don't know where to start: which method use the one responsible for scaling...

EDIT4: I don't know if he question is clear enough. Here is an example of states:

State one: initial state, we have 3 images in view

State 2: we detect vertical touches going up with 2 fingers = we have to zoom out

state 3: we start zooming = animation on the gallery or on the children???

state 4: gallery detects that it's 3 children are smaller

state 5: gallery adds 1 /more children according to the new available space

LAST UPDATE: Thanks to all that have posted but I have finally reached a conclusion and that is to not use Gallery at all: 1. It's deprecated 2. It's not customizable enough for my case

If you want to animate several images at once you may want to consider using OpenGl, I am using libgdx library: https://github.com/libgdx/libgdx

解决方案

The following ScalingGallery implementation might be of help. This gallery subclass overrides the getChildStaticTransformation(View child, Transformation t) method in which the scaling is performed. You can further customize the scaling parameters to fit your own needs.

Please note the ScalingGalleryItemLayout.java class. This is necessary because after you have performed the scaling operationg on the child views, their hit boxes are no longer valid so they must be updated from with the getChildStaticTransformation(View child, Transformation t) method.

This is done by wrapping each gallery item in a ScalingGalleryItemLayout which extends a LinearLayout. Again, you can customize this to fit your own needs if a LinearLayout does not meet your needs for layout out your gallery items.

File : /src/com/example/ScalingGallery.java

/**
 * A Customized Gallery component which alters the size and position of its items based on their position in the Gallery.
 */
public class ScalingGallery extends Gallery {

    public static final int ITEM_SPACING = -20;

    private static final float SIZE_SCALE_MULTIPLIER = 0.25f;
    private static final float ALPHA_SCALE_MULTIPLIER = 0.5f;
    private static final float X_OFFSET = 20.0f;

    /**
     * Implemented by child view to adjust the boundaries after it has been matrix transformed. 
     */
    public interface SetHitRectInterface {
        public void setHitRect(RectF newRect); 
    }

    /**
     * @param context
     *            Context that this Gallery will be used in.
     * @param attrs
     *            Attributes for this Gallery (via either xml or in-code)
     */
    public ScalingGallery(Context context, AttributeSet attrs) {
        super(context, attrs);
        setStaticTransformationsEnabled(true);
        setChildrenDrawingOrderEnabled(true);
    }

    /**
     * {@inheritDoc}
     * 
     * @see #setStaticTransformationsEnabled(boolean)
     *
     * This is where the scaling happens.
     */
    protected boolean getChildStaticTransformation(View child, Transformation t) {

        child.invalidate();

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

        // Position of the child in the Gallery (... +2  +1  0  -1  -2 ... 0 being the middle)
        final int childPosition = getSelectedItemPosition() - getPositionForView(child);
        final int childPositionAbs = (int) Math.abs(childPosition);

        final float left = child.getLeft();
        final float top = child.getTop();
        final float right = child.getRight();
        final float bottom = child.getBottom();

        Matrix matrix = t.getMatrix();
        RectF modifiedHitBox = new RectF();

        // Change alpha, scale and translate non-middle child views.
        if (childPosition != 0) {

            final int height = child.getMeasuredHeight();
            final int width = child.getMeasuredWidth();

            // Scale the size.
            float scaledSize = 1.0f - (childPositionAbs * SIZE_SCALE_MULTIPLIER);
            if (scaledSize < 0) {
                scaledSize = 0;
            }
            matrix.setScale(scaledSize, scaledSize);

            float moveX = 0;
            float moveY = 0;

            // Moving from right to left -- linear move since the scaling is done with respect to top-left corner of the view.
            if (childPosition < 0) {
                moveX = ((childPositionAbs - 1) * SIZE_SCALE_MULTIPLIER * width) + X_OFFSET;
                moveX *= -1;

            } else { // Moving from left to right -- sum of the previous positions' x displacements.

                // X(n) = X(0) + X(1) + X(2) + ... + X(n-1)
                for (int i = childPositionAbs; i > 0; i--) {
                    moveX += (i * SIZE_SCALE_MULTIPLIER * width);
                }
                moveX += X_OFFSET;
            }

            // Moving down y-axis is linear.
            moveY = ((childPositionAbs * SIZE_SCALE_MULTIPLIER * height) / 2);

            matrix.postTranslate(moveX, moveY);

            // Scale alpha value.
            final float alpha = (1.0f / childPositionAbs) * ALPHA_SCALE_MULTIPLIER;
            t.setAlpha(alpha);

            // Calculate new hit box.  Since we moved the child, the hitbox is no longer lined up with the new child position.
            final float newLeft = left + moveX;
            final float newTop = top + moveY;
            final float newRight = newLeft + (width * scaledSize);
            final float newBottom = newTop + (height * scaledSize);
            modifiedHitBox = new RectF(newLeft, newTop, newRight, newBottom);
        } else {
            modifiedHitBox = new RectF(left, top, right, bottom);
        }

        // update child hit box so you can tap within the child's boundary
        ((SetHitRectInterface) child).setHitRect(modifiedHitBox);

        return true;
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {

        // Helps to smooth out jittering during scrolling.
        // read more - http://www.unwesen.de/2011/04/17/android-jittery-scrolling-gallery/
        final int viewsOnScreen = getLastVisiblePosition() - getFirstVisiblePosition();
        if (viewsOnScreen <= 0) {
            super.onLayout(changed, l, t, r, b);
        }
    }

    private int mLastDrawnPosition;

    @Override
    protected int getChildDrawingOrder(int childCount, int i) {

        //Reset the last position variable every time we are starting a new drawing loop
        if (i == 0) {
            mLastDrawnPosition = 0;
        }

        final int centerPosition = getSelectedItemPosition() - getFirstVisiblePosition();

        if (i == childCount - 1) {
            return centerPosition;
        } else if (i >= centerPosition) {
            mLastDrawnPosition++;
            return childCount - mLastDrawnPosition;
        } else {
            return i;
        }
    }
}

File : /src/com/example/ScalingGalleryItemLayout.java

public class ScalingGalleryItemLayout extends LinearLayout implements SetHitRectInterface {

    public ScalingGalleryItemLayout(Context context) {
        super(context);
    }

    public ScalingGalleryItemLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public ScalingGalleryItemLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    private Rect mTransformedRect;

    @Override
    public void setHitRect(RectF newRect) {

        if (newRect == null) {
            return;
        }

        if (mTransformedRect == null) {
            mTransformedRect = new Rect();
        }

        newRect.round(mTransformedRect);
    }

    @Override
    public void getHitRect(Rect outRect) {

        if (mTransformedRect == null) {
            super.getHitRect(outRect);
        } else {
            outRect.set(mTransformedRect);
        }
    }
}

File : /res/layout/ScaledGalleryItemLayout.xml

<?xml version="1.0" encoding="utf-8"?>
<com.example.ScalingGalleryItemLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/gallery_item_layout"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:gravity="center"
    android:orientation="vertical"
    android:padding="5dp" >

    <ImageView
        android:id="@+id/gallery_item_image"
        android:layout_width="360px"
        android:layout_height="210px"
        android:layout_gravity="center"
        android:antialias="true"
        android:background="@drawable/gallery_item_button_selector"
        android:cropToPadding="true"
        android:padding="35dp"
        android:scaleType="centerInside" />

    <TextView
        android:id="@+id/gallery_item_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:textColor="@drawable/white"
        android:textSize="30sp" />

</com.example.ScalingGalleryItemLayout>