本篇文章為大家展示了怎么在Android中通過自定義控件實現(xiàn)不規(guī)則區(qū)域點擊事件,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。
創(chuàng)新互聯(lián)從2013年成立,是專業(yè)互聯(lián)網(wǎng)技術服務公司,擁有項目成都做網(wǎng)站、網(wǎng)站設計網(wǎng)站策劃,項目實施與項目整合能力。我們以讓每一個夢想脫穎而出為使命,1280元防城做網(wǎng)站,已為上家服務,為防城各地企業(yè)和個人服務,聯(lián)系電話:028-86922220
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; public class SVGXmlParserUtils { public static void parserXml(final InputStream in, final ParserCallBack mParserCallBack){ new Thread(new Runnable() { @Override public void run() { Listlist=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 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:// 文檔開始事件,可以進行數(shù)據(jù)初始化處理 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代表的是選中區(qū)域的path,如果不為空則一點擊選中區(qū)域了 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(); }
實現(xiàn)上面的方法就可以會出一個地圖了,但是沒有點擊事件,接下來實現(xiàn)點擊事件代碼如下:
@Override public boolean onTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) {//點擊的時候出發(fā) 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區(qū)域中藥除以上面的縮放比例 mPath = cityPath.getmPath(); postInvalidate(); Toast.makeText(getContext(), cityPath.getTitle(), Toast.LENGTH_SHORT).show(); break; } } } return super.onTouchEvent(event); }
出發(fā)事件實現(xiàn)中主要的核心是判斷點是否在path區(qū)域內實現(xiàn)代碼如下:
public boolean isArea(float x,float y){ RectF r=new RectF(); //計算控制點的邊界 mPath.computeBounds(r, true); //設置區(qū)域路徑和剪輯描述的區(qū)域 re.setPath(mPath, new Region((int)r.left,(int)r.top,(int)r.right,(int)r.bottom)); return re.contains((int)x, (int)y); }
上面的代碼就可以實現(xiàn)不規(guī)則區(qū)域的點擊了,接下來主要文件就是如何保證通過解析的svg文件可以再不同手機上的顯示適配,我這里實現(xiàn)的方法是將每個path的最小外嵌矩形的大小都統(tǒng)計出來,然后進行整合獲取所有path所在區(qū)域的最小值,然后和控件的大小進行比較算出縮放比代碼如下:
//處理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); }
Android是一種基于Linux內核的自由及開放源代碼的操作系統(tǒng),主要使用于移動設備,如智能手機和平板電腦,由美國Google公司和開放手機聯(lián)盟領導及開發(fā)。
上述內容就是怎么在Android中通過自定義控件實現(xiàn)不規(guī)則區(qū)域點擊事件,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注創(chuàng)新互聯(lián)行業(yè)資訊頻道。