自定义尺子

为了进一步学习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  ==  || i ==  1   ) {
            top = 
mTotalHeight  mLineHeight  ;
        

        
//   绘制中间线 
        
else if   (i %  ==  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  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 >  ? 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() 会被调用,否则不一定会刷新界面,看不到滚动效果
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值