Kotlin ááœáẠááá¯ážááŸááºážáá±á¬ á¡ááŒá¶ááŒá¯áá»áẠááœááºáá»ááºáááºážááᯠáááºáá®ážáááºážááᯠááá·áºá¡á¬áž ááŒááá¬ážáááºá ááá¯ááá¯áááá»á
á±áááºá¡ááœááºá Kotlin 1.3.21á Android 4á Android Studio 3á Android á¡ááºááºáá®áá±ážááŸááºážáá»á¬áž áá®ááœááºáááºáá®ážáá¬ááœáẠáááºážááá¯á·áááá®ážááᯠá
áááºáá°áá»á¬ážá¡ááœáẠááááá¯á¶ážá¡áá±ááŒáá·áº á€áá±á¬ááºážáá«ážááẠá
áááºáááºá
á¬ážá
áá¬áá±á¬ááºážáááºááŒá
áºáááºá áááºážááẠááá·áºá¡á¬áž á¡ááá®áá±ážááŸááºážá¡ááœááºáž áááºááá·áºá¡áá¬ááŸáá·áº áááºááá¯á·á¡áá¯ááºáá¯ááºáááºááᯠáá¬ážáááºááá¯ááºá
á±áá«áááºá
á
á¬ážáá±á¬ááºááá¯áẠááá¯á·ááá¯áẠáá±á¬áºáá®ááá¯ááºááœáẠá¡áá»áááºááŒá¯ááºážááẠáá¯á¶ážááŒááºááá·áº áá¯áá¹ááá®áá
áºáá¯á០á¡ááŒá¶ááŒá¯áá»áẠááá¬áááᯠááœááºáá»ááºááẠááá¯á¡ááºááá·áºá¡áá« ááá¯ááááºážááœááºá
ááºááẠá¡áá¯á¶ážáááºáááºá áá¯ááºáá«áááºá áá°ááá¯ááºážá á
á¬ážááœá²ááá¯ážááœá±á¡ááœáẠáááºáááºáááºááᯠá¡ááŒá²ááá»ááºáá¬ážáá«áá°ážá áá«á á¡áá±á¬ááºááá¯ááºáž á¡á
ááºá¡áá¬áá
áºáá¯áá«áá²á áá«áá±ááá·áº áá®ááᯠá¡ááºááá®áá±ážááŸááºážááᯠáá®ááœááºáá²á· áá¯ááºáááºážá
ááºá áááºááá¯áá²ááŒá
áºááŒá
Ạá
áááºáááºá
á¬ážá
áá¬áá«áá²á
áá«ááá¯á·áááºážááá¯ááááá±ážááẠ"Habr" áá á¬áááºáá°á¡á¬ážáá¯á¶ážá¡ááœáẠ- "Habr" áááá¯ááá¯ážááŸááºážáá¯ááºááᯠá¡áá¯á¶ážááŒá¯á áááºááá·áº Skillbox áááºáááºážááœááºá á¬áááºážááœááºážááá·áºá¡áá« 10 áá°áááºáá»áŸá±á¬á·á á»á±ážá
Skillbox á០á¡ááŒá¶ááŒá¯áá¬ážáááº- áááºááœá±á·áááºáááºáž
"ááá¯ááá¯ááºáž Developer PRO .
áááºážááẠáá¯ááºáá±á¬ááºáá»ááºááœáẠá¡ááá®áá±ážááŸááºážááá¯á¶ááá¹áá¬ááºááŒá áºáááºá
áááºááẠá
á¯á
á¯áá±á«ááºážááá¬áá ááá¯áá»ááºáá±á¬áá¬ááá¯ááºááŸá¯ááºážá á¡á
ááºážá¡áá±ážááœááºáá«áááºáá°á¡áá±á¡ááœááºááᯠááá·áºááœááºážááŒá®áž ááááºááá¯ááá°áá« - áá»ááºáá¬ážááá·áºáá±á¬ á¡ááŒá¶ááŒá¯áá»ááºááá¬áá
á áááº
á¡ááºááºá á¡ááºáá¬áá±á·á
Ạá¡ááŒáá·áºá¡á
á¯á¶ááŸá¬ á€áá²á·ááá¯á· ááŒá
áºáááº-
ááááá¯ááºáá±á¬ááºáá»ááº-
á¡áá¯á¶ážááŒá¯áá° áá¯ááºáá±á¬ááºáá»ááºáá»á¬ážááᯠááá±á¬áá»ááºááœáẠá¡áá»áááºááŸáá·áº áááŒá±ážáá® áá±ážáá¬ážáá±á¬ááŒá±á¬áá·áº á¡áá¬á¡á¬ážáá¯á¶áž ááŸááºážáááºážááŒááºáá¬ážáááºá áááºážááá¯ááŒáá·áºááŸá¯ááẠView -> Tool Windows -> TODO ááá¯ááœáá·áºáá«á
áá»áœááºá¯ááºááá¯á·ááẠááá±á¬áá»ááºááᯠáá±á·áá¬ááŒá®áž á¡áá±á¬áẠpalette ááᯠá¡áá²ááŒááºááẠColors.xml ááá¯ááœáá·áºáá«á strings.xml ááœáẠá á¬áá¬ážáá±áᬠ(á á¬áááºážáá»á¬áž) áá«áááºááŒá®áž styles.xml ááœáẠáá±á¬áá·áºáá¯á¶á á¶áá¯á¶á á¶áá»á¬ážá áœá¬ áá«ááŸááááºá
áá¯ááºáá»á ááááºá¡ááá¯ááºáž ááœá¶á·ááŒáá¯ážááá¯ážáááºáá±áž
activity_main.xml ááá¯ááœáá·áºááŒá®áž LinearLayout (#1) ááœáẠá¡á±á¬ááºáá«áá¯ááºááᯠááá·áºáá«á
<TextView
android_id="@+id/expensePerPersonTextView"
android_layout_width="match_parent"
android_layout_height="wrap_content"
android_paddingTop="30dp"
style="@style/h1Bold"
android_textColor="@color/colorAccent"
android_text="0"/>
<TextView
android_layout_width="match_parent"
android_layout_height="wrap_content"
android_paddingBottom="25dp"
style="@style/h2"
android_textColor="@color/colorAccent"
android_text="@string/perPersonStaticText"/>
ááá¯áááºááẠáááºááá¯ážáá»á¬ážáááºážááœáŸááºááᯠáá¯á¶á
á¶ááœááºážááá¯ááºááẠááá¯á·ááá¯áẠá¡áá±á¬ááºáá»á¬ážááᯠá¡áá¯á¶ážááŒá¯á áá
á¬ážááá¯ááºáááºá
ááᯠááá±á¬áá»ááºááẠá€áá²á·ááá¯á· ááŒá áºáááº-
áááºááœá±á·ááŒááºáááá·áºá¡ááá¯ááºážá á¡áá¯á¶ážááŒá¯áá°ááá·áºááœááºážááá·áºáá±áá¬á¡áá±á«áºá¡ááŒá±áá¶á áá¯ááºáá»á
ááááºáá»á¬ážááᯠááœááºáá»ááºáá«áááºá
á¡áá±á¬áá·áºááœá¶á·ááŒáá¯ážááá¯ážáááºááŸá¯á¡ááá¯ááºáž
áá¯ááºáá»á ááááºá¡ááá¯ááºáž (#2) ááŒá®ážáá±á¬áẠLinearLayout ááœáẠá¡á±á¬ááºáá«áá¯ááºááᯠááá·áºáá«á
<LinearLayout
android_layout_width="match_parent"
android_layout_height="match_parent"
android_orientation="vertical"
android_background="@color/colorAccent">
<! â TODO #3: Build Bill Section â
âŠ
</LinearLayout>
TODOs á á¬áááºážááŒá®ážáá±á¬áẠLinearLayout ááá¯ááááºááŒá®áž LinearLayout (#3) ááœááºááá·áºáᬠáá¯ááºá¡áá áºááá¯ááá·áºáá«á
<TextView
android_layout_margin="15dp"
android_layout_width="match_parent"
android_layout_height="wrap_content"
android_textColor="@color/colorWhite"
style="@style/h4"
android_text="@string/billStaticText"/>
<EditText
android_id="@+id/billEditText"
android_layout_width="match_parent"
android_layout_height="wrap_content"
android_textColor="@color/colorWhite"
android_inputType="numberDecimal"
android_maxLines="1"
style="@style/h2Bold"
android_text="0"/>
á¡ááá®áá±ážááŸááºážáá¡ááááá¬áááºááŸá¬ á á¬ážáá±á¬ááºááá¯ááºááŸáá á¯áá±ážááœá²áá»á¬ážááœááºáá«áááºáá°ááá¯ááºážá¡ááœáẠáá áºáŠážáá»ááºážáá¯ááºáá»á ááááºáá»á¬ážááᯠááœááºáá»ááºáááºááŒá áºáá±á¬ááŒá±á¬áá·áº costPerPersonTextView ááẠá¡áááá¡áááºážááá¹áááŸáá«áááºáááºá
EditText ááẠááá·áºááœááºážááŸá¯ááᯠá á¬ááŒá±á¬ááºážáá áºááŒá±á¬ááºážááœáẠááá·áºáááºáá¬ážááŒá®ážá á€ááá·áºáááºáá»ááºááᯠNumberDecimal inputType á¡ááŒá ẠáááºááŸááºááá«áááºá
áá»áœááºá¯ááºááá¯á·ááẠá
ááºážáááºááŒááºážá¡ááœáẠááá±á¬áá»ááºááᯠá
áááºááŒá®áž á
á¯á
á¯áá±á«ááºáž áá»ááºá
á®ážááŸá¯á áá±á¬ááºáá»á¬áž (ááœá²áá±áá±á¬ ááœááºáá»á¬ážá áááºážáááºáá»á¬áž á
áááº) ááᯠááá·áºááœááºážáá«á
"áá°áá»á¬ážááŸáá·áº á¡ááŒá¶á¥á¬ááºáá»á¬áž" ááá¹áááᯠááœá¶á·ááŒáá¯ážááá¯ážáááºáá±áž
á¡ááŒá¶ááŒá¯áá»áẠááá¬áááœá±ážáá»ááºáá±ážáá°ááᯠááá·áºáááºá á¡á±á¬ááºáá±á¬áºááŒáá« áá¯ááºááᯠLinearLayout á¡ááá¯ááºáž (#4) á¡áá áºááœáẠáá°ážááá·áºáá«á
<TextView
android_layout_margin="15dp"
android_layout_width="match_parent"
android_layout_height="wrap_content"
android_textColor="@color/colorWhite"
style="@style/h4"
android_text="@string/tipStaticText"/>
<LinearLayout
android_layout_width="match_parent"
android_layout_height="wrap_content"
android_orientation="horizontal">
<ImageButton
android_id="@+id/subtractTipButton"
style="@style/operationButton"
android_layout_marginLeft="20dp"
android_layout_marginStart="20dp"
android_src="@drawable/subtract"/>
<TextView
android_id="@+id/tipTextView"
android_layout_margin="15dp"
android_layout_width="0dp"
android_layout_height="wrap_content"
android_textColor="@color/colorWhite"
android_layout_weight="1"
style="@style/h2Bold"
android_text="20%"/>
<ImageButton
android_id="@+id/addTipButton"
style="@style/operationButton"
android_layout_marginEnd="20dp"
android_layout_marginRight="20dp"
android_src="@drawable/add"/>
</LinearLayout>
ááááºáá»á¬ážááá¬áááᯠáááá»á áœá¬ááœááºáá»ááºááẠá€áá¯ááºá¡ááá¯ááºážáá áºáᯠááá¯á¡ááºáá«áááºá áá°áááºážá á¬áá¬ážáááºááá¯ážááŸá¬ 20 ááŒá áºáááºá ImageButtons áá»á¬ážááᯠáá±ážáá¬ážááœáá·áºááœáá·áºááŒá¯áá»ááºáá«ááŸááá±á¬ ááá¯áá«áá áºáá¯ááœáẠá¡áá¯ááºááœááºáá»á¬áž áá±ážáá¬ážáááºá
á¡ááá¯ááºážááᯠá¡ááŒáá·áºá¡á á¯á¶áá°ážáá°ááŒá®áž á¡á±á¬ááºáá« (#5) ááᯠááá·áºáá«á
- ImageButton ids (subtractPeopleButtoná addPeopleButton)
- TextView ids (numberOfPeopleStaticTextá numberOfPeopleTextView)
- numberOfPeopleTextView á¡ááœáẠáá°áááºážá á¬áá¬áž (4 ááŒá áºááá·áºáááº)á
ááᯠá¡ááá®áá±ážááŸááºážááᯠá
áááºááá·áºá¡áá« ááŒá±á
á¬ááá¬áááᯠáá±á«ááºážááá·áºááá¯ááºáááºá Add/Subtract ááá¯ááºáá»á¬ážáááºáž á¡áá¯ááºáá¯ááºáá±á¬áºáááºáž ááá¯á¡áá»áááºá¡áá áá¬ááŸáááŒá
áºáá«á
ááŒááºááœááºážáá»á¬ážááá·áºáá«á
MainActivity.kt ááá¯ááœáá·áºááŒá®áž áááºážááᯠinitViews áá¯ááºáá±á¬ááºáá»áẠ(#6) ááá¯á·ááá·áºáá«á
private fun initViews() {
expensePerPersonTextView = findViewById(R.id.expensePerPersonTextView)
billEditText = findViewById(R.id.billEditText)
addTipButton = findViewById(R.id.addTipButton)
tipTextView = findViewById(R.id.tipTextView)
subtractTipButton = findViewById(R.id.subtractTipButton)
addPeopleButton = findViewById(R.id.addPeopleButton)
numberOfPeopleTextView = findViewById(R.id.numberOfPeopleTextView)
subtractPeopleButton = findViewById(R.id.subtractPeopleButton)
//TODO #8: Bind Buttons to Listener
//TODO #16: Bind EditText to TextWatcher
}
ááá¯ááºáá»á¬ážááᯠá¡ááŒá®ážáááºááŒááºážá
ááá¯ááºááŸáááºááŒááºážáá»á¬ážá¡ááœáẠáá¶á·ááá¯ážááŸá¯ááá·áºáááºá á¡áááºážá¡ááá·áº (#7) ááœáẠView.OnClickListener ááᯠá¡áá±á¬ááºá¡áááºáá±á¬áºáá«á
á¡áááºáž MainActivity- AppCompatActivity(), View.OnClickListener {
ááᯠááá±á¬áá»ááºááᯠááŒá¯á á¯ááŒááºážááẠá¡áá¯ááºáááŒá áºáá«á áá±á¬ááºááẠá¡ááá·áº (#8) ááᯠáááºáá¯ááºáá±á¬ááºááẠááá¯á¡ááºáá«áááºá
override fun onClick(v: View?) {
when (v?.id) {
R.id.addTipButton -> incrementTip()
R.id.subtractTipButton -> decrementTip()
R.id.addPeopleButton -> incrementPeople()
R.id.subtractPeopleButton -> decrementPeople()
}
}
ááá¯ááºáá»á¬ážááŸáá·áº ááá¯ááºáá»á¬ážááŸáá·áºáááºáááºá Kotlin ááẠá¡áá¬á¡á¬ážáá¯á¶ážááᯠá¡ááœááºáá±á¬ááºážááœááºá
áœá¬ á
á®áá¶áá¬ážáááºá á¡á±á¬ááºáá±á¬áºááŒáá« áá¯ááºááᯠá¡ááá¯ážááŸáá·áº á¡áá»áŸá±á¬á·áá¯ááºááá·áº áá¯ááºáá±á¬ááºáá»ááºáá»á¬ážá¡á¬ážáá¯á¶ážááœáẠááá·áºáá«á
(#9 â #12):
private fun incrementTip() {
if (tipPercent != MAX_TIP) {
tipPercent += TIP_INCREMENT_PERCENT
tipTextView.text = String.format("%d%%", tipPercent)
}
}
private fun decrementTip() {
if (tipPercent != MIN_TIP) {
tipPercent -= TIP_INCREMENT_PERCENT
tipTextView.text = String.format("%d%%", tipPercent)
}
}
private fun incrementPeople() {
if (numberOfPeople != MAX_PEOPLE) {
numberOfPeople += PEOPLE_INCREMENT_VALUE
numberOfPeopleTextView.text = numberOfPeople.toString()
}
}
private fun decrementPeople() {
if (numberOfPeople != MIN_PEOPLE) {
numberOfPeople -= PEOPLE_INCREMENT_VALUE
numberOfPeopleTextView.text = numberOfPeople.toString()
}
}
á€áá±áá¬ááœáẠáá¯ááºááẠá¡áá»á¬ážáá¯á¶ážáááºááá¯ážáá»á¬áž (MAX_TIP & MAX_PEOPLE) ááŒáá·áº ááá¯ážááŒáá·áºáá¯ááºáá±á¬ááºááŸá¯áá»á¬ážááᯠáá¬ááœááºáá±ážáá«áááºá ááá¯á·á¡ááŒááºá áá¯ááºááẠá¡áááá·áºáá¯á¶ážáááºááá¯ážáá»á¬áž (MIN_TIP & MIN_PEOPLE) ááŒáá·áº áá»áŸá±á¬á·áá»ááŒááºážáá¯ááºáá±á¬ááºáá»ááºáá»á¬ážááᯠáá¬ááœááºáá±ážáá«áááºá
ááᯠáá»áœááºá¯ááºááá¯á·ááẠinitViews áá¯ááºáá±á¬ááºáá»áẠ(#13) ááŸá áá¬ážáááºáá°áá»á¬ážááŸáá·áº ááá¯ááºáá»á¬ážááᯠáá»áááºááœá²áá¬ážáá«áááºá
private fun initViews() {
...
addTipButton.setOnClickListener(this)
subtractTipButton.setOnClickListener(this)
addPeopleButton.setOnClickListener(this)
subtractPeopleButton.setOnClickListener(this)
//TODO #15: Bind EditText to TextWatcher
}
ááᯠáááºááẠá
á¯á
á¯áá±á«ááºážáá»ááºá
á®ážáá¯á¶ážááŸá¯á¶ážááŸá¯á á¡ááŒá¶ááŒá¯áá»ááºáá»á¬ážááŸáá·áº á¡á
ááºážá¡áá±ážáááºáá±á¬ááºáá°á¡áá±á¡ááœááºááᯠááá·áºááœááºážááá¯ááºáá«ááŒá®á áá² á¡áá±ážááŒá®ážáá¯á¶ážá...
áá¯ááºáá»á ááááºá¡ááá¯ááºáž
á€áá¯ááºááẠáá¯ááºáá»á ááááºáá»á¬ážááᯠááœááºáá»ááºááẠ(#14)á
private fun calculateExpense() {
val totalBill = billEditText.text.toString().toDouble()
val totalExpense = ((HUNDRED_PERCENT + tipPercent) / HUNDRED_PERCENT) * totalBill
val individualExpense = totalExpense / numberOfPeople
expensePerPersonTextView.text = String.format("$%.2f", individualExpense)
}
áá±á¬ááºážááŒá®á á€áá±áá¬ááœáẠáá¯áá¹ááá®ááŸá áá°á¡áá±á¡ááœááºááᯠááá·áºááœááºážááœááºáá»ááºááŒá®áž á¡ááŒá¶ááŒá¯áá»áẠ(#15) ááᯠááœááºáá»ááºááá¯ááºá á±ááá·áº áá¯ááºáá±á¬ááºáá»ááºááᯠáá±á«áºáááºá
private fun incrementTip() {
âŠ
}
private fun decrementTip() {
âŠ
}
private fun incrementPeople() {
âŠ
}
private fun decrementPeople() {
âŠ
}
áá»áœááºá¯ááºááá¯á·ááẠá¡ááá®áá±ážááŸááºážááᯠá áááºááá¯ááºáá«á áá¯ááºáááºáá±á¬ááºážááœááºááŒá®áž á¡áá¯ááºáá¯ááºáá«áááºá áá«áá±ááá·áº ááá¯áá±á¬ááºážáá¬ááá¯ááºáááºá
áá±ááºááá¬áááᯠáááºááŸá¬ážááŒá®ážáá±á¬áẠá¡ááááºá¡ááŒáœáẠááá¯á·ááá¯áẠáá°áááºáá»ááºážá¡áá±á¡ááœááºááᯠááá¯ážááŒáŸáá·áºááẠááŒáá¯ážá á¬ážáá«áá áá¯ááºáá»á áááẠáá¯áá¡ááœáẠá á áºáá±ážááŒááºážáááŸááá±ážáá±á¬ááŒá±á¬áá·áº á¡ááºááºááẠáá»ááºá á®ážááœá¬ážáááºááŒá áºáááºá ááá¯á·á¡ááŒááºá ááœá±áá±á¬ááºážáá¶ááœáŸá¬ááá¬áááᯠááŒá±á¬ááºážáá²ááẠááŒáá¯ážá á¬ážáá«áá áá»ááá·áºááœá±áá»á¬ážááᯠá¡ááºááááºáá¯ááºáááºááá¯ááºáá«á
áá±á¬ááºáá¯á¶ážá¡ááá·áº
TextWatcher (#16) ááá·áºáá«-
á¡áááºážá¡á á¬áž MainActivity- AppCompatActivity(), View.OnClickListener, TextWatcher {
ááá¯á·áá±á¬áẠáá»áœááºá¯ááºááá¯á·ááẠbillEditText áá¬ážáááºáá° (#17) ááᯠááŒáŸá¯ááºááŸá¶áá¬ážáááº-
billEditText.addTextChangedListener(á€)
TextWatcher (#18) ááᯠáá¯ááºáá±á¬ááºááẠáá¯ááºááá·áºáá«á
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
if (!billEditText.text.isEmpty()) {
calculateExpense()
}
}
override fun afterTextChanged(s: Editable?) {}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
áá²á áá¯áá±á¬á· á¡áá¬á¡á¬ážáá¯á¶áž á¡áááºááŒá±ááœá¬ážááŒá®á áá¯ááºáá°áá«áááºá áááºááẠKotlin ááœáẠáááºáááá¯ááºááá¯áẠ"Tip Calculator" ááᯠáá±ážáá¬ážáá²á·áááºá
Skillbox á០á¡ááŒá¶ááŒá¯áá¬ážáááº-
- ááŸá áºááŸá áºá á¬áááºááœá±á·áááºáááºáž
"áá»áœááºáá±á¬áºá PRO Web Developer áá áºáá±á¬ááºáá«" .- á¡áœááºááá¯ááºážáááºáááºáž
"C# developer" .- áááºááœá±á· áá áºááŸá áºáááºáááºáž
"PHP developer 0 á០PRO" .
source: www.habr.com