博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
android尺子的自定义view——RulerView
阅读量:5890 次
发布时间:2019-06-19

本文共 12168 字,大约阅读时间需要 40 分钟。

项目中用到自定义尺子的样式:

原代码在github上找的,地址:https://github.com/QQabby/HorizontalRuler

原效果为

 

因为跟自己要使用的view稍有不同  所以做了一些修改,修改的注释都放在代码中了,特此记录一下。

首先是一个自定义View:

1 public class RuleView extends View {  2   3     private Paint paint;  4   5     private Context context;  6   7     private int maxValue = 500;  8     /**  9      * 起点x的坐标 10      */ 11     private float startX ; 12  13     private float startY ; 14     /** 15      * 刻度线的长度 16      */ 17     private float yLenght ; 18     /** 19      * 刻度的间隙 20      */ 21 //    private float gap = 8f; 22     private float gap = 10; 23     /** 24      * 文本的间隙 25      */ 26     private float textGap = 10f; 27     /** 28      * 短竖线的高度 29      */ 30     private float smallHeight = 10f; 31     /** 32      * 长竖线的高度 33      */ 34     private float largeHeight = 22f; 35      36     /** 37      * 文本显示格式化 38      */ 39     private DecimalFormat format; 40  41     private DisplayMetrics metrics = null; 42     /** 43      * 文本的字体大小 44      */ 45     private float mFontSize; 46  47     private Handler mScrollHandler = null; 48  49     private MyHorizontalScrollView horizontalScrollView; 50  51     private int mCurrentX = -999999999; 52     /** 53      * 刻度进制 54      */ 55 //    private float unit = 10f; 56     private int unit = 10;//隔unit个刻度写一个数字 57     //每个大刻度代表值iValue 58     private int iValue = 10; 59  60     boolean isDraw = true; 61  62     public RuleView(Context context) { 63         super(context); 64         this.context = context; 65         init(); 66     } 67  68     public void setHorizontalScrollView( 69             MyHorizontalScrollView horizontalScrollView) { 70         this.horizontalScrollView = horizontalScrollView; 71  72         this.horizontalScrollView.setOnTouchListener(new OnTouchListener() { 73  74             @Override 75             public boolean onTouch(View v, MotionEvent event) { 76  77                 final int action = event.getAction(); 78                 switch (action) { 79                 case MotionEvent.ACTION_DOWN: 80  81                     break; 82                 case MotionEvent.ACTION_MOVE: 83  84                     mScrollHandler.removeCallbacks(mScrollRunnable); 85                     break; 86                 case MotionEvent.ACTION_UP: 87  88                     mScrollHandler.post(mScrollRunnable); 89                     break; 90                 } 91                 return false; 92             } 93         }); 94     } 95  96     public RuleView(Context context, AttributeSet attrs) { 97         super(context, attrs); 98         this.context = context; 99 100         init();101     }102 103     public void init() {104 105 //        format = new DecimalFormat("0.0");106         format = new DecimalFormat("0");//不使用浮点数格式107 108         metrics = new DisplayMetrics();109         WindowManager wmg = (WindowManager) context110                 .getSystemService(Context.WINDOW_SERVICE);111         wmg.getDefaultDisplay().getMetrics(metrics);112 113         paint = new Paint(Paint.ANTI_ALIAS_FLAG);114         paint.setStyle(Paint.Style.FILL);115         paint.setStrokeWidth(getResources().getDimension(R.dimen.ui_1_dip));116 //        paint.setStrokeWidth(2);117         paint.setColor(Color.parseColor("#999999"));118 119         mFontSize = ScreenUtil.dip2px(context, 16);120 //        startY = ScreenUtil.dip2px(context, 20f);121         startY = ScreenUtil.dip2px(context, 0);//Y轴由0开始,即最顶端,不用设置适配布局文件RuleView的android:layout_marginTop="-20dp"122         yLenght = ScreenUtil.dip2px(context, 10);123 //        gap = ScreenUtil.dip2px(context, 8f);124         gap = ScreenUtil.dip2px(context, 10);125 //        startX = ScreenUtil.getScreenWidth(context)/ 2.0f- getResources().getDimension(R.dimen.ui_10_dip)  ;126         startX = ScreenUtil.getScreenWidth(context)/ 2.0f;//X轴不减去10dp,则三角形顶点可以刚好最准0位置127 128         // + getResources().getDimension(R.dimen.text_h2)/2.0f129         // Util.dip2px(context, 13f) +130 131         mScrollHandler = new Handler(context.getMainLooper());132 133     }134 135     @Override136     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {137 138         float width =  maxValue * gap + ScreenUtil.getScreenWidth(context) - getResources().getDimension(R.dimen.ui_10_dip)*2.0f ;139 140         // int widthMode = MeasureSpec.getMode(heightMeasureSpec);141         // if(widthMode == MeasureSpec.AT_MOST){142         // Log.d("TAG", "mode::AT_MOST");143         // }else if(widthMode == MeasureSpec.EXACTLY){144         // Log.d("TAG", "mode::EXACTLY");145         // }else if(widthMode == MeasureSpec.UNSPECIFIED){146         // Log.d("TAG", "mode::UNSPECIFIED");147         // }148 149         setMeasuredDimension((int) width, heightMeasureSpec);150     }151 152     @Override153     protected void onDraw(final Canvas canvas) {154         super.onDraw(canvas);155 156         // 画刻度线157         paint.setColor(getResources().getColor(R.color.gray_bg_high));// 刻度颜色158         for (int i = 0; i <= maxValue; i++) {159 160             if (i % 5 == 0) {161                 yLenght = ScreenUtil.dip2px(context, largeHeight);162             } else {163                 yLenght = ScreenUtil.dip2px(context, smallHeight);164             }165             canvas.drawLine(i * gap + startX, startY, i * gap + startX, yLenght166                     + startY, paint);167         }168 169         paint.setTextSize(mFontSize);170 171         // 每10个刻度写一个数字172         textGap = gap * unit;173 174         // 画刻度文字30175         paint.setColor(getResources().getColor(R.color.textGray));// 文字颜色176         for (int i = 0; i <= maxValue / unit; i++) {177 178 //            String text = format.format(i + 1) + "";//从0开始计数时不用加1179             String text = format.format(i * iValue) + "";//乘以每刻度的值iValue180             // 获取文本的宽度181             float width = ScreenUtil.px2dip(context, calculateTextWidth(text)) / 2f;182 183             canvas.drawText(184                     text,185                     startX - width + i * textGap,186                     (startY + ScreenUtil.dip2px(context, largeHeight))187                             + ScreenUtil.dip2px(context, 24), paint);//字体大小188         }189     }190 191     /**192      * 获取TextView中文本的宽度193      */194     private float calculateTextWidth(String text) {195         if (TextUtils.isEmpty(text)) {196             return 0;197         }198         TextPaint textPaint = new TextPaint();199         textPaint.setTextSize(mFontSize * metrics.scaledDensity);200         final float textWidth = textPaint.measureText(text);201 202         return textWidth;203     }204 205     DecimalFormat df = new DecimalFormat("0.0");206 207     /**208      * 当滑动尺子的时候209      */210     int scrollWidth = 0;211 212     public void setScrollerChanaged(int l, int t, int oldl, int oldt) {213         // 滑动的距离214         scrollWidth = l;215 216         float number = scrollWidth / gap;217         float result = number / unit;218 219         listener.onSlide(result);220     }221 222     public onChangedListener listener;223 224     public interface onChangedListener {225 226         void onSlide(float number);227     }228 229     public void onChangedListener(onChangedListener listener) {230         this.listener = listener;231     }232 233     /**234      * 滚动监听线程235      */236     private Runnable mScrollRunnable = new Runnable() {237 238         @Override239         public void run() {240             if (mCurrentX == horizontalScrollView.getScrollX()) {
// 滚动停止了241 242 try {243 244 float x = horizontalScrollView.getScrollX();245 float value = (x / (gap * unit));// 当前的值246 String s = df.format(value);247 248 // 滑动到11.0 ok249 int scrollX = (int) (Double.parseDouble(s) * gap * unit);250 251 horizontalScrollView.smoothScrollTo(scrollX, 0);252 253 } catch (NumberFormatException numExp) {254 numExp.printStackTrace();255 }256 mScrollHandler.removeCallbacks(this);257 } else {258 mCurrentX = horizontalScrollView.getScrollX();259 mScrollHandler.postDelayed(this, 50);260 }261 }262 };263 264 /**265 * 设置默认刻度尺的刻度值,不会滚动到相应的位置266 * 267 * @param scaleValue268 */269 public void setDefaultScaleValue(float scaleValue) {270 271 // final int scrollX = (int) ((scaleValue - 1.0f) * gap * unit);//从0开始计数时不用减去1272 final int scrollX = (int) (scaleValue * gap * unit / 10);//每个值在设置刻度时会乘以10,所以除去273 274 new Handler().postDelayed(new Runnable() {275 276 @Override277 public void run() {278 279 horizontalScrollView.smoothScrollTo(scrollX, 0);280 }281 }, 100);282 }283 284 /**285 * 设置刻度值286 */287 public void setScaleValue(int iValue) {288 this.iValue = iValue;289 }290 291 /**292 * 设置刻度最小值293 */294 public void setMinScaleValue(Float minScaleValue) {295 // this.minScaleValue = minScaleValue;296 }297 298 /**299 * 获取刻度最大值300 */301 public Float getMaxScaleValue() {302 // return maxScaleValue;303 return 33.0f;304 }305 306 /**307 * 设置刻度最大值308 */309 public void setMaxScaleValue(Float maxScaleValue) {310 // this.maxScaleValue = maxScaleValue;311 }312 313 /**314 * 设置当前刻度尺的刻度值,并滚动到相应的位置315 * 316 * @param scaleValue317 */318 public void setScaleScroll(float scaleValue) {319 320 int scrollX = (int) ((scaleValue - 1.0f) * gap * unit);321 322 horizontalScrollView.smoothScrollTo(scrollX, 0);323 }324 }

另外用到一个自定义的scrollView:

1 public class MyHorizontalScrollView extends HorizontalScrollView { 2  3     private OnScrollListener onScrollListener = null; 4  5     public MyHorizontalScrollView(Context context) { 6         this(context, null); 7     } 8     public MyHorizontalScrollView(Context context, AttributeSet attrs) { 9         this(context, attrs, 0);10     }11     public MyHorizontalScrollView(Context context, AttributeSet attrs,12             int defStyleAttr) {13         super(context, attrs, defStyleAttr);14     }15 16     @Override17     protected void onScrollChanged(int l, int t, int oldl, int oldt) {18         super.onScrollChanged(l, t, oldl, oldt);19         if(onScrollListener != null){20             onScrollListener.onScrollChanged(l, t, oldl, oldt);21         }22     }23 24     public interface OnScrollListener {25         public void onScrollChanged(int l, int t, int oldl, int oldt);26     }27 28     public void setOnScrollListener(OnScrollListener onScrollListener) {29         this.onScrollListener = onScrollListener;30     }31 }

直尺上的黄色三角标其实是嵌在布局上的,在drawble文件中实现

shape_triangle

下面是布局文件,注意RuleView是嵌在ScrollView中的:

最后在界面中的使用:

ruleView = (RuleView) findViewById(R.id.rule_view);        horizontalScrollView = (MyHorizontalScrollView) findViewById(R.id.hor_scrollview);        horizontalScrollView.setOverScrollMode(View.OVER_SCROLL_NEVER);// 去掉超出滑动后出现的阴影效果        // 设置水平滑动        ruleView.setHorizontalScrollView(horizontalScrollView);        ruleView.setDefaultScaleValue(num);        // 当滑动尺子的时候        horizontalScrollView.setOnScrollListener(new MyHorizontalScrollView.OnScrollListener() {            @Override            public void onScrollChanged(int l, int t, int oldl, int oldt) {                ruleView.setScrollerChanaged(l, t, oldl, oldt);            }        });        ruleView.onChangedListener(new RuleView.onChangedListener() {            @Override            public void onSlide(float number) {                int num = (int) (number * 10);                tvNum.setText(num+"");            }        });

 

转载地址:http://usfsx.baihongyu.com/

你可能感兴趣的文章
我所思考的生活,致半年后的自己
查看>>
csharp skype send message in winform
查看>>
jQuery plugin: Tablesorter 2.0
查看>>
csharp:datagridview enter Half Width and Full Width characters
查看>>
MMORPG 游戏服务器端设计--转载
查看>>
C#实现无标题栏窗体点击任务栏图标正常最小化或还原的解决方法
查看>>
[转]GetLastInputInfo计时用户离开电脑及软件在指定时间锁定等
查看>>
Windows 操作系统与 .NET Framework
查看>>
Box2dの自定义多边形
查看>>
HDU 1425 ( sort )
查看>>
Windows Phone 7 框架和页面
查看>>
Directx11教程(31) 纹理映射(1)
查看>>
Android——Button的颜色
查看>>
创建ITS mobile 应用程序步骤
查看>>
《星辰傀儡线》人物续:“灭世者”、“疯狂者”、“叛逆者”三兄妹
查看>>
安装系统字体
查看>>
Spring的ApplicationContext加载备忘
查看>>
GoogleMapAPIV3.8.6离线包下载
查看>>
SILK 的 Tilt的意思
查看>>
IPC通信:Posix共享内存2
查看>>