80,362
社区成员
发帖
与我相关
我的任务
分享
public class TableView extends ViewGroup {
private Scroller mScroller;
private GestureDetector mGestureDetector;
private Cont mCont;
private int mVisibleWidth = 0;
private int mVisibleHeight = 0;
private int mRemovableX; // 可移动宽
private int mRemovableY; // 可移动高
private Paint mContPaint = new Paint();
private int mTableWidth = 2000;
private int mEdgeWidth = 10;
private int mTitleHeight = 30;
private int mContHeight = 900;
public TableView(Context context, AttributeSet attrs) {
super(context, attrs);
/* 实例化相关对象 */
mScroller = new Scroller(context);
mGestureDetector = new GestureDetector(context, new Gesture());
if(Build.VERSION.SDK_INT < 17) {
setPadding(mEdgeWidth, mEdgeWidth, mEdgeWidth, mEdgeWidth);
} else {
setPaddingRelative(mEdgeWidth, mEdgeWidth, mEdgeWidth, mEdgeWidth);
}
setBackgroundColor(Color.YELLOW);
mCont = new Cont(context, attrs);
addView(mCont, 0);
}
/**
* 测量父视图大小, 对子视图不限制
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = MeasureSpec.getSize(widthMeasureSpec) - mEdgeWidth*2;
int height = MeasureSpec.getSize(heightMeasureSpec) - mEdgeWidth*2;
/* 如果容器宽度改变并且宽度不等于 0 设置尺寸相关参数 */
if((width != mVisibleWidth) || (height != mVisibleHeight)) {
mVisibleWidth = width;
mVisibleHeight = height;
/* 计算可移动范围 */
mRemovableX = mTableWidth - mVisibleWidth;
if(mRemovableX < 0) {
mRemovableX = 0;
}
mRemovableY = mContHeight - (mVisibleHeight - mTitleHeight);
if(mRemovableY < 0) {
mRemovableY = 0;
}
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mCont.measure( MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
}
/**
* 设置子 View 显示位置和大小
*/
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
mCont.layout(mEdgeWidth, mEdgeWidth, mVisibleWidth + mEdgeWidth, mVisibleHeight + mEdgeWidth);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
return mGestureDetector.onTouchEvent(event);
}
class Gesture implements OnGestureListener {
@Override
public void onShowPress(MotionEvent e) { }
/* 按下 */
@Override
public boolean onDown(MotionEvent e) { return true; }
@Override
public boolean onSingleTapUp(MotionEvent e) { return false; }
/* 长按 */
@Override
public void onLongPress(MotionEvent e) {
}
/* 拖动 */
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
mScroller.forceFinished(true);
mScroller.startScroll(mScroller.getFinalX(), mScroller.getFinalY(), (int)distanceX, (int)distanceY);
invalidate();
return true;
}
/* 滑动 */
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
return true;
}
}
@Override
public void computeScroll() {
if(mScroller.computeScrollOffset()) {
int currX = mScroller.getCurrX();
if(currX < 0) {
currX = 0;
} else if(currX > mRemovableX) {
currX = mRemovableX;
}
int currY = mScroller.getCurrY();
if(currY < 0) {
currY = 0;
} else if(currY > mRemovableY) {
currY = mRemovableY;
}
mCont.scrollTo(currX, currY);
invalidate();//继续让系统重绘
}
}
public class Cont extends View {
public Cont(Context context, AttributeSet attrs) {
super(context);
setVerticalScrollBarEnabled(true);
setScrollBarStyle(View.SCROLLBARS_OUTSIDE_INSET);
TypedArray typedArray = context.obtainStyledAttributes(R.styleable.ScrollbarsView);
initializeScrollbars(typedArray);
typedArray.recycle();
setScrollBarSize(12);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(mTableWidth, mContHeight);
}
/**
* 滚动条滑块在滚动条滑道中的长度。
*/
@Override
protected int computeVerticalScrollExtent() {
return 100;
}
/**
* 可滚动范围, 该值为所有子元素之和.
*/
@Override
protected int computeVerticalScrollRange() {
return mContHeight;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mContPaint.setColor(Color.RED);
canvas.drawRect(0, 0,mTableWidth, mContHeight, mContPaint);
mContPaint.setColor(Color.GREEN);
mContPaint.setTextSize(100);
canvas.drawText("abcdefghijklmnopqrstuvwxyz", 0, 90, mContPaint);
}
}
}