Android自定义View之坐标系
在我的学习过程中,我感到自定义View的东西还是比较多的,需要一步一步的深入,我自己的想法是要把整个体系分解为若干个章节来记录以及梳理,而这个开始,我决定用坐标系来引出,自定义View绘制的的过程中肯定要有坐标系来控制位置,接下来就简单而愉快的进行吧。
首先在Android体系中,有两种坐标系来辅助开发者进行开发,第一种是Android相对于整个手机的坐标系和自定义View的坐标系。
先看第一种,Android坐标系,请原谅我画的图灼伤了您的眼睛。
713B90ED-8A4A-4D32-98FD-F0B41922A374 2.jpeg
和我们正常的坐标系区别只是Y轴画反了。😂
第二种,View坐标系,每个View都存在这种坐标系
B0D61F81-BBEA-4FD5-9582-99B4A0994F92.png绿色的坐标轴是红色View的边,为了标注故画了条绿色的线,我想表达的就是View本身也是一个坐标系。例如这个画了这个红色的View中间的小黑圆。
canvas.drawCircle(300,300,50,paint);
圆心坐标是300,300 可以看出drawCircle这个函数是画在View的坐标系中的。
接着学习一下相关的函数
CA592A2F-D1CC-4D44-9592-18B8008FF1FA.png
可以看到图中的函数所对应的距离,很清晰,图中包含了Android坐标系和View的坐标系,
函数 | 描述 |
---|---|
getTop() | View上方到父容器上方的距离 |
getLeft() | View左侧到父容器左侧的距离 |
getBottom() | 父容器上方到View下侧的距离 |
getRight() | 父容器左侧到View右侧的距离 |
getHeight() | View自身的高度 |
getWidth() | View自身的宽度 |
然后看一下触摸相关的函数
函数 | 描述 |
---|---|
getX() | 触摸点到View左侧边界的距离 |
getY() | 触摸点到View上方边界的距离 |
getRawX() | 触摸点到屏幕左侧边界的距离 |
getRawX() | 触摸点到屏幕上方边界的距离 |
看一下演示View坐标系图2的完整的例子
public class MyView extends View {
public MyView(Context context) {
super(context);
}
public MyView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
canvas.drawColor(Color.RED);
canvas.drawCircle(300,300,50,paint);
int top = getTop();
int left = getLeft();
int right = getRight();
int bottom =getBottom();
int height = getHeight();
int width = getWidth();
int viewHeight = getRight() -getLeft();
int viewWidth = getBottom() -getTop();
Log.d("view-top:",top+"");
Log.d("view-left:",left+"");
Log.d("view-right:",right+"");
Log.d("view-bottom:",bottom+"");
Log.d("view-height:",height+"");
Log.d("view-width:",width+"");
Log.d("view-viewHeight:",viewHeight+"");
Log.d("view-viewWidth:",viewWidth+"");
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
float rawX = event.getRawX();
float rawY = event.getRawY();
Log.d("view-x:",x+"");
Log.d("view-y:",y+"");
Log.d("view-rawX:",rawX+"");
Log.d("view-rawY:",rawY+"");
return true;
}
}
Log日志
07-16 09:23:33.633 5911-5911/? E/view-top:: 402
07-16 09:23:33.633 5911-5911/? E/view-left:: 90
07-16 09:23:33.633 5911-5911/? E/view-right:: 990
07-16 09:23:33.633 5911-5911/? E/view-bottom:: 1302
07-16 09:23:33.633 5911-5911/? E/view-height:: 900
07-16 09:23:33.633 5911-5911/? E/view-width:: 900
07-16 09:23:33.633 5911-5911/? E/view-viewHeight:: 900
07-16 09:23:33.633 5911-5911/? E/view-viewWidth:: 900
07-16 10:54:09.018 5911-5911/com.pro.aj.recyclerviewdemo E/view-x:: 285.30396
07-16 10:54:09.018 5911-5911/com.pro.aj.recyclerviewdemo E/view-y:: 322.34766
07-16 10:54:09.018 5911-5911/com.pro.aj.recyclerviewdemo E/view-rawX:: 375.30396
07-16 10:54:09.018 5911-5911/com.pro.aj.recyclerviewdemo E/view-rawY:: 796.34766
每次触摸都会触发事件流,哪怕是再细微的操作。