自定义ViewGroup时,重要的就是子View的测量和布局,以及交互,因此,需要重写onMeasure onLayout 和 onTouchEvent.
/**
* 使用遍历的方式通知子View去测量自身
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View childView = getChildAt(i);
// Ask one of the children of this view to measure itself
measureChild(childView, widthMeasureSpec, heightMeasureSpec);
}
}
/**
* 对子View进行放置位置的设定,每个子View高度为一屏。
*/
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int childCount = getChildCount();
// 设置ViewGroup的高度(所有子View的高度和,设定每个子View高度为一屏)
MarginLayoutParams params = (MarginLayoutParams) getLayoutParams();
params.height = childCount * mScreenHeight;
setLayoutParams(params);
for (int i = 0; i < childCount; i++) {
View childView = getChildAt(i);
if (childView.getVisibility() != View.GONE) {
childView.layout(l, i*mScreenHeight, r, (i + 1)*mScreenHeight);
}
}
}
当利用 Scroller 去滑动屏幕或者扩展 ScrollView 的时候,总是会用到 getScrollX 和 getScrollY 去获取当前View 滑动到的位置,那么getScrollX() 和 getScrollY() 获取的到底是什么呢?
中间黄色区域为手机屏幕,整个坐标系是以手机屏幕左上角为原点(0, 0)。绿色的区域,可以理解为一块可以左右拉动的幕布,其实也就是我们要显示在屏幕上面的内容,它其实是可以很大的,大到无限大,只是没在窗口中间的,所以我们就看不到。
scrollTo(int x, int y)说明:
它表示移动到视图的那个坐标点。哪个视图调用这个方法,那么这个视图的(x,y)点就与手机屏幕的左上角对齐(也可以理解为,手机屏幕的左上角就移动到(x,y)坐标)。
scrollBy(int dx, int dy) 说明:
它表示在视图的X、Y方向上各移动dx、dy距离
dx>0表示视图(View或ViewGroup)的内容从右向左滑动;反之,从左向右滑动
dy>0表示视图(View或ViewGroup)的内容从下向上滑动;反之,从上向下滑动
getScrollX()说明:
=手机屏幕显示区域左上角x坐标减去MultiViewGroup视图左上角x坐标=320
getScrollY()说明:
=手机屏幕显示区域左上角y坐标减去MultiViewGroup视图左上角y坐标=0(因为子视图的高度和手机屏幕高度一样)
第二幅图中,幕布向右拉动,getScrollX()的值即-100 - 0 = -100;
第三幅图中,幕布向左拉动,getScrollX()的值即100 - 0 = 100;