您好,登錄后才能下訂單哦!
這篇文章主要介紹了Kotlin中Anko庫(kù)怎么用,具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
正文
開(kāi)始做安卓UI開(kāi)發(fā)一直是使用XML文件來(lái)實(shí)現(xiàn)。雖然理論上,UI可以使用Java語(yǔ)言來(lái)實(shí)現(xiàn),但并沒(méi)有太多的用處。不久前,JetBrains推出了Kotlin,一種面向JVM的現(xiàn)代語(yǔ)言,可以很好的實(shí)現(xiàn)安卓UI。
Jetbrains宣稱(chēng)Anko是Android中更快,更輕松的開(kāi)發(fā)風(fēng)格。Kotlin提供Anko庫(kù)來(lái)作為DSL(領(lǐng)域?qū)S谜Z(yǔ)言)去設(shè)計(jì)安卓界面,一個(gè)簡(jiǎn)單的例子:
下面的界面由一個(gè)圖片和一個(gè)按鈕組成:
使用Anko實(shí)現(xiàn)如下:
verticalLayout{ imageView(R.drawable.anko_logo). lparams(width= matchParent) { padding = dip(20) margin = dip(15) } button("Tap to Like") { onClick { toast("Thanks for the love!") } } }
我們定義了一個(gè)垂直的線性布局作為容器包含圖片和按鈕,使用lparams定義了布局的位置信息,由Kotlin的內(nèi)聯(lián)函數(shù)也實(shí)現(xiàn)了按鈕的點(diǎn)擊事件。
使用Anko的優(yōu)點(diǎn):
我們可以將UI布局嵌入到代碼中,從而使其類(lèi)型安全。
由于我們不用XML編寫(xiě),所以它增加了效率,因?yàn)樵诜治鯴ML浪費(fèi)CPU時(shí)間。
在UI的程序化轉(zhuǎn)換之后,我們可以將Anko DSL片段放入一個(gè)函數(shù)中。這樣便于代碼重用。
顯然,代碼更簡(jiǎn)潔,可讀和可掌握性更高。
現(xiàn)在我們使用Anko Layout和Kotlin構(gòu)建一個(gè)to-do app,來(lái)列出我們今天需要做的事。
你可以在GitHub上找到這個(gè)項(xiàng)目 to-do app
將Anko庫(kù)添加到Android Studio:
在streamline-android-java-code-with-kotlin去學(xué)習(xí)如何添加Kotlin到你的安卓項(xiàng)目中,有了Kotlin,我們需要添加Anko依賴(lài)在app/build.gradle中,這樣我們就可以順利編譯項(xiàng)目了。
compile [size=1em]'org.jetbrains.anko:anko-sdk15:0.8.3' // sdk19,21,23 也可以使用
可以根據(jù)你項(xiàng)目的minSdkVersion來(lái)添加這個(gè)依賴(lài),上面的例子說(shuō)明15<=minSdkVersion<19,你可以在Anko的GitHub庫(kù)中找到自己需要的其他Anko依賴(lài)庫(kù)。
我們準(zhǔn)備使用下面的依賴(lài)庫(kù):
compile 'org.jetbrains.anko:anko-design:0.8.3' compile 'org.jetbrains.anko:anko-appcompat-v7:0.8.3'
在Activity中調(diào)用Anko布局:
我們不再使用XML來(lái)寫(xiě)布局文件,所以我們不需要XML View,所以也不需要findViewById()方法了。這里我們假設(shè)我們的Anko布局類(lèi)為MainUI,然后我們可以開(kāi)始寫(xiě)我們的activit內(nèi)容:
var ui =MainUI() //MainUI類(lèi)代替了XML布局 ui.setContentView(this) //this代表Activity類(lèi)
現(xiàn)在我們創(chuàng)建一個(gè)Kotlin文件MainActivity.kt,寫(xiě)上如下代碼:
class MainActivity : AppCompatActivity() { val task_list = ArrayList<String>() //任務(wù)清單表 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) savedInstanceState?.let { val arrayList = savedInstanceState.get("ToDoList") task_list.addAll(arrayList as List<String>) } var adapter=TodoAdapter(task_list) //定義適配器 var ui = MainUI(adapter) //定義將要使用的Anko UI 布局 ui.setContentView(this) //給Activity設(shè)置Anko布局 } override fun onSaveInstanceState(outState: Bundle?) { outState?.putStringArrayList("ToDoList", task_list) super.onSaveInstanceState(outState) } }
task_list是ArrayList,將填充ListView的TodoAdapter。MainUI(adapter)是我們的Anko UI文件,它采用TodoAdapter類(lèi)作為適配器參數(shù)。所以,接下來(lái)我們?cè)賱?chuàng)建一個(gè)TodoAdapter類(lèi)。
用于ListView的TodoAdapter適配器
TodoAdapter類(lèi)有一個(gè)ArrayList<String>類(lèi)型的list,并且繼承了BaseAdapter。所以我們需要重寫(xiě)一下四個(gè)方法:
public int getCount()public Object getItem(int i)public long getItemId(int i)public View getView(int i, View view, ViewGroup viewGroup)
在getView()方法中我們需要使用Anko設(shè)計(jì)一個(gè)表元素的布局。
public int getCount()public Object getItem(int i)public long getItemId(int i)public View getView(int i, View view, ViewGroup viewGroup) 在getView()方法中我們需要使用Anko設(shè)計(jì)一個(gè)表元素的布局。 override fun getView(i : Int, v : View?, parent : ViewGroup?) : View { return with(parent!!.context) { //任務(wù)數(shù)從1開(kāi)始 var taskNum: Int = i +1 //清單表元素布局 linearLayout { lparams(width = matchParent, height = wrapContent) padding = dip(10) orientation = HORIZONTAL //任務(wù)號(hào) textView { id = R.id.taskNum text=""+taskNum textSize = 16f typeface = Typeface.MONOSPACE padding =dip(5) } //任務(wù)名 textView { id = R.id.taskName text=list.get(i) textSize = 16f typeface = DEFAULT_BOLD padding =dip(5) } } } }
在這個(gè)方法中,我們返回一個(gè)包含一個(gè)horizontalListView布局列表項(xiàng)的視圖。這是使用Kotlin的with語(yǔ)法完成的,它允許我們一次在對(duì)象實(shí)例上調(diào)用很多方法。
每個(gè)列表項(xiàng)包含兩個(gè)textview用于顯示任務(wù)號(hào)和任務(wù)名稱(chēng)。
linearLayout,textView是擴(kuò)展功能。擴(kuò)展功能使我們有能力啟用具有新功能的任何類(lèi)。
text,textSize,typeface在android.widget.TextView有g(shù)etter和setter方法,padding是Anko添加的屬性。
繼續(xù)下一步,我們需要定義列表的操作功能。因此,我們需要在TodoAdapter中定義add(String)和delete(Int)方法。add(String)將任務(wù)名稱(chēng)作為參數(shù)添加到任務(wù)中。delete(Int)將任務(wù)所在的位置作為參數(shù)來(lái)刪除任務(wù)。下面是具體的實(shí)現(xiàn):
//將任務(wù)添加到任務(wù)清單的方法 fun add(text: String) { list.add(list.size, text) notifyDataSetChanged() //更新數(shù)據(jù) } //將任務(wù)從任務(wù)清單中移除的方法 fun delete(i:Int) { list.removeAt(i) notifyDataSetChanged() //更新數(shù)據(jù) }
所以,現(xiàn)在我們?cè)O(shè)計(jì)了列表,我們也可以添加和刪除項(xiàng)目到我們的列表中。接下來(lái)完成此適配器類(lèi)的代碼。
TodoAdapter(val list: ArrayList<String> = ArrayList<String>()) : BaseAdapter() { override fun getView(i : Int, v : View?, parent : ViewGroup?) : View { return with(parent!!.context) { //taskNum will serve as the S.No. of the list starting from 1 var taskNum: Int = i +1 //Layout for a list view item linearLayout { id = R.id.listItemContainer lparams(width = matchParent, height = wrapContent) padding = dip(10) orientation = HORIZONTAL textView { id = R.id.taskNum text=""+taskNum textSize = 16f typeface = Typeface.MONOSPACE padding =dip(5) } textView { id = R.id.taskName text=list.get(i) textSize = 16f typeface = DEFAULT_BOLD padding =dip(5) } } } } override fun getItem(position : Int) : String { return list[position } override fun getCount() : Int { return list.size } override fun getItemId(position : Int) : Long { //can be used to return the item's ID column of table eturn 0L } //function to add an item to the list fun add(text: String) { list.add(list.size, text) notifyDataSetChanged() } //function to delete an item from list fun delete(i:Int) { list.removeAt(i) notifyDataSetChanged() } }
注意,使用Anko DSL類(lèi)中必須要導(dǎo)入org.jetbrains.anko.*。
設(shè)計(jì)項(xiàng)目的外觀
Anko為我們提供了在單獨(dú)的Kotlin類(lèi)中為Activity使用UI的便利。因此,每個(gè)屏幕都可以被認(rèn)為是Kotlin類(lèi)的UI-Activity匹配對(duì)。這個(gè)UI類(lèi)是通過(guò)繼承在org.jetbrains.anko包中定義的AnkoComponent<T>接口的功能來(lái)實(shí)現(xiàn)的。
除了這個(gè)接口,JetBrains還提供免費(fèi)的DSL布局預(yù)覽功能。下面是Anko DSL布局預(yù)覽在Android Studio中的樣子:
Anko Preview的相應(yīng)插件可以從這里下載。請(qǐng)注意,在撰寫(xiě)本文時(shí),Android Studio 2.2的Anko DSL 布局預(yù)覽被列為開(kāi)源issue。
回到正題,我們接下來(lái)設(shè)計(jì)MainUI類(lèi)展示所有任務(wù)列表。MainUI類(lèi)繼承了AnkoComponent<T>接口,其中T指的是UI的所有者,activity的內(nèi)容將會(huì)是這個(gè)UI。在我們的例子中,所有者就是我們已經(jīng)在上面定義的MainActivity。接下來(lái),在初始化時(shí),我們必須將TodAadapter對(duì)象傳遞給此類(lèi),因?yàn)榇诉m配器將用于填充列表。所以,MainUI聲明變成:
class MainUI(val todoAdapter : TodoAdapter) : AnkoComponent<MainActivity>
現(xiàn)在我們需要重寫(xiě)方法 createView() ,使用 AnkoContext 對(duì)象作為參數(shù)并返回一個(gè)View 類(lèi)型:
override fun createView(ui: AnkoContext<MainActivity>): View = with(ui) { }
我們?cè)赾reateView() 方法中UI定義返回給所有者即activity,在這里也就是MainActivity,所以接下來(lái)寫(xiě)createView() 方法:
Step1-設(shè)計(jì)首頁(yè)
最初,首頁(yè)是空列表。所以,我們有一個(gè)textView要求用戶創(chuàng)建一天的Todo List:
return relativeLayout { //聲明ListView var todoList : ListView? =null //當(dāng)沒(méi)有任務(wù)時(shí)顯示textView內(nèi)容"What's your Todo List for today?" val hintListView = textView("What's your Todo List for today?") { textSize = 20f }.lparams { centerInParent() } }
centerInParent() 是將視圖的布局定義為垂直和水平相對(duì)中心的輔助方法。因?yàn)樗且粋€(gè)todo性質(zhì)的應(yīng)用,其本質(zhì)在于顯示任務(wù)的列表。所以,我們?cè)谶@里定義listView:
//listView verticalLayout { todoList=listView { //assign adapter adapter = todoAdapter } }.lparams { margin = dip(5) }
todoAdapter是我們?cè)贛ainUI類(lèi)聲明中定義成員變量。我們用todoAdapter的值初始化listView的adapter,這是一個(gè)TodoAdpater類(lèi)的對(duì)象,將會(huì)用于填充列表。
為了幫助用戶添加任務(wù),我們?cè)谥髌聊坏挠蚁路教峁┝艘粋€(gè)Material design風(fēng)格的floatingActionButton。所以我們使用Anko編程floatingActionButton為:
floatingActionButton { imageResource = android.R.drawable.ic_input_add }.lparams { //設(shè)置按鈕在屏幕的右下方 margin = dip(10) alignParentBottom() alignParentEnd() alignParentRight() gravity = Gravity.BOTTOM or Gravity.END }
感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“Kotlin中Anko庫(kù)怎么用”這篇文章對(duì)大家有幫助,同時(shí)也希望大家多多支持億速云,關(guān)注億速云行業(yè)資訊頻道,更多相關(guān)知識(shí)等著你來(lái)學(xué)習(xí)!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。