【问题标题】:Animate view sliding out of another view, pushing views below out of the way动画视图滑出另一个视图,将下面的视图推开
【发布时间】:2018-04-25 19:19:46
【问题描述】:

我有一个按钮列表。当我按下按钮时,视图应该以向下的方式滑出按钮,如下所示:

开始:

中途:

结束:

我该怎么做呢?应该滑出的 View 比按钮大,所以首先将 View 隐藏在按钮后面,然后向下滑动会使 View 在按钮上方可见。那不应该发生。

关于如何解决这个问题的任何想法或示例?

【问题讨论】:

  • 或者就此而言,这不是 ExpandableListView 无法实现的吗? techdroid.kbeanie.com/2010/09/…
  • 我正在为最小 8 开发。我将研究可扩展的列表视图,谢谢。不过,我希望看到一个自定义解决方案,因为我想在我也只有 1 个横幅的其他环境中使用它。
  • 可展开的列表视图似乎没有提供这样的动画。虽然我使用的 minSdkVersion 为 8,但如果动画在低于 11 的 sdk 版本上不起作用,这不是一个大问题。
  • 我只是想问一下....流畅的动画是否是强制性的...或者你想要显示/隐藏效果
  • 我确实需要流畅的动画,但是在API

标签: android android-animation


【解决方案1】:

我认为最简单的方法是扩展 Animation 类并覆盖 applyTransformation() 以更改视图的高度,如下所示:

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

要使用它,请将您的onclick() 设置如下:

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

问候。

【讨论】:

  • 很高兴为您提供帮助。感谢您的赏金:-)
  • 谢谢!对我很有用
  • 对不起老兄,MyAnimation 是什么??
  • 我尝试使用它,效果很好。但是我在第一次扩展它时遇到了一些错误,它没有显示动画只是显示视图。之后动画就会显示出来。
  • 就我而言,view2 突然出现,即。没有滑动动画,但它会随着完美的滑动动画消失。如何将滑动效果也应用到EXPAND
【解决方案2】:

使用类似的东西:

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

【讨论】:

  • 在某种程度上,这不会为视图设置动画。但是会调用 applyTransformation 方法。动画完成后,会显示视图(“弹出”到视线中)。此外,视图的高度为 match_parent,而不是 xml 文件中定义的 150dp
  • 嗯,这样的作品。但是,滑动视图下方的视图会弹出,而不是流畅的动画。
  • 为了能够在下面的动画上制作流畅的动画,您可能必须让另一个动画向下移动(同时或在此动画之前)。
【解决方案3】:

这是一个简单的手工动画示例,提供您想要的。它适用于测试应用程序,但我不确定是否有错误:

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
    }
}
}

【讨论】:

  • 我已经将它复制粘贴到一个测试项目中,看起来不错。明天我会在我的主要项目中尝试一下!
  • 虽然这适用于空视图,但当我将其应用于 TextView 时,它会进行动画处理,但会跳回原始大小。
【解决方案4】:

也许您可以将高度设置为 0 并逐渐增加高度。但是你会遇到一个问题,你必须确保你的文本在视图的底部对齐。并且还要知道视图的最大高度应该是多少。

【讨论】:

    【解决方案5】:

    使用滑动列表适配器比使用动画更容易

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

    【讨论】:

      【解决方案6】:

      只需将android:animateLayoutChanges 传递给包含所有视图的LinearLayout,您将获得您想要的结果。

      【讨论】:

        【解决方案7】:

        我会那样做。首先是整个可折叠面板组件的布局:(伪xml)

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

        这应该确保内容始终位于句柄下方。

        那么当你需要折叠时:

        • 将内容的上边距设置为从 0 到 -content.height 的动画
        • 将面板的高度从 current 设置为 current-content.height

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-12-16
          相关资源
          最近更新 更多