Search code examples
androidandroid-gallery

Creating a custom gallery


I want to create a custom gallery in which the center most view in the gallery is showing a zoom out animation. So when I scroll my gallery, the items coming to the center will get zoomed. So what I need to know is :

  1. How can I find the center item in a gallery.(If 5 items are displayed, I need the 3rd item as center one).
  2. How can I animate it to get a smooth bulging effect when scrolling happens?

Solution

  • With the help of a pipe kind of structure using queue, i got it when combined with addViewToLayout Method of Gallery.

    Code :

    Custom Gallery class

    public class NGallery extends Gallery {
    
    private Pipe<View> childViews;
    private int pipeSize;
    private View previousAnimatedView;
    private boolean isScrollLeft;
    
    public NGallery(Context context, AttributeSet attrs) {
        super(context, attrs);
        final Timer tmr = new Timer();
        TimerTask task = new TimerTask() {
    
            @Override
            public void run() {
                initialize();
                if (pipeSize > 0) {
                    tmr.cancel();
                }
            }
        };
        tmr.scheduleAtFixedRate(task, 100, 100);
    }
    
    private void initialize() {
        View childView = getChildAt(0);
        if (childView != null && childView.getWidth() > 0) {
            pipeSize = getWidth() / childView.getWidth();
            childViews = new Pipe<View>(pipeSize);
        }
    }
    
    @Override
    protected boolean addViewInLayout(View child, int index,
            android.view.ViewGroup.LayoutParams params,
            boolean preventRequestLayout) {
        View viewToAnimate = getViewToAnimate(child);
        if (viewToAnimate != null) {
            if (previousAnimatedView != null) {
                previousAnimatedView.clearAnimation();
            }
            viewToAnimate.requestFocus();
            AnimationSet animationSet = getAnimationSet(viewToAnimate);
            viewToAnimate.startAnimation(animationSet);
            previousAnimatedView = viewToAnimate;
        }
        return super
                .addViewInLayout(child, index, params, preventRequestLayout);
    }
    
    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
            float distanceY) {
        isScrollLeft = distanceX > 0;
        return super.onScroll(e1, e2, distanceX, distanceY);
    }
    
    private AnimationSet getAnimationSet(View viewToAnimate) {
        AnimationSet animationSet = new AnimationSet(false);
    
        Animation scaleAnimation = new ScaleAnimation(1, 1.5f, 1, 1.5f);
        scaleAnimation.setDuration(100);
        animationSet.addAnimation(scaleAnimation);
    
        Animation transAnimation = new TranslateAnimation(0, 0, 0, 25);
        transAnimation.setDuration(100);
        animationSet.addAnimation(transAnimation);
    
        animationSet.setFillAfter(true);
    
        return animationSet;
    }
    
    private View getViewToAnimate(View child) {
        if (childViews != null) {
            if (isScrollLeft) {
                childViews.addFirst(child);
            } else {
                childViews.addLast(child);
            }
            return childViews.getCenterItem();
        } else {
            return null;
        }
    }
    
    }
    

    Pipe class :

    public class Pipe<E> {
    
    private LinkedList<E> list;
    private int pipeSize;
    
    public Pipe(int size) {
        list = new LinkedList<E>();
        pipeSize = size;
    }
    
    public E getItemAt(int position) {
        return list.get(position);
    }
    
    public E getCenterItem() {
        int pos = pipeSize / 2;
        if (pos < list.size()) {
            return list.get(pos);
        } else {
            return null;
        }
    }
    
    public void addFirst(E item) {
        if (list.size() >= pipeSize) {
            list.removeLast();
        }
        list.addFirst(item);
    }
    
    public void addLast(E item) {
        if (list.size() >= pipeSize) {
            list.removeFirst();
        }
        list.addLast(item);
    }
    
    }