基本概念介紹
XML 命名空間提供避免元素命名沖突的方法跨嘉。
打個(gè)比方,A學(xué)校有名學(xué)生叫做林小明,B學(xué)校也有名學(xué)生叫林小明,那我們?nèi)绾巫R(shí)別這兩名擁有相同名字的同學(xué)呢?這時(shí)候命名空間就派上用場(chǎng)了歧譬。A和B此時(shí)就可以被當(dāng)成是命名空間了。也就是說(shuō)泼返,命名空間里面存放的是特定屬性的集合,
下面分別介紹android、tools宝恶、app(自定義命名空間)這幾個(gè)常見(jiàn)的命名空間
xmlns:android=”http://schemas.android.com/apk/res/android”?
在Android布局文件中我們都必須在根元素上定義這樣一個(gè)命名空間,接下來(lái)對(duì)這行代碼進(jìn)行逐一講解:?
xmlns:即xml namespace,聲明我們要開(kāi)始定義一個(gè)命名空間了?
android:稱作namespace-prefix垫毙,它是命名空間的名字?
http://schemas.android.com/apk/res/android:這看起來(lái)是一個(gè)URL霹疫,但是這個(gè)地址是不可訪問(wèn)的。實(shí)際上這是一個(gè)URI(統(tǒng)一資源標(biāo)識(shí)符),所以它的值是固定不變的,相當(dāng)于一個(gè)常量)综芥。
有了他丽蝎,就會(huì)提示你輸入什么,也可以理解為語(yǔ)法文件膀藐。
使用這行代碼屠阻,我們就可以引用命名空間中的屬性,如:
在這個(gè)布局中,只要以android:開(kāi)頭的屬性便是引用了命名空間中的屬性,
android是賦予命名空間一個(gè)名字,就跟我們平時(shí)在定義變量一樣,比如我把它取成myns,那么上面的代碼我們也可以寫(xiě)成:
xmlns:tools=”http://schemas.android.com/tools”
接下來(lái)會(huì)介紹国觉,關(guān)于tools的三種使用方法吧,也算是他的特性虾啦。
我們可以把他理解為一個(gè)工具(tools)的命名空間,它的只作用于開(kāi)發(fā)階段,當(dāng)app被打包時(shí),所有關(guān)于tools屬性將都會(huì)被摒棄掉!
例如,基本上在android命名空間內(nèi)的屬性,我們想在編寫(xiě)代碼階段測(cè)試某個(gè)組件在屏幕上的效果,而當(dāng)app安裝到手機(jī)上時(shí)傲醉,摒棄掉這條代碼,那么我們就可以用tools命名空間來(lái)代替掉android:
以上是在layout中的布局,當(dāng)我們切換到視圖窗口(Design)中查看時(shí),看到的是標(biāo)簽頂部居中顯示:
然后,當(dāng)我們運(yùn)行到手機(jī)上時(shí),確是這樣的:
如上所示,tools:layoutgravity= “center”確實(shí)在運(yùn)行后背拋棄掉了!
2.2蝇闭、tools:context開(kāi)發(fā)中查看Activity布局效果
context的用法,在后面跟一個(gè)Activtiy的完整包名,它有什么作用呢?
當(dāng)我們?cè)O(shè)置一個(gè)Activity主題時(shí),是在AndroidManifest.xml中設(shè)置中,而主題的效果又只能在運(yùn)行后在Activtiy中顯示
使用context屬性, 可以在開(kāi)發(fā)階段中看到設(shè)置在Activity中的主題效果
tools:context=”com.littlehan.myapplication.MainActivity”
在布局中加入這行代碼,就可以在design視圖中看到與MainActivity綁定主題的效果硬毕。
2.3呻引、tools:layout開(kāi)發(fā)中查看fragment布局效果
當(dāng)我們?cè)贏ctivity上加載一個(gè)fragment時(shí),是需要在運(yùn)行后才可以看到加載后的效果,有沒(méi)有方法在測(cè)試階段就在布局預(yù)覽窗口上顯示呢?
答案是有的,借助layout屬性,例如,在布局中加入這樣一行代碼:?
tools:layout=@layout/yourfragmentlayoutname?
這樣你的編寫(xiě)的fragment布局就會(huì)預(yù)覽在指定主布局上了
如果使用DataBinding 會(huì)在xml用到 app屬性逻悠,其實(shí)這是個(gè)自定義命名空間。
xmlns:app=”http://schemas.android.com/apk/res-auto”
有朋友可能會(huì)問(wèn)了韭脊,這里哪里體現(xiàn)出是自定義的蹂风??
實(shí)際上也可以這么寫(xiě):?
xmlns:app=”http://schemas.android.com/apk/res/完整的包名”?
在res/后面填寫(xiě)包名即可乾蓬。但是惠啄,在Android Studio2.0上,是不推薦這么寫(xiě)的任内,所以建議大家還是用第一種的命名方法撵渡。
通常自定義命名空間往往是和自定義View分不開(kāi)的,當(dāng)Android自帶的控件不能滿足需求時(shí)死嗦,可以自己去繪制一些View趋距,而要為自定義View加上自定義的屬性時(shí),就需要?jiǎng)?chuàng)建自定義命名空間越除。
命名空間里面存放的是特定屬性的集合节腐,這樣一來(lái)外盯,思路就很清晰,也就是說(shuō)自定義命名空間的實(shí)際過(guò)程就是自定義屬性。
我們通過(guò)一個(gè)簡(jiǎn)單的自定義TextView來(lái)學(xué)習(xí)下自定義命名空間是怎么一回事翼雀,自定義View的過(guò)程可以分成以下幾個(gè)步驟:
創(chuàng)建一個(gè)類名為CustomTextView繼承View(View是所有視圖的父類)并實(shí)現(xiàn)它三個(gè)構(gòu)造方法
publicclassCustomTextViewextendsView{privatePaint mPaint =newPaint(Paint.ANTI_ALIAS_FLAG);//畫(huà)筆publicCustomTextView(Context context) {super(context);? ? }publicCustomTextView(Context context, AttributeSet attrs){this(context, attrs,0);//注意不是super(context,attrs,0);}publicCustomTextView(Context context, AttributeSet attrs,intdefStyleAttr){super(context,attrs,defStyleAttr);? ? }@OverrideprotectedvoidonDraw(Canvas canvas) {super.onDraw(canvas);? ? ? ? canvas.drawText("I am a CustomTextView",100,100, mPaint);? ? }}
將自定義的控件引入布局
到了這里狼渊,一個(gè)自定義的控件就被引入布局使用了箱熬,我們可以切換到視圖窗口看看效果
但是這個(gè)自定義控件,并不能在xml中去改變字體顏色狈邑,字體大小城须、自定義文本等。這個(gè)功能的實(shí)現(xiàn)米苹,需要XML創(chuàng)建自定義屬性和在自定義View中解析屬性
在values根目錄下新建一個(gè)名為attrs的xml文件來(lái)自定義屬性(自定義的屬性便是自定義命名空間里面的屬性)
name定義的是屬性的名字?
format定義的是屬性的類型
自定義屬性也可以不使用declare-styleable,參考這里
在CustomeTextView中解析這些屬性
publicclassCustomTextViewextendsView{privateintmColor = Color.RED;//默認(rèn)為紅色privateString mText="I am a Custom TextView";//默認(rèn)顯示該文本privatePaint mPaint =newPaint(Paint.ANTI_ALIAS_FLAG);//畫(huà)筆publicCustomTextView(Context context) {super(context);//? ? ? ? init();}publicCustomTextView(Context context, AttributeSet attrs){this(context, attrs,0);//注意不是super(context,attrs,0);init();? ? }publicCustomTextView(Context context, AttributeSet attrs,intdefStyleAttr){//解析自定義屬性super(context,attrs,defStyleAttr);? ? ? ? TypedArray typedArray = context.obtainStyledAttributes(attrs,R.styleable.CustomTextView);? ? ? ? mColor = typedArray.getColor(R.styleable.CustomTextView_customColor, Color.RED);//? ? ? ? 如果沒(méi)有判斷赤炒,當(dāng)沒(méi)有指定該屬性而去加載該屬性app便會(huì)崩潰掉if(typedArray.getText(R.styleable.CustomTextView_customText) !=null){? ? ? ? ? ? mText = typedArray.getText(R.styleable.CustomTextView_customText).toString();? ? ? ? }? ? ? ? typedArray.recycle();//釋放資源init();? ? }privatevoidinit(){? ? ? ? mPaint.setColor(mColor);// 為畫(huà)筆添加顏色}@OverrideprotectedvoidonDraw(Canvas canvas) {super.onDraw(canvas);? ? ? ? canvas.drawText(mText,100,100, mPaint);? ? }}
要使用自定義屬性亏较,就需要自定義屬性命名空間莺褒,在布局文件的根元素下插入這樣一行代碼:?
xmlns:app=”http://schemas.android.com/apk/res-auto”
于是就可以使用自定義屬性了:
切換到視圖預(yù)覽窗口,可以看到自定義的屬性已經(jīng)生效了:
在Android中雪情,命名空間可分為3種:
xmlns:android=”http://schemas.android.com/apk/res/android”
xmlns:tools=”http://schemas.android.com/tools”
xmlns:app=”http://schemas.android.com/apk/res-auto”
其中遵岩,1和2命名空間里的屬性是系統(tǒng)封裝好的,第3種命名空間里的屬性是用戶自定義的