如何使用 onScroll 和 GestureDetector 让视图跟随我的手指 - Android

发布于 2025-01-02 22:47:21 字数 193 浏览 1 评论 0原文

我有一个relativelayout,中间有一个textview。我已经使用 SimpleOnGestureListener() 检测 onFling、onDown 和 onScroll 事件。

我希望 TextView 跟随我的手指在屏幕上移动(可以只是在 x 轴上),当我抬起手指时,动画要么离开屏幕,要么回到中间(取决于我已经移动了多远)移动了它)。

I have a RelativeLayout with a TextView in the middle. I've got it to detect onFling, onDown, and onScroll events using SimpleOnGestureListener().

I would like the TextView to follow my finger around the screen (can be just in the x axis), and when I lift my finger for it so animate either out of the screen or back to the middle (depending on how far I've moved it).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

千笙结 2025-01-09 22:47:21

这就是我在这些情况下通常所做的。

首先,您的 onScroll 方法应如下所示:

@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)
{
    // Make sure that mTextView is the text view you want to move around

    if (!(mTextView.getLayoutParams() instanceof MarginLayoutParams))
    {
        return false;
    }

    MarginLayoutParams marginLayoutParams = (MarginLayoutParams) mTextView.getLayoutParams();

    marginLayoutParams.leftMargin = (int) marginLayoutParams.leftMargin - distanceX;
    marginLayoutParams.topMargin = (int) marginLayoutParams.topMargin - distanceY;

    mTextView.requestLayout();

    return true;
}

我们将 leftMargintopMargin 修改为相当于滚动距离的量。

接下来,要使文本视图以动画方式返回到其原始位置,您需要在事件为 ACTION_UPACTION_CANCEL 时执行此操作:

@Override
public boolean onTouch(View arg0, MotionEvent event)
{
    if (event.getActionMasked() == MotionEvent.ACTION_UP || event.getActionMasked() == MotionEvent.ACTION_CANCEL)
    {
        snapBack();
    }
    return mScrollDetector.onTouchEvent(event);
}

然后在 snapBack 方法中,我们以动画方式返回文本视图:

private void snapBack ()
{
    if (mTextView.getLayoutParams() instanceof MarginLayoutParams)
    {
        final MarginLayoutParams marginLayoutParams = (MarginLayoutParams) mTextView.getLayoutParams();

        final int startValueX = marginLayoutParams.leftMargin;
        final int startValueY = marginLayoutParams.topMargin;
        final int endValueX = 0;
        final int endValueY = 0;

        mTextView.clearAnimation();

        Animation animation = new Animation()
        {
            @Override
            protected void applyTransformation(float interpolatedTime, Transformation t)
            {
                int leftMarginInterpolatedValue = (int) (startValueX + (endValueX - startValueX) * interpolatedTime);
                marginLayoutParams.leftMargin = leftMarginInterpolatedValue;

                int topMarginInterpolatedValue = (int) (startValueY + (endValueY - startValueY) * interpolatedTime);
                marginLayoutParams.topMargin = topMarginInterpolatedValue;

                mTextView.requestLayout();
            }
        };
        animation.setDuration(200);
        animation.setInterpolator(new DecelerateInterpolator());
        mTextView.startAnimation(animation);
    }
}

应该可以!您可以修改 endValueXendValueY 变量来控制当您松开手指时文本视图返回的位置。

This is what I normally do in these cases.

First of all, your onScroll method should look something like this:

@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)
{
    // Make sure that mTextView is the text view you want to move around

    if (!(mTextView.getLayoutParams() instanceof MarginLayoutParams))
    {
        return false;
    }

    MarginLayoutParams marginLayoutParams = (MarginLayoutParams) mTextView.getLayoutParams();

    marginLayoutParams.leftMargin = (int) marginLayoutParams.leftMargin - distanceX;
    marginLayoutParams.topMargin = (int) marginLayoutParams.topMargin - distanceY;

    mTextView.requestLayout();

    return true;
}

We are modifying the leftMargin and topMargin an amount equivalent to the distance that has been scrolled.

Next, to make the text view animate back to its original position you need to do so when the the event is ACTION_UP or ACTION_CANCEL:

@Override
public boolean onTouch(View arg0, MotionEvent event)
{
    if (event.getActionMasked() == MotionEvent.ACTION_UP || event.getActionMasked() == MotionEvent.ACTION_CANCEL)
    {
        snapBack();
    }
    return mScrollDetector.onTouchEvent(event);
}

Then in the snapBack method we animate back the text view:

private void snapBack ()
{
    if (mTextView.getLayoutParams() instanceof MarginLayoutParams)
    {
        final MarginLayoutParams marginLayoutParams = (MarginLayoutParams) mTextView.getLayoutParams();

        final int startValueX = marginLayoutParams.leftMargin;
        final int startValueY = marginLayoutParams.topMargin;
        final int endValueX = 0;
        final int endValueY = 0;

        mTextView.clearAnimation();

        Animation animation = new Animation()
        {
            @Override
            protected void applyTransformation(float interpolatedTime, Transformation t)
            {
                int leftMarginInterpolatedValue = (int) (startValueX + (endValueX - startValueX) * interpolatedTime);
                marginLayoutParams.leftMargin = leftMarginInterpolatedValue;

                int topMarginInterpolatedValue = (int) (startValueY + (endValueY - startValueY) * interpolatedTime);
                marginLayoutParams.topMargin = topMarginInterpolatedValue;

                mTextView.requestLayout();
            }
        };
        animation.setDuration(200);
        animation.setInterpolator(new DecelerateInterpolator());
        mTextView.startAnimation(animation);
    }
}

And that should do! You can modify the endValueX and endValueY variables to control where the text view goes back when you lift your finger.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文