Animate view sliding out of another view, pushing views below out of the way

后端 未结 7 1551
野趣味
野趣味 2020-12-22 21:27

I have a list of buttons. When I press a button, a View should slide in a downwards motion out of the button, like this:

Start:

相关标签:
7条回答
  • 2020-12-22 21:45

    use a sliding list adapter so much easier than messing around with animations

    https://github.com/tjerkw/Android-SlideExpandableListView

    0 讨论(0)
  • 2020-12-22 21:49

    Simply pass android:animateLayoutChanges to LinearLayout that holds all the views, you will achieve your desired result.

    0 讨论(0)
  • 2020-12-22 21:59

    Use something like:

     Animation a = new ScaleAnimation(1, 1, 0, 1, Animation.RELATIVE_TO_SELF, (float) 0.5,    Animation.RELATIVE_TO_SELF, (float) 0);
     a.setFillAfter(true);
     view.setAnimation(a);
     a.setDuration(1000);
     view.startAnimation(a);
    
    0 讨论(0)
  • 2020-12-22 22:08

    I would do it like that. First the layout for the whole collapsible panel component: (pseudo xml)

    RelativeLayout (id=panel, clip)
        LinearLayout (id=content, alignParentBottom=true)
        LinearLayout (id=handle, above=content)
    

    This should ensure that the content is always below the handle.

    Then when you need to collapse:

    • Animate the top margin of content from 0 to -content.height
    • Animate the height of the panel from current to current-content.height
    0 讨论(0)
  • 2020-12-22 22:10

    I believe the simplest approach is to extend Animation class and override applyTransformation() to change the view's height as follows:

    import android.view.View;
    import android.view.ViewGroup.LayoutParams;
    import android.view.animation.Animation;
    import android.view.animation.Transformation;
    import android.widget.LinearLayout;
    
    public class MyCustomAnimation extends Animation {
    
        public final static int COLLAPSE = 1;
        public final static int EXPAND = 0;
    
        private View mView;
        private int mEndHeight;
        private int mType;
        private LinearLayout.LayoutParams mLayoutParams;
    
        public MyCustomAnimation(View view, int duration, int type) {
    
            setDuration(duration);
            mView = view;
            mEndHeight = mView.getHeight();
            mLayoutParams = ((LinearLayout.LayoutParams) view.getLayoutParams());
            mType = type;
            if(mType == EXPAND) {
                mLayoutParams.height = 0;
            } else {
                mLayoutParams.height = LayoutParams.WRAP_CONTENT;
            }
            view.setVisibility(View.VISIBLE);
        }
    
        public int getHeight(){
            return mView.getHeight();
        }
    
        public void setHeight(int height){
            mEndHeight = height;
        }
    
        @Override
        protected void applyTransformation(float interpolatedTime, Transformation t) {
    
            super.applyTransformation(interpolatedTime, t);
            if (interpolatedTime < 1.0f) {
                if(mType == EXPAND) {
                    mLayoutParams.height =  (int)(mEndHeight * interpolatedTime);
                } else {
                    mLayoutParams.height = (int) (mEndHeight * (1 - interpolatedTime));
                }
                mView.requestLayout();
            } else {
                if(mType == EXPAND) {
                    mLayoutParams.height = LayoutParams.WRAP_CONTENT;
                    mView.requestLayout();
                }else{
                    mView.setVisibility(View.GONE);
                }
            }
        }
    }
    

    To use it, set your onclick() as follows:

    int height;
    
    @Override
    public void onClick(View v) {
        if(view2.getVisibility() == View.VISIBLE){
            MyCustomAnimation a = new MyCustomAnimation(view2, 1000, MyCustomAnimation.COLLAPSE);
            height = a.getHeight();
            view2.startAnimation(a);
        }else{
            MyCustomAnimation a = new MyCustomAnimation(view2, 1000, MyCustomAnimation.EXPAND);
            a.setHeight(height);
            view2.startAnimation(a);
        }
    }
    

    Regards.

    0 讨论(0)
  • 2020-12-22 22:10

    Here is simple example of hand-made animation, that provide what you want. It works in test app, but I'm not sure that there is no bugs:

    public class MainActivity extends Activity implements OnClickListener {
    private Timer timer;
    private TimerTask animationTask;
    private View view1;
    private View view2;
    boolean animating;
    boolean increasing = true;
    int initHeight = -1;
    private LayoutParams params;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        timer = new Timer();
    
        view1 = findViewById(R.id.view1);// clickable view
        view1.setOnClickListener(this); 
    
        view2 = findViewById(R.id.view2);// animated view
        params = view2.getLayoutParams();
    }
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
        timer.cancel();
    }
    
    @Override
    public void onClick(View v) {
        Toast.makeText(this, "start animating...", Toast.LENGTH_SHORT).show();
    
        animationTask = new TimerTask() {
            @Override
            public void run() {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        if (animationFinished()) {
                            animating = false;
                            cancel();//canceling animating task
                            return;
                        }
                        params.height += increasing ? 1 : -1;
                        view2.setLayoutParams(params);
                    }
                });
            }
    
            private boolean animationFinished() {
                int viewHeight = view2.getHeight();
                if (increasing && viewHeight >= initHeight) {
                    return true;
                }
                if (!increasing && viewHeight <= 0) {
                    return true;
                }
                return false;
            }
        };
    
        //if we already animating - we just change direction of animation
        increasing = !increasing;
        if (!animating) {
            animating = true;
            int height = view2.getHeight();
    
            params.height = height;
            view2.setLayoutParams(params);//change param "height" from "wrap_conent" to real height
    
            if (initHeight < 0) {//height of view - we setup it only once
                initHeight = height;
            }
            timer.schedule(animationTask, 0, 10);//changing repeat time here will fasten or slow down animation
        }
    }
    }
    
    0 讨论(0)
提交回复
热议问题