最近项目中,客户要求实现一些自定义地图.要求的功能是:可以实现放大,缩小,点击不同的地理位置,可以提示不同的地地理信息.

所使用的类文件有如下几个:

1) myMap.java 2)Position.java 3)testCanvasActivity.java 4)TouchImageView.java

如下图所示:

1)myMap.java 如下所示:

package wsf.Canvas.demo;

public class myMap { }

2)Position.java

package wsf.Canvas.demo;

import android.util.Log; public class Position { /** * 位置所在的标题 */ public String title=""; /** * 位置所在的介绍内容 */ public String content=""; /** * 位置所在的图片连接 */ public String imgUrl=""; /** * 在原图中的x传票 */ public int ori_x=0; /** * 非原图中的x坐标 */ public int ori_y=0; /** * 续度 */ public float longitude=0; /** * * 现实中的经度 */ public float latitude=0; /** *触碰点与该点的最大触发距离 *当外办触发时的点与此点距离小于2个单位时,会提示 */ private int max_distance=2; public IPosition Ipos; public void set_max_distance(int dis) { max_distance=dis; } /*** * * @param pos 回调接口 * @param ori_x 此点在图片中的座标x * @param ori_y 此点在原图中的座标y * @param longitude 此点在实际中的纬度 * @param latidude 此点在实际中的经度 * @param max_distance 在图片上的触碰点与该点座标的最大值(一但小于这个值,则会触发提示信息) * @param title 此点的小标题简单 * @param content 此点的主要内容 * @param imgurl 此点的相关超介绍连接 */ public Position(IPosition pos,int ori_x,int ori_y,float longitude, float latidude,int max_distance,String title,String content, String imgurl) { this.Ipos=pos; this.ori_x=ori_x; this.ori_y=ori_y; this.longitude=longitude; this.latitude=latidude; this.max_distance=max_distance; this.title=title; this.content=content; this.imgUrl=imgurl; } /** * 计算当前触碰点与自己的距离 * @return */ public int docalc_distance_bit(int n_x,int n_y) { return (int)Math.sqrt((n_x-ori_x)*(n_x-ori_x)+(n_y-ori_y)*(n_y-ori_y)); } public void doShow(int n_x,int n_y) { if(docalc_distance_bit(n_x, n_y)<=max_distance) { this.Ipos.doShow(this); } } public interface IPosition { void doShow(Position pos); } public void tostring() { Log.i("positionInfo", "positionInfo-->"+this.ori_x+ this.ori_y+ this.longitude+ this.latitude+ this.max_distance+ this.title+ this.content+ this.imgUrl ); } }

3)testCanvasActivity.java

package wsf.Canvas.demo;//wsf.Canvas.demo.testCanvasActivity import android.app.Activity; import android.os.Bundle; public class testCanvasActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); TouchImageView img = new TouchImageView(this); setContentView(img); } }

4)TouchImageView.java

package wsf.Canvas.demo;

import java.util.ArrayList; import java.util.List; import wsf.Canvas.demo.Position.IPosition; import wsf.study.demo.R; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.PointF; import android.util.DisplayMetrics; import android.util.FloatMath; import android.util.Log; import android.view.MotionEvent; import android.widget.ImageView; public class TouchImageView extends ImageView implements IPosition { float x_down = 0; float y_down = 0; PointF start = new PointF(); PointF mid = new PointF(); float oldDist = 1f; float oldRotation = 0; Matrix matrix = new Matrix(); Matrix matrix1 = new Matrix(); Matrix savedMatrix = new Matrix(); private static final int NONE = 0; private static final int DRAG = 1; private static final int ZOOM = 2; int mode = NONE; boolean matrixCheck = false; int widthScreen; int heightScreen; Bitmap gintama; int oldimgwidth=0; int oldimgheight=0; /**测试数据*/ List<Position> list_pos=new ArrayList<Position>(); public TouchImageView(testCanvasActivity activity) { super(activity); gintama = BitmapFactory.decodeResource(getResources(), R.drawable.gintama); DisplayMetrics dm = new DisplayMetrics(); activity.getWindowManager().getDefaultDisplay().getMetrics(dm); widthScreen = dm.widthPixels; heightScreen = dm.heightPixels; matrix = new Matrix(); oldimgheight=gintama.getHeight(); oldimgwidth=gintama.getWidth(); Position p1=new Position(this, 100, 100, 0, 0, 30, "1北京大学", "1北京大学历史悠久", "人生古都,外国人也会有所向往"); Position p2=new Position(this, 200, 200, 0, 0, 30, "2北京大学", "2北京大学历史悠久", "人生古都,外国人也会有所向往"); Position p3=new Position(this, 300, 300, 0, 0, 30, "3北京大学", "3北京大学历史悠久", "人生古都,外国人也会有所向往"); Position p4=new Position(this, 400, 400, 0, 0, 30, "4北京大学", "4北京大学历史悠久", "人生古都,外国人也会有所向往"); Position p5=new Position(this, 500, 500, 0, 0, 30, "5北京大学", "5北京大学历史悠久", "人生古都,外国人也会有所向往"); list_pos.add(p1); list_pos.add(p2); list_pos.add(p3); list_pos.add(p4); list_pos.add(p5); } protected void onDraw(Canvas canvas) { canvas.save(); canvas.drawBitmap(gintama, matrix, null); canvas.restore(); } public boolean onTouchEvent(MotionEvent event) { //Log.i("touch", "x_down-->"+x_down+" y_down-->"+y_down+" start-->x"+start.x+" y"+start.y+" oldDist-->"+oldDist+" oldRotation-->"+oldRotation); switch (event.getAction() & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: mode = DRAG; x_down = event.getX(); y_down = event.getY(); savedMatrix.set(matrix); break; case MotionEvent.ACTION_POINTER_DOWN: mode = ZOOM; oldDist = spacing(event); oldRotation = rotation(event); savedMatrix.set(matrix); midPoint(mid, event); break; case MotionEvent.ACTION_MOVE: if (mode == ZOOM) { matrix1.set(savedMatrix); float rotation = rotation(event) - oldRotation; float newDist = spacing(event); float scale = newDist / oldDist; matrix1.postScale(scale, scale, mid.x, mid.y);// 縮放 Log.i("touch", " newDist-->"+newDist+" oldDist-->"+oldDist+" scale-->"+scale+" mid.x-->"+mid.x+" mid.y"+mid.y); //matrix1.postRotate(rotation, mid.x, mid.y);// 旋轉 matrixCheck = matrixCheck(); if (matrixCheck == false) { matrix.set(matrix1); invalidate(); } } else if (mode == DRAG) { matrix1.set(savedMatrix); matrix1.postTranslate(event.getX() - x_down, event.getY() - y_down);// 平移 matrixCheck = matrixCheck(); matrixCheck = matrixCheck(); if (matrixCheck == false) { matrix.set(matrix1); invalidate(); } } break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_POINTER_UP: mode = NONE; break; } return true; } private boolean matrixCheck() { float[] f = new float[9]; matrix1.getValues(f); // 图片4个顶点的坐标 float x1 = f[0] * 0 + f[1] * 0 + f[2]; float y1 = f[3] * 0 + f[4] * 0 + f[5]; float x2 = f[0] * gintama.getWidth() + f[1] * 0 + f[2]; float y2 = f[3] * gintama.getWidth() + f[4] * 0 + f[5]; float x3 = f[0] * 0 + f[1] * gintama.getHeight() + f[2]; float y3 = f[3] * 0 + f[4] * gintama.getHeight() + f[5]; float x4 = f[0] * gintama.getWidth() + f[1] * gintama.getHeight() + f[2]; float y4 = f[3] * gintama.getWidth() + f[4] * gintama.getHeight() + f[5]; // 图片现宽度 double width = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)); //图片高度 double height=Math.sqrt((x1 - x3) * (x1 - x3) + (y1 - y3) * (y1 - y3)); //横向拉伸x float scale_x=(float)(width/oldimgwidth); //纵向拉伸 float scale_y=(float)(height/oldimgheight); for(Position p:list_pos) { p.doShow((int)((x_down-x1)/scale_x)/2, (int)((y_down-y1)/scale_y)/2); } Log.i("touch", "imgheight-->"+oldimgheight+" width-->"+oldimgwidth); Log.i("touch","xdown-->"+x_down+" ydown-->"+y_down+" width-->"+ width+"p1->"+x1+" "+y1+" p2-->"+x2+" "+y2+" p3-->"+x3+" "+y3+" p4-->"+x4+" "+y4); // 缩放比率判断 if (width < widthScreen / 3 || width > widthScreen * 3) { return true; } // 出界判断 if ((x1 < widthScreen / 3 && x2 < widthScreen / 3 && x3 < widthScreen / 3 && x4 < widthScreen / 3) || (x1 > widthScreen * 2 / 3 && x2 > widthScreen * 2 / 3 && x3 > widthScreen * 2 / 3 && x4 > widthScreen * 2 / 3) || (y1 < heightScreen / 3 && y2 < heightScreen / 3 && y3 < heightScreen / 3 && y4 < heightScreen / 3) || (y1 > heightScreen * 2 / 3 && y2 > heightScreen * 2 / 3 && y3 > heightScreen * 2 / 3 && y4 > heightScreen * 2 / 3)) { return true; } return false; } // 触碰两点间距离 private float spacing(MotionEvent event) { float x = event.getX(0) - event.getX(1); float y = event.getY(0) - event.getY(1); return FloatMath.sqrt(x * x + y * y); } // 取手势中心点 private void midPoint(PointF point, MotionEvent event) { float x = event.getX(0) + event.getX(1); float y = event.getY(0) + event.getY(1); point.set(x / 2, y / 2); } // 取旋转角度 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); } // 将移动,缩放以及旋转后的图层保存为新图片 // 本例中沒有用到該方法,需要保存圖片的可以參考 public Bitmap CreatNewPhoto() { Bitmap bitmap = Bitmap.createBitmap(widthScreen, heightScreen, Config.ARGB_8888); // 背景图片 Canvas canvas = new Canvas(bitmap); // 新建画布 canvas.drawBitmap(gintama, matrix, null); // 画图片 canvas.save(Canvas.ALL_SAVE_FLAG); // 保存画布 canvas.restore(); return bitmap; } Position lastpos=null; @Override public void doShow(Position pos) { // TODO Auto-generated method stub if(pos==lastpos) { } else { pos.tostring(); lastpos=pos; } } }

6)实现效果:

7) 点击图片上的座标时显示效果:

更多相关文章

  1. 动画
  2. 初学Android,OpenGL ES之使用纹理(八十三)
  3. Android(安卓)shap Animation
  4. android Gallery镜像倒影特效另一种方法
  5. Android拖动控件
  6. Android动画效果translate、scale、alpha、rotate详解
  7. Android:动画效果translate、scale、alpha、rotate详解
  8. Android动画效果translate、scale、alpha、rotate
  9. android 手势

随机推荐

  1. Android(安卓)Studio和MAT结合使用来分析
  2. 启动模式"singleTask"和FLAG_ACTIVITY_NE
  3. Android判断Activity是否全屏的方式!!!(最全)
  4. 【转】 Android(安卓)Performance Case S
  5. Android实现镜花水月的效果
  6. Qt5.12.7 搭建 Android(安卓)开发环境
  7. Android:Handler学习总结
  8. Android(安卓)自定义控件属性赋值
  9. Android时间计时器
  10. android 绘图的基本知识