文章目錄
大家好,我叫趙健,目前是一名Android開發工程師。今天開始我們一起步入Android開發的時間。本系列課程一共分爲6節課,分別講解了從事Android開發從知道到實際應用幾個難點。本系列課程主要有以下幾部分:
- 快速創建一個安卓應用以及基本UI的掌握
- 跨入Android大門的Kotlin語言篇
- 所有的動畫都來源於這些操作
- 自定義UI及一些概念
- 快速接入第三方應用
- 分析一下優秀的開源程序
那麼現在我們開始第一部分,快速創建一個安卓應用以及基本UI的掌握。開始開發之前,我們需要下載一個android開發的IDE工具Android Studio。我們可以從這個網址下載一個IDE工具。
AndroidDevTools :https://www.androiddevtools.cn/
我們也可以使用下面的鏈接直接下載
3.6.1正式版(windows64) https://dl.google.com/dl/android/studio/ide-zips/3.6.1.0/android-studio-ide-192.6241897-windows.zip?utm_source=androiddevtools&utm_medium=website
3.6.1正式版(mac) https://dl.google.com/dl/android/studio/ide-zips/3.6.1.0/android-studio-ide-192.6241897-mac.dmg?utm_source=androiddevtools&utm_medium=website
下載完成後,直接安裝即可,如果安裝有困難的朋友,也可以通過網絡上搜索相應的文章進行安裝
https://www.baidu.com/s?ie=UTF-8&wd=AndroidStudio 環境搭建
這裏需要注意的是,我們在安裝Android Studio之前需要先安裝JAVA開發環境,具體操作步驟,可以參考上面的鏈接。
好了,最後安裝好的Android Studio是這個樣子的:
現在我們開始創建一個新的Android應用。點擊這個界面的
Start a new Android Studio project
創建項目選擇
Phone and Tablet中的Empty Activity
創建一個空的APP,選擇
next
此時,我們會看見一個這樣的界面:
在這裏,我們填入APP的詳細信息。
大家可能對這些條目不熟悉,我來給大家解釋以下:
- Name:是我們APP的名稱,我們改成LearningAndroid。作爲我們要學習Android第一個項目的名稱。
- Package name:是每一個APP標識,我們的安卓手機通過這個pakcage name認出我們的app。而且每一個手機上面不能存在同一個package name的APP。這裏我們使用com.flannery.learningandroid。這裏有一點需要注意的是,com.flannery可以替換成你自己域名的倒寫,如果沒有你自己的域名,這裏可以就用我這個,不影響後邊的功能。
- Save Location:顧名思義,就是我們的項目需要保存的位置。
- Language:3.6.1版本默認的語言是Kotlin,這裏就是用默認的Kotlin。
點擊Finish。然後經過一些不傷大雅的等待。我們終於進入了開發界面,就是這個樣子的。
在簡單的創建了一個Android APP後,我們就要學習一些簡單的控件UI了。在開始之前,我們應該瞭解到,Android的界面是通過xml來進行編輯的,也就是代碼編輯器區的activity_mian.xml中編輯。我們也可以創建一個新的xml文件。
就是在Android->app->java->res->layout目錄下,點擊右鍵->New->Layout Resource File創建一個新的xml文件。
好了,知道怎麼創建之後,我們就開始學習下面的界面控件了。界面控件部分主要分爲兩部分,第一部分就是佈局控件部分,由:
- 線性佈局(LinearLayout)
- 相對佈局(RelativeLayout)
- 幀佈局(FrameLayout)
- 約束佈局(ConstraintLayout)
組成,這也是我們Android開發的時候幾種最常用的幾種佈局結構。
第二部分就是一些展示控件部分,由:
- 文本框(TextView)與編輯框(EditText)
- 按鈕(Button)
- 單選按鈕(RadioButton)和複選框(CheckBox)
- 圖像視圖(ImageView)
- 滾動視圖(ScrollView)
- 列表視圖(RecyclerView)
- Toast顯示提示信息框
幾種最常用的展示控件部分組成。這幾種也是最常用的幾種。
在正式開始之前,我們要先了解控件層級間的關係。如下圖:這是控件之間的關係。ViewGroup就是一個容器,下邊可以存放容器,也可以存放View。但View下面是沒有任何東西了。
好的,知道了這些,那我們就開始了。
第一個佈局就是LinearLayout,是一個線性佈局,意思就是說只能橫向或縱向排布View。
就像下面這個樣子,就是橫向佈局結果。
代碼中通過android:orientation="horizontal"
來設置橫向佈局
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:contentDescription="橫向佈局"
android:orientation="horizontal">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="111" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="222" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="333" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="444" />
</LinearLayout>
同樣的道理,將標籤設置成這樣android:orientation="vertical"
,就會變成縱向佈局。就像下面圖片這個樣子。
在線性佈局中,我們想讓內部的控件全部居中顯示,而不是單單的左靠齊。這時候就會遇到android:gravity="center"
標籤,就像這樣:
代碼是這個樣子的
<LinearLayout
android:layout_width="match_parent"
android:layout_height="100dp"
android:contentDescription="橫向佈局 | 居中"
android:gravity="center"
android:orientation="horizontal">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="111" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="222" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="333" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="444" />
</LinearLayout>
這個標籤還有其他的一些值,比如垂直居中(center_horizontal)、水平居中(center_vertical)。
有時候我們還會遇到這樣的需求,向下面的圖:
左右兩邊都是圖片,中間的文字的文字要充滿整個空白的地方。這個時候我們就可以文字控件(TextView)中使用android:layout_weight="1"
屬性來進行操作。
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:gravity="center_vertical"
android:orientation="horizontal">
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:src="@mipmap/ic_launcher" />
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:ellipsize="end"
android:gravity="center_vertical"
android:singleLine="true"
android:text="中間的文字中間的文字中間的文字中間的文字中間的文字中間的文字"
android:textSize="25sp" />
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:src="@mipmap/ic_launcher" />
</LinearLayout>
這時候你會問,"android:layout_weight"屬性到底是怎麼個原理呢。就跟下圖一樣:
這裏面水平佈局有三個控件,weight的值分別是1、2、3。當繪製屏幕的時候,系統會把幾個weight加起來,然後根據權重,第一個分配到1/6的寬度,第二個分到2/6的寬度,第三個分到3/6。
這樣你應該大致有些明白了。實際開發中,這個用到的機會很多,但是基本上都是擴充空白部分。所以你能明白這個道理就可以了。
下面,我們來說第二個佈局:相對佈局(RelativeLayout),顧名思義,就就是相對某一點。這時候,我們用一個例子來了解RelativeLayout。請看這張圖:
我們看到,一個十字型的排布,CCC在最中間,AAA在CCC的左邊,DDD在CCC的右邊,並且他們三個在同一個水平線上。同理BBB和CCC和EEE也是一樣的。
這裏就有相對的概念了。
怎樣做到這樣的呢。首先我們先將CCC的設置一個ID,也叫做ccc。然後AAA的id取名aaa。在aaa上設置android:layout_toLeftOf="@+id/ccc"
標籤就會看到已經在最左邊了。但是這時候只是在CC的左邊,而沒有在同一個水平線上,這是後設置android:layout_centerVertical="true"
標籤,讓他們都在屏幕的水平線上。同理其他的也這麼做。下面些就是源碼了:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:contentDescription="https://www.jianshu.com/p/7286e1be14fa"
android:layout_height="match_parent">
<Button
android:id="@+id/aaa"
android:contentDescription="左邊"
android:layout_toLeftOf="@+id/ccc"
android:layout_centerVertical="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="aaa"/>
<Button
android:contentDescription="上邊"
android:id="@+id/bbb"
android:layout_centerHorizontal="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@+id/ccc"
android:text="bbb"/>
<Button
android:id="@+id/ccc"
android:contentDescription="居中"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="ccc"/>
<Button
android:contentDescription="右邊"
android:id="@+id/ddd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toRightOf="@+id/ccc"
android:text="ddd"/>
<Button
android:contentDescription="下邊"
android:id="@+id/eee"
android:layout_centerHorizontal="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/ccc"
android:text="eee"/>
</RelativeLayout>
下面我們該看看幀佈局了,也就是FrameLayout。這種佈局沒什麼特別的,就是放在這個標籤下的所有控件口試按層級來排列的,就像這樣:
一層一層的往上摞。
最後一個是約束佈局(ConstraintLayout),相對與相對佈局,更加高效,功能更加強大。我從王章找到一篇文章,講的很詳細,大家有興趣可以去看看。
一文看懂ConstraintLayout的用法(https://www.cnblogs.com/angrycode/p/9739513.html)
好了,看完佈局,我們該看控件了。佈局就是一個容器,決定着控件的排布。各個控件纔是真正要展示功能的部分。
第一個迎面來的是TextView(文本框),這個是顯示文字的一個控件,請看下面的圖片:
整個xml代碼是這個樣子的:
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="這是一個TextView"
android:textColor="#0000FF"
android:textSize="24sp"
android:textStyle="normal" />
在<TextView/>
下,通過android:text="這是一個TextView"
就可以設置要顯示的文字,其中還可以設置文字大小(android:textSize="24sp"
)和文字顏色(android:textColor="#0000FF"
),這裏我們設置文字大小的時候用的是sp, 安卓官方專門給文字設置大小的一個單位。
此外,還可以設置文字位置,居中還是右對齊。也可以單排顯示。具體的請看下面的代碼:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_marginTop="10dp"
android:background="@android:color/darker_gray"
android:text="學習安卓"
android:textColor="#0000FF"
android:textSize="24sp"
android:textStyle="normal" />
<TextView
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_marginTop="10dp"
android:background="@android:color/darker_gray"
android:gravity="center_vertical"
android:text="學習安卓"
android:textColor="#0000FF"
android:textSize="24sp"
android:textStyle="normal" />
<TextView
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_marginTop="10dp"
android:background="@android:color/darker_gray"
android:gravity="right|center_vertical"
android:text="學習安卓"
android:textColor="#0000FF"
android:textSize="24sp"
android:textStyle="normal" />
<TextView
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_marginTop="10dp"
android:background="@android:color/darker_gray"
android:text="學習安卓學習安卓學習安卓學習安卓學習安卓學習安卓學習安卓學習安卓學習安卓學習安卓學習安卓學習安卓學習安卓學習安卓學習安卓學習安卓學習安卓學習安卓學習安卓學習安卓學習安卓學習安卓學習安卓學習安卓學習安卓學習安卓"
android:textColor="#0000FF"
android:textSize="24sp"
android:textStyle="normal" />
<TextView
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_marginTop="10dp"
android:background="@android:color/darker_gray"
android:ellipsize="end"
android:maxLines="1"
android:text="學習安卓學習安卓學習安卓學習安卓學習安卓學習安卓學習安卓學習安卓學習安卓學習安卓學習安卓學習安卓學習安卓學習安卓學習安卓學習安卓學習安卓學習安卓學習安卓學習安卓學習安卓學習安卓學習安卓學習安卓學習安卓學習安卓"
android:textColor="#0000FF"
android:textSize="24sp"
android:textStyle="normal" />
</LinearLayout>
結果是這個樣子的:
下面我們說EditText(編輯框),也就是可以編輯文字。
上圖是兩個輸入框,一個是輸入文字,下邊的是一個輸入密碼的EditText。有EditText是TextView的子類,所以TextView的很多屬性EditText都可以用。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<EditText
android:id="@+id/mEtName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:contentDescription="可以顯示光標"
android:cursorVisible="true"
android:hint="輸入文字"
android:textSize="24sp" />
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:contentDescription="可以顯示光標"
android:cursorVisible="true"
android:hint="輸入密碼"
android:inputType="textPassword"
android:maxLength="10"
android:textSize="24sp" />
</LinearLayout>
通過android:inputType="textPassword"
可以設置文字輸入的類型,這個標籤就是要輸入密碼的類型。
通過```android:hint=“輸入密碼”``可以設置提示文字,在輸入真正文字的時候,這個提示文字就會消失。等一個輸入的文字都沒有的時候,就會顯示出來 .
按鈕,不用說,就是要點擊用的,看下面集中常見的按鈕:
第一個就是默認的按鈕,第二個是設置了圖片的按鈕,第三個就是設置圖片改變了位置的按鈕。就是下面的代碼。
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="默認按鈕" />
<Button
android:layout_width="44dp"
android:layout_height="44dp"
android:background="@mipmap/next" />
<Button
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_gravity="center_horizontal"
android:background="@drawable/selector_button_pressed" />
</LinearLayout>
不僅是按鈕,像繼承View的所有控件都可以設置點擊時間。
在Activity中通過id,對Button進行按鈕點擊事件的註冊。
button.setOnClickListener { view ->
// doSomething
}
單選按鈕(RadioButton)很少單獨使用,通常是在RadioGroup下,跟很多個RadioButton共同使用。多箇中選擇一個。
代碼是這個樣子的:
<RadioGroup
android:id="@+id/rg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<RadioButton
android:id="@+id/rb1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="男" />
<RadioButton
android:id="@+id/rb2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="女" />
<RadioButton
android:id="@+id/rb3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="第三種" />
</RadioGroup>
想要知道按鈕選中事件,只需註冊setOnheckedChangeListener即可
rg.setOnCheckedChangeListener { group, checkedId ->
when (checkedId) {
R.id.rb1 -> {
Toast.makeText(this@ButtonActivity, "選中第一個", Toast.LENGTH_SHORT).show()
}
R.id.rb2 -> {
Toast.makeText(this@ButtonActivity, "選中第二個", Toast.LENGTH_SHORT).show()
}
else -> {
Toast.makeText(this@ButtonActivity, "選中其他", Toast.LENGTH_SHORT).show()
}
}
}
複選框(CheckBox)可以進行選中和取消選中。
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="喜歡" />
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="有用" />
ImageView是一個專門用來展示圖片的一個控件,下面的圖片就是通過ImageView顯示出來的。
代碼是這樣的:
<ImageView
android:layout_width="300dp"
android:layout_height="300dp"
android:src="@mipmap/breakfast004" />
你使用手機的時候會發現,APP中的內容可能一屏幕裝不下,可能要往下滑,也可能左右滑。這個就會用到ScrollView和RecyclerView。
先說ScrollView是一個滾動視圖,就是固定的放入一個控件,一般是LinearLayout(也可能是其他的佈局控件),然後LinearLayout設置成vertical(垂直的),往裏面放入好多好多東西。當內容不能在一個屏幕上顯示的時候,就可以上下滾動了。
這裏把代碼貼到這裏:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="第一個"
android:textSize="60sp" />
<ImageView
android:layout_width="300dp"
android:layout_height="300dp"
android:src="@mipmap/breakfast004" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="第二個"
android:textSize="60sp" />
<ImageView
android:layout_width="300dp"
android:layout_height="300dp"
android:src="@mipmap/breakfast004" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="第三個"
android:textSize="60sp" />
<ImageView
android:layout_width="300dp"
android:layout_height="300dp"
android:src="@mipmap/breakfast004" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="第四個"
android:textSize="60sp" />
<ImageView
android:layout_width="300dp"
android:layout_height="300dp"
android:src="@mipmap/breakfast004" />
</LinearLayout>
</ScrollView>
還有一種滾動視圖,RecyclerView,這個控件很強大。可以顯示列表,可以顯示網格,也可以顯示瀑布流。下圖是分別演示了三種列表樣式。
他們是怎麼實現的呢。這裏主要理解三部分:數據源部分、適配器部分、顯示部分。
我們先在xml文件中創建一個RecyclerView標籤,這就是我們要顯示的部分。
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/mRecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
我們創建一個List<String>
的數據源:
var list = arrayListOf("趙", "錢", "孫", "李", "周", "吳", "鄭", "王",
"1", "2", "3", "4", "5", "6", "7", "8", "趙", "錢", "孫", "李", "周",
"吳", "鄭", "王", "1", "2", "3", "4", "5", "6", "7", "8")
最後就是一個很重要的部分,適配器部分,這部分將數據源轉換成要展示的條目界面,顯示在RecyclerView上。我們先貼上代碼:
inner class ListHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var title = itemView.findViewById<TextView>(R.id.title)
}
inner class ListAdapter(var list: List<String>) : RecyclerView.Adapter<ListHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ListHolder {
var itemView = LayoutInflater.from(parent.context)
.inflate(R.layout.learning_recyclerview_item_list, parent, false)
return ListHolder(itemView)
}
override fun getItemCount(): Int {
return list.size
}
override fun onBindViewHolder(holder: ListHolder, position: Int) {
holder.title.text = list.get(position)
}
}
其中ListHolder繼承自RecyclerView.ViewHolder,是保存了每個item的View。
ListAdapter繼承自RecyclerView.Viewholder<ListHolder>
,也就是那個適配器。
這裏需要必須重寫三個方法:
onCreateViewHolder(…)主要是將給每個條目的View創建成ViewHolder,然後綁定到Adapter中。
getItemCount() 是告訴RecyclerView要顯示多少個item。
onBindViewHolder(…)是將數據源綁定到ItemView中。也就是自定義顯示數據的部分。
最後,我們看最後將三個結合起來
var list = arrayListOf("趙", "錢", "孫", "李", "周", "吳", "鄭", "王",
"1", "2", "3", "4", "5", "6", "7", "8", "趙", "錢", "孫", "李", "周",
"吳", "鄭", "王", "1", "2", "3", "4", "5", "6", "7", "8")
"8"
)
mRecyclerView.adapter = ListAdapter(list)
mRecyclerView.layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
這時候我們就可以看到:
- 創建數據源。
- 將數據源跟ListAdapter綁定,並設置給mRecyclerView.adapter中。
- 設置layoutManager,這是告訴RecyclerView是顯示什麼樣的、
常見的RecylerView中的layoutManager有三種:
//列表佈局
mRecyclerView.layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
// 網格佈局
mRecyclerView.layoutManager = GridLayoutManager(this, 2)
// 瀑布流佈局
mRecyclerView.layoutManager =
StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL)
好了,常見控件的部分完了。
下面我們補充一個控件,Toast,是一個提示信息框。比如這樣:
這個彈窗默認創建在屏幕第中下部。
最後,大家也許還不明白,這些控件是如何顯示到屏幕上的。這就涉及到一個叫Activity的東西。他是能顯示在手機屏幕上的主要功臣。
現在我們通過新創建一個Activity,來詳細瞭解Activity是怎麼來的。
我們找到一個package下右鍵-New-Activity,找到一個你需要的Activity樣本,這裏我們選Empty Activity。
然後我們下一步下一步完成,就可以創建有個新的NewActivity了。
class NewActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_new)
}
}
新創建的就是這個樣子的,我們使用setContentView(R.layout.activity_new)
將我們上邊創建的佈局文件顯示在屏幕上。
這裏需要注意的是,Activity是需要註冊到AndroidManifest.xml清單文件中的,這樣安卓系統纔可以知道,這是一個要顯示的Activity。不然的話會出錯哦。
小結:
本節課程第一部分講了如何大家環境,並創建了一個簡單的APP工程。第二部分講解了佈局文件和控件的創建及應用。最後說了Activity是怎樣顯示到界面上的。
下面,整節課的代碼全部放到的git上,鏈接如下:
https://gitee.com/WhatINeed/LearningAndroid