Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
155 views
in Technique[技术] by (71.8m points)

android - Creating animation for images from small to large when scrolling vertical

I am creating images in which when scrolled up, the image should get enlarged and remaining images should get smaller. Similarly when second image pushed up, it should enlarge and show. I used accordion type but nothing works. I searched but couldn't find.

In IPhone, it has features but I couldn't find how to create for android. This is for

enter image description here

same effect to be implemented in android.

I used ScaleAnimation with hide and show of layouts to open where image been placed inside the layout. But that also didn't work.

if(openLayout == panel1){
    panel1.startAnimation(new ScaleAnimToHide(1.0f, 1.0f, 1.0f, 0.0f, 200, panel1, true));
}

Can someone help me to solve this issue?

Thanks in advance!!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I have created a basic custom view which replicates this behaviour, it's not completely the same but I think it's close enough for now, if it needs to be exactly the same this can be quickly achieved by modifying the updateChildViews() method. I wrote this class in 20 minutes so it's far from perfect, for a production ready solution some additional work has to be done. Generally this solution works with all kinds of child views, but to replicate the exact behaviour use an ImageView as background for your child views and set this property on the ImageViews:

android:scaleType="centerCrop"

Problems I see with my solution in it's current state:

  • Only works in vertical orientation
  • No view recycling.
  • Should be derived from AdapterView and not LinearLayout.

Anyway that's how it looks so far:

enter image description here

Here is the source code:

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;

public class Accordion extends LinearLayout {

    private static final String LOG_TAG = Accordion.class.getSimpleName();

    private double scrollProgress = 0.0;
    private double topViewScaleFactor = 2.0;
    private double collapsedViewHeight = 200.0;
    private double expandedViewHeight = 700.0;
    private double scrollProgressPerView = expandedViewHeight;

    private final ScrollTouchListener touchListener = new ScrollTouchListener() {
        @Override
        protected void onScroll(float x, float y) {
            scrollProgress += y;
            if(scrollProgress < 0.0) {
                scrollProgress = 0.0;
            }

            int viewCount = getChildCount();
            double maxScrollProgress = (viewCount - 1) * scrollProgressPerView + 1;
            if(scrollProgress > maxScrollProgress) {
                scrollProgress = maxScrollProgress;
            }

            Log.i(LOG_TAG, String.format("Scroll Progress: %f", scrollProgress));

            updateChildViews();
        }
    };

    public Accordion(Context context) {
        super(context);

        this.setOnTouchListener(this.touchListener);
    }

    public Accordion(Context context, AttributeSet attrs) {
        super(context, attrs);

        this.setOnTouchListener(this.touchListener);
    }

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

        this.setOnTouchListener(this.touchListener);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);

        updateChildViews();
    }

    private void updateChildViews() {
        int viewCount = getChildCount();
        double progress = scrollProgress;
        double overflow = 0;
        for(int i = 0; i < viewCount; i++) {
            View child = getChildAt(i);
            if(child != null) {
                if(progress >= scrollProgressPerView) {
                    progress -= scrollProgressPerView;
                    child.setVisibility(View.GONE);
                    setChildHeight(child, 0);
                } else if (progress > 0) {
                    setChildHeight(child, expandedViewHeight - progress);
                    overflow = progress;
                    child.setVisibility(View.VISIBLE);
                    progress = 0;
                } else {
                    if(overflow > 0) {
                        double height = collapsedViewHeight + overflow;
                        if(height > expandedViewHeight) {
                            height = expandedViewHeight;
                        }
                        setChildHeight(child, height);
                        overflow = 0;
                    } else {
                        setChildHeight(child, i > 0 ? collapsedViewHeight : expandedViewHeight);
                    }
                    child.setVisibility(View.VISIBLE);
                }
            }
        }
    }

    private void setChildHeight(View child, double height) {
        child.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, (int)height));
    }

    private static abstract class ScrollTouchListener implements OnTouchListener {

        private static final String LOG_TAG = ScrollTouchListener.class.getSimpleName();

        private boolean scrolling = false;
        private float x = 0;
        private float y = 0;

        @Override
        public boolean onTouch(View view, MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    x = event.getX();
                    y = event.getY();
                    scrolling = true;
                    return true;

                case MotionEvent.ACTION_UP:
                    scrolling = false;
                    return true;

                case MotionEvent.ACTION_MOVE:
                    if (scrolling) {
                        float newX = event.getX();
                        float newY = event.getY();

                        float difX =  x - newX;
                        float difY =  y - newY;
                        onScroll(difX, difY);

                        x = newX;
                        y = newY;
                    }
                    return true;

                default:
                    return false;
            }
        }

        protected abstract void onScroll(float x, float y);
    }
}

To use it just put it in a layout like this:

<at.test.app.Accordion xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:orientation="vertical">

    <ImageView android:layout_width="match_parent"
               android:layout_height="wrap_content"
               android:scaleType="centerCrop"
               android:src="@drawable/alpen"/>

    <ImageView android:layout_width="match_parent"
               android:layout_height="wrap_content"
               android:scaleType="centerCrop"
               android:src="@drawable/alpen"/>

    <ImageView android:layout_width="match_parent"
               android:layout_height="wrap_content"
               android:scaleType="centerCrop"
               android:src="@drawable/alpen"/>

    <ImageView android:layout_width="match_parent"
               android:layout_height="wrap_content"
               android:scaleType="centerCrop"
               android:src="@drawable/alpen"/>

</at.test.app.Accordion>

If you have any additional questions feel free to ask!


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...