1. <div id="f8mbs"></div>
        您好,歡迎來到源碼搜藏網!分享精神,快樂你我!
        [加入VIP] 設為首頁 | 收藏本站 | 網站地圖 | Sitemap | TAG標簽
      2. 首 頁
      3. 在線工具
      4. jquery手冊
      5. 當前位置:首頁 > 安卓源碼 > 技術博客 >

        使用Java和XML為Android創建自己的控件

        時間:2018-08-08 23:24 來源:互聯網 作者:源碼搜藏 瀏覽:收藏 挑錯 推薦 打印

        介紹 在Android中,我們有很多方法將布局分組在一起,使它們可以重復使用。 在我們的XML設計中 有一個 include Tag(以及鮮為人知的 merge ),它只包含當前版本中的另一個布局 Fragments ,當然,我們可以隨時從任何基類派生出來,比如 View 或 LinearLayou

        介紹

        在Android中,我們有很多方法將布局“分組”在一起,使它們可以重復使用。在我們的XML設計中有一個<include>Tag(以及鮮為人知的<merge>),它只包含當前版本中的另一個布局Fragments,當然,我們可以隨時從任何基類派生出來,比如ViewLinearLayout

        本文將深入探討后者:

        • 如何編寫一個擴展自己布局的控件?
        • 如何為我的控件創建自定義屬性?
        • 這些都與風格和主題混合在一起怎么樣?

        本文的范圍是擴展自己的布局的控件,因此我們將從匹配的基類(a LinearLayout或a)派生RelativeLayout,具體取決于我們的自定義布局的構建方式。

        我將在這里使用我自己的一個控件作為示例,向您展示它是如何完成的。這個控件是一個簡單的工具欄,有四個按鈕,支持我的軟件標簽的一些標準功能,比如給我發電子郵件,打開我的G +頁面,在Google Play上打開我的開發者頁面以及評價當前正在運行的應用程序。

        它非常簡單,因此在文章中進行分析是一個很好的選擇。

        在運行時,我的控件如下所示:

        使用Java和XML為Android創建自己的控件

        這是從我的一個使用黑暗主題的應用程序的屏幕截圖中獲取的。

        XML設計中的聲明:

        <mbar.ui.controls.MbarBar
        
           android:id="@+id/contact_mbar_button_frame"
        
           android:layout_width="wrap_content"
        
           android:layout_height="wrap_content"
        
           android:layout_below="@+id/contact_mbar_credit_text"
        
           android:layout_centerHorizontal="true"
        
           android:layout_marginTop="@dimen/mbar_default_control_distance"
        
           mbar:barSize="small"/>

        可能有不同的方法來實現這一目標:

        • 只是<include>從庫中預先繪制的布局,并在代碼中分配按鈕偵聽器
        • 在每個應用程序中手工繪制它(只是開個玩笑......甚至不考慮這個!:))
        • 創建一個控件并按上面顯示的方式執行

        當然,我們將采用本文中的第三種方法。您可以在此XML代碼段中看到的是控件至少使用一個自定義屬性:barSize它是一個enum類型屬性,知道值“ small”(0)和“ large”(1)。我們將很快創建它,以及第二個自定義屬性showTitle,一個簡單的布爾值。

        我們假設您的庫/項目是使用minAPI 17設置的

        第1步:創建您的控件類

        最好的事情是:創建你的類并決定你的基類是什么。在我們的例子中,這很簡單LinearLayout

        你需要知道什么

        有幾個構造函數可用,并不是所有構造函數都需要提供,但我總是試圖盡可能完全覆蓋基類。

        所以,當你開始上課時extends LinearLayout,有4個構造函數可用:

        public class MbarBar extends LinearLayout {
           private @MbarBarSize int barSize = MbarBarSize.SMALL;
           private boolean showTitle = true;
           
           // <editor-fold desc="Constructors">
           public MbarBar(Context context) {
              super(context);
              init(null, 0, 0);
           }
           
           public MbarBar(Context context, @Nullable AttributeSet attrs) {
              super(context, attrs);
              init(attrs, 0, 0);
           }
           
           public MbarBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
              super(context, attrs, defStyleAttr);
              init(attrs, defStyleAttr, 0);
           }
           
           @TargetApi(21)
           public MbarBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
              super(context, attrs, defStyleAttr, defStyleRes);
              init(attrs, defStyleAttr, defStyleRes);
           }
           // </editor-fold>

        你可以看到,我將它們全部重定向到一個init(...)方法。我們將稍后介紹一下,讓我們現在專注于構造函數。

        @TargetApi(21)第4 構造函數周圍有一個注釋,因為這個注釋只能在21+以上。

        系統提供給構造函數的值是多少?

        第一條規則:將它們傳遞給超級班級,除非你有充分的理由,不要這樣做!

        第二:對于我們的開發人員,第二個參數AttributeSet是最感興趣的,因為這個參數包含來自XML的指定屬性,包括我們的自定義屬性 barSizeshowTitle所以這已經揭開了第一個謎團:我們如何從XML獲取值到我們的控制?答案是:通過AttributeSet當我們討論該init(...)方法時,我們如何從中獲取我們的價值

        將xml-enum值映射到代碼值

        @interfaces非常喜歡那些,所以我創造了一個barSize如果您不知道它是什么:它或多或少是將整數或字符串組合在一起的另一種方法。Android SDK在很多方面做到了這一點,而且你遇到過它們。就像一個簡單的例子:每當你設置某些東西時,View.VISIBLE或者View.GONE你正在接觸其中一個。

        在課程的頂部,您會看到聲明:

        private @MbarBarSize int barSize = MbarBarSize.SMALL;
        

        這與XML設計中的這一行相關:

        mbar:barSize="small"

        稍后我們討論這個自定義屬性的聲明時,您會看到術語“ small”和“ large”代表值“ 0”和“ 1”。現在,我們當然希望用相同的名稱(SMALL和LARGE處理Java中的這些值,我們不想使用01

        那么這是什么@MbarBarSize以及它做了什么?@annotation講述這個int變量只能存放在定義的值@MbarBarSize如果您嘗試分配其他內容,則會收到lint警告。

        要為成員宣布此類限制,會發布@interface聲明。MbarBarSize定義為:

        @Retention(RetentionPolicy.CLASS)
        public @interface MbarBarSize {
           int SMALL = 0;
           int LARGE = 1;
        }

        通過這樣的聲明,您可以分配我稱之為value-restrictionvalue-constraint通常允許其他值的數據類型。

        的RetentionPolicy

        了解何時使用哪個策略非常重要。有三種政策可供選擇:

        • CLASS :(默認值)。這個策略可以在任何地方使用,但我主要在庫中使用它。Class意味著,這@interface將在編譯后繼續存在,并且仍可供您的庫用戶使用。他們可以使用這些值SMALLLARGE就像他們在自己的app / lib中定義它們一樣。這就是你想要的,如果你需要它作為方法參數和你想要的話,lint可以警告lib的用戶,如果他們分配了一個不允許的值。庫中,您希望您的值與其給定名稱一起使用。您不希望強制庫的用戶將“ 0”和“ 1”作為參數值提供給您的方法。他們也應該使用SMALLLARGE
        • SOURCE:此策略告訴編譯器放棄該定義。對于人類思維,這意味著:當您定義@interface不需要在編譯過程中存活時,可以使用SOURCE策略舉個例子:在你的應用程序,沒事的時候你的應用程序之外,需要與他們的指定名稱(以訪問值SMALLLARGE在上面的例子)。外當前項目的,SMALLLARGE未知的用戶必須提供“ 0”和“ 1”作為參數值。這不是您想要的public接口和方法,但您可以將它用于private庫中的內容。
        • RUNTIME:這是所有人中最寬泛的政策。它不僅可以在編譯過程中存在并且可供您的用戶使用,甚至可以在程序運行時使用,并且可以通過反射訪問!除此之外,它的行為類似于CLASS

        第2步:定義自定義屬性

        好的,我們已經看到,我們如何將屬性值映射到我們的Java代碼,但該屬性是如何定義的

        您可以通過將名為attrs.xml的文件添加項目的values文件夾創建自定義屬性右鍵單擊values項目資源管理器中節點,然后選擇“ 新建” - >“ 值資源文件”將文件命名為attrs.xml

        使用Java和XML為Android創建自己的控件

        在此文件中,您可以創建自定義屬性。語法并不令人驚訝且易于理解。我在這里向您展示MbarBar控件的完整屬性集

        <declare-styleable name="MbarBar">
           <attr name="barSize" format="enum">
              <enum name="small" value="0"/>
              <enum name="large" value="1"/>
           </attr>
           <attr name="showTitle" format="boolean"/>
        </declare-styleable>

        styleable在此處聲明了一個資源,這將使XML設計器可以使用它。

        有幾種格式可供選擇,這篇文章的范圍太遠,無法在這里覆蓋它們,但enum格式是最有趣的格式之一,我們將看一下:

        • 最重要的是:<declare-styleable name="class_name_of_your_control">你可能不會name在這里自由選擇“ ”屬性!這已經是你的控件類的連接(以及我們在第一步創建類的原因以及之后的屬性)!我們的控件被命名MbarBar,這是這個確切的控件/類名。使用此單行,您此樣式中聲明的所有內容都將附加到MbarBar該類。

        然后,聲明了兩個自定義屬性:

        • 定義為format="enum",然后我們可以添加<enum value我們喜歡的任意數量的列表我們給他們一個名字和一個價值。你看,“ 0”和“ 1”在這里對應于01我們的整數表示的@interface控件的用戶可以在XML布局中將值指定為“ small”和“ large”。
        • 定義為format="boolean"我們添加一個簡單的開關來顯示/隱藏標題文本“ More mbar Software”以進一步定制到控件中。

        第3步:將各個部分組合在一起:init(...)方法

        因此,現在您已經定義了自定義屬性,您已經了解了它在XML布局中的外觀,讓我們將它們放在一起并查看AttributeSet以獲取開發人員在XML中輸入的值。

        方法首先,后來說明:

        private void init(@Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
           if (attrs != null) {
              TypedArray array = getContext().getTheme().obtainStyledAttributes
                                 (attrs, R.styleable.MbarBar, defStyleAttr, defStyleRes);
              barSize = array.getInt(R.styleable.MbarBar_barSize, 0);
              showTitle = array.getBoolean(R.styleable.MbarBar_showTitle, true);
           }
           
           switch (barSize) {
              case MbarBarSize.SMALL:
                 View smallMe = inflate(getContext(), R.layout.mbar_button_frame_small, this);
                 break;
              case MbarBarSize.LARGE:
                 View largeMe = inflate(getContext(), R.layout.mbar_button_frame, this);
                 break;
           }
           
           setTitleBarVisibility();
           connectListeners();
        }

        其中一個構造函數(第一個)將null作為attrs值發送給此方法,因此我們需要null-check。在這種情況下,控件將在默認情況下使用所有值:barSize=SMALLshowTitle=true(參見本文中的第一個代碼塊 - 構造函數,這是類成員的設置方式)。

        這里最重要的部分是從XML獲取屬性。這是通過該方法完成的,該方法obtainStyledAttributes與我們當前的主題相關聯context正如我們所得到的LinearLayout,我們有一個getContext()可用方法,所以我們不需要參數或其他方法來獲得有效的上下文。我們已經有一個。

        參數是:

        • attrs這是AttributeSet我們想要獲得價值的地方。它是構造函數中提供的那個。
        • R.styleable.MbarBar我相信,現在你知道那是什么了。我們在attrs.xml中定義的自定義屬性我們希望得到這些價值。
        • defStyleAttrRes一切都是主題和風格。Android將應用當前主題和樣式的任何修改,并考慮我們將獲得的值。

        這個電話后,我們可以為我們將訪問同樣簡單的方式訪問我們的屬性ExtrasBundle隨著getIntgetBoolgetWhatYouNeed非常簡單的界面。這些調用中的第二個參數是default-if-not-found。

        接下來,有一個switch 聲明,膨脹兩個預定義布局之一(小和大按鈕框架)。這些布局沒有什么特別之處,它們也被設計為任何其他布局。只是一堆圖像和文本視圖。標準。您可以像充氣的任何其他布局一樣給它充氣。

        然后調用一些其他支持方法,如隱藏標題欄和連接單擊偵聽器,但它們不是本文的范圍。我們想用自定義屬性創建自定義控件:)。

        很酷的事:這在設計時已經可見了!如果您打開了預覽窗口,則在布局時看到設計已膨脹!

        如果您更改XML設計器中的任何自定義屬性(例如設置“ showTitle”到“ false”),它會立即反映在布局中,如您所料。

        使用Java和XML為Android創建自己的控件

        我們創造了什么

        • 我們定義了一個派生自的新控件類 LinearLayout
        • 我們在可設置樣式的資源中創建了兩個自定義屬性
        • 我們創建了一個在同一代碼中@interface反映自定義屬性enum值的方法
        • 我們已經通過Java訪問了Java代碼中的自定義屬性 AttributeSet
        • 我們在控件中夸大了自定義布局

        最后一件事

        當您第一次使用自定義控件時,不要感到困惑,在鍵入自定義屬性的名稱時,您在XML中沒有智能感知!

        您需要知道在android:命名空間中找不到屬性,也不在app:命名空間中找不到屬性您將為此添加您喜歡的任何命名空間名稱(如果是此控件,您可以在我使用的頂部XML中看到mbar:)。

        當您開始鍵入新的命名空間名稱時,Android Studio會讓您插入...

        xmlns:mbar="http://schemas.android.com/apk/res-auto"

        ...使用Alt + Enter。接受(=按Alt + Enter)。然后您的自定義屬性可用此前綴。

        所以...我們在這里!

        我希望這篇文章可以幫助您完成自定義控件的第一步,并使該部分失去神秘感。

        歡迎評論一如既往,我會盡力回答任何問題!

        使用Java和XML為Android創建自己的控件轉載http://www.rhcg.tw/appboke/38809.html
        辽宁十一选五单双