本文记录一下我如何完成工作中的功能,借鉴了这个项目:https://www.jb51.net/article/216743.htm
这是完成的样子:
要求:根据一个有像素坐标的json文件,输入坐标后显示坐标在地图上的位置
这个有点像平时的商场地图导航,不过那是静态的,而这个是动态的。
一共被我分为3个部分完成:
- 获取json文件的地图的像素坐标
- 自定义控件,包括父容器,地图图片,坐标视图,计算偏移
- activity监听输入框,输入正确坐标时显示坐标视图
1和3自己找资料是很容易找到的,这里主要讲计算偏移,是根据像素坐标,使坐标视图显示在正确的位置上。
计算地图图片的偏移量
总结一下就是imageview的内外边距(对照上图的红色蓝色部分)加上图片在imageview的平移量(因为图片并不一定铺满imageview,不理解可以参考https://www.jianshu.com/p/49f8d5e5965b?utm_campaign=haruki)。
public class MapImageView extends AppCompatImageView {
int offset[] = new int[2];
public MapImageView(@NonNull Context context) {
super(context);
}
public MapImageView(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public MapImageView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public int[] getBitmapOffset(Boolean includeLayout){
float values[] = new float[9];
//不想用这个Matrix的也可以试试adjustViewBounds这个属性,自行查阅资料设置
Matrix m= getImageMatrix();
m.getValues(values);
offset[0] = (int) values[2]; //图片并不是铺满imageview的,获取图片在imageview里平移的偏移量
offset[1] = (int) values[5]; //获取MTRANS_X、MTRANS_Y
if (includeLayout) {//如果外面有父容器
ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) getLayoutParams();
offset[0] += getPaddingLeft() + lp.leftMargin; //加上内边距和外边距
offset[1] += getPaddingTop() + lp.topMargin;//对照上面图片的paddingTop和layout_marginTop
}
return offset;
}
}
计算坐标的偏移量
这个就比较复杂了,分为两个部分吧,一个是坐标在地图图片的位置,一个是坐标视图准确指向坐标的点。
x = markBean.getX() / 6000;//像素坐标除图片像素长度,例如0.5则表示在图片中央
y = markBean.getY() / 4500;
mapWidth = mapImage.getWidth() - mapLeft * 2; //imageview的长度减去图片在imageview的偏移量
mapHeight = mapImage.getHeight() - mapTop * 2;//获取图片的长宽
signX = mapWidth *x//获取坐标在地图图片上的x方向的长度位置
signY = mapHeigt *y
上面的是坐标视图,如果我们直接setLayoutParams,就会发现坐标视图的左上角指向了坐标位置,我们需要让左边指示图片的小白点指向坐标位置。
我们需要计算出小白点leftmargin和topmargin,leftmargin就是坐标指示图片的宽/2,topmargin就是坐标视图的height减小白点的leftmargin。
最后的计算为:x=内外边距left+图片在imageview的偏移left+坐标在图片上x方向的长度-坐标偏移
y同理
想要更多的功能或者源代码去翻我在本文开头的网址,感谢他让我完成了这个功能,否则我真的懵了。