package com.hwann.pathmeasurexu.maps;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathMeasure;
import android.graphics.RectF;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.LinearInterpolator;
import com.hwann.pathmeasurexu.R;
import com.hwann.pathmeasurexu.map.PathParser;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
/**
* @author :yellow
* @date: 2017/11/8 19:20
* @update: 2017/11/8
* @describe:
*/
public class Chians extends View {
private Context context;
private List itemList;
private ProvinceltemS provin;
private float scales = 0.8f;
private int minWidth;
private int minHeigth;
private int[] colorArray = new int[]{0xFF239BD7, 0xFFFBB3E5, 0xFFBB2BD7};
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (itemList != null) {
scales = viewWidth / rectMIN.width();
float scales1 = viewHeight / rectMIN.height();
scales = Math.min(scales, scales1);
Log.i("1111","scales>>"+scales);
int colorNunber = itemList.size();
for (int i = 0; i < colorNunber; i++) {
int color = colorArray[0];
int flag = i % 4;
switch (flag) {
case 1:
color = colorArray[1];
break;
case 2:
color = colorArray[2];
break;
case 3:
color = colorArray[0];
break;
}
itemList.get(i).setColor(color);
}
postInvalidate();
}
}
};
private Paint paintW;
private Paint paintm;
private Path pathm;
private float aniMoto;
private int viewWidth;
private int viewHeight;
public Chians(Context context) {
super(context);
}
public Chians(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
init(context);
}
private void init(Context context) {
itemList = new ArrayList<>();
paintW = new Paint();
paintm = new Paint();
paintm.setAntiAlias(true);
minHeigth = context.getResources().getDimensionPixelSize(R.dimen.map_max_height);
minWidth = context.getResources().getDimensionPixelSize(R.dimen.map_min_width);
paintm.setColor(Color.RED);
paintm.setStrokeWidth(4);
paintm.setStyle(Paint.Style.STROKE);
pathm = new Path();
thread.start();
startVAnimation();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int width = MeasureSpec.getSize(widthMeasureSpec);
int heigthMode = MeasureSpec.getMode(heightMeasureSpec);
int heigth = MeasureSpec.getSize(heightMeasureSpec);
viewWidth = width;
viewHeight = heigth;
switch (widthMode) {
case MeasureSpec.EXACTLY:
viewWidth = width > minWidth ? width : minWidth;
break;
case MeasureSpec.AT_MOST:
case MeasureSpec.UNSPECIFIED:
viewWidth = minWidth;
break;
}
//得到参考高度
int computHeight = (minHeigth * viewHeight / minWidth);
switch (heigthMode) {
case MeasureSpec.EXACTLY:
viewHeight = heigth;
break;
case MeasureSpec.AT_MOST:
case MeasureSpec.UNSPECIFIED:
//取最大的那个值
viewHeight = minHeigth > computHeight ? minHeigth : computHeight;
break;
}
setMeasuredDimension(MeasureSpec.makeMeasureSpec(viewWidth, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(viewHeight, MeasureSpec.EXACTLY));
}
GestureDetector gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onDown(MotionEvent e) {
handerOnDown(e.getX(), e.getY());
return true;
}
});
private void handerOnDown(float x, float y) {
if (itemList != null) {
ProvinceltemS provinceltem = null;
for (ProvinceltemS provinceltemS : itemList) {
if (provinceltemS.isonTouth(x / scales, y / scales)) {
provinceltem = provinceltemS;
break;
}
}
if (provinceltem != null) {
provin = provinceltem;
postInvalidate();
}
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
return gestureDetector.onTouchEvent(event);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.save();
canvas.scale(scales, scales);
for (int i = 0; i < itemList.size(); i++) {
//没有被选中
if (itemList.get(i) != provin) {
itemList.get(i).onDrow(canvas, paintW, false);
}
}
if (provin != null) {
pathm.reset();
pathm.lineTo(0, 0);
provin.onDrow(canvas, paintW, true);
PathMeasure pathMeasure = new PathMeasure(provin.getPath(), false);
float pathLength = pathMeasure.getLength();
pathMeasure.getSegment(pathLength * aniMoto - 100, pathLength * aniMoto, pathm, true);
canvas.drawPath(pathm, paintm);
postInvalidate();
}
}
public void startVAnimation() {
ValueAnimator animator = ValueAnimator.ofFloat(0, 1);
animator.setDuration(1000);
animator.setInterpolator(new LinearInterpolator());
animator.setRepeatCount(ValueAnimator.INFINITE);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
aniMoto = (float) animation.getAnimatedValue();
}
});
animator.start();
}
private RectF rectMIN;
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
InputStream inputStream = context.getResources().openRawResource(R.raw.chinas);
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builders = null;
try {
builders = builderFactory.newDocumentBuilder();
Document doc = builders.parse(inputStream);
Element element = doc.getDocumentElement();
NodeList pathList = element.getElementsByTagName("path");
float left = -1;
float right = -1;
float top = -1;
float bottom = -1;
for (int i = 0; i < pathList.getLength(); i++) {
Element elements = (Element) pathList.item(i);
String pathData = elements.getAttribute("android:pathData");
Path svgPath = PathParser.createPathFromPathData(pathData);
RectF rectF = new RectF();
svgPath.computeBounds(rectF, true);
left = left == -1 ? rectF.left : Math.min(rectF.left, left);
right = right == -1 ? rectF.right : Math.max(rectF.right, right);
top = top == -1 ? rectF.top : Math.min(rectF.top, top);
bottom = bottom == -1 ? rectF.bottom : Math.max(rectF.bottom, bottom);
ProvinceltemS provinceItem = new ProvinceltemS(svgPath);
itemList.add(provinceItem);
}
rectMIN = new RectF(left, top, right, bottom);
handler.sendEmptyMessage(1);
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
绘制实体,这思路很不错
package com.hwann.pathmeasurexu.maps;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.graphics.Region;
/**
* @author :yellow
* @date: 2017/11/8 19:21
* @update: 2017/11/8
* @describe:
*/
public class ProvinceltemS {
private int color;
private Path path;
public ProvinceltemS(Path path) {
this.path = path;
}
public Path getPath() {
return path;
}
public void setColor(int color) {
this.color = color;
}
public void onDrow(Canvas canvas, Paint paint, boolean isTouch) {
//被选中
if (isTouch) {
//画阴影部分
paint.setStrokeWidth(2);
paint.setColor(Color.BLACK);
paint.setStyle(Paint.Style.STROKE);
paint.setShadowLayer(8, 0, 0, Color.BLUE);
canvas.drawPath(path, paint);
//画省份
paint.clearShadowLayer();
paint.setColor(color);
paint.setStyle(Paint.Style.FILL);
paint.setStrokeWidth(1);
canvas.drawPath(path,paint);
} else {
//填充背景
paint.clearShadowLayer();
paint.setColor(color);
paint.setStyle(Paint.Style.FILL);
canvas.drawPath(path, paint);
//绘制边界线
paint.setStrokeWidth(1);
paint.setColor(Color.BLUE);
paint.setStyle(Paint.Style.STROKE);
canvas.drawPath(path, paint);
}
}
public boolean isonTouth(float x, float y) {
RectF rectF = new RectF();
getPath().computeBounds(rectF,true);
Region region = new Region();
region.setPath(path, new Region((int) rectF.left, (int) rectF.top, (int) rectF.right, (int) rectF.bottom));
return region.contains((int)x,(int)y);
}
}