Количество пикселей, перемещаемых при перемещении прокрутки

Я пробовал это несколько раз, но я не могу решить это. У меня есть ScrollView с несколькими представлениями, которые перемещаются ObjectAnimator. Когда вы нажимаете кнопку, представления перемещаются по вертикали в течение заданного времени. Я выполняю PLAY и PAUSE, но когда я перемещаю прокрутку пальцем, я не могу узнать количество пикселей, на которые прокрутка была перемещена.

Я хочу двигать прокрутку пальцем, пульсировать Play, и я хотел бы, чтобы прокрутка начинала прокручиваться там, где я ее поставил, а не с начала. Я пробовал это:

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. Заранее спасибо!


person user3711263    schedule 05.06.2014    source источник
comment
Вы уже выбрали правильный подход, но каковы все эти переменные? S, K, P, V, A, E, Z, X, Y? Зачем вам они все? Вам просто нужно вычислить разницу между координатами x и y, чтобы узнать, насколько сильно сдвинулся палец.   -  person Xaver Kapeller    schedule 05.06.2014


Ответы (2)


Вам просто нужно вычислять разницу между координатами x и y каждый раз, когда вы получаете событие ACTION_MOVE. Попробуйте что-то вроде этого:

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.  
    }
});
person Xaver Kapeller    schedule 05.06.2014
comment
Возможно, это хорошее решение, но в моем случае оно не работает. Он вычисляет смещение сверху, дельту, но предотвращает прокрутку. См. stackoverflow.com/questions/3327087/. - person CoolMind; 02.11.2015
comment
@CoolMind, устанавливающий прослушиватель касаний и использующий сенсорные события, конечно, означает, что ScrollView не будет прокручиваться. В этом-то и дело. - person Xaver Kapeller; 02.11.2015

Вот мое решение, работает отлично, попробуйте прочитать код

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()
        {

        }
    });
person Aleksey Timoshchenko    schedule 09.06.2017