【问题标题】:Number of pixels moved when I move a scrollview移动滚动视图时移动的像素数
【发布时间】:2014-06-05 13:10:18
【问题描述】:

我已经尝试了几次,但我无法解决它。 我有一个带有多个视图的 ScrollView,它们由 ObjectAnimator 移动。当您按下按钮时,视图会在给定时间内垂直移动。 我会播放和暂停,但是当我用手指移动滚动条时,我无法知道滚动条已移动的像素数。

我想用我的手指移动滚动条,脉冲播放,我希望滚动条从我放置的位置开始滚动,而不是从头开始滚动。 我试过这个:

view.setOnTouchListener(new OnTouchListener() {
           @Override
           public boolean onTouch(View v, MotionEvent event) {
               //Choose which motion action has been performed
               switch(event.getAction())
               {
               case MotionEvent.ACTION_DOWN:
                   //Get X, Y coordinates from the ImageView
                   X = (int) event.getX();
                   Y = (int) event.getY();
                   startX = event.getRawX();
                   startY = event.getRawY();
                   break;
               case MotionEvent.ACTION_MOVE:
                  Z = (int) event.getX();
                   S = (int) event.getY();
                   K = (int) event.getRawX();
                   P = (int) event.getRawY();
                   V = (int) (event.getRawY() - startY);
                   break;
               case MotionEvent.ACTION_UP:
                   A = (int) event.getX();
                   E = (int) event.getY();
                   break;
               }
               return true;
           }

});

当我举起手指时它没有给出坐标。当我移动滚动条时,我怎么知道移动的像素数?这是一个Android应用程序。 提前致谢!

【问题讨论】:

  • 您已经采取了正确的方法,但所有这些变量是什么? S, K, P, V, A, E, Z, X, Y?为什么你需要它们?您只需要计算 x 和 y 坐标之间的差值即可得出手指移动了多少。

标签: android scroll scrollview move pixels


【解决方案1】:

每次收到ACTION_MOVE 事件时,您只需计算 x 和 y 坐标之间的差值。试试这样的:

public abstract class ScrollTouchListener implements View.OnTouchListener {

    private double x = 0;
    private double y = 0;

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

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                // User started scrolling
                x = event.getX();
                y = event.getY();
                onScrollStarted(x, y);
                return true;

            case MotionEvent.ACTION_UP:
                // User stopped scrolling
                x = event.getX();
                y = event.getY();
                onScrollEnded(x, y);
                return true;

            case MotionEvent.ACTION_MOVE:
                // Finger was moved get new x and y coordinates 
                // and calculate the difference
                double newX = event.getX();
                double newY = event.getY();

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

                onScroll(difX, difY);

                x = newX;
                y = newY;
                return true;

            default:
                return false;
        }
    }

    protected abstract void onScrollStarted(double x, double y);
    protected abstract void onScroll(double deltaX, double deltaY);
    protected abstract void onScrollEnded(double x, double y);
}

你可以这样使用它:

scrollView.setOnTouchListener(new ScrollTouchListener() {
    @Override
    protected void onScrollStarted(double x, double y) {
        // Called when you start scrolling. 
        // x and y are the coordinates where the user started scrolling.     
    }

    @Override
    protected void onScroll(double deltaX, double deltaY) {
        // Called while scrolling. 
        // deltaX and deltaY tell you how much the finger was moved.
    }

    @Override
    protected void onScrollEnded(double x, double y) {
        // Called when you stop scrolling. 
        // x and y are the coordinates where the user stopped scrolling.  
    }
});

【讨论】:

  • 可能这是一个很好的解决方案,但在我的情况下它不起作用。它计算从顶部的偏移量,一个增量,但它会阻止滚动。见stackoverflow.com/questions/3327087/…
  • @CoolMind 设置触摸监听器并使用触摸事件当然意味着ScrollView 不会滚动。这就是重点。
【解决方案2】:

有我的解决方案,完美运行,尝试阅读代码

public class CustomScrollView extends NestedScrollView
{

private boolean mIsScrolling;
private boolean mIsTouching;
private OnScrollListener mOnScrollListener;
private Runnable mScrollingRunnable;

public interface OnScrollListener
{
    void onScrollChanged(CustomScrollView scrollView, int x, int y, int oldX, int oldY);

    void onEndScroll(CustomScrollView scrollView);

    void onGoUp();

    void onGoDown();
}

public CustomScrollView(final Context context)
{
    super(context);
}

public CustomScrollView(final Context context, final AttributeSet attrs)
{
    super(context, attrs);
}

public CustomScrollView(final Context context, final AttributeSet attrs, final int defStyleAttr)
{
    super(context, attrs, defStyleAttr);
}

private int y = 0;

@Override
public boolean dispatchTouchEvent(MotionEvent iEv)
{
    if (isEnabled())
    {

        processEvent(iEv);

        super.dispatchTouchEvent(iEv);

        return true; //to keep receive event that follow down event
    }
    return super.dispatchTouchEvent(iEv);
}

private void processEvent(final MotionEvent iEv)
{
    switch (iEv.getAction())
    {
        case MotionEvent.ACTION_DOWN:
            y = (int) iEv.getY();
            break;

        case MotionEvent.ACTION_UP:
            y = (int) iEv.getY();

            if (mIsTouching && !mIsScrolling)
            {
                if (mOnScrollListener != null)
                {
                    //If you need to know when end of scrolling just uncomment
                    mOnScrollListener.onEndScroll(this);
                }
            }

            mIsTouching = false;
            break;
        case MotionEvent.ACTION_MOVE:
            mIsTouching = true;
            mIsScrolling = true;

            int newY = (int) iEv.getY();
            int difY = y - newY;

            int MAX_VALUE = 200;
            int MIN_VALUE = -200;
            if (difY > MAX_VALUE)
            {
                AppUtils.printLog(Log.ERROR, "TAG", "difY down : " + difY + " , y : " + y + ", newY : " + newY);
                if (mOnScrollListener != null)
                {
                    mOnScrollListener.onGoDown();
                }
                y = newY;
            }
            else if (difY < MIN_VALUE)
            {
                AppUtils.printLog(Log.ERROR, "TAG", "difY  up : " + difY + " , y : " + y + ", newY : " + newY);
                if (mOnScrollListener != null)
                {
                    mOnScrollListener.onGoUp();
                }
                y = newY;
            }

            break;
    }
}

@Override
protected void onScrollChanged(int iX, int iY, int iOldX, int iOldY)
{
    super.onScrollChanged(iX, iY, iOldX, iOldY);

    if (Math.abs(iOldX - iX) > 0)
    {
        if (mScrollingRunnable != null)
        {
            removeCallbacks(mScrollingRunnable);
        }

        mScrollingRunnable = new Runnable()
        {
            public void run()
            {
                if (mIsScrolling && !mIsTouching)
                {
                    if (mOnScrollListener != null)
                    {
                        mOnScrollListener.onEndScroll(CustomScrollView.this);
                    }
                }

                mIsScrolling = false;
                mScrollingRunnable = null;
            }
        };

        postDelayed(mScrollingRunnable, 200);
    }

    if (mOnScrollListener != null)
    {
        mOnScrollListener.onScrollChanged(this, iX, iY, iOldX, iOldY);
    }
}

public OnScrollListener getOnScrollListener()
{
    return mOnScrollListener;
}

public void setOnScrollListener(OnScrollListener mOnEndScrollListener)
{
    this.mOnScrollListener = mOnEndScrollListener;
}
}

用法:只需在 XML 中添加这个自定义视图

<ui.customWidgets.CustomScrollView
        android:id="@+id/scroll_frag_detail"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:overScrollMode="never"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        android:scrollbars="none"
        app:behavior_overlapTop="192dp"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

           <!--Your code here-->

        </LinearLayout>

    </ui.customWidgets.CustomScrollView>

在代码中

mScrollView.setOnScrollListener(new CustomScrollView.OnScrollListener()
    {
        @Override
        public void onScrollChanged(final CustomScrollView scrollView, final int x, final int y, final int oldX, final int oldY)
        {

        }

        @Override
        public void onEndScroll(final CustomScrollView scrollView)
        {

        }

        @Override
        public void onGoUp()
        {

        }

        @Override
        public void onGoDown()
        {

        }
    });

【讨论】:

    猜你喜欢
    • 2014-01-07
    • 2018-03-14
    • 1970-01-01
    • 1970-01-01
    • 2020-01-07
    • 2014-10-12
    • 2014-10-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多