国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android自定義控件實現不規則區域點擊事件

2019-10-22 18:10:35
字體:
來源:轉載
供稿:網友

本文實例為大家分享了Android實現不規則區域點擊事件的具體代碼,供大家參考,具體內容如下

先看看效果

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); } 

適配完成之后就大功告成,下面是代碼的地址,如有改進的地方歡迎提出

下載:代碼地址

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 三门县| 阿瓦提县| 安国市| 湘阴县| 安溪县| 扎鲁特旗| 岳池县| 文水县| 宿州市| 巨野县| 曲阜市| 廉江市| 商河县| 深水埗区| 临西县| 临清市| 鄂尔多斯市| 宜良县| 桦南县| 宁陕县| 玛曲县| 靖江市| 苍山县| 牟定县| 盐池县| 沙河市| 嘉义县| 新丰县| 商河县| 九台市| 平湖市| 贵定县| 赤水市| 桂阳县| 黑龙江省| 绥阳县| 阳西县| 千阳县| 余干县| 武冈市| 宁阳县|