Android 사용자 정의 컨트롤 불규칙 영역 클릭 이벤트 구현
일단 효 과 를 볼 게 요.
위의 도형 에 대해 서 는 주로 svg 를 사용 합 니 다.svg 를 분석 하여 불규칙 한 도형 을 가 져 옵 니 다.svg 파일 에 대해 서 는 일반적으로 미공 이 제공 해 야 합 니 다.우리 가 개발 하여 실현 할 필요 가 없습니다.
위의 효 과 를 실현 하 는 첫 번 째 단 계 는 svg 파일 코드 를 다음 과 같이 분석 하 는 것 입 니 다.
package demo.zjd.com.taiwandemo.utils;
import android.graphics.RectF;
import android.util.Xml;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import demo.zjd.com.taiwandemo.bean.CityPath;
import demo.zjd.com.taiwandemo.bean.ViewAttr;
import demo.zjd.com.taiwandemo.calback.ParserCallBack;
/**
* Created by zhangjd on 2017/6/1.
* svg xml
*/
public class SVGXmlParserUtils {
public static void parserXml(final InputStream in, final ParserCallBack mParserCallBack){
new Thread(new Runnable() {
@Override
public void run() {
List<CityPath> list=new ArrayList<>();
ViewAttr mViewAttr=new ViewAttr();
parserXml(in,list,mViewAttr);
if(mParserCallBack!=null){
mParserCallBack.callback(list,mViewAttr);
}
}
}).start();
}
private static void parserXml(InputStream in, List<CityPath> list, ViewAttr mViewAttr){
XmlPullParser parser = Xml.newPullParser();
RectF mRectF=new RectF();
try {
parser.setInput(in, "UTF-8");
int eventType = parser.getEventType();
String name = null;
CityPath mCityPath = null;
list.clear();
while (eventType != XmlPullParser.END_DOCUMENT) {
switch (eventType) {
case XmlPullParser.START_DOCUMENT:// ,
break;
case XmlPullParser.START_TAG://
name = parser.getName();
if ("path".equals(name)) {
mCityPath = new CityPath();
mCityPath.setId(parser.getAttributeValue(null, "id"));
mCityPath.setTitle(parser.getAttributeValue(null, "title"));
mCityPath.setPathData(parser.getAttributeValue(null, "d"));
}
break;
case XmlPullParser.END_TAG://
name = parser.getName();
if ("path".equals(name)) {// ,
mCityPath.initPath();
// path
//
mCityPath.getmPath().computeBounds(mRectF, true);
mViewAttr.colSize(mRectF);
list.add(mCityPath);
}
break;
}
eventType = parser.next();
}
} catch (XmlPullParserException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(in!=null){
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
svg 파일 을 분석 한 후 그림 코드 를 다음 과 같이 그립 니 다.
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (list == null) {
return;
}
// Matrix mMatrix = new Matrix();
// mMatrix.postScale(0.5f,0.5f);
// mMatrix.setScale(0.5f,0.5f);// concat
// canvas.concat(mMatrix);
//
// canvas.restore();
canvas.scale(scale, scale);
canvas.drawColor(Color.YELLOW);
for (int i = 0; i < list.size(); i++) {
CityPath path = list.get(i);
//
mPaint.setStrokeWidth(2);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setColor(Color.GRAY);
canvas.drawPath(path.getmPath(), mPaint);
}
if (mPath != null) {//mPath path,
mPaint.setStrokeWidth(1);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setColor(Color.GREEN);
mPaint.setShadowLayer(8,2,2,Color.BLACK);
canvas.drawPath(mPath, mPaint);
}
mPaint.clearShadowLayer();
}
위의 방법 을 실현 하면 지 도 를 만 들 수 있 지만 이 벤트 를 클릭 하지 않 았 습 니 다.그 다음 에 이벤트 코드 를 클릭 하면 다음 과 같 습 니 다.
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {//
float x = event.getX();
float y = event.getY();
if (list != null)
for (int i = 0; i < list.size(); i++) {// path
CityPath cityPath = list.get(i);
if (cityPath.isArea(x / scale, y / scale)) {// , path
mPath = cityPath.getmPath();
postInvalidate();
Toast.makeText(getContext(), cityPath.getTitle(), Toast.LENGTH_SHORT).show();
break;
}
}
}
return super.onTouchEvent(event);
}
출발 이벤트 실현 의 주요 핵심 은 path 구역 에서 코드 를 실현 하 는 지 여 부 를 판단 하 는 것 입 니 다.다음 과 같 습 니 다.
public boolean isArea(float x,float y){
RectF r=new RectF();
//
mPath.computeBounds(r, true);
//
re.setPath(mPath, new Region((int)r.left,(int)r.top,(int)r.right,(int)r.bottom));
return re.contains((int)x, (int)y);
}
위의 코드 는 불규칙 한 구역 의 클릭 을 실현 할 수 있 습 니 다.그 다음 에 주요 파일 은 분 석 된 svg 파일 을 통 해 서로 다른 핸드폰 의 디 스 플레이 를 적당 하 게 할 수 있 도록 하 는 것 입 니 다.제 가 실현 하 는 방법 은 모든 path 의 최소 외 장 사각형 의 크기 를 통계 한 다음 에 모든 path 가 있 는 구역 의 최소 값 을 통합 시 키 는 것 입 니 다.그리고 컨트롤 의 크기 와 비교 하여 크기 조정 코드 는 다음 과 같 습 니 다.
// path
//
mCityPath.getmPath().computeBounds(mRectF, true);
mViewAttr.colSize(mRectF);
public void colSize(RectF mRectF) {
left = left == null ? mRectF.left : Math.min(mRectF.left, left);
top = top == null ? mRectF.top : Math.min(mRectF.top, top);
right = right == null ? mRectF.right : Math.max(mRectF.right, right);
bottom = bottom == null ? mRectF.bottom : Math.max(mRectF.bottom, bottom);
}
적당 한 배합 이 완 료 된 후에 큰 성 과 를 거 두 었 습 니 다.다음은 코드 의 주소 입 니 다.개 선 된 부분 이 있 으 면 환영 합 니 다.다운로드:코드 주소
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Bitrise에서 배포 어플리케이션 설정 테스트하기이 글은 Bitrise 광고 달력의 23일째 글입니다. 자체 또는 당사 등에서 Bitrise 구축 서비스를 사용합니다. 그나저나 며칠 전 Bitrise User Group Meetup #3에서 아래 슬라이드를 발표했...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.