700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > android 带刻度的滑动条_Android自定义控件尺子 滚动刻度尺

android 带刻度的滑动条_Android自定义控件尺子 滚动刻度尺

时间:2022-04-15 02:14:22

相关推荐

android 带刻度的滑动条_Android自定义控件尺子 滚动刻度尺

自定义控件是件很有乐趣的事,慢慢的会爱上它,哈哈哈。废话不多说先上设计图

接下来我们我们要先分析一下页面中需要到哪些东西

1.一条无限长的底线;

2.一根在屏幕中间的红色标记线,代表当前位置;

3.一个半透明的蓝色背景,改背景超过部分才会被展现;

4.刻度 整数高一点刻度 非整第一点的刻度

5.一个大刻度上都会标的数值

6.滚动

接下来进入正题,让我们开始绘制:

首先我们先给控件定义它的属性,根据刚才的分析我给他定义了一下的属性

接下来在控件的构造方法中获取这些值,里面还涉及到一些需要初始化的值都有备注

public RulerView(Context context, AttributeSet attrs) {

super(context, attrs);

WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);

DisplayMetrics dm = new DisplayMetrics();

windowManager.getDefaultDisplay().getMetrics(dm);

screenWidth = dm.widthPixels;

TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RulerView);

maxValue = typedArray.getDimensionPixelOffset(R.styleable.RulerView_max_value, 200000);

minValue = typedArray.getDimensionPixelOffset(R.styleable.RulerView_min_value, 0);

scaleTextSize = typedArray.getDimensionPixelOffset(R.styleable.RulerView_scale_text_size, 24);

scaleTextColor = typedArray.getColor(R.styleable.RulerView_scale_text_color, Color.parseColor("#d8d8d8"));

scaleSelectColor = typedArray.getColor(R.styleable.RulerView_scale_select_color, Color.parseColor("#76e4ff"));

scaleSelectBackgroundColor = typedArray.getColor(R.styleable.RulerView_scale_select_background_color, Color.parseColor("#6676e4ff"));

scaleUnSelectColor = typedArray.getColor(R.styleable.RulerView_scale_unselect_color, Color.parseColor("#d8d8d8"));

cursorColor = typedArray.getColor(R.styleable.RulerView_tag_color, Color.parseColor("#ff5555"));

if (currLocation == 0) {

currLocation = typedArray.getDimensionPixelOffset(R.styleable.RulerView_start_location, 0);

}

showItemSize = typedArray.getInteger(R.styleable.RulerView_show_item_size, 5);

oneItemValue = typedArray.getInteger(R.styleable.RulerView_show_item_size, 1000);

typedArray.recycle();

//一个刻度的宽度

scaleWidth = (screenWidth / (showItemSize * 10));

//尺子长度总的个数*一个的宽度

viewWidth = maxValue / oneItemValue * scaleWidth;

//滚动计算器

scroller = new Scroller(context);

//手势解析器

gestureDetector = new GestureDetector(context, gestureListener);

gestureDetector.setIsLongpressEnabled(false);

}

我们先从简单的开始画一条在底部的线,那问题来了这个View底部坐标在哪里呢?不用担心View有个onMeasure方法,在里面我们可以直接获取到View的高度

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

viewHeight = MeasureSpec.getSize(heightMeasureSpec);

}

private void drawBottomLine(Canvas canvas) {

paint = new Paint(Paint.ANTI_ALIAS_FLAG);

paint.setStrokeWidth(3);

paint.setColor(scaleUnSelectColor);

canvas.drawLine(0, viewHeight, viewWidth, viewHeight, paint);

}

绘制刻度以及刻度值,以及超过时的颜色

private void drawScale(Canvas canvas) {

paint = new Paint(Paint.ANTI_ALIAS_FLAG);

paint.setStrokeWidth(2);

//计算游标开始绘制的位置

float startLocation = (screenWidth / 2) - ((scaleWidth * (currLocation / oneItemValue)));

for (int i = 0; i < maxValue / oneItemValue; i++) {

//判断当前刻度是否小于当前刻度

if (i * oneItemValue <= currLocation) {

paint.setColor(scaleSelectColor);

} else {

paint.setColor(scaleUnSelectColor);

}

float location = startLocation + i * scaleWidth;

if (i % 10 == 0) {

canvas.drawLine(location, viewHeight - scaleHeight, location, viewHeight, paint);

paintText = new Paint(Paint.ANTI_ALIAS_FLAG);

paintText.setTextSize(scaleTextSize);

if (i * oneItemValue <= currLocation) {

paintText.setColor(scaleSelectColor);

} else {

paintText.setColor(scaleTextColor);

}

String drawStr = oneItemValue * i + "";

Rect bounds = new Rect();

paintText.getTextBounds(drawStr, 0, drawStr.length(), bounds);

canvas.drawText(drawStr, location - bounds.width() / 2, viewHeight - (scaleHeight + 5), paintText);

} else {

canvas.drawLine(location, viewHeight - scaleHeight / 2, location, viewHeight, paint);

}

//绘制选中的背景

paint = new Paint(Paint.ANTI_ALIAS_FLAG);

paint.setStyle(Paint.Style.FILL);

paint.setColor(scaleSelectBackgroundColor);

canvas.drawRect(startLocation, viewHeight - scaleHeight / 3, startLocation + currLocation / oneItemValue * scaleWidth, viewHeight, paint);

}

}

最后绘制一条中线

private void drawCursor(Canvas canvas) {

paint = new Paint(Paint.ANTI_ALIAS_FLAG);

paint.setStrokeWidth(3);

paint.setColor(cursorColor);

canvas.drawLine(screenWidth / 2, viewHeight / 5, screenWidth / 2, viewHeight, paint);

}

上面的方法都要在View的onDraw方法中调用一遍,这样刻度尺就绘制完成了。最后我们的工作就是让刻度尺跟着我们的手指动起来,直接重写onTouchEvent方法将所有事件交给手势处理器来处理然后重写onScroll(滚动),onFling(抛事件)方法

@Override

public boolean onTouchEvent(MotionEvent event) {

gestureDetector.onTouchEvent(event);

return true;

}

private GestureDetector.SimpleOnGestureListener gestureListener = new GestureDetector.SimpleOnGestureListener() {

public boolean onScroll(MotionEvent e1, MotionEvent e2,

float distanceX, float distanceY) {

if (!isScrollingPerformed) {

isScrollingPerformed = true;

}

doScroll((int) -distanceX);

invalidate();

return true;

}

public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,

float velocityY) {

lastScrollX = getCurrentItem() * getItemWidth() + scrollingOffset;

int maxX = getItemsCount()

* getItemWidth();

int minX = 0;

scroller.fling(lastScrollX, 0, (int) (-velocityX / 1.5), 0, minX, maxX, 0, 0);

setNextMessage(MESSAGE_SCROLL);

return true;

}

};

private void doScroll(int delta) {

//偏移量叠加

scrollingOffset += delta;

//总共滚动了多少个Item

int count = scrollingOffset / getItemWidth();

//当前位置

int pos = getCurrentItem() - count;

//限制滚到范围

if (isScrollingPerformed) {

if (pos < 0) {

count = getCurrentItem();

pos = 0;

} else if (pos >= getItemsCount()) {

count = getCurrentItem() - getItemsCount() + 1;

pos = getItemsCount() - 1;

}

}

int offset = scrollingOffset;

//移动了一个Item的距离,就更新页面

if (pos != getCurrentItem()) {

setCurrentItem(pos);

}

// 重新更新一下偏移量

scrollingOffset = offset - count * getItemWidth();

}

public int getItemWidth() {

return scaleWidth;

}

public int getCurrentItem() {

return currLocation / oneItemValue;

}

public int getItemsCount() {

return maxValue / oneItemValue;

}

public void setCurrentItem(int index) {

scrollingOffset = 0;

currLocation = index * oneItemValue;

invalidate();

if (onRulerChangeListener != null) {

onRulerChangeListener.onChanged(currLocation);

}

}

private void setNextMessage(int message) {

animationHandler.removeMessages(MESSAGE_SCROLL);

animationHandler.sendEmptyMessage(message);

}

// 动画处理

private Handler animationHandler = new Handler() {

public void handleMessage(Message msg) {

puteScrollOffset();

int currX = scroller.getCurrX();

int delta = lastScrollX - currX;

lastScrollX = currX;

if (delta != 0) {

doScroll(delta);

}

// 滚动还没有完成,到最后,完成手动

if (Math.abs(currX - scroller.getFinalX()) < MIN_DELTA_FOR_SCROLLING) {

scroller.forceFinished(true);

}

if (!scroller.isFinished()) {

animationHandler.sendEmptyMessage(msg.what);

} else {

finishScrolling();

}

}

};

private void finishScrolling() {

if (isScrollingPerformed) {

isScrollingPerformed = false;

}

invalidate();

}

最后上一张效果图

源码地址:/detail/fengzhongdeyang/9638371

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。