需求
这是一个很早之前的需求了,之前没有发博客的习惯,最近想做一个回顾,也是为了做一个小小的总结把,把之前做的一些东西,和碰到的一些问题,总体的回顾一下,反思一下。因为从事房地产相关的工作,所以需要实现一个沙盘的功能,让客户可以在手机上查看相关的楼栋信息,在网上找了两天,没有找到类似的,只能自己硬着头皮写了,当时写的时候整整花了一个星期,也是这方面的接触实在太少,一些炫酷的东西从来都是拿来主义,都是抱着网上能找到的东西从来不会动脑子自己去弄,不过每次写完类似的东西,心里还是挺开心的,扯了这么多闲篇,进入正题。
-效果图
思路
1. 了解了需求之后,其实有点头皮发麻,脑子里出现的第一个想法就是上网找,结果遗憾收场!然后只能自己分析了,首先需要显示一张沙盘的图片,然后图片可以缩放,可以拖拽,想到这里这不是经常用的相册里面的大图预览的功能吗,果断打开项目看了用到的用于大图浏览的框架,缩放拖拽的功能都有,但是怎么加标注,而且标注还要随着图片的改变而变化位置,放弃了这个思路。清一清脑子,看到同事在开发地图相关的功能,脑子一亮?哈哈,这个不就是类似地图的一小部分功能吗,然后写了个demo集成了百度地图的sdk,往上添加标注,果然需要的就是这个!但是不能直接用地图的功能,不过好歹有了个思路,后面通过验证,确实可行。
2. 确定实现方案:首先需要确定一些关键点,图片不能被裁剪,只能被等比例缩放,所以我在FramLayout里面又放了一个FramLayout,作为容器来放图片,和需要放到特定位置的标注。拖拽和缩放的都是里面的一个容器FramLayout,确定了思路接下来就是开始码代码了。
准备工作
真正开始编码之前需要做一些必须的准备工作,那就是确定缩放、拖拽的范围,还有就是关于标注的位置超界的判定等等。这时候画几个图就一目了然了。
开发之前画一些类似的图可以让我们开发的时候脑子更清晰,一开始我是没有画的,结果写的时候脑子越来越糊涂!!!
代码实现
/**
* @author :Chenqi
* <p>
* date :2018/5/23 下午2:37
* description :自定义沙盘View
*/
@SuppressWarnings("unused")
public class SandTabView extends FrameLayout implements
ScaleGestureDetector.OnScaleGestureListener {
//点击事件的时间判定值
private static final int CLICK_STANDARD_TIME = 200;
//最大放大倍数
private static final int SCALE_MAX_VALUE = Integer.MAX_VALUE;
//声明拖拽帮助类
private ViewDragHelper mDragHelper;
//声明缩放手势手势监听
private ScaleGestureDetector mScaleGestureDetector;
//声明沙盘图、标注的容器
private FrameLayout mContentView;
//声明手指按下时间
private long mPointDownTimeStamp;
//声明触摸事件类型
private int mTouchMode;
//声明缩放事件类型
private int mScaleMode;
//记录开始触摸前两指距离
private float mPointDistanceBeforeScale;
//当前缩放比
private float mCurScaleFactor = 1;
//总缩放比
private float mAllScaleFactor = 1;
//初始缩放比
private float mOriginalFactor;
//单击按下坐标
private PointF mPointDown = new PointF();
//单击抬起坐标
private PointF mPointUp = new PointF();
//声明缩放中心点
private PointF mScaleCenPoint = new PointF();
//缩放前距左,距右边距
private PointF mPointLeftAndTop = new PointF();
//开始缩放前标注父容器位置记录
private Rect mOriginRect = new Rect();
//声明初始加载的View大小
private PointF mViewOriginSize;
//点击回调
private ISandTabItemClick mISandTabItemClick;
//加载回调
private ISandTabLoadCallBack mLoadCallBack;
//是否可以点击
private boolean mIsTouchEnable = true;
//是否已经生成图片展示
private boolean mHaveViewCut = false;
//第一次加载是否完成
private boolean mFirstLoaded = false;
public SandTabView(@NonNull Context context) {
this(context, null);
}
pub