博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android 自定义坐标轴控件
阅读量:5870 次
发布时间:2019-06-19

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

  在上一篇中,我们见到了一个很简单的坐标轴,并且可以实现拖动等效果。本文在此基础上进行进一步深入探讨。仅供初学者学习,大牛看了请别乱喷哦~~谢谢~~

  图为放大前和放大并拖动后

控件功能

1.       支持坐标轴单位长度的放大缩小

2.       放大缩小基于坐标轴中间位置缩放,即中间位置的那个点为参考点,在程序中需要记录它的物理坐标和逻辑坐标,并且逻辑坐标随着拖动和缩放而不断变化,其他所有坐标的物理逻辑坐标之间的转换都是以此作为参考点的,这样可以使得缩放的时候让人感觉在用google地图(夸张了点)。

3.       支持内容拖动

4.       支持坐标轴名称和单位设置

5.       支持标题设置

6.       支持边距和标题高度设置

7.       支持添加任意多条不同折线,且可以由用户决定用什么样的Paint

实现缩放和移动的关键为参考点的变化和坐标转换。

1.       坐标轴密度K

/*      * 横轴纵轴密度、长度和比例。 */ private float mXValuePerPix, mYValuePerPix; private float mXScale, mYScale;     mXValuePerPix / mXScale 为X轴的密度     mYValuePerPix / mYScale 为Y轴的密度

2.       移动的时候参考点的变化

/*      * 用于保存拖动时的上一个点的位置 */ int x0, y0; /*      * 拖动事件监听 */     @Override public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction(); /* * (x,y)点为发生事件时的点,它的坐标值为相对于该控件左上角的距离 */ int x = (int) event.getX(); int y = (int) event.getY(); switch (action) {
case MotionEvent.ACTION_DOWN: // 按下 x0 = x; y0 = y; Log.i("down", "(" + x0 + "," + y0 + ")"); break; case MotionEvent.ACTION_MOVE: // 拖动 /* * (x-x0, y-y0)为物理坐标相对运动矢量 * mXValuePerPix / mXScale 为X轴的密度 * mYValuePerPix / mYScale 为Y轴的密度 * 即每个像素长度代表的长度 * * 向右和向上移动的时候,坐标值都是变大的,而参考点是不动的所以相对来说是变小的 * 但是物理Y轴的矢量应该先取反,因为物理坐标点的坐标轴是向下Y增大的。 */ mPointBaseValue.x -= (x - x0) * mXValuePerPix / mXScale; mPointBaseValue.y -= -(y - y0) * mYValuePerPix / mYScale; x0 = x; y0 = y; Log.i("move", "(" + x0 + "," + y0 + ")"); invalidate(); break; case MotionEvent.ACTION_UP: // 弹起 break; } /* * 注意:这里一定要返回true 返回false和super.onTouchEvent(event)都会本监听只能检测到按下消息 * 这是因为false和super.onTouchEvent(event)的处理都是告诉系统该控件不能处理这样的消息, * 最终系统会将这些事件交给它的父容器处理。 */ return true; }

3.       坐标转换

/**      * 逻辑坐标转化为屏幕坐标      * 将逻辑坐标logPointF点转换为物理坐标 */ private PointF point2Physical(PointF logPointF) {
PointF physicalPointF = new PointF(); physicalPointF.set((logPointF.x - mPointBaseValue.x) * mXScale / mXValuePerPix + mPointBase.x, -(logPointF.y - mPointBaseValue.y) * mYScale / mYValuePerPix + mPointBase.y); return physicalPointF; } /** * 物理坐标转化为逻辑坐标 * 将物理坐标phyPointF点转换为逻辑坐标 */ private PointF point2Logical(PointF phyPointF) {
float x = (phyPointF.x - mPointBase.x) * mXValuePerPix / mXScale + mPointBaseValue.x; float y = (mPointBase.y - phyPointF.y) * mYValuePerPix / mYScale + mPointBaseValue.y; PointF logicalPointF = new PointF(x, y); return logicalPointF; }

 4.       程序中所用的成员变量一览

/*      * 颜料 */ private Paint mPaint; /*      * 数据集合 */ private List
mPointsList; private List
mPaintList; /* * 标题 */ private boolean mHasTitle; private String mTitle; private int mTitleHeight; private PointF mTitlePoint; /* * 边距 */ private int mLeftPad, mRightPad, mBottomPad, mTopPad; /* * 横轴纵轴密度、长度和比例。 */ private float mXValuePerPix, mYValuePerPix; private int mXLen, mYLen; private float mXScale, mYScale; /* * 横轴纵轴标识和单位 */ private String mXAxisPrickle, mYAxisPrickle; private String mXAxisName = "X", mYAxisName = "Y"; /* * 圆心(坐标值是相对与控件的左上角的) */ // private PointF mPointZero = new PointF(); /* * 参考坐标 */ private PointF mPointBase = new PointF(); private PointF mPointBaseValue = new PointF(); /* * 交叉点坐标中心点 */ private PointF mPointOrigin = new PointF();

源码下载:

转载于:https://www.cnblogs.com/zgx2012/archive/2011/10/12/2208720.html

你可能感兴趣的文章
ElasticSearch学习(8)-Restful接口查询操作
查看>>
URL—base64加密
查看>>
打包审核的那些个坑 (含swift)
查看>>
电子秤示数读取方案
查看>>
我的友情链接
查看>>
Nginx+Keepalived搭建高可用负载均衡集群
查看>>
js获取当前物理地址
查看>>
一个例子说明java局部代码块、静态代码块、构造代码块区别
查看>>
LVS的三种模式区别详解
查看>>
Nginx(1)-nginx的编译安装
查看>>
Unity3d iOS 如何添加Admob
查看>>
Backtrack5 下WEB模糊测试
查看>>
活动目录之占用操作主机实例分析
查看>>
Docker启动kafka
查看>>
http2.4.2+mysql5.5.24+postfix2.9.3
查看>>
我的友情链接
查看>>
Photoshop脚本 > 压缩并输出JPEG图片
查看>>
Ueditor代码高亮
查看>>
数据索引学习(1)
查看>>
jQuery HTML 操作
查看>>