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

匿名 (未验证) 提交于 2019-12-03 01:05:01

问题:

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:

Halfway:

End:

How would I go about this? The View that should slide out is bigger than the button, so first hiding the View behind the button and then sliding it downwards causes the View to be visible above the button. That should not happen.

Any ideas or examples on how to approach this?

回答1:

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 

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.



回答2:

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);


回答3:

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 


回答4:

Maybe you can set the height to 0 and gradually increase the height. But then you will have the problem that you have to be sure your text is aligned at the bottom of the view. And also to know what the maximal height of the view should be.



回答5:

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


回答6:

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

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



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!