<span style="font-size:18px;">
</span>
自定义控件时有五个较为重要的回调
onFinishInflate():从xml加载组件后回调
onSizeChanged();组件大小改变时回调
onMeasure();回调该方法来进行测量(主动回调,需要主动写出来实现功能)
onLayout();回调该方法来进行来确定显示的位置(主动回调,需要主动写出来实现功能)
onTouchEvent()监听到触摸事件时回调
自定义ViewGroup大致步骤1,测量,2,设定子view放置位置,在放置子view前需要确定整个ViewGroup的高度
<span style="font-size:18px;"><span style="font-size:18px;">@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);//控件的默认大小
//获得子view个数
// int count = getChildCount();
// for (int i = 0; i < count; ++i) {
// View childView = getChildAt(i);
// measureChild(childView,
// widthMeasureSpec, heightMeasureSpec);
// }
}</span></span>
<span style="font-size:18px;"></pre><pre name="code" class="java"><span style="font-size:18px;">
</span></span>
<span style="font-size:18px;"><span style="font-size:18px;">可以从MeasureSpec对象中获得测量模式和大小</span><pre style="font-family: Menlo; font-size: 11.3pt; background-color: rgb(204, 232, 207);"><span style="color:#000080;"><strong>int </strong></span>specMode = MeasureSpec.<span style="font-style:italic;">getMode</span>(measureSpec);//获得测量模式</span>
int specSize = MeasureSpec.getSize(measureSpec);//获得大小
放置子view的位置
<span style="font-size:18px;">@Override
protected void onLayout(boolean changed,
int l, int t, int r, int b) {
int childCount = getChildCount();
// 设置ViewGroup的高度
MarginLayoutParams mlp = (MarginLayoutParams) getLayoutParams();
mlp.height = mScreenHeight * childCount;
setLayoutParams(mlp);
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
if (child.getVisibility() != View.GONE) {
child.layout(l, i * mScreenHeight,
r, (i + 1) * mScreenHeight);//bottom的位置参考字符串截取目标最后一位
}
}
}</span>
此时可以将子view放置到ViewGroup中了,再添加触控事件
<span style="font-size:18px;">@Override
public boolean onTouchEvent(MotionEvent event) {
int y = (int) event.getY();//模板 获取当前触点的y坐标
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mLastY = y;//触点到父控件顶部距离
mStart = getScrollY();//记录触摸起点
break;
case MotionEvent.ACTION_MOVE:
if (!mScroller.isFinished()) {
mScroller.abortAnimation();
}
int dy = mLastY - y;//y方向的偏移量=触点到父控件顶部的距离-最初触点到父控件顶部距离
if (getScrollY() < 0) {
dy = 0;
}
if (getScrollY() > getHeight() - mScreenHeight) {
dy = 0;
}
scrollBy(0, dy);
mLastY = y;
break;
case MotionEvent.ACTION_UP:
int dScrollY = checkAlignment();
if (dScrollY > 0) {
if (dScrollY < mScreenHeight / 3) {
mScroller.startScroll(
0, getScrollY(),
0, -dScrollY);
} else {
mScroller.startScroll(
0, getScrollY(),
0, mScreenHeight - dScrollY);
}
} else {
if (-dScrollY < mScreenHeight / 3) {
mScroller.startScroll(//滑动之scroller
0, getScrollY(),
0, -dScrollY);
} else {
mScroller.startScroll(
0, getScrollY(),
0, -mScreenHeight - dScrollY);
}
}
break;
}
postInvalidate();
return true;
}</span>
//使用Scroller类的核心
@Override
public void computeScroll() {
super.computeScroll();
if (mScroller.computeScrollOffset()) {
scrollTo(0, mScroller.getCurrY());
postInvalidate();
}
}
getCurrx()和getScrollX()都会在内容下拉时减小直至为负数,内容上拉时增大