2016-09-03 3 views
8

Я только начал писать пользовательский вид в Android (в первый раз), и я понял, что мне нужно реализовать функцию прокрутки.Как добавить прокрутку для пользовательского представления в Android

В пользовательском представлении также используется заголовок, содержащий некоторый текст (который должен оставаться фиксированным, а не прокручиваться).

Я прочитал документацию по GestureDetector.SimpleOnGestureListener и Scroller. Я также прочитал документацию по Animating a Scroll Gesture, но я нашел примеры, которые трудно понять. Я также рассмотрел другие вопросы о переполнении стека, которые помогли немного.

Используя то, что я понял из документации с the Stack Overflow answer в качестве ссылки, чтобы вести меня, я добавил следующее моей настраиваемое представление:

переменных и полей:

private OverScroller mScroller; 
private final GestureDetector mGestureDetector = 
     new GestureDetector(getContext(), new GestureDetector.SimpleOnGestureListener() { 

      @Override 
      public boolean onScroll(MotionEvent e1, MotionEvent e2, 
            float distanceX, float distanceY) { 
       // Note 0 as the x-distance to prevent horizontal scrolling 
       scrollBy(0, (int) distanceY); 
       return true; 
      } 

      @Override 
      public boolean onFling(MotionEvent e1, MotionEvent e2, 
            float velocityX, float velocityY) { 
       final int maxScrollX = 0; 

       // wholeViewHeight is height of everything that is drawn 
       int wholeViewHeight = calculateWholeHeight(); 
       int visibleHeight = getHeight(); 
       final int maxScrollY = wholeViewHeight - visibleHeight; 

       mScroller.forceFinished(true); 

       mScroller.fling(0, // No startX as there is no horizontal scrolling 
         getScrollY(), 
         0, // No velocityX as there is no horizontal scrolling 
         - (int) velocityY, 
         0, 
         maxScrollX, 
         0, 
         maxScrollY); 

       invalidate(); 

       return true; 
      } 

      @Override 
      public boolean onDown(MotionEvent e) { 
       if (!mScroller.isFinished()) { 
        mScroller.forceFinished(true); 
       } 
       return true; 
      } 
     }); 

Инициализация mScroller:

// Called from the constructor 
private void init() { 
    mScroller = new OverScroller(getContext(), new FastOutLinearInInterpolator()); 

    ... 
} 

Материал в onDraw():

@Override 
protected void onDraw(Canvas canvas) { 
    super.onDraw(canvas); 

    ... 

    if (mScroller.computeScrollOffset()) { 
     scrollTo(mScroller.getCurrX(), mScroller.getCurrY()); 
    } 
} 

Материал в onTouchEvent():

@Override 
public boolean onTouchEvent(MotionEvent event) { 
    return mGestureDetector.onTouchEvent(event); 
} 

В результате этих дополнений является пользовательский вид, который может прокручивать вертикально (а не по горизонтали), тем не менее существует несколько вопросов:

  1. Я могу прокрутить дальше мимо того, что нарисовано
  2. Там нет никакого эффекта края свечения, как я дойти до конца пользовательского вида (я имею в виду, как RecyclerView или ScrollView)
  3. Все пользовательские зрения свитков, а не просто некоторая часть его
  4. Я не Полностью понять, что происходит

Может ли кто-нибудь объяснить, как прокрутка работает в пользовательском представлении и как правильно ее реализовать с помощью этих функций?

+0

Здравствуйте, Фарбод Саламат-Заде. Вы нашли решение для этого? Я также придерживался той же проблемы.е; «Я могу прокрутить дальше мимо того, что нарисовано» –

+0

@AdeelShahzad Пока нет. Если вы придумаете решение, сообщите мне об этом. :) –

+0

Привет, Фарбод. Я не мог придумать решение, поэтому просто бросил ScrollView внутри ViewPager. –

ответ

4

Могу ли я предложить простой макет с фиксированным заголовком и вертикальным прокруткой контента, который звучит так, как будто он будет делать то, что вы хотите, и не требует сложного программирования? Это может спасти вас от необходимости тратить часы исследования и разработки программ в долгосрочной перспективе:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical"> 

    <FrameLayout 
     android:id="@+id/header" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content"/> 

    <android.support.v4.widget.NestedScrollView 
     android:layout_width="match_parent" 
     android:layout_height="0dp" 
     android:layout_weight="1" 
     android:fillViewport="true"> 

     <FrameLayout 
      android:id="@+id/scrolling_content" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content"/> 
    </android.support.v4.widget.NestedScrollView> 

</LinearLayout> 

Используя этот макет, вы должны заменить или вставить внутрь FrameLayout с ID «заголовок» с вашей точки зрения фиксированного заголовка. Затем вы помещали бы свой scolling-контент внутри FrameLayout с идентификатором «scrolling_content». NestedScrollingView будет расположен непосредственно под вашим фиксированным заголовком и автоматически даст вам поведение прокрутки, которое вы хотите, без какого-либо дополнительного кода.

+0

Спасибо за ваш ответ. Смогу ли я заменить второй «FrameLayout» частью моего пользовательского представления, чтобы он мог прокручиваться? –

+0

Да, но помните, что NestedScrollView может иметь только один прямой дочерний элемент. Пока вы не пытаетесь поместить 2 представления непосредственно в NestedScrollView, он будет работать нормально. Также помните, что любые представления внутри вертикального прокрутки NestedScrollView не могут иметь layout_height из «match_parent», как если бы это значение было выполнено, он создавал бесконечно длинный свиток. – happydude

+0

Спасибо за разъяснение. Я попробую использовать «NestedScrollView» и посмотрю, как это работает для меня. Однако мне все же хотелось бы знать, как это можно реализовать (используя «GestureDetector», «OverScroller» и т. Д.) Для пользовательского представления. Я начал щедрость за это, поэтому, если у вас есть альтернативный ответ, отправляйте его. :) –