我刚开始在Android中编写自定义视图(这是第一次),我意识到我需要实现滚动功能。
自定义视图还使用包含一些文本的标题(应该保持固定而不是滚动)。
我已阅读GestureDetector.SimpleOnGestureListener
和Scroller
上的文档。我还阅读了 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);
}
这些添加的结果是一个可以垂直滚动(而不是水平滚动)的自定义视图,但是有一些问题:
RecyclerView
或ScrollView
)有人可以解释滚动在自定义视图中的工作原理以及如何使用这些功能正确实现它吗?
答案 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
将位于固定标题的正下方,并自动为您提供所需的滚动行为,而无需任何其他代码。