在認識 android
的時候,應該先從認識 app 的 lifecycle 開始,但這部分打算留待幾天之後再來討論。
這兩天先感受一下幾個元件的操作,分享一個簡單的登入介面,以及如何串接第三方 FB
以及 Google
提供的登入 api,第三天將實作一個簡單的後端伺服器,去處理 android
發來的帳密資訊。稍為體會一下 android
以及後端在傳接封包的感覺吧!
P.S. 在第 (三) 篇一併提供程式碼唷
(一)簡單登入界面
(二)串接第三方 api
(三)簡單伺服器接收帳密資訊
因為接下來系列的作品,打算都把作品都以 fragment
形式裝進去 navigation activity
裡面,方便之後自己如果想看的話,不用再去到處尋找寫過的專案 app,當然讀者也可以把個別作品都分開!
選擇 navigation drawer activity
並且取個專案名字,在這我取名 Kangaroo
進到 menu/activity_main_drawer.xml
把多餘的 item 都砍掉,目前只需要一個 item,之後如果新增作品,此處再自行新增即可
更改 title 的名稱
每次要寫新的作品時,都創一個新的 packge 資料夾方便管理
建立 fragment
先新增一個 kotlin class
出來之後,去繼承 Fragment()
。在 Fragment()
裡頭能夠去 override
函式 onCreateView()
, 這裡提到的 fragment
以及 lifecycle 將會在之後更加深提到
class loginFragment : Fragment()
建立 fragment
的骨架
這裡講的骨架其實就是 xml
檔案,每個 fragment
都會去 inflate 一個 xml
檔案,簡單來講,就是生長出這個 xml
定義的外觀 (這邊 inflate 有點難解釋,很像是對著氣球吹氣,讓整個 xml 形狀長出來(?)裡頭包含要填帳密的 EditText
、提示的 TextView
、Button
以及最上面鎖圖案的 ImageView
建立元件 (component) 的監聽器 (listener)
監聽器的意思簡單來講,監聽著某個元件,當那個元件被點擊、滑動 ... 等等動作時,會觸發監聽器,而當監聽器被觸發的時候,可以去執行一些特定的動作。
在這邊,我們希望當按鈕 Submit 被按下的時候,擷取(透過 id
) account 以及 password 上面的文字,來做驗證。當帳密都符合初始值時,就使用 setImageResource()
改變 image
的圖片檔
view.accountSubmit.setOnClickListener {
val account = view.account.text.toString()
val password = view.password.text.toString()
if(account == "admin" && password == "admin"){
Toast.makeText(context, "登入成功", Toast.LENGTH_SHORT).show()
view.img_lock.setImageResource(R.drawable.ic_lock_open_black_24dp)
}else{
Toast.makeText(context, "登入失敗", Toast.LENGTH_SHORT).show()
}
view.account.text.clear()
view.password.text.clear()
}
建立裝 fragment
的容器 (FrameLayout
)
概念大致上是這樣,我們希望按下左邊 bar 的 login
選項時,先清空容器裡面的 fragment
,並且把 login fragment 放進去這個容器。
建立切換 fragment
的動畫
切換的時候,原本在容器裡面的 fragment
要離開,新的 fragment
要進去,在離開和進去的同時,都能夠有動畫來加強視覺效果,而我希望舊的 fragment
可以淡出 (fade out),新的 fragment
可以淡入 (fade in),淡出淡入的動畫就是在透明度 (alpha) 上面做調整
<alpha android:fromAlpha="0.0" android:toAlpha="1.0"
android:duration="@android:integer/config_mediumAnimTime" />
<alpha android:fromAlpha="1.0" android:toAlpha="0.0"
android:duration="@android:integer/config_mediumAnimTime" />
建立切換 fragment
的 fragmentManager
這個 fragmentManager
很像是一個管理 fragment
的管家,當我們今天需要去更換容器裡面的 fragment
時,可以請這個管家來幫我們處理!
以下是設定動畫,以及要對哪個容器做替換
fm.beginTransaction()
.setCustomAnimations(R.anim.fade_in, R.anim.fade_out)
.replace(R.id.loginFrame, loginFragment())
.commit()
內建圖檔在哪兒?
使用圖檔想說要到網路上找素材,再放進來,但其實 Android Studio
有內建豐富的素圖可以使用,要去新增 vector Asset
點進去了之後點擊 Clip Art
,就可以找到啦~相當快速方便
打完帳號之後,按下鍵盤右下角的 enter
,鍵盤不會收起來?游標還一直閃?
在這邊我做了一個監聽處理,也就是當觸發了 setOnEditorActionListener
後,我去看使用者是否按下 enter
。
如果按下的話就清除當前該 EditText
的 focus,並且收起鍵盤。
view.account.setOnEditorActionListener { textView, i, keyEvent ->
if(i == EditorInfo.IME_ACTION_DONE){
view.account.clearFocus();
val imm = activity!!.getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(view.account.getWindowToken(), 0)
true
}
false
}
收起鍵盤是透過 InputMethodManager
去處理,麻煩的是 EditText
的 focus,也就是游標還會一直閃不會消失。
根據 [1] 的討論,當執行 clearFocus
的時候,會返回去找上一個 focusableInTouchMode
是 True
的元件。
處理方法就是到 parent 的 focusableInTouchMode
設為 True
,讓返回去找的時候可以找到他的 parent。如果不這麼做,當往回去找的時候會再找到自己,就會再次 focus 到自己這個 EditText
所以看起來就像是這程式碼並沒有作用的感覺
<android:focusable="true"
android:focusableInTouchMode="true"/>
輸入完帳號之後,按下 enter
會自動跳到密碼區,如果不想自動往下跳該怎辦?
加入以下程式碼,告訴 app 這個結束之後就別再去找其他的 EditText
囉!
android:imeOptions="actionDone"
[1] 連結 | clearFocus
的運作討論