如何在Android中为自定义视图添加滚动

时间:2016-09-03 14:48:47

标签: android android-custom-view gesturedetector

我刚开始在Android中编写自定义视图(这是第一次),我意识到我需要实现滚动功能。

自定义视图还使用包含一些文本的标题(应该保持固定而不是滚动)。

我已阅读GestureDetector.SimpleOnGestureListenerScroller上的文档。我还阅读了 Animating a Scroll Gesture 上的文档,但我发现这些示例很难理解。我还查看了有关Stack Overflow的其他问题,这些问题有所帮助。

使用我在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. 当我到达自定义视图的末尾时(我的意思是RecyclerViewScrollView
  3. ,没有边缘发光效果
  4. 所有自定义视图都滚动而不仅仅是它的某个部分
  5. 我不完全了解正在发生的事情
  6. 有人可以解释滚动在自定义视图中的工作原理以及如何使用这些功能正确实现它吗?

1 个答案:

答案 0 :(得分: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&#34;标题&#34;使用固定的标题视图。然后,您可以将您的scolling内容放在FrameLayout的ID&#34; scrolling_content&#34;中。 NestedScrollingView将位于固定标题的正下方,并自动为您提供所需的滚动行为,而无需任何其他代码。