【问题标题】:Create animation when tap to slide up and push down to slide down android当点击向上滑动并按下以向下滑动android时创建动画
【发布时间】:2014-04-25 01:26:18
【问题描述】:

继续这种类似的效果,[创建动画] (Creating animation for images from small to large when scrolling vertical) 我需要点击打开图像,而不是拖动图像直到顶部和向下。怎么做? 有什么想法吗?

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

这只是从图像滚动到顶部。我需要点击才能打开图像。怎么做?

提前致谢。

【问题讨论】:

  • 点击打开是什么意思?我是回答您链接到的问题的人。我可以帮助您修改我发布的自定义视图以满足您的需求。
  • 非常感谢@XaverKapeller 的回复,正如您之前所做的那样,用户需要将图像滚动到顶部,反之亦然。但我的要求是除此之外,1.当用户点击(点击)图像时,它应该上升。 2.当你把图像拖到50%到顶部(它不应该停留在那个50%本身)并离开时,它应该上升!同样,当您将图像也向下拖动时..我很震惊地找到了两天的解决方案来满足这个要求:(
  • 我想我明白你的意思,但你必须稍微说明一下你想要它的样子。否则我将无法真正修改自定义视图以满足您的需求。
  • 我没有演示可显示:( 因为它已在 IOS(超可视化应用程序)itunes.apple.com/in/app/ultravisual/id711280582?mt=8 中实现,但是我将用 this.for 进行说明,例如:在这个 gif 图像中。(@ 987654323@)如果点击图像“场景”或移动 50%(这只是我在看到 ios 应用程序后的假设)意味着,它会自动上升非常平滑,无需用户推到顶部,类似地向下推,点击图像,它上升了。@XaverKapeller
  • 我想我明白我会尝试修改视图,但给我几个小时的时间。

标签: android android-layout android-intent android-animation


【解决方案1】:

好的,我从您链接到的问题 (Creating animation for images from small to large when scrolling vertical) 中玩了自定义视图,添加动画非常容易。结果如下所示:

首先,我们必须让自定义视图捕捉到某个项目。为此,我们必须像这样修改ScrollTouchListener:

public abstract class ScrollTouchListener implements View.OnTouchListener {

    private boolean touching = false;
    private boolean scrolling = false;
    private double x = 0;
    private double y = 0;

    private double scrollPositionX = 0;
    private double scrollPositionY = 0;

    @Override
    public boolean onTouch(View view, MotionEvent event) {


        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                x = event.getX();
                y = event.getY();
                touching = true;
                return true;

            case MotionEvent.ACTION_UP:
                touching = false;
                if(scrolling) {
                    scrolling = false;
                    onScrollEnded(scrollPositionX, scrollPositionY);
                } else {
                    onClick(x, y); 
                }
                return true;

            case MotionEvent.ACTION_MOVE:
                double newX = event.getX();
                double newY = event.getY();

                double difX =  x - newX;
                double difY =  y - newY;

                if (scrolling) {
                    performScroll(difX, difY);
                } else if(difX > 0 || difY > 0)  {
                    scrolling = true;
                    onScrollStarted(scrollPositionX, scrollPositionY);
                    performScroll(difX, difY);
                }

                x = newX;
                y = newY;
                return true;

            default:
                return false;
        }
    }

    protected abstract void onScrollStarted(double scrollPositionX, double scrollPositionY);
    protected abstract void onScroll(double scrollPositionX, double scrollPositionY, double deltaX, double deltaY);
    protected abstract void onScrollEnded(double scrollPositionX, double scrollPositionY);
    protected abstract void onClick(double x, double y);

    private void performScroll(double difX, double difY) {
        scrollPositionX += difX;
        scrollPositionY += difY;

        onScroll(scrollPositionX, scrollPositionY, difX, difY);
    }

    public double getScrollPositionX() {
        return scrollPositionX;
    }

    public void setScrollPositionX(double scrollPositionX) {
        this.scrollPositionX = scrollPositionX;
    }

    public double getScrollPositionY() {
        return scrollPositionY;
    }

    public void setScrollPositionY(double scrollPositionY) {
        this.scrollPositionY = scrollPositionY;
    }
}

基本上我只是为onScrollStarted() 添加了回调,当用户开始滚动时调用它——在这种情况下我们不需要它——以及当用户停止滚动时调用的onScrollEnded()。为了方便起见,我将跟踪滚动进度的责任转移到了ScrollTouchListener,我还添加了getter 和setter,以便我们可以在需要时修改滚动进度——在我们的例子中,视图可以捕捉到某个位置。我添加的另一件事是onClick 回调形式的点击检测。我们需要它,以便我们可以单击视图以使其展开。我们不能为此使用普通的OnClickListener,因为在我们的例子中我们添加了OnTouchListenerScrollTouchListener,它消耗所有的触摸事件,所以点击监听器停止工作。但是点击检测并不完美,因为它是在那里实现的。主要问题是,只有在您不移动手指时,点击才算数。如果你只移动手指一个像素,它就已经算作滚动了。这里应该有一些额外的逻辑,你可以将手指移动几个像素,它仍然算作点击,如有必要,可以稍后实现。

然后在自定义视图中,我们向ScrollTouchListener 中的onScroll() 方法的实现添加一个计算,该计算计算当前展开视图和顶部第一个可见视图的索引:

double relativeScroll = scrollPositionY / scrollProgressPerView;
currentItemIndex = (int)Math.round(relativeScroll);

currentItemIndex是自定义视图的成员变量。之后添加onScrollEnded() 和onClick() 方法的实现。我们所做的只是计算自定义视图应该滚动多远。捕捉到某个项目或滚动到单击的项目:

@Override
protected void onScrollEnded(double scrollPositionX, double scrollPositionY) {
    scrollProgress = currentItemIndex * scrollProgressPerView + 1;
    setScrollPositionY(scrollProgress);
    updateChildViews();
}

@Override
protected void onClick(double x, double y) {
    int clickedIndex = (int) Math.round((getScrollPositionY() + y) / scrollProgressPerView) + 1;
    scrollProgress = clickedIndex * scrollProgressPerView + 1;
    setScrollPositionY(scrollProgress);
    updateChildViews();
}

就是这样。这就是启用捕捉和选择Views 所需的全部内容。因此,自定义视图中 ScrollTouchListener 的整个实现应如下所示:

private final ScrollTouchListener touchListener = new ScrollTouchListener() {

    @Override
    protected void onScrollStarted(double scrollPositionX, double scrollPositionY) {
        // Nothing to do here
    }

    @Override
    protected void onScroll(double scrollPositionX, double scrollPositionY, double deltaX, double deltaY) {
        scrollProgress += deltaY;
        if(scrollProgress < 0.0) {
            scrollProgress = 0.0;
        }

        if(scrollProgress > maxScrollProgress) {
            scrollProgress = maxScrollProgress;
        }

        double relativeScroll = scrollPositionY / scrollProgressPerView;
        currentItemIndex = (int)Math.round(relativeScroll);

        updateChildViews();
    }

    @Override
    protected void onScrollEnded(double scrollPositionX, double scrollPositionY) {
        scrollProgress = currentItemIndex * scrollProgressPerView + 1;
        setScrollPositionY(scrollProgress);
        updateChildViews();
    }

    @Override
    protected void onClick(double x, double y) {
        int clickedIndex = (int) Math.round((getScrollPositionY() + y) / scrollProgressPerView) + 1;
        scrollProgress = clickedIndex * scrollProgressPerView + 1;
        setScrollPositionY(scrollProgress);
        updateChildViews();
    }
};

您可能想知道实际的动画内容是从哪里来的,但实际上我们不必关心这些。有一个非常方便的功能可以为我们处理所有动画。您只需要将其添加到 xml 布局中的自定义视图的属性:

android:animateLayoutChanges="true"

例如,我用于测试目的的布局如下所示:

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

    <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.customviews.accordion.view.Accordion>

注意我添加到自定义视图中的android:animateLayoutChanges="true"。这就是让这个视图为任何布局更改设置动画所需的全部内容。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-13
    • 2013-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-03
    • 1970-01-01
    相关资源
    最近更新 更多