Сделайте автопрокрутку scrollView с помощью перетаскивания в Android - PullRequest
4 голосов
/ 08 сентября 2011

Я искал по всему, но не смог найти решение.

У меня есть представление (давайте назовем это myView) внутри прокрутки. myView больше экрана. Поскольку я могу получить положение пальца в относительно x, y внутри myView, я бы хотел, чтобы scrollView автоматически прокручивал верх / низ, когда мой палец входит в определенный верхний / нижний порог. У меня есть некоторые идеи, а именно перевод места перетаскивания в положение экрана, но это не решило эту проблему.

заранее спасибо

ура

Ответы [ 3 ]

10 голосов
/ 09 сентября 2011

Хорошо, я понял это сам.

Сначала мне пришлось расширить класс ScrollView и добавить интерфейс OnScrollViewListener.

public class MyScrollView extends ScrollView {
    private OnScrollViewListener mListener;

    public MyScrollView(Context c, AttributeSet attrs) {
       super(c, attrs);
    }

    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
       super.onScrollChanged(l, t, oldl, oldt);
       if (mListener != null) {
           mListener.onScrollChanged((OnScrollViewListener) this);
       }
    }


    public void setOnScrollViewListener(OnScrollViewListener listener) {
       mListener = listener;
    }


    public static interface OnScrollViewListener {
       public void onScrollChanged(OnScrollViewListener listener);
    }
}

Далее в своей деятельности я вставил член mScrollDistanceэто указывает количество пикселей, которые пользователь прокручивает.

public class ScrollActivity extends Activity {
   private int mScrollDistance;

   @Override
   protected void OnCreate(...) {
     ...

     final MyScrollView myScrollView = (MyScrollView) findViewById(R.id.scroll_view);
     myScrollView.setOnScrollViewListener(new MyScrollView.OnScrollViewListener() {

          public void onScrollChanged(OnScrollViewListener listener) {
             mScrollDistance = listener.getScrollY();
          }
     }

     // making an drag and drop in an view that is inside the MyScrollView
     final LinearLayout myLayout = (LinearLayout)findViewById(R.id.linear_layout);
     myLayout.setOnDragListener(new View.OnDragListener() {
       public boolean onDrag (View v, DragEvent event) {
         int action = event.getAction();
         switch(action) {
            case DragEvent.ACTION_DRAG_STARTED: {
            }
            case DragEvent.ACTION_DRAG_LOCATION: {

              int y = Math.round(event.getY());
              int translatedY = y - mScrollDistance;
              int threshold = 50;
              // make a scrolling up due the y has passed the threshold
              if (translatedY < threshold) {
                 // make a scroll up by 30 px
                 myScrollView.scrollBy(0, -30);
              }
              // make a autoscrolling down due y has passed the 500 px border
              if (translatedY + threshold > 500) {
                 // make a scroll down by 30 px
                 myScrollView.scrollBy(0, 30);
              }
              // listen for more actions here
              // ...
            }
         }
       }
     }

Теперь mScrollDistance всегда получает новое значение, и местоположение перетаскивания будет преобразовано в местоположение просмотра.Я проверил это, и он работает на макетах / видах, которые больше, чем размер экрана.

Надеюсь, это поможет.

4 голосов
/ 01 октября 2013

Я предложил другое решение, и я доволен им.

Я хочу иметь возможность перетаскивать представления в ScrollView.Затем ScrollView необходимо автоматически прокручивать вверх и вниз, когда тень достигает краев вида прокрутки.

В итоге я нашел решение, которое обнаруживает, полностью ли видна зона перетаскивания внутри вида прокрутки (с полем 100 пикселей) и настройте режим прокрутки в противном случае.

@Override
public boolean onDrag(View view, DragEvent event) {

    MainWidget dropZoneView = (MainWidget) view;

    int action = event.getAction();
    switch (action) {
        case DragEvent.ACTION_DRAG_STARTED:
        //(... other stuff happens here)
        case DragEvent.ACTION_DRAG_LOCATION:

            ScrollView mainScrollView = (ScrollView) findViewById(R.id.main_scroll);

            int topOfDropZone = dropZoneView.getTop();
            int bottomOfDropZone = dropZoneView.getBottom();

            int scrollY = mainScrollView.getScrollY();
            int scrollViewHeight = mainScrollView.getMeasuredHeight();

            Log.d(LOG_TAG,"location: Scroll Y: "+ scrollY + " Scroll Y+Height: "+(scrollY + scrollViewHeight));
            Log.d(LOG_TAG," top: "+ topOfDropZone +" bottom: "+bottomOfDropZone);

            if (bottomOfDropZone > (scrollY + scrollViewHeight - 100))
                mainScrollView.smoothScrollBy(0, 30);

            if (topOfDropZone < (scrollY + 100))
                mainScrollView.smoothScrollBy(0, -30);

            break;
        default:
            break;
    }
    return true;
}

Надеюсь, это поможет!

1 голос
/ 03 апреля 2015

Я использовал таймер в In C #

ScrollCalendar ScrollCalendar = new ScrollCalendar (yourScrollView);

Внутри события перетаскивания

    public bool OnDrag (View v, DragEvent e)
    {
        var dragshadow = new EventDateDragShadow (v);
        switch (e.Action) {
        case DragAction.Started:
            return true;
        case DragAction.Entered:
            break;
        case Android.Views.DragAction.Location:

            if (e.GetY () < 90) {
                ScrollCalendar.StartScroll (-15);
            } else if (e.GetY () > yourScrollView.Height - 90) {
                ScrollCalendar.StartScroll (15);
            } else
                ScrollCalendar.StopScroll ();

            return (true);
        case DragAction.Exited:
            return true;
        case DragAction.Drop:
            return true;
        case DragAction.Ended:
            ScrollCalendar.StopScroll ();
            v.SetOnDragListener (null);
            return true;
        }

        return true;
    }

Класс ScrollCalendar

public class ScrollCalendar
{
    private ScrollView Calendar;
    private System.Timers.Timer Timer;
    private int ScrollDistance;

    public ScrollCalendar(ScrollView calendar)
    {
        Calendar = calendar;
        Timer = new System.Timers.Timer();
        Timer.Elapsed+=new ElapsedEventHandler(Scroll);
        Timer.Interval = 50;
    }

    public void StartScroll(int scrollDistance)
    {
        if (Timer.Enabled) {
            return;
        }
        ScrollDistance = scrollDistance;
        Timer.Enabled = true;
    }

    public void StopScroll()
    {
        Timer.Enabled = false;
    }

    private void Scroll(object source, ElapsedEventArgs e)
    {
        Calendar.SmoothScrollBy (0, ScrollDistance);
    }

}

Измените значение StartScroll и Timer.Interval, чтобы настроить скорость прокрутки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...