android 系统音量的刻度,android中获取屏幕信息,做标准刻度的尺子

在教学app中会有尺子的出现,我们如何获取标准的刻度呢

实现的关键是:

1.获取设备屏幕的信息

2.根据参数绘制尺子

3.设定尺子的相关动作

第一步的关键是DisplayMetrics,它的介绍是A structure describing general information about a display, such as its size, density, and font scaling.

和getWindowManager().getDefaultDisplay().getMetrics();它的介绍是Gets display metrics that describe the size and density of this display.

我们通过

dm = new DisplayMetrics();

getWindowManager().getDefaultDisplay().getMetrics(dm);将屏幕信息传入到dm结构体中,再将dm作为传参给我们的RulerView类

构造方法:

public RulerView(Context context, DisplayMetrics dm) {

super(context);

find_pixal(dm);

ruler_length = 6 * xcm; // 设置一开始为6厘米的尺子

ruler_width = xcm;

mid_point.set((float) (ruler_length * 0.5), 0);

rect = new Rect(0, 0, (int) (ruler_length), (int) ruler_width);

}

protected void find_pixal(DisplayMetrics dm) {

xcm = (float) (dm.xdpi / 2.54); // 单位都是pixal

xmm = xcm / 10;

}

dm.xdpi是The exact physical pixels per inch of the screen in the X dimension.,我们将pixal/inch转换成pixal每厘米只需要除以2.54即可,毫米同理。

其实实际上应该是要用上x和y一起计算的,不过基本所有设备x和y上的dpi都是一样的,所以我们只用xdpi就好了

声明FPoint mid_point做尺子的中点坐标。

重写onDraw方法:

先设置好画笔的样式,然后让在canvas上以中点为标准画长度为ruler_length并且标有刻度和数字的尺子。

我们这里设置了angle_rotate,这是用于我们后面旋转尺子用的

protected void onDraw(Canvas canvas) {

// TODO Auto-generated method stub

super.onDraw(canvas);

Paint paint = new Paint();

paint.setColor(Color.BLACK);

paint.setStyle(Style.STROKE);

paint.setStrokeWidth(2);

paint.setTextSize(30);

canvas.save();

canvas.rotate(angle_rotate, mid_point.x, mid_point.y);

canvas.drawRect(mid_point.x - ruler_length / 2, mid_point.y,

mid_point.x + ruler_length / 2, mid_point.y + ruler_width,

paint);

for (int i = 0; i < ruler_length / xmm; i++) {

float Left = mid_point.x - ruler_length / 2;

if (i % 10 == 0 && i != 0) {

canvas.drawLine(Left + i * xmm, mid_point.y, Left + i * xmm,

mid_point.y + 50, paint);

canvas.drawText(Integer.toString(i / 10), Left + i * xmm,

mid_point.y + 55, paint);

} else if (i == 0) {

canvas.drawLine(Left + i * xmm, mid_point.y, Left + i * xmm,

mid_point.y + 50, paint);

canvas.drawText(Integer.toString(i / 5) + "cm", Left + i * xmm,

mid_point.y + 55, paint);

} else {

canvas.drawLine(Left + i * xmm, mid_point.y, Left + i * xmm,

mid_point.y + 30, paint);

}

}

canvas.restore();

}

接着我们处理拖拽和旋转事件:

public boolean onTouchEvent(MotionEvent event) {

PointF touchPoint1;

switch (event.getAction() & MotionEvent.ACTION_MASK) {

// 主点按下

case MotionEvent.ACTION_DOWN:

touchPoint1 = supposedPoint(new PointF(event.getX(), event.getY()));

if (rect.contains((int) touchPoint1.x, (int) touchPoint1.y)) {

MODE = "DRAG";

finger_first_down.set(event.getX(), event.getY());

mid_point_saved.set(mid_point);

} else {

return false;

}

break;

case MotionEvent.ACTION_POINTER_1_DOWN:

PointF touchPoint2 = supposedPoint(new PointF(event.getX(1),

event.getY(1)));

if (rect.contains((int) touchPoint2.x, (int) touchPoint2.y)) {

MODE = "ZOOM";

finger_first_down.set(event.getX(0), event.getY(0));

finger_second_down.set(event.getX(1), event.getY(1));

angle_initial = rotation(event);

angle_saved = angle_rotate;

SingleToMulti = true;

distance_initial = distance(event);

distance_saved = ruler_length;

mid_point_between_fingers_down.set(

(event.getX(0) + event.getX(1)) / 2,

(event.getY(0) + event.getY(1)) / 2);

} else {

return false;

}

break;

case MotionEvent.ACTION_MOVE:

if (MODE == "DRAG") {

if (MultiToSingle) {

finger_first_down.set(event.getX(), event.getY());

mid_point_saved.set(mid_point);

MultiToSingle = false;

}

mid_point.set(mid_point_saved.x + event.getX()

- finger_first_down.x, mid_point_saved.y + event.getY()

- finger_first_down.y);

renewRect();

} else if (MODE == "ZOOM") {

if (SingleToMulti) {

mid_point_saved.set(mid_point);

SingleToMulti = false;

}

mid_point_between_fingers.set(

(event.getX(0) + event.getX(1)) / 2,

(event.getY(0) + event.getY(1)) / 2);

mid_point.set(mid_point_saved.x + mid_point_between_fingers.x

- mid_point_between_fingers_down.x, mid_point_saved.y

+ mid_point_between_fingers.y

- mid_point_between_fingers_down.y);

angle_rotate = angle_saved + rotation(event) - angle_initial;

ruler_length = distance_saved * distance(event)

/ distance_initial;

renewRect();

}

invalidate();

break;

case MotionEvent.ACTION_UP:

MODE = "NONE";

break;

case MotionEvent.ACTION_POINTER_1_UP:

MultiToSingle = true;

//MODE = "DRAG";

//System.out.println(MODE);

//break;

MODE = "NONE";

break;

}

return true;

}

private float rotation(MotionEvent event) {

double delta_x = (event.getX(0) - event.getX(1));

double delta_y = (event.getY(0) - event.getY(1));

double radians = Math.atan2(delta_y, delta_x);

return (float) Math.toDegrees(radians);

}

private float distance(MotionEvent event) {

double x = (event.getX(0) - event.getX(1));

double y = (event.getY(0) - event.getY(1));

return (float) Math.sqrt(x * x + y * y);

}

protected float in360(float angel) {

if (angel >= 360) {

do {

angel -= 360;

} while (angel < 360);

} else if (angel < 0) {

do {

angel += 360;

} while (angel > 0);

}

return angel;

}

protected float distanceToMidPoint(PointF touchPoint) {

double x = (touchPoint.x - mid_point.x);

double y = (touchPoint.y - mid_point.y);

return (float) Math.sqrt(x * x + y * y);

}

protected PointF supposedPoint(PointF touchPoint) {

Float k = new Float(Math.toRadians(angle_rotate));

PointF point_map = new PointF();

point_map.x = new Float((touchPoint.x - mid_point.x) * Math.cos(k)

+ (touchPoint.y - mid_point.y) * Math.sin(k) + mid_point.x);

point_map.y = new Float(-(touchPoint.x - mid_point.x) * Math.sin(k)

+ (touchPoint.y - mid_point.y) * Math.cos(k) + mid_point.y);

return point_map;

}

protected void renewRect() {

rect.left = (int) (mid_point.x - ruler_length * 0.5);

rect.right = (int) (mid_point.x + ruler_length * 0.5);

rect.top = (int) mid_point.y;

rect.bottom = (int) (mid_point.y + ruler_width);

}

这中间的逻辑略复杂。。

可以专门写一篇博客了

0818b9ca8b590ca3270a3433284dd417.png

源码在此→http://download.csdn.net/detail/edwardwayne/8492939

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值