Slide 1

Slide 1 text

KotlinͰAndroid։ൃ Λؾ࣋ͪΑ͘͠Α͏ Benoît Quenaudon @oldergod

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

Data Class

Slide 5

Slide 5 text

public final class Task { @NonNulla private final String id; @Nullableb private final String title; @Nullablec private final String description; private final boolean completed; public Task(@Nullable String title, @Nullable String description, @NonNull String id, boolean completed) { this.id = id; this.title = title; this.description = description; this.completed = completed; }a }l

Slide 6

Slide 6 text

this.description = description; this.completed = completed; }a @NonNulld public String getId() { return id; }b @Nullablee public String getTitle() { return title; }c @Nullablef public String getTitleForList() { if (!Strings.isNullOrEmpty(title)) { return title; } else { return description; }z }d @Nullableg public String getDescription() { return description; }e public boolean isCompleted() { return completed; }f public boolean isActive() { return !completed; }g public boolean isEmpty() { return Strings.isNullOrEmpty(title) && Strings.isNullOrEmpty(description); }h }l

Slide 7

Slide 7 text

}e public boolean isCompleted() { return completed; }f public boolean isActive() { return !completed; }g public boolean isEmpty() { return Strings.isNullOrEmpty(title) && Strings.isNullOrEmpty(description); }h @Overrideh public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Task task = (Task) o; return Objects.equal(id, task.id) && Objects.equal(title, task.title) && Objects.equal(description, task.description); }i @Overridei public int hashCode() { return Objects.hashCode(id, title, description); }j @Overridej public String toString() { return "Task with title " + title; }k }l

Slide 8

Slide 8 text

public final class Task { @NonNulla private final String id; @Nullableb private final String title; @Nullablec private final String description; private final boolean completed; public Task(@Nullable String title, @Nullable String description, @NonNull String id, boolean completed) { this.id = id; this.title = title; this.description = description; this.completed = completed; }a @NonNulld public String getId() { return id; }b @Nullablee public String getTitle() { return title; }c @Nullablef public String getTitleForList() { if (!Strings.isNullOrEmpty(title)) { return title; } else { return description; } }d @Nullableg public String getDescription() { return description; }e public boolean isCompleted() { return completed; }f public boolean isActive() { return !completed; }g public boolean isEmpty() { return Strings.isNullOrEmpty(title) && Strings.isNullOrEmpty(description); }h @Overrideh public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Task task = (Task) o; return Objects.equal(id, task.id) && Objects.equal(title, task.title) && Objects.equal(description, task.description); }i @Overridei public int hashCode() { return Objects.hashCode(id, title, description); }j @Overridej public String toString() { return "Task with title " + title; }k }l

Slide 9

Slide 9 text

@Getter @AllArgsConstructor @EqualsAndHashCode @ToString public final class Task { @NonNull private final String id; @Nullable private final String title; @Nullable private final String description; private final boolean completed; @Nullable public String getTitleForList() { if (!Strings.isNullOrEmpty(title)) { return title; } else { return description; } } public boolean isActive() { return !completed; } public boolean isEmpty() { return Strings.isNullOrEmpty(title) && Strings.isNullOrEmpty(description); } } Lombok

Slide 10

Slide 10 text

@AutoValue public abstract class Task { @NonNull abstract String getId(); @Nullable abstract String getTitle(); @Nullable abstract String getDescription(); abstract boolean isCompleted(); public static Task create(@Nullable String title, @Nullable String description, @NonNull String id, boolean completed) { return new AutoValue_Task(id, title, description, completed); } public boolean isActive() { return !isCompleted(); } @Nullable public String getTitleForList() { if (!Strings.isNullOrEmpty(getTitle())) { return getTitle(); } else { return getDescription(); } } public boolean isEmpty() { return Strings.isNullOrEmpty(getTitle()) && Strings.isNullOrEmpty(getDescription()); } } AutoValue

Slide 11

Slide 11 text

data class Task( val id: String, val title: String?, val description: String?, val completed: Boolean ) { val titleForList = if (title.isNotNullNorEmpty()) { title } else { description } val active = !completed val empty = title.isNullOrEmpty() && description.isNullOrEmpty() } Kotlin

Slide 12

Slide 12 text

data class Task( val id: String, val title: String?, val description: String?, var completed: Boolean )

Slide 13

Slide 13 text

data class Task( val id: String, val title: String?, val description: String?, var completed: Boolean ) • constructor • getters • setters (var only) • toString • equals & hashCode • copy • componentN

Slide 14

Slide 14 text

data class Task( val id: String, val title: String?, val description: String?, var completed: Boolean ) • constructor • getters • setters (var only) • toString • equals & hashCode • copy • componentN

Slide 15

Slide 15 text

data class Task( val id: String, val title: String?, val description: String?, var completed: Boolean ) • constructor • getters • setters (var only) • toString • equals & hashCode • copy • componentN

Slide 16

Slide 16 text

data class Task( val id: String, val title: String?, val description: String?, var completed: Boolean ) • constructor • getters • setters (var only) • toString • equals & hashCode • copy • componentN

Slide 17

Slide 17 text

data class Task( val id: String, val title: String?, val description: String?, var completed: Boolean ) • constructor • getters • setters (var only) • toString • equals & hashCode • copy • componentN

Slide 18

Slide 18 text

data class Task( val id: String, val title: String?, val description: String?, var completed: Boolean ) • constructor • getters • setters (var only) • toString • equals & hashCode • copy • componentN

Slide 19

Slide 19 text

data class Task( val id: String, val title: String?, val description: String?, var completed: Boolean ) • constructor • getters • setters (var only) • toString • equals & hashCode • copy • componentN

Slide 20

Slide 20 text

Sealed Class

Slide 21

Slide 21 text

sealed class ViewHolder { data class HeaderViewHolder(val text: String) : ViewHolder() class ItemViewHolder(val data: String) : ViewHolder() object LoadingViewHolder : ViewHolder() }z

Slide 22

Slide 22 text

sealed class ViewHolder { data class HeaderViewHolder(val text: String) : ViewHolder() class ItemViewHolder(val data: String) : ViewHolder() object LoadingViewHolder : ViewHolder() }z

Slide 23

Slide 23 text

sealed class ViewHolder { data class HeaderViewHolder(val text: String) : ViewHolder() class ItemViewHolder(val data: String) : ViewHolder() object LoadingViewHolder : ViewHolder() }z

Slide 24

Slide 24 text

sealed class ViewHolder { data class HeaderViewHolder(val text: String) : ViewHolder() class ItemViewHolder(val data: String) : ViewHolder() object LoadingViewHolder : ViewHolder() }z

Slide 25

Slide 25 text

sealed class ViewHolder { data class HeaderViewHolder(val text: String) : ViewHolder() class ItemViewHolder(val data: String) : ViewHolder() object LoadingViewHolder : ViewHolder() }z

Slide 26

Slide 26 text

sealed class ViewHolder(val root: View) : RecyclerView.ViewHolder(view) { class HeaderViewHolder(root: View) : ViewHolder(root) class ItemViewHolder(root: View) : ViewHolder(root) class LoadingViewHolder(root: View) : ViewHolder(root) }z

Slide 27

Slide 27 text

sealed class ViewHolder(val root: View) : RecyclerView.ViewHolder(view) { class HeaderViewHolder(root: View) : ViewHolder(root) class ItemViewHolder(root: View) : ViewHolder(root) class LoadingViewHolder(root: View) : ViewHolder(root) }z

Slide 28

Slide 28 text

sealed class ViewHolder(val root: View) : RecyclerView.ViewHolder(view) { class HeaderViewHolder(root: View) : ViewHolder(root) class ItemViewHolder(root: View) : ViewHolder(root) class LoadingViewHolder(root: View) : ViewHolder(root) }z

Slide 29

Slide 29 text

override fun onBindViewHolder(holder: ViewHolder, position: Int) { return when (holder) { is HeaderViewHolder -> { /*****/ } is ItemViewHolder -> { /*****/ } is LoadingViewHolder -> { /*****/ } } }

Slide 30

Slide 30 text

sealed class ViewHolder(val root: View) : RecyclerView.ViewHolder(view) { class HeaderViewHolder(root: View) : ViewHolder(root) class ItemViewHolder(root: View) : ViewHolder(root) class LoadingViewHolder(root: View) : ViewHolder(root) }d

Slide 31

Slide 31 text

sealed class ViewHolder(val root: View) : RecyclerView.ViewHolder(view) { class HeaderViewHolder(root: View) : ViewHolder(root) class ItemViewHolder(root: View) : ViewHolder(root) class LoadingViewHolder(root: View) : ViewHolder(root) class FooterViewHolder(root: View) : ViewHolder(root) }d

Slide 32

Slide 32 text

override fun onBindViewHolder(holder: ViewHolder, position: Int) { return when (holder) { is HeaderViewHolder -> { /*****/ } is ItemViewHolder -> { /*****/ } is LoadingViewHolder -> { /*****/ } } }

Slide 33

Slide 33 text

override fun onBindViewHolder(holder: ViewHolder, position: Int) { return when (holder) { is HeaderViewHolder -> { /*****/ } is ItemViewHolder -> { /*****/ } is LoadingViewHolder -> { /*****/ } }z }d

Slide 34

Slide 34 text

override fun onBindViewHolder(holder: ViewHolder, position: Int) { return when (holder) { is HeaderViewHolder -> { /*****/ } is ItemViewHolder -> { /*****/ } is LoadingViewHolder -> { /*****/ } is FooterViewHolder -> { /*****/ }f }z }d

Slide 35

Slide 35 text

override fun onBindViewHolder(holder: ViewHolder, position: Int) { return when (holder) { is HeaderViewHolder -> { /*****/ } is ItemViewHolder -> { /*****/ } is LoadingViewHolder -> { /*****/ } is FooterViewHolder -> { /*****/ }f }z }d

Slide 36

Slide 36 text

override fun onBindViewHolder(holder: ViewHolder, position: Int) { return when (holder) { is HeaderViewHolder -> { /*****/ } is ItemViewHolder -> { /*****/ } is LoadingViewHolder -> { /*****/ } is FooterViewHolder -> { val footerVH = holder as FooterViewHolder footerVH.stuff() }f }z }d

Slide 37

Slide 37 text

override fun onBindViewHolder(holder: ViewHolder, position: Int) { return when (holder) { is HeaderViewHolder -> { /*****/ } is ItemViewHolder -> { /*****/ } is LoadingViewHolder -> { /*****/ } is FooterViewHolder -> { holder.stuff() }f }z }d

Slide 38

Slide 38 text

override fun onBindViewHolder(holder: ViewHolder, position: Int) { return when (holder) { is HeaderViewHolder -> { /*****/ } is ItemViewHolder -> { /*****/ } is LoadingViewHolder -> { /*****/ } is FooterViewHolder -> { /*****/ }f }z }d

Slide 39

Slide 39 text

Collections API

Slide 40

Slide 40 text

List actions; List tasks = new ArrayList<>(actions.size()); for (Action action : actions) { Task task = new Task(action.title(), action.description()); tasks.add(task); }

Slide 41

Slide 41 text

List actions; List tasks = new ArrayList<>(actions.size()); for (Action action : actions) { Task task = new Task(action.title(), action.description()); tasks.add(task); }

Slide 42

Slide 42 text

List actions; List tasks = new ArrayList<>(actions.size()); for (Action action : actions) { Task task = new Task(action.title(), action.description()); tasks.add(task); }

Slide 43

Slide 43 text

List actions; List tasks = new ArrayList<>(actions.size()); for (Action action : actions) { Task task = new Task(action.title(), action.description()); tasks.add(task); }

Slide 44

Slide 44 text

List actions; List tasks = new ArrayList<>(actions.size()); for (Action action : actions) { Task task = new Task(action.title(), action.description()); tasks.add(task); }

Slide 45

Slide 45 text

List actions; List tasks = new ArrayList<>(actions.size()); for (Action action : actions) { Task task = new Task(action.title(), action.description()); tasks.add(task); }

Slide 46

Slide 46 text

valaactions:zList valbtasksz= ArrayList(actions.size) for (action in actions) { valctask = Task(action.title, action.description) tasks.add(task) }

Slide 47

Slide 47 text

valaactions:zList valbtasksz= actions.map { Task(it.title, it.description) }

Slide 48

Slide 48 text

• map() • filter() • find() • distinct() • any() • groupBy() • zip() • …

Slide 49

Slide 49 text

• map() • filter() • find() • distinct() • any() • groupBy() • zip() • … val list: List = listOf(1, 2, 3) val map: Map = mapOf("a" to 1, "b" to 2) val set: Set = setOf("a", "b", “c")

Slide 50

Slide 50 text

• map() • filter() • find() • distinct() • any() • groupBy() • zip() • … val list: List = listOf(1, 2, 3) val map: Map = mapOf("a" to 1, "b" to 2) val set: Set = setOf("a", "b", “c")

Slide 51

Slide 51 text

Lazy Delegate

Slide 52

Slide 52 text

private lateinit var viewModel: TaskViewModel private lateinit var taskId: String override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) viewModel = ViewModelProviders .of(this, ViewModelFactory()) .get(TaskViewModel::class.java) taskId = arguments?.getString(ARGUMENT_EDIT_TASK_ID) }c

Slide 53

Slide 53 text

private lateinit var viewModel: TaskViewModel private lateinit var taskId: String override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) viewModel = ViewModelProviders .of(this, ViewModelFactory()) .get(TaskViewModel::class.java) taskId = arguments?.getString(ARGUMENT_EDIT_TASK_ID) }c

Slide 54

Slide 54 text

private lateinit var viewModel: TaskViewModel private lateinit var taskId: String override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) viewModel = ViewModelProviders .of(this, ViewModelFactory()) .get(TaskViewModel::class.java) taskId = arguments?.getString(ARGUMENT_EDIT_TASK_ID) }c

Slide 55

Slide 55 text

private lateinit var viewModel: TaskViewModel private lateinit var taskId: String override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) viewModel = ViewModelProviders .of(this, ViewModelFactory()) .get(TaskViewModel::class.java) taskId = arguments?.getString(ARGUMENT_EDIT_TASK_ID) }c

Slide 56

Slide 56 text

private val viewModel: TaskViewModel by lazy { ViewModelProviders .of(this, ViewModelFactory()) .get(TaskViewModel::class.java) }x private val taskId: String by lazy { arguments?.getString(ARGUMENT_EDIT_TASK_ID) }y override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) }c

Slide 57

Slide 57 text

private val viewModel: TaskViewModel by lazy { ViewModelProviders .of(this, ViewModelFactory()) .get(TaskViewModel::class.java) }x private val taskId: String by lazy { arguments?.getString(ARGUMENT_EDIT_TASK_ID) }y override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) }c

Slide 58

Slide 58 text

private val viewModel: TaskViewModel by lazy { ViewModelProviders .of(this, ViewModelFactory()) .get(TaskViewModel::class.java) }x private val taskId: String by lazy { arguments?.getString(ARGUMENT_EDIT_TASK_ID) }y override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) }c

Slide 59

Slide 59 text

private val viewModel: TaskViewModel by lazy { ViewModelProviders .of(this, ViewModelFactory()) .get(TaskViewModel::class.java) }x private val taskId: String by lazy { arguments?.getString(ARGUMENT_EDIT_TASK_ID) }y override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) }c

Slide 60

Slide 60 text

private val viewModel: TaskViewModel by lazy { ViewModelProviders .of(this, ViewModelFactory()) .get(TaskViewModel::class.java) }x private val taskId: String by lazy { arguments?.getString(ARGUMENT_EDIT_TASK_ID) }y override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) }

Slide 61

Slide 61 text

Operators

Slide 62

Slide 62 text

class TaskDetailFragment(val taskId: String) : Fragment()

Slide 63

Slide 63 text

class TaskDetailFragment(val taskId: String) : Fragment() val fragment = TaskDetailFragment(taskId)

Slide 64

Slide 64 text

class TaskDetailFragment(val taskId: String) : Fragment() val fragment = TaskDetailFragment(taskId)

Slide 65

Slide 65 text

class TaskDetailFragment(val taskId: String) : Fragment() val fragment = TaskDetailFragment(taskId)

Slide 66

Slide 66 text

val fragment = TaskDetailFragment()

Slide 67

Slide 67 text

val fragment = TaskDetailFragment() val bundle = Bundle() bundle.putString(ARGUMENT_TASK_ID, taskId)

Slide 68

Slide 68 text

val fragment = TaskDetailFragment() val bundle = Bundle() bundle.putString(ARGUMENT_TASK_ID, taskId) fragment.arguments = bundle

Slide 69

Slide 69 text

class TaskDetailFragment : Fragment() { companion object { fun newInstance(taskId: String): TaskDetailFragment { val fragment = TaskDetailFragment() val bundle = Bundle() bundle.putString(ARGUMENT_TASK_ID, taskId) fragment.arguments = bundle return fragment }a }b }c

Slide 70

Slide 70 text

class TaskDetailFragment : Fragment() { companion object { fun newInstance(taskId: String): TaskDetailFragment { val fragment = TaskDetailFragment() val bundle = Bundle() bundle.putString(ARGUMENT_TASK_ID, taskId) fragment.arguments = bundle return fragment }a }b }c val fragment = TaskDetailFragment.newInstance(taskId)

Slide 71

Slide 71 text

class TaskDetailFragment : Fragment() { companion object { fun newInstance(taskId: String): TaskDetailFragment { val fragment = TaskDetailFragment() val bundle = Bundle() bundle.putString(ARGUMENT_TASK_ID, taskId) fragment.arguments = bundle return fragment }a }b }c val fragment = TaskDetailFragment.newInstance(taskId)

Slide 72

Slide 72 text

class TaskDetailFragment : Fragment() { companion object { operator fun invoke(taskId: String): TaskDetailFragment { val fragment = TaskDetailFragment() val bundle = Bundle() bundle.putString(ARGUMENT_TASK_ID, taskId) fragment.arguments = bundle return fragment }a }b }c val fragment = TaskDetailFragment.newInstance(taskId)

Slide 73

Slide 73 text

class Foo() { operator fun invoke(): String { return "invoked !" } } fun main(args: Array) { val foo: Foo = Foo() println(foo()) // invoked ! }

Slide 74

Slide 74 text

class TaskDetailFragment : Fragment() { companion object { operator fun invoke(taskId: String): TaskDetailFragment { val fragment = TaskDetailFragment() val bundle = Bundle() bundle.putString(ARGUMENT_TASK_ID, taskId) fragment.arguments = bundle return fragment }a }b }c val fragment = TaskDetailFragment.newInstance(taskId)

Slide 75

Slide 75 text

class TaskDetailFragment : Fragment() { companion object { operator fun invoke(taskId: String): TaskDetailFragment { val fragment = TaskDetailFragment() val bundle = Bundle() bundle.putString(ARGUMENT_TASK_ID, taskId) fragment.arguments = bundle return fragment }a }b }c val fragment = TaskDetailFragment.newInstance(taskId)

Slide 76

Slide 76 text

class TaskDetailFragment : Fragment() { companion object { operator fun invoke(taskId: String): TaskDetailFragment { val fragment = TaskDetailFragment() val bundle = Bundle() bundle.putString(ARGUMENT_TASK_ID, taskId) fragment.arguments = bundle return fragment }a }b }c val fragment = TaskDetailFragment(taskId)

Slide 77

Slide 77 text

class TaskDetailFragment : Fragment() { companion object { operator fun invoke(taskId: String): TaskDetailFragment { val fragment = TaskDetailFragment() val bundle = Bundle() bundle.putString(ARGUMENT_TASK_ID, taskId) fragment.arguments = bundle return fragment }a }b }c val fragment = TaskDetailFragment(taskId)

Slide 78

Slide 78 text

class TaskDetailFragment : Fragment() { companion object { operator fun invoke(taskId: String): TaskDetailFragment { val fragment = TaskDetailFragment() val bundle = Bundle() bundle.putString(ARGUMENT_TASK_ID, taskId) fragment.arguments = bundle return fragment }a }b }c val fragment = TaskDetailFragment(taskId)

Slide 79

Slide 79 text

class TaskDetailFragment : Fragment() { companion object { operator fun invoke(taskId: String): TaskDetailFragment { val fragment = TaskDetailFragment() val bundle = Bundle().apply { this.putString(ARGUMENT_TASK_ID, taskId) }p fragment.arguments = bundle return fragment }a }b }c val fragment = TaskDetailFragment(taskId)

Slide 80

Slide 80 text

class TaskDetailFragment : Fragment() { companion object { operator fun invoke(taskId: String): TaskDetailFragment { val fragment = TaskDetailFragment() val bundle = Bundle().apply { putString(ARGUMENT_TASK_ID, taskId) }p fragment.arguments = bundle return fragment }a }b }c val fragment = TaskDetailFragment(taskId)

Slide 81

Slide 81 text

class TaskDetailFragment : Fragment() { companion object { operator fun invoke(taskId: String): TaskDetailFragment { val fragment = TaskDetailFragment() fragment.arguments = Bundle().apply { putString(ARGUMENT_TASK_ID, taskId) }p return fragment }a }b }c val fragment = TaskDetailFragment(taskId)

Slide 82

Slide 82 text

class TaskDetailFragment : Fragment() { companion object { operator fun invoke(taskId: String): TaskDetailFragment { val fragment = TaskDetailFragment().apply { arguments = Bundle().apply { putString(ARGUMENT_TASK_ID, taskId) }p }p return fragment }a }b }c val fragment = TaskDetailFragment(taskId)

Slide 83

Slide 83 text

class TaskDetailFragment : Fragment() { companion object { operator fun invoke(taskId: String): TaskDetailFragment { return TaskDetailFragment().apply { arguments = Bundle().apply { putString(ARGUMENT_TASK_ID, taskId) }p }p }a }b }c val fragment = TaskDetailFragment(taskId)

Slide 84

Slide 84 text

class TaskDetailFragment : Fragment() { companion object { operator fun invoke(taskId: String) = TaskDetailFragment().apply { arguments = Bundle().apply { putString(ARGUMENT_TASK_ID, taskId) }p }p }a }b }c val fragment = TaskDetailFragment(taskId)

Slide 85

Slide 85 text

class TaskDetailFragment : Fragment() { companion object { operator fun invoke(taskId: String) = TaskDetailFragment().apply { arguments = Bundle().apply { putString(ARGUMENT_TASK_ID, taskId) }p }p }a }b }c val fragment = TaskDetailFragment(taskId)

Slide 86

Slide 86 text

Fin Benoît Quenaudon @oldergod