Slide 1

Slide 1 text

#devfestbkk

Slide 2

Slide 2 text

#devfestbkk Android Studio 3 SDK > 21 Emulator https://github.com/VerachadW/sneaker-app/

Slide 3

Slide 3 text

#devfestbkk

Slide 4

Slide 4 text

#devfestbkk

Slide 5

Slide 5 text

#devfestbkk @RunWith(AndroidJUnit4.class) public class NotesActivityTest { @Rule public ActivityTestRule activity = new ActivityTestRule<>(Activity.class); @Test public void notesActivityTest2() { onView(allOf(withParent(withId(R.id.my_button)),isDisplayed())) .perform(click()); } }

Slide 6

Slide 6 text

#devfestbkk @RunWith(AndroidJUnit4.class) public class NotesActivityTest { @Rule public ActivityTestRule activity = new ActivityTestRule<>(Activity.class); @Test public void notesActivityTest2() { onView(allOf(withParent(withId(R.id.my_button)),isDisplayed())) .perform(click()); } }

Slide 7

Slide 7 text

#devfestbkk @RunWith(AndroidJUnit4.class) public class NotesActivityTest { @Rule public ActivityTestRule activity = new ActivityTestRule<>(Activity.class); @Test public void notesActivityTest2() { onView(allOf(withParent(withId(R.id.my_button)),isDisplayed())) .perform(click()); } }

Slide 8

Slide 8 text

#devfestbkk @RunWith(AndroidJUnit4.class) public class NotesActivityTest { @Rule public ActivityTestRule activity = new ActivityTestRule<>(Activity.class); @Test public void notesActivityTest2() { onView(allOf(withParent(withId(R.id.my_button)),isDisplayed())) .perform(click()); } }

Slide 9

Slide 9 text

#devfestbkk @RunWith(AndroidJUnit4.class) public class NotesActivityTest { @Rule public ActivityTestRule activity = new ActivityTestRule<>(Activity.class); @Test public void notesActivityTest2() { onView(allOf(withParent(withId(R.id.my_button)),isDisplayed())) .perform(click()); } } onView check perform

Slide 10

Slide 10 text

#devfestbkk @RunWith(AndroidJUnit4.class) public class NotesActivityTest { @Rule public ActivityTestRule activity = new ActivityTestRule<>(Activity.class); @Test public void notesActivityTest2() { onView(allOf(withParent(withId(R.id.my_button)),isDisplayed())) .perform(click()); } }

Slide 11

Slide 11 text

#devfestbkk

Slide 12

Slide 12 text

#devfestbkk @RunWith(AndroidJUnit4::class) class NotesActivityTest { @Rule var activity = ActivityTestRule(NotesActivity::class.java) @Test fun notesActivityTest2() { onView(allOf(withParent(withId(R.id.my_button)),isDisplayed())) .perform(click()); } }

Slide 13

Slide 13 text

#devfestbkk @RunWith(AndroidJUnit4::class) class NotesActivityTest { @Rule var activity = ActivityTestRule(NotesActivity::class.java) @Test fun notesActivityTest2() { onView(allOf(withParent(withId(R.id.my_button)),isDisplayed())) .perform(click()); } }

Slide 14

Slide 14 text

#devfestbkk @RunWith(AndroidJUnit4::class) class NotesActivityTest { @Rule var activity = ActivityTestRule(NotesActivity::class.java) @Test fun notesActivityTest2() { onView(allOf(withParent(withId(R.id.my_button)),isDisplayed())) .perform(click()); } }

Slide 15

Slide 15 text

#devfestbkk @RunWith(AndroidJUnit4::class) class NotesActivityTest { @Rule var activity = ActivityTestRule(NotesActivity::class.java) @Test fun notesActivityTest2() { onView(allOf(withParent(withId(R.id.my_button)),isDisplayed())) .perform(click()); } }

Slide 16

Slide 16 text

#devfestbkk @RunWith(AndroidJUnit4::class) class NotesActivityTest { @Rule var activity = ActivityTestRule(NotesActivity::class.java) @Test fun notesActivityTest2() { onView(allOf(withParent(withId(R.id.my_button)),isDisplayed())) .perform(click()); } }

Slide 17

Slide 17 text

#devfestbkk @RunWith(AndroidJUnit4::class) class NotesActivityTest { @Rule var activity = ActivityTestRule(NotesActivity::class.java) @Test fun notesActivityTest2() { onView(allOf(withParent(withId(R.id.my_button)),isDisplayed())) .perform(click()); } } @RunWith(AndroidJUnit4.class) public class NotesActivityTest { @Rule public ActivityTestRule activity = new ActivityTestRule<>(Activity.class); @Test public void notesActivityTest2() { onView(allOf(withParent(withId(R.id.my_button)),isDisplayed())) .perform(click()); } }

Slide 18

Slide 18 text

#devfestbkk

Slide 19

Slide 19 text

#devfestbkk DSL

Slide 20

Slide 20 text

#devfestbkk DSL Domain Specific Language

Slide 21

Slide 21 text

#devfestbkk body { background-color: lightblue; }

Slide 22

Slide 22 text

#devfestbkk apply plugin: 'com.android.application' apply plugin: 'kotlin-android' android { compileSdkVersion 25 buildToolsVersion "26.0.0" defaultConfig { applicationId "bkk.firebase.com.myapplication" minSdkVersion 15 targetSdkVersion 26 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } }

Slide 23

Slide 23 text

#devfestbkk verticalLayout { padding = dip(32) imageView(android.R.drawable.ic_menu_manage).lparams { margin = dip(16) gravity = Gravity.CENTER } val name = editText { hintResource = R.string.name } val password = editText { hintResource = R.string.password inputType = TYPE_CLASS_TEXT or TYPE_TEXT_VARIATION_PASSWORD } button("Log in") { onClick { ui.owner.tryLogin(ui, name.text, password.text) } } myRichView() }.applyRecursively(customStyle)

Slide 24

Slide 24 text

#devfestbkk DSL +

Slide 25

Slide 25 text

#devfestbkk Kotin in Action

Slide 26

Slide 26 text

#devfestbkk Lambdas

Slide 27

Slide 27 text

#devfestbkk { x : Int, y: Int -> x + y } Lambdas

Slide 28

Slide 28 text

buttonSend.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View v){ send(); } }); #devfestbkk

Slide 29

Slide 29 text

buttonSend.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View v){ send(); } }); buttonSend.setOnClickListener(object :OnClickListener{ override fun onClick(view : View){ send(); } }) #devfestbkk

Slide 30

Slide 30 text

buttonSend.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View v){ send(); } }); buttonSend.setOnClickListener(object :OnClickListener{ override fun onClick(view : View){ send(); } }) buttonSend.setOnClickListener(View.OnClickListener { view : View -> doSomething() } #devfestbkk

Slide 31

Slide 31 text

#devfestbkk /** * Calls the specified function [block] with `this` value as its receiver and returns `this` value. */ @kotlin.internal.InlineOnly public inline fun T.apply(block: T.() -> Unit): T { block(); return this }

Slide 32

Slide 32 text

#devfestbkk /** * Calls the specified function [block] with `this` value as its receiver and returns `this` value. */ @kotlin.internal.InlineOnly public inline fun T.apply(block: T.() -> Unit): T { block(); return this } fun alphabet() = StringBuilder().apply { for (letter in 'A'..'Z') { append(letter) } append("\nNow I know the alphabet!") }.toString()

Slide 33

Slide 33 text

#devfestbkk /** * Calls the specified function [block] with `this` value as its receiver and returns `this` value. */ @kotlin.internal.InlineOnly public inline fun T.apply(block: T.() -> Unit): T { block(); return this } /** * Calls the specified function [block] with the given [receiver] as its receiver and returns its result. */ @kotlin.internal.InlineOnly public inline fun with(receiver: T, block: T.() -> R): R = receiver.block()

Slide 34

Slide 34 text

#devfestbkk /** * Calls the specified function [block] with `this` value as its receiver and returns `this` value. */ @kotlin.internal.InlineOnly public inline fun T.apply(block: T.() -> Unit): T { block(); return this } /** * Calls the specified function [block] with the given [receiver] as its receiver and returns its result. */ @kotlin.internal.InlineOnly public inline fun with(receiver: T, block: T.() -> R): R = receiver.block() fun alphabet() = with(StringBuilder()) { for (letter in 'A'..'Z') { append(letter) } append("\nNow I know the alphabet!") toString() }

Slide 35

Slide 35 text

#devfestbkk infix fun T.execute(fn: T.() -> Unit) = this.fn()

Slide 36

Slide 36 text

#devfestbkk infix fun T.execute(fn: T.() -> Unit) = this.fn() val myFragment = Fragment() myFragment execute { onPause() onDestroy() }

Slide 37

Slide 37 text

#devfestbkk infix fun T.execute(fn: T.() -> Unit) = this.fn() val myFragment = Fragment() myFragment execute { onPause() onDestroy() }

Slide 38

Slide 38 text

#devfestbkk Kakao

Slide 39

Slide 39 text

#devfestbkk Kakao Ilya Ivan Konstantin Zoey

Slide 40

Slide 40 text

#devfestbkk @Test fun test() { screen { content { isVisible() } textViewLarge { click() isVisible() hasAnyText() } } }

Slide 41

Slide 41 text

#devfestbkk androidTestCompile 'com.agoda.kakao:kakao:1.0.0'

Slide 42

Slide 42 text

#devfestbkk class TestActivityScreen: Screen()

Slide 43

Slide 43 text

#devfestbkk class TestActivityScreen: Screen() val content: KView = KView { withId(R.id.content) } val textViewLarge: KTextView = KTextView { withId(R.id.text_view_small) }

Slide 44

Slide 44 text

#devfestbkk @Test fun test() { screen { content { isVisible() } textViewLarge { click() isVisible() hasAnyText() } } }

Slide 45

Slide 45 text

#devfestbkk @Test fun test() { screen { content { isVisible() } textViewLarge { click() isVisible() hasAnyText() } } } @Test fun notesActivityTest2() { onView(allOf(withParent(withId(R.id.my_button)),isDisplayed())) .perform(click()); }

Slide 46

Slide 46 text

#devfestbkk https://github.com/agoda-com/Kakao

Slide 47

Slide 47 text

#devfestbkk https://github.com/agoda-com/Kakao

Slide 48

Slide 48 text

#devfestbkk Birth/Ju/Inaki