Android 矢量圖詳解

来源:https://www.cnblogs.com/sydmobile/archive/2019/05/13/10854553.html
-Advertisement-
Play Games

"官方文檔" 關於 Vector,在官方開髮指南中介紹。本文章是由個人翻譯官方指南然後添加個人理解完成。 由於個人精力有限,多個渠道發佈,排版上可能會有問題,如果影響查看,請移步 Android 開發者家園 Vector Drawables 概述 VectorDrawable 和 AnimatedV ...


官方文檔

關於 Vector,在官方開髮指南中介紹。本文章是由個人翻譯官方指南然後添加個人理解完成。

由於個人精力有限,多個渠道發佈,排版上可能會有問題,如果影響查看,請移步 Android 開發者家園

Vector Drawables 概述

VectorDrawable 和 AnimatedVectorDrawable 是在 Android 5.0 系統中第一次加入,當然我們可以使用 Android 的支持庫,來支持舊的版本,通過 VectorDrawableCompat 和 AnimateVectorDrawableCompat 來實現。

VectorDrawble 是在 xml 文件中定義的矢量圖形。xml 文件中定義的矢量圖形,它是一組帶有顏色信息的點、線和曲線,使用矢量圖主要的優點是圖形可伸縮性。可以在不損失顯示質量的情況下進行縮放,這意味著我們可以在不同的屏幕密度的手機上使用相同的文件。這樣會使 APK 文件變小更加有利於開發人員維護。我們還可以通過多個 XML 文件和矢量圖結合用於動畫。

既然說起 VectorDrawable 了,那就不得不提 SVG (Scalable Vector Graphic)了,這兩個經常混淆,其實 SVG 就是一種基於可擴展語言(xml),用於描述二維矢量圖形的一種圖形格式(和我們常見的 .png 等等圖片一樣,都是一種圖片格式),它有自己的一套編寫規範(使用 XML 編寫的),所以這種圖片是根據他自己的一套規範通過 XML 語言編寫而成的圖片。而我們的 VectorDrawable 是編程中的,它僅支持 SVG 規範中有限的內容。Android Studio 支持將 SVG 文件轉換成 VectorDrawable 。這就是他們兩者的關係。

path 中的常用的簡單繪製命令

  • moveto 命令 M 移動到新的位置
  • closepath 命令 Z 封閉路徑,從當前的位置畫一條直線到該路徑或者子路徑起始位置
  • lineto 命令 L ,從當前的位置畫一條線到指定的位置
  • horizontal lineto 命令 H 水平畫一條直線到指定位置
  • vertical lineto 命令 V 垂直畫一條直線到指定位置
  • 貝塞爾曲線 命令 Q
  • 光滑二次貝塞爾曲線 命令 T
  • elliptical arc 命令 A 橢圓弧

每個命令都有大小寫的形式,大寫代表後面的參數是絕對坐標,小寫表示相對坐標(我們一般用大寫就可以了),參數之間用空格或者逗號隔開。所謂的相對坐標是相對於前面一個點的,比如:M30,0 l 10,10 換算成絕對坐標就是 M30,0 L40,10

命令使用實例

  • M(x y) 移動到坐標 x,y 處
  • Z 後面不接參數,直接連接起點和終點
  • L(x y)直線連接到坐標 x,y 處
  • H(x) 水平連接
  • V(y) 垂直連接
  • C(x1 y1 x2 y2 x y)控制點 x1,y1 x2,y2 終點坐標 x,y
  • Q(x1 y1 x y)控制帶點 x1,y1 終點坐標 x ,y;
  • A(rx,ry,x-axis-rotation,large-arc-flag,sweep-flag,x,y);
    • rx,ry 橢圓半徑
    • x-axis-rotation x 軸旋轉角度
    • large-arc-flag 為 0 的時候表示取小弧度,1 的時候取大弧度
    • sweep-flag 0 取逆時針方向,1 取順時針方向
    • (x,y) 是終點的坐標

VectorDrawable 如何定義

VectorDrawable 在 drawable 文件夾中通過 來定義,這裡先來詳細的介紹一下 vector 中的各個屬性(和網上的許多不一樣,網上的大多都沒有自己驗證過)

<!--用於定義 vector drawable-->
<vector
        android:name(用於定義這個 vector drawable 的名字)、
        android:width(定義該 drawble 的內部寬度,支持所有的 Android 系統支持的尺寸單位,通常使用 dp)
        android:height(定義該 drawble 的內部高度,支持所有的 Android 系統支持的尺寸單位,通常使用 dp)
        android:viewportWidth(定義矢量圖視圖的寬度,實際上就是對應 path 路徑所使用的數據)
        android:viewportHeight(定義矢量圖視圖的高度,實際上就是對應 path 路徑所使用的數據)
        android:tint(定義該 drawble 線條的顏色,定義了後,你再在路徑裡面設置顏色就沒有作用了)
        android:tintMode(定義 tint 顏色的 Porter-Duff blending 模式,預設值為 src_in,暫時不用理會)
        android:autoMirrored 設置當系統為 RTL (right-to-left)佈局的時候,是否自動鏡像該圖片。
        android:alpha 該圖片的透明屬性
        >
    <grup
          // 有時候我們需要對幾個路徑一起處理,這樣就可以使用 group 元素來把多個 path 放到一起,group 支持的屬性有
          android:name 定義 group 的名字
          android:rotation 定義該 group 的路徑旋轉多少度(順時針旋轉)
          android:pivotX 定義縮放和旋轉該 group 時候的 X 參考點。該值相對於 vector 的 viewport 值來指定的。
          android:pivotY 定義縮放和旋轉該 group 時候的 Y 參考點。該值相對於 vector 的 viewport 值來指定的。
          android:scaleX 定義 X 軸的縮放倍數
          android:scaleY 定義 Y 軸的縮放倍數
          android:translateX 定義移動 X 軸的位移。相對於 vector 的 viewport 值來指定的
          android:translateY 定義移動 Y 軸的位移。相對於 vector 的 viewport 值來指定的>
          <path 
                // path 元素裡面的 pathData 就是矢量圖的路徑數據,除此之外還可以設置其他的屬性。path 的屬性有:
                android:name 定義該 path 的名字,這樣在其他地方可以通過名字來引用這個路徑
                android:pathData 和 SVG 中 d 元素一樣的路徑信息
                android:fillColor 定義填充路徑的顏色,如果沒有定義則不填充路徑
                android:strokeWidth 定義路徑邊框的粗細尺寸
                android:strokeAlpha 定義路徑邊框的透明度
                android:fillAlpha 定義填充路徑顏色的透明度
                android:trimPathStart 從路徑起始位置(path 的 M 位置)截取後剩下的內容,取值範圍從 0 到 1,比如,取值是 0.3 則截取後的內容就是 原長度 - (原長度*0.3) 
                android:trimPathEnd 從路徑起始位置位置截取的內容,取值範圍從 0 到 1,比如,取值是 0.3,則截取後的內容就是 原長度*0.3  
                需要註意的是如果 trimPathStart 和 strimPathEnd 一塊使用的話,這裡有個規律如果 trimPathEnd 取值大於等於 trimPathStart 的時候結果就是他們兩者分別截取後內容的交集,如果 trimPathEnd 小於 trimPathStart 的時候,取值就是他們倆的合集(這是經過我無數的實驗得出的規律,你也可以嘗試一下)
                android:trimPathOffset 其實就是設置開始點的偏移位置(取值 從 0 到 1)1 的話就是開始點和結束的互換了,註意這個路徑是可以迴圈的(下麵畫圖說明)
                android:strokeLineCap 設置路徑的線頭的形狀,取值為 butt,round,square 預設是 butt
                android:strokeLineJoin 設置路徑交界處的連接方式,取值為 miter、round、bevel 預設是 miter
                android:strokeMiterLimit 設置斜角的上界 預設是 4 (當 strokeLineJoin 設置為 "miter" 的時候,繪製兩條線段以銳角相交的時候,所得的斜面可能相當長,當斜面太長,就會變的不協調。strokeMiterLimit 屬性為斜面的長度設置了一個上限。這個屬性表示斜面長度和線條長度的比值。當 strokeLineJoin 設置為其他屬性時,這個屬性是無效的)
               
        </path>
        
        vector 還支持 clip-path 元素,定義當前繪製的剪切路徑。註意:clip-path 只對當前的 group 和子 group 有效。需要 API 大於等於 21
                
                
                
                
               
    
    
    
    </grup>

</vector>

offset說明.png

矢量動畫

利用 XML 文件來設置矢量動畫

  1. 創建一個矢量圖

    <?xml version="1.0" encoding="utf-8"?>
    <vector xmlns:android="http://schemas.android.com/apk/res/android"
            android:width="200dp"
            android:height="200dp"
            android:viewportWidth="100"
            android:viewportHeight="100">
        <group android:name="head_eyes">
            <path
                android:fillColor="@color/colorPrimary"
                android:name="head"
                android:pathData=" M50,50 A15,15,0,1,1 50,51Z"
                android:strokeWidth="2"
                android:strokeColor="@color/colorPrimary"/>
            <group android:name="eyes">
                <path android:fillColor="@android:color/white"
                      android:name="eye_left"
                      android:pathData="M55,40A2,2,0,1,1,55,41"/>
                <path android:fillColor="@android:color/white"
                      android:name="eye_right"
                      android:pathData="M69,40A2,2,0,1,1,69,41"/>
            </group>
    
            <path android:fillColor="@color/colorAccent"
                android:pathData="M60,55L55,60H65Z"/>
    
        </group>
    </vector>

head.png

哈哈,樣子太醜了,大家就湊合著看把。

  1. 在 drawble 創建矢量動畫

    目的就是將我們的矢量圖和 objectAnimator 關聯起來

    <?xml version="1.0" encoding="utf-8"?>
    <animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
        // 對應動畫文件
        android:drawable="@drawable/vector_simple">
        <target
            android:animation="@animator/head"
            // 這裡的名字對應你的矢量圖中想要產生動畫的 path 或者 group 或者 clip-path 的名字
            android:name="head_eyes"/>
    
    </animated-vector>
    
  2. 在 animator 中創建動畫

    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android">
        <objectAnimator
            android:duration="200"
            android:propertyName="translateY"
            android:repeatCount="infinite"
            android:repeatMode="reverse"
            android:valueFrom="0"
            android:valueTo="20"
            android:valueType="floatType"/>
    </set>
  3. 佈局文件中添加圖片

    <ImageView
            android:id="@+id/iv_android"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/animated_head"
            android:contentDescription="@string/app_name"/>
  4. 在程式中啟動動畫

    Drawable drawable =  ivAndroid.getDrawable();
    ((Animatable)drawable).start();

效果圖
效果圖.gif

在 objectAnimator 的 propertyName 中有兩個很重要的屬性值,trimPathEndtrimPathStart 表示截取,和前面介紹的 path 裡面的類似,利用這個可以繪製 vectordrawble。註意如果動畫使用這個兩個屬性值的話,animated-vector 中 target 對應的 name 必須是 path 類型不能是 group 效果圖:

trimPathStart.gif

SVG 圖片轉成 vectordrawble

利用我們 Android Studio 提供的工具就可以將 SVG 格式的圖片直接轉成我們的 vectordrawble 了。

svgtovector.png

選擇圖片.png

歡迎大家關註我的微信公眾號,和我交流分享


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 完成這個要求之前,可以先參考另外一個函數《獲取當月的天數列表》https://www.cnblogs.com/insus/p/10837900.html: 然後要知道標題三個節日的常識,母親節在每年5月份的第二個星期天,父親節在每年6月份的第三個星期天,而感恩節是在每年的11月份第四個星期的星期四。 ...
  • 將數據表的某一列值,轉換為逗號分隔字元串: 先準備一些數據: DECLARE @t AS TABLE([Datas] NVARCHAR(40)) INSERT INTO @t ([Datas]) VALUES(N'DF'),(N'W4F'),(N'EYY'),(N'ER'),(N'GFF'),(N' ...
  • 比如: DECLARE @t AS TABLE([Datas] NVARCHAR(40)) INSERT INTO @t ([Datas]) VALUES(N'DF'),(N'W4F'),(N'EYY'),(N'ER'),(N'GFF'),(N'A445') SELECT [Datas] FROM ...
  • 1、創建表時數據預設值的設置:(預設值可以為NULL) 2、數據的非空限制: 3、數據的唯一性的設置:(可以插入多個NULL,不是重覆,是都沒有值) 4、主鍵:(非空+唯一) 5、自增長(必須是int類型,而且是主鍵) 6、外鍵約束(減少冗餘):(正常欄位1與欄位5名一樣,如一個為部門表,一個為員工 ...
  • SQL(Structred Query Language)結構化查詢語言:和資料庫交互的語言,進行資料庫管理的語言。 一、資料庫的操作: 1、查詢所有資料庫: show databases; 2、創建資料庫: create database 資料庫名 [default] character set ...
  • 一、序言 1、MySQL簡介 本機安裝的是MySQL5.7資料庫,採用離線安裝的方式,筆者打算把資料庫學懂後再升級為8.0版本的。MySQL其實是一個數據管理系統(DataBase Managment System, DBSM),既包括數據的存儲,又具有有數據的管理功能。MySQL5.7預設的引擎是 ...
  • 今天是母親節,它是在每一年的五月份的第二個星期天,而父親節,是在每一個的六月份的第三個星期天。 把星期天設置為每周的開始,將一周的第一天設置為從 1 到 7 的一個數字。 參考MSDN:https://docs.microsoft.com/zh-cn/sql/t-sql/statements/set ...
  • 文章大綱 一、基礎知識學習二、Redis常見的幾種架構及優缺點總結三、Redis之Redis Sentinel(哨兵)實戰四、Redis之Redis Cluster(分散式集群)實戰五、Java之Jedis連接Redis(Redis Cluster版本)六、Redis之雲平臺介紹七、項目源碼與資料下 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...