中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么在Android中通過自定義控件實現不規則區域點擊事件

發布時間:2021-05-24 18:05:49 來源:億速云 閱讀:203 作者:Leah 欄目:移動開發

本篇文章為大家展示了怎么在Android中通過自定義控件實現不規則區域點擊事件,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。

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

Android是什么

Android是一種基于Linux內核的自由及開放源代碼的操作系統,主要使用于移動設備,如智能手機和平板電腦,由美國Google公司和開放手機聯盟領導及開發。

上述內容就是怎么在Android中通過自定義控件實現不規則區域點擊事件,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

江安县| 元江| 黄梅县| 新乡市| 泸西县| 额尔古纳市| 赤壁市| 高州市| 新津县| 永胜县| 漳州市| 甘南县| 余庆县| 西和县| 从化市| 玉溪市| 涪陵区| 天峻县| 怀远县| 滦平县| 尉犁县| 云梦县| 河南省| 贵定县| 灵丘县| 遵义县| 峨山| 安陆市| 安西县| 法库县| 洛阳市| 桑日县| 高雄市| 灌阳县| 齐齐哈尔市| 西充县| 巴东县| 广德县| 林州市| 鞍山市| 博乐市|