最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android自定義控件實(shí)現(xiàn)不規(guī)則區(qū)域點(diǎn)擊事件

 更新時(shí)間:2018年05月26日 17:15:02   作者:zhangjundi  
這篇文章主要為大家詳細(xì)介紹了Android自定義控件實(shí)現(xiàn)不規(guī)則區(qū)域點(diǎn)擊事件,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

本文實(shí)例為大家分享了Android實(shí)現(xiàn)不規(guī)則區(qū)域點(diǎn)擊事件的具體代碼,供大家參考,具體內(nèi)容如下

先看看效果

對(duì)于上面的圖形實(shí)現(xiàn)主要用到svg,通過(guò)解析svg獲取不規(guī)則的圖形,對(duì)于svg文件這個(gè)一般需要美工提供,不需要我們開(kāi)發(fā)實(shí)現(xiàn)。

實(shí)現(xiàn)上面效果第一步是解析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:// 文檔開(kāi)始事件,可以進(jìn)行數(shù)據(jù)初始化處理 
            break; 
          case XmlPullParser.START_TAG:// 開(kāi)始元素事件 
            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:// 結(jié)束元素事件 
            name = parser.getName(); 
            if ("path".equals(name)) {//這個(gè)地方主要處理屏幕適配問(wèn)題,后面后詳細(xì)講解 
              mCityPath.initPath(); 
              //處理path的邊界 
              //計(jì)算控制點(diǎn)的邊界 
              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);//這個(gè)地方要用concat方法不能用這個(gè)方法 
//    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,如果不為空則一點(diǎn)擊選中區(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(); 
 
} 

實(shí)現(xiàn)上面的方法就可以會(huì)出一個(gè)地圖了,但是沒(méi)有點(diǎn)擊事件,接下來(lái)實(shí)現(xiàn)點(diǎn)擊事件代碼如下:

@Override 
public boolean onTouchEvent(MotionEvent event) { 
  if (event.getAction() == MotionEvent.ACTION_DOWN) {//點(diǎn)擊的時(shí)候出發(fā) 
    float x = event.getX(); 
    float y = event.getY(); 
    if (list != null) 
      for (int i = 0; i < list.size(); i++) {//多所有的path進(jìn)行遍歷 
        CityPath cityPath = list.get(i); 
        if (cityPath.isArea(x / scale, y / scale)) {//這個(gè)地方要注意了,在查找點(diǎn)是否在path區(qū)域中藥除以上面的縮放比例 
          mPath = cityPath.getmPath(); 
          postInvalidate(); 
          Toast.makeText(getContext(), cityPath.getTitle(), Toast.LENGTH_SHORT).show(); 
          break; 
        } 
      } 
  } 
  return super.onTouchEvent(event); 
} 

出發(fā)事件實(shí)現(xiàn)中主要的核心是判斷點(diǎn)是否在path區(qū)域內(nèi)實(shí)現(xiàn)代碼如下:

public boolean isArea(float x,float y){ 
   RectF r=new RectF(); 
   //計(jì)算控制點(diǎn)的邊界 
   mPath.computeBounds(r, true); 
   //設(shè)置區(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); 
} 

上面的代碼就可以實(shí)現(xiàn)不規(guī)則區(qū)域的點(diǎn)擊了,接下來(lái)主要文件就是如何保證通過(guò)解析的svg文件可以再不同手機(jī)上的顯示適配,我這里實(shí)現(xiàn)的方法是將每個(gè)path的最小外嵌矩形的大小都統(tǒng)計(jì)出來(lái),然后進(jìn)行整合獲取所有path所在區(qū)域的最小值,然后和控件的大小進(jìn)行比較算出縮放比代碼如下:

//處理path的邊界 
//計(jì)算控制點(diǎn)的邊界 
  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); 
} 

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

下載:代碼地址

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Android自動(dòng)播放Banner圖片輪播效果

    Android自動(dòng)播放Banner圖片輪播效果

    這篇文章主要介紹了Android自動(dòng)播放Banner圖片輪播效果的相關(guān)資料,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-07-07
  • Android App中的GridView網(wǎng)格布局使用指南

    Android App中的GridView網(wǎng)格布局使用指南

    GridView布局所實(shí)現(xiàn)的就是類似于九宮格的矩陣界面效果,下面整理了Android App中的GridView網(wǎng)格布局使用指南,包括分割線的添加與自定義GridView的實(shí)現(xiàn)等技巧,需要的朋友可以參考下
    2016-06-06
  • android webview中使用Java調(diào)用JavaScript方法并獲取返回值

    android webview中使用Java調(diào)用JavaScript方法并獲取返回值

    這篇文章主要介紹了android webview中使用Java調(diào)用JavaScript方法并獲取返回值,本文直接給出代碼示例,需要的朋友可以參考下
    2015-03-03
  • Android帶清除功能的輸入框控件EditTextWithDel

    Android帶清除功能的輸入框控件EditTextWithDel

    這篇文章主要為大家詳細(xì)介紹了Android帶清除功能的輸入框控件EditTextWithDel,感興趣的小伙伴們可以參考一下
    2016-09-09
  • Jetpack?Compose狀態(tài)專篇精講

    Jetpack?Compose狀態(tài)專篇精講

    在今年的Google/IO大會(huì)上,亮相了一個(gè)全新的?Android?原生?UI?開(kāi)發(fā)框架-Jetpack?Compose,?與蘋果的SwiftIUI一樣,Jetpack?Compose是一個(gè)聲明式的UI框架,這篇文章主要介紹了Jetpack?Compose狀態(tài)管理
    2022-10-10
  • Android開(kāi)發(fā)中超好用的正則表達(dá)式工具類RegexUtil完整實(shí)例

    Android開(kāi)發(fā)中超好用的正則表達(dá)式工具類RegexUtil完整實(shí)例

    這篇文章主要介紹了Android開(kāi)發(fā)中超好用的正則表達(dá)式工具類RegexUtil,結(jié)合完整實(shí)例形式分析了Android正則表達(dá)式常見(jiàn)操作技巧,包括針對(duì)證件號(hào)、銀行賬號(hào)、手機(jī)號(hào)、郵編等的正則判斷相關(guān)操作技巧,需要的朋友可以參考下
    2017-11-11
  • Android集成微信登錄的步驟詳解

    Android集成微信登錄的步驟詳解

    這篇文章給大家整理Android集成微信登錄的詳細(xì)步驟,通過(guò)文章整理的內(nèi)容,大家只需要幾行代碼就可以實(shí)現(xiàn)微信登錄的功能了,剛興趣的朋友們下面來(lái)一起看看吧。
    2016-09-09
  • Android數(shù)據(jù)持久化之Preferences機(jī)制詳解

    Android數(shù)據(jù)持久化之Preferences機(jī)制詳解

    這篇文章主要介紹了Android數(shù)據(jù)持久化之Preferences機(jī)制,較為詳細(xì)的分析了Android數(shù)據(jù)持久化的概念、Preferences機(jī)制的原理與相關(guān)實(shí)現(xiàn)、使用技巧,需要的朋友可以參考下
    2017-05-05
  • Android 開(kāi)發(fā)中l(wèi)ayout下的子文件夾

    Android 開(kāi)發(fā)中l(wèi)ayout下的子文件夾

    這篇文章主要介紹了android 開(kāi)發(fā)中l(wèi)ayout下的子文件夾,需要的朋友可以參考下
    2017-12-12
  • Android Toast自定義顯示時(shí)間

    Android Toast自定義顯示時(shí)間

    這篇文章主要為大家詳細(xì)介紹了Android Toast自定義顯示時(shí)間,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-08-08

最新評(píng)論

锡林浩特市| 昆山市| 博爱县| 汪清县| 青阳县| 鹰潭市| 太康县| 乳山市| 陆川县| 平江县| 南昌县| 鸡泽县| 南郑县| 通渭县| 临高县| 沂南县| 彭水| 杭锦后旗| 怀柔区| 六枝特区| 兖州市| 调兵山市| 商洛市| 莆田市| 咸阳市| 襄樊市| 湘西| 定结县| 瑞安市| 威信县| 桃源县| 丰镇市| 梁平县| 英吉沙县| 荣昌县| 且末县| 开鲁县| 肇州县| 弋阳县| 米易县| 马公市|