若要在Android Wear Watch專案中能夠跑在實體手表時,都必須開啟Debug Mode來進行開發時的測試。

為此紀錄一下如何開啟Android Wear Watch的Debug模式:

首先你必須在手錶上的Settings > About > Build Number的選項,並對他進行7次點擊來開啟開發者模式。

之後回到Settings頁面時,下方會多出一個Developer Options,點選此項目來進行開發模式的設定如下:

開啟ADB debuggingDebug over Bluetooth這兩個選項,接著回到手機上的開發者模式,確認USB debugging為開啟的狀態,並開啟藍芽連線。

此時可以開啟手機內的Wear OS App,點選進階設定 > 開啟透過藍牙偵錯,一開始主機所顯示的是已中斷連線的狀態。

這時,將手機透過USB連接上電腦,並分別在Command Line下執行輸入這兩個命令:

adb forward tcp:4444 localabstract:/adb-hub

adb connect localhost:4444

此時你會看到Wear OS App中透過藍牙偵錯選項的主機狀態由已中斷連線切換為已連線

最後可以看到手錶上會出現是否接受Debug模式的提示訊息,只需要點選OK即可完成Debug模式的開啟。


Image for post
Image for post

常常聽到許多人抱怨著存錢好難?
其實存錢並不難,而是需要選對方法,才能有效的儲蓄。

國外廣為流傳的52週存錢法,其實就是一個很好的儲蓄方式!
什麼是階梯式存錢法?
1. 第一週,先存10元
2. 第二週以後,每週再比前一週多存10元
3. 52週後就能存下13,780元

在2018的2月,跟朋友討論到52週存錢法,覺得可以透過手機來紀錄自己的存錢目標,輕鬆地確認每週的存錢狀況,來取代以往使用紙本的條列式記帳。因此,開始著手製作52週存錢挑戰這個App,並給自己限時七日內完成的挑戰目標!

App發想:

透過First Time Flow來進行目標與週期的設定,模式與幣別選擇
透過Unsplash API來Random更換Background,提升畫面的質感
加入QuotesCard方式,來加強使用者繼續存錢的Motivation
加入HappyCard方式,來推廣使用者幫忙給予5星評論

持續增加中……

App功能特色:

App頁面:

Image for post
Image for post

App網址:
https://play.google.com/store/apps/details?id=com.yulocus.money52


Image for post
Image for post

Lambda

  • 將函數當作值的功能傳入
// 語法結構
input -> body
input(parameters):
不輸入:()
單個輸入:x
多個輸入:(int x, int y)或簡寫(x,y)
body:
什麼都不做:{}
單行不回傳值:print("NO")
多行不回傳值:
{
print("NO");
print("NO2");
}
單行回傳值:x+y
多行回傳值:
{
x++;
y-=x;
return x+y;
}
  • 使用Runnable來解釋Lambda
// Android
Runnable runnbale = new Runnable() {
public void run() {
System.out.println("run me!");
}
};
// Lambda
Runnable runnbale = () -> System.out.println("run me!");
  • 使用Lambda時,不會多new一個實體出來,而是將Lambda的body區塊先放到記憶體中,透過Call Function的方式來進行呼叫,如此一來可以提升程式效能
// Java
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
/* actions on click */
}
});
// Lambda
button.setOnClickListener { view -> /* actions on click */ }

新觀念:以前必須自己實作所有東西的習慣,現在可以透過Lambda和相關的操作子來改正這習慣

//找出最大年齡fun findTheOldest(people: List<Person>) {
var maxAge = 0
var theOldest: Person? = null
for (person in people) {
if (person.age …


Image for post
Image for post

類別與物件

繼承類別

  • open修飾符是用來表示該類別可以被繼承,原本Java是使用public來做為預設值,但在Kotlin是使用final來做為類別的預設值,所以當該類別需要被其他類別所繼承時,必須先在父類別設定為open才能使用
// 其他類別可以繼承這個類別
open class RichButton : Clickable {
// 這個函數是不可以被修改的(final),不可以在子類別中override它
fun disable() {}
// 這個函數是可以被修改的(open),可以在子類別中override它
open fun animate() {}
// 這函數override了一個已經open的函數,所以他也是可以被override的
override fun click() {}
// 但是如果你不希望子類別去override其父類別所繼承的函數時,可使用final
final override fun click() {}
}

抽象類別

  • 由於抽象類別是不需被初始化,內部也會包含許多需要在子類別去實作抽象的成員函數,因此成員函數預設是open,不需特別定義
// 這是抽象類別
abstract class Animated {

// 這是抽象函數,不需再父類別進行實作,但必須在子類別去override並實作
abstract fun animate()
// 抽象類別中的非抽象函數預設是final,但是可以透過open來打開它
open fun stopAnimating() { ... }

fun animateTwice() { ... }
}

類別的可見性修飾符

  • public(預設值):代表所有地方都能使用這類別
  • internal:代表只有在相同的module內才可以使用這類別
  • protected:代表只有在子類別中能使用
  • private:代表只有該類別內可以使用

內部類別,嵌套類別,密封類別

  • 預設為嵌套類別
  • 透過inner來表示該類別為內部類別
  • 透過sealed來將該類別進行密封,所有子類別都必須嵌套在父類別當中
// 嵌套類別
class Outer {
private val bar: Int = 1
class Nested {
fun foo() = 2
}
}

val demo = Outer.Nested().foo() …


Image for post
Image for post

函數的使用技巧

  • 利用對函數設定參數的預設值,在Kotlin中可以避免函數的過度重載
fun <T> joinToString(
collection: Collection<T>,
separator: String = ", ", // 預設參數值
prefix: String = "",
postfix: String = ""
): String
// 現在你可以使用以下方法來進行函數的調用
joinToString(list)
joinToString(list, ", ", "", "")
joinToString(list, ";")
joinToString(list, prefix = "#")
  • 一般在Java中常見的靜態工具類別,在Kotlin中如何實現
  • 在Kotlin中,你可以將函數放置在文件的最頂層開頭位置,而不需要創建額外無意義的Util類別
// Java
public class StringUtils {
public static String joinToString(...) { ... }
}
// Kotlin
fun joinToString(...): String { ... }
// 如果需要對這些function進行歸類時,可以使用改变文件的类名方式
@file:JvmName("StringFunctions")
package strings
fun joinToString(...): String { ... }
// 呼叫時一樣需要進行import
import strings.StringFunctions
StringFunctions.joinToString(...)
  • 擴展函數是一個可以被類別成員調用的一個函數,但定義在外部類別
// 在函數前添加需要擴展的類別或interface (receiver type)也就是接收型態
// 在後方的this則代表著擴展函數的值(receiver object)也就是接收物件
fun String.lastChar(): Char = this.get(this.length - 1)// 此時的"Kotlin"同時為接收型態與接收物件print("Kotlin".lastChar())
輸出:n
// 其實就有點像var text: String = get() { field.length - 1 }
fun lastChar(text: String): Char {
return text…


Image for post
Image for post

基礎概念

  • val用來表示常數,類似Java的final,不可以被改變的變數
  • var用來表示變數,可以對他進行數值的改變

新觀念:盡可能地去使用val來作為宣告的變數,或函數中的參數,這樣可以幫助程式在使用變數時能更清楚了解哪些變數是可被改變,而透過編譯器來進行判斷

  • 函數改用fun,參數型態寫在參數後方
  • 函數不一定需要將他放在一個class中,每行結束不再需要分號(;)
  • 回傳值型態設定在函數後方,若為void則使用Unit或直接省略
  • 當function的內容僅使用一個表達式時,可使用“=[表達式]”來簡寫
fun main(args: Array<String>) {
print(sayHello())
}
fun sayHello(): String {
return "Hello, world!"
}
fun max(a: Int, b: Int): Int = if (a > b) a else b
  • 字串模板
In Java
String name = "Locus";
輸出:"Hello," + name + "!";
In Kotlin
val name: String = "Locus"
輸出:"Hello, $name!"
另外也可以使用複雜的表達式
輸出:"Hello, ${if(args.size() > 0) args[0] else "someone"}!"
  • 類別屬性
  • getter & setter
// 基本款簡單的人物類別
class Person {
val name: String
var gender: Int // 0: male, 1: female, 2: other
}
創建人物
val person = Person("Locus", 0)
print(person.name) // Locus
print(person.gender) // 0
修改屬性,讓Locus變性
person.gender …

Locus Yu

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store