您的位置:首页 > 其它

自定义尺子

2016-01-05 15:17 239 查看
为了进一步学习Canvas,弄了个简单的可以左右滑动的尺子,没有进一步优化,希望以后做到可以想加多少就加多少。现在说下基本思路:
在画线跟画文字的时候用到了Canvas.translate、Canvas.save、Canvas.restore,这几个函数有利于尺寸计算。
/**

* 初始化属性

*/

private void initAttrs (AttributeSet
attrs) {

TypedArray a = mContext .obtainStyledAttributes(attrs ,

R.styleable. RulerView );

lineColor =
a.getColor(R.styleable. RulerView_lineColor, Color. BLACK );

mLineHeight =
a.getDimensionPixelOffset(R.styleable. RulerView_lineHeight, LINE_HEIGHT );

a.recycle() ;
}
在这里主要用到了自定义属性,可以修改线的高度跟线的颜色。
/**

* 初始化画笔

*/

private void initPaint ()
{

mLinePaint = new Paint() ; // 初始绘制线的画笔

mLinePaint .setAntiAlias( true) ; // 去除画笔锯齿

mLinePaint .setStyle(Paint.Style. FILL ); // 设置风格为实线

mLinePaint .setColor( lineColor) ; // 设置画笔颜色

mOuterPaint = new Paint(Paint. ANTI_ALIAS_FLAG ) ;

mOuterPaint .setColor(Color. BLACK) ;

mOuterPaint .setStyle(Paint.Style. STROKE );

mOuterPaint .setStrokeWidth( 1) ;

mTextPaint = new Paint(Paint. ANTI_ALIAS_FLAG ) ;// 初始绘制线的画笔

mTextPaint .setAntiAlias( true) ; // 去除画笔锯齿

mTextPaint .setStyle(Paint.Style. STROKE ); // 设置风格为实线

mTextPaint .setTextSize( 10) ;

mTextPaint .setColor(Color. BLACK) ; // 设置画笔颜色

mBitmapPaint = new Paint() ;

mBitmapPaint .setAntiAlias( true) ;

mBitmapPaint .setDither( true) ;

mBitmapPaint .setFilterBitmap( true) ;

}

/**

* 将 dp 转化为 px, 为了适配

*/

private void initData ()
{

touchSlop =
ViewConfiguration.get( mContext ).getScaledTouchSlop() ;

this. mScroller = new Scroller( mContext) ;

mHalfLineHeight = mLineHeight / 2 ;

mMiddleLineHeight = mLineHeight / 3 ;

mRulerLeftRightMargin =
UiUtils.dipToPx( mContext , RULER_MARGIN_LEFT_RIGHT) ;

mRulerTopBottomMargin =
UiUtils.dipToPx( mContext , RULER_MARGIN_TOP_BOTTOM) ;

mFirstLineMargin =
UiUtils. dipToPx( mContext, FIRST_LINE_MARGIN ) ;

rulerBitmap =
((BitmapDrawable)mContext .getResources().getDrawable(R.mipmap. ruler )).getBitmap();

mRulerWidth =
UiUtils. dipToPx( mContext, mRulerWidth ) ;

mRulerHeight =
UiUtils. dipToPx( mContext, mRulerHeight ) ;
}

/**

* 绘制处边框

* @param canvas

*/

private void drawOuter (Canvas
canvas) {

canvas.drawRect(mOutRect , mOuterPaint) ;

}

/**

* 绘制线

* @param canvas

*/

private void drawLine (Canvas
canvas) {

canvas.save();

// 第一条线间隔

canvas.translate(( float )
(mFirstLineMargin * 1.5 + mRulerLeftRightMargin ) , 0 ) ;

int top = 0 ;

for( int i
= 1 ; i
<= DEFAULT_LINE_COUNT * DEFAULT_LINE_COUNT ; i++)
{

// 绘制最长线

if (i
% 10 == 0 ||
i == 1 )
{

top = mTotalHeight - mLineHeight ;

}

// 绘制中间线

else if (i
% 5 == 0 )
{

top = mTotalHeight - mHalfLineHeight ;

}

// 绘制短线

else {

top = mTotalHeight - mMiddleLineHeight ;

}

canvas.drawLine(0 , top, 0 , mTotalHeight - mRulerTopBottomMargin , mLinePaint) ;

// 增加相应的间隔

canvas.translate( mLineDivider , 0 ) ;

}

canvas.restore();

}

/**

* 绘制文本

* @param canvas

*/

private void drawText (Canvas
canvas) {

canvas.save();

// 第一条线间隔

canvas.translate(( float )
(mFirstLineMargin * 1.5 + mRulerLeftRightMargin )
- 2, 0 );

for( int i
= 1 ; i
<= DEFAULT_LINE_COUNT * DEFAULT_LINE_COUNT ; i++)
{

canvas.drawText(i + "" , 0, mTotalHeight , mTextPaint ) ;

// 增加相应的间隔

canvas.translate( mLineDivider , 0 ) ;

}

canvas.restore();
}

这样就完成了基本的绘制,但为了可以左右滑动,增加了一个scroller,scoroller滑动的只是内容,位置不变。
/**

* 画标志

* @param canvas

*/

private void drawSymbol (Canvas
canvas) {

canvas.save();

// 第一条线间隔

canvas.translate(( float )
(mFirstLineMargin * 1.5 + mRulerLeftRightMargin )
- 5, mRulerTopBottomMargin ) ;

canvas.drawBitmap( rulerBitmap , mRulerSrcRect , mRulerDestRect , mBitmapPaint) ;

canvas.restore() ;

}

@Override

protected void onSizeChanged (int w ,
int h ,
int oldw,
int oldh) {

super .onSizeChanged(w , h , oldw, oldh) ;

// 记录下 view 的宽高

mTotalWidth =
w ;

mTotalHeight =
h ;

mLineDivider =
( int)
Math. round(( mTotalWidth - mRulerLeftRightMargin * 2 - mFirstLineMargin * 2 )
/ (DEFAULT_LINE_COUNT * DEFAULT_LINE_MIDDLE_COUNT - 1.0 ));

mRulerSrcRect = new Rect( 0 , 0 , mRulerWidth, mRulerHeight ) ;

mRulerDestRect = new Rect( 0 , 0 , mRulerWidth, mRulerHeight ) ;

mWholeRulerWidth =
( DEFAULT_LINE_COUNT *
(DEFAULT_LINE_COUNT - DEFAULT_LINE_MIDDLE_COUNT ))
* mLineDivider ;

mOutRect = new Rect( mRulerLeftRightMargin , mRulerTopBottomMargin , mWholeRulerWidth + mTotalWidth ,mTotalHeight - mRulerTopBottomMargin ) ;

}

@Override

public boolean onTouchEvent (MotionEvent
event) {

int action
= event.getAction() ;

int x = ( int )
event.getX();

int y = ( int )
event.getY();

switch (action) {

case MotionEvent. ACTION_DOWN:

break;

case MotionEvent. ACTION_MOVE :

if (
(x > mRulerLeftRightMargin + mFirstLineMargin )
&& (x < mTotalWidth - mRulerLeftRightMargin -mFirstLineMargin ))
{

int temp
= ( int )
(x - (mRulerLeftRightMargin + mFirstLineMargin * 1.5 ))
- 5 ;

temp = temp > 0 ?
temp : 0;

mRulerDestRect = new Rect(temp, 0 , temp
+ mRulerWidth , mRulerHeight ) ;

postInvalidate();

scrollerSmoothScrollBy( lastX -
x , 0 );

}

break;

case MotionEvent. ACTION_UP :

break;

}

lastX =
x ;

return true;

}

@Override

public void computeScroll ()
{

// 先判断 mScroller 滚动是否完成

if ( mScroller.computeScrollOffset())
{

// 这里调用 View 的scrollTo() 完成实际的滚动

scrollTo( mScroller .getCurrX(), mScroller .getCurrY()) ;

// 必须调用该方法,否则不一定能看到滚动效果

postInvalidate() ;

}

}

// 调用此方法滚动到目标位置

public void scrollerSmoothScrollTo ( int fx ,
int fy) {

int dx
= fx - mScroller.getFinalX() ;

int dy = fy - mScroller .getFinalY();

scrollerSmoothScrollBy(dx , dy);

}

// 调用此方法设置滚动的相对偏移

public void scrollerSmoothScrollBy ( int dx ,
int dy) {

// 设置 mScroller的滚动偏移量

mScroller .startScroll( mScroller.getFinalX() , mScroller .getFinalY() , dx , dy);

invalidate() ; //这里必须调用 invalidate() 才能保证 computeScroll()会被调用,否则不一定会刷新界面,看不到滚动效果
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: