# Okostelefon és IoT eszkzk programozása (mil-geial51d-ml) - Android Studio Bumblebee beadandó
## Beadandó ismertetése
A beadandó feladatom egy teend lista applikáció Kotlin[^1] nyelvbe írva, Android Studio Bumblebee [^2] verziójú IDE-t használva. A felhasználó képes teendket felvinni az alkalmazásba, teljesíteni illetve trlni a teljesített teendket.
## Fbb project struktúra
```
└── app
└── src
...
└── main
└── java/com/example/mil_geial51d_ml
└── MainActivity.kt
└── Todo.kt
└── TodoAdapter.kt
└── res
...
└── layout
└── activity_main.xml
└── item_todo.xml
...
└── .gitignore
└── build.gradle
```
### build.gradle konfiguráció
Kikellett egészíteni sorral, ugyanis ezzel engedélyezem a View Binding funkciót, amely megknnyíti a kezeli felület-elemek programkódból való hozzáférését, anélkül, hogy findViewById hívásokat kellene használni.[^3]
```
viewBinding {
enabled = true
}
```
### activity_main.xml
Ez a f layout fájl az alkalmazásban, ahová felrakom az elemeket.
Elérési útja: ```app/src/main/res/layout/activity_main.xml```
#### RecyclerView
Ez a beépített komponens lehetvé teszi listák és rácsok megjelenítését, ez lesz az alapja a Teendknek (tbb teend lista elemek felvitelét)[^4]
Attribútumai:
- android:id : itt definálom az id-t a komponensnek, amit késbb felfogok használni.
- android:layout_width : itt definiálom a komponens szélességét, ```match_parent``` beállítással, a szélesség ki fog tlteni minden rendelkezésre álló helyet vízszintesen a szülelemében.
- android:layout_height : itt definiálom a komponens magasságát, ```0dp``` beállítással, a ConstraintLayout[^5] miatt a magassága dinamikusan, a korlátok által meghatározott tér kitltésével fog változni.
- app:layout_constraintBottom_toTopOf : alsó korlátot az editTextTodoTitle ID-j elem fels széléhez rgzíti, ami azt jelenti, hogy a RecyclerView alja az említett elem tetejéig terjed.
- app:layout_constraintEnd_toEndOf : a jobb szélét a szül elem végéhez igazítja.
- app:layout_constraintStart_toStartOf : a bal szélét a szül elem kezdetéhez igazítja.
- app:layout_constraintTop_toTopOf : a tetejét a szül elem tetejéhez igazítja.
```
```
#### EditText
Ez a beépített komponens lehetvé teszi, hogy egy input mezt adjunk az alkalmazáshoz, ez lesz az alapja Teendk felviteléhez.[^6]
Attribútumai:
- android:id : itt definálom az id-t a komponensnek, amit késbb felfogok használni.
- android:layout_width : itt definiálom a komponens szélességét, ```0dp``` beállítással, a ConstraintLayout miatt a szélesség a korlátok határozzák meg, kifeszítve a megadott korlátok kztt.
- android:layout_height : itt definiálom a komponens magasságát, ```wrap_content``` beállítással, elegend helyet biztosít a beírt szveg megjelenítésére, anélkül, hogy felesleges teret foglalna el.
- android:hint : szveges útmutatást jelenít meg, amikor nincs benne szveg.
- app:layout_constraintBottom_toBottomOf : az alját a szülelem aljához rgzíti
- app:layout_constraintEnd_toStartOf : a jobb oldalát a buttonAddTodo ID-j elem bal oldalához igazítja, tehát az EditText és a gomb kztt nem marad szabad hely.
- app:layout_constraintStart_toStartOf : a bal oldalát a szülelem bal oldalához igazítja.
```
```
#### Button
Ez a beépített komponens lehetvé teszi, hogy egy gombot adjunk az alkalmazához, 2 gombot fogok hozzáadni:
1. Hozzáadás (Add)
Ezzel a gombbal viszek fel új teendt.
Attribútumai:
- android:id : itt definálom az id-t a komponensnek, amit késbb felfogok használni.
- android:layout_width, android:layout_height : a gomb mérete igazodik megjelen szveg méretéhez, így csak annyi helyet foglal el, amennyi szükséges.
- android:text : a gombon megjelen szveg.
- app:layout_constraintBottom_toBottomOf : a gomb alját a szülelem aljához rgzíti.
- app:layout_constraintEnd_toStartOf : a gomb jobb oldalát buttonDeleteTodo ID-j gomb bal oldalához igazítja. Ez azt jelenti, hogy a "Hozzáadás" gomb és a "Trlés" gomb kztt kzvetlenül nem marad hely.
- app:layout_editor_absoluteX : abszolút X koordinátát ad meg a layout.
```
```
2. Trlés (Delete)
Ezzel a gombbal trlk teljesített teendt.
Attribútumai:
- android:id : itt definálom az id-t a komponensnek, amit késbb felfogok használni.
- android:layout_width, android:layout_height : a gomb mérete igazodik megjelen szveg méretéhez, így csak annyi helyet foglal el, amennyi szükséges.
- android:text : a gombon megjelen szveg.
- app:layout_constraintBottom_toBottomOf : a gomb alját a szülelem aljához igazítja.
- app:layout_constraintEnd_toEndOf : a gomb jobb szélét a szülelem jobb széléhez igazítja.
- app:layout_editor_absoluteX : abszolút X koordinátát ad meg a layout.
```
```
### item_todo.xml
Ez a layout a teendk kinézetéért felels.
Elérési útja: ```app/src/main/res/layout/item_todo.xml```
#### TextView
Ez a beépített komponens lehetvé teszi, hogy a teendk label-ét megjelenítsem. [^8]
Attribútumai:
- android:id : itt definálom az id-t a komponensnek, amit késbb felfogok használni.
- android:layout_width : a szélességét 0 dp-re állítja, ConstraintLayout miatt, a szélességét a korlátok határozzák meg, kifeszítve a megadott korlátok kztt.
- android:layout_height : a magasságát a benne lév tartalomhoz igazítja, így csak annyi helyet foglal el, amennyi a megjelenített szveg magasságához szükséges.
- android:text : a megjelenítend szveg.
- android:textSize : a szveg méretét 24sp-re (skálapontok) nveli.
- app:layout_constraintBottom_toBottomOf : az alját a szülelem aljához rgzíti.
- app:layout_constraintEnd_toStartOf : a jobb oldalát checkBoxTodo ID-j elem bal oldalához igazítja.
- app:layout_constraintStart_toStartOf : a bal oldalát a szülelem bal oldalához igazítja.
- app:layout_constraintTop_toTopOf : a tetejét a szülelem tetejéhez rgzíti.
```
```
#### CheckBox
Ez a beépített komponens lehetvé teszi, hogy a teendket kipipáljuk.[^9]
Attribútumai:
- android:id : itt definálom az id-t a komponensnek, amit késbb felfogok használni.
- android:layout_width, android:layout_height : a mérete alkalmazkodik a benne lév tartalomhoz, azaz csak annyi helyet foglal el, amennyi a megjelenített elem (a jellnégyzet és a szveg, ha van) megjelenítéséhez szükséges.
- app:layout_constraintBottom_toBottomOf :az alját a szülelem aljához rgzíti.
- app:layout_constraintEnd_toEndOf : a jobb szélét a szülelem jobb széléhez igazítja.
- app:layout_constraintTop_toTopOf : a tetejét a szülelem tetejéhez rgzíti.
```
```
### MainActivity.kt
Activity osztály része amely az alkalmazás f képernyjét valósítja meg [^10]
#### Kési inicializálású változók deklarálása
- todoAdapter: az adapter kezeli a teendk listáját a RecyclerView-ban.
- binding: ViewBinding használatával inicializál egy változót, amely lehetvé teszi a layout elemek knny és biztonságos elérését.
```
private lateinit var todoAdapter: TodoAdapter
private lateinit var binding: ActivityMainBinding
```
#### onCreate metódus
Akkor hívódik meg, amikor az aktivitás létrejn, az alapvet inicializálást csinálom meg.
- setContentView(R.layout.activity_main): az aktivitás felületének layoutja, késbb felülírják a ViewBindinggal.
- todoAdapter: inicializálja a TodoAdapter-t egy üres MutableListtel.
- binding: inicializálja a binding változót, amely lehetvé teszi a layout elemek programkódból trtén elérését.
- setContentView: beállítja a tartalmat a ViewBinding által generált root-ra, ami lehetvé teszi a ViewBinding használatát.
- binding.recyclerViewTodoItems.adapter: beállítja a RecyclerView adapterét a todoAdapter-re.
- binding.recyclerViewTodoItems.layoutManager: beállítja a RecyclerView LayoutManagerét[^11] egy új LinearLayoutManager[^12] példányra, ami lineáris listát hoz létre.
Teend hozzáadása:
Amikor a felhasználó rákattint a Hozzáadás gombra, a kód létrehoz egy új Todo objektumot szvegével, hozzáadja ezt az adapter listájához, majd trli a beviteli mez tartalmát.
Teend trlése:
Amikor a felhasználó rákattint a Trlés gombra, a kód meghívja a ```todoAdapter.deleteTodo()``` metódust, ami eltávolítja a kijellt teendket a listából.
```
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
todoAdapter = TodoAdapter(mutableListOf())
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.recyclerViewTodoItems.adapter = todoAdapter
binding.recyclerViewTodoItems.layoutManager = LinearLayoutManager(this)
binding.buttonAddTodo.setOnClickListener {
val todoTitle = binding.editTextTodoTitle.text.toString()
if(todoTitle.isNotEmpty()) {
val todo = Todo(todoTitle)
todoAdapter.addTodo(todo)
binding.editTextTodoTitle.text.clear()
}
}
binding.buttonDeleteTodo.setOnClickListener {
todoAdapter.deleteTodo()
}
}
```
### Todo.kt
Kotlin adat osztály definícióját tartalmazza, ami a Todo típusú objektumokat írja le, célja az adattárolás.[^13]
- title: teend címét tárolja.
- isChecked: azt tárolja, hogy a teend be van-e jellve, alapértelmezés szerint a teend nincs kijellve.
```
data class Todo (
val title: String,
var isChecked: Boolean = false
)
```
### TodoAdapter.kt
Az adapter feladata, hogy sszekapcsolja teendk listáját a RecyclerView-val, amely megjeleníti a teendket.[^14]
- TodoAdapter: Az adapter, amely egy MutableList típusú listát kap, megjelenítend teendket.
- TodoViewHolder: ViewHolder [^15], amely a RecyclerView egyes eleminek a nézeteit tárolja, ItemTodoBinding segítségével hozzáfér a layout elemekhez.
- onCreateViewHolder: új ViewHolder példányokat hoz létre, létrehozza az egyes listaelemek layoutját és inicializálja a ViewHolder-t.
- onBindViewHolder: sszekti a teendk adatait az egyes listaelemek nézeteivel.
- getItemCount: visszaadja a listában lév elemek számát, ami szükséges a RecyclerView számára, hogy tudja, hány elemet kell megjeleníteni.
- addTodo: új teendt ad hozzá a listához, és értesíti az adaptert, hogy egy új elem került beszúrásra.
![image](https://github.com/plummogo/mil-geial51d-ml/assets/16595977/f009198a-9130-437a-93ba-b2861fb15572)
- deleteTodo: eltávolítja az sszes kijellt teendt a listából, és értesíti az adaptert az adatok változásáról.
![image](https://github.com/plummogo/mil-geial51d-ml/assets/16595977/f309c71e-7a3c-4521-bd4f-96c30ce783b9)
- toggleStrikeThrough: áthúzza a teend címét, TextView paintFlags beállításával végzi, ahol a STRIKE_THRU_TEXT_FLAG használata jelzi az áthúzást. [^16]
![image](https://github.com/plummogo/mil-geial51d-ml/assets/16595977/26bab6ad-4c7a-4df0-bbd6-2f26e4186e50)
```
class TodoAdapter(private val todoList: MutableList) : RecyclerView.Adapter() {
class TodoViewHolder(val binding: ItemTodoBinding) : RecyclerView.ViewHolder(binding.root)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TodoViewHolder {
val binding = ItemTodoBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return TodoViewHolder(binding)
}
fun addTodo(newTodo: Todo) {
todoList.add(newTodo)
notifyItemInserted(todoList.size - 1)
}
fun deleteTodo() {
todoList.removeAll { todo -> todo.isChecked}
notifyDataSetChanged()
}
private fun toggleStrikeThrough(title: TextView, isChecked: Boolean) {
if(isChecked) {
title.paintFlags = title.paintFlags or STRIKE_THRU_TEXT_FLAG
} else {
title.paintFlags = title.paintFlags and STRIKE_THRU_TEXT_FLAG.inv()
}
}
override fun onBindViewHolder(holder: TodoViewHolder, position: Int) {
val currentTodo = todoList[position]
with(holder.binding) {
textViewTodoTitle.text = currentTodo.title
checkBoxTodo.isChecked = currentTodo.isChecked
toggleStrikeThrough(textViewTodoTitle, currentTodo.isChecked)
checkBoxTodo.setOnCheckedChangeListener { _, isChecked ->
toggleStrikeThrough(textViewTodoTitle, isChecked)
currentTodo.isChecked = !currentTodo.isChecked
}
}
}
override fun getItemCount(): Int {
return todoList.size
}
}
```
[^1]:https://kotlinlang.org/
[^2]: https://hu.wikipedia.org/wiki/Caesar-rejtjel](https://developer.android.com/studio/releases/past-releases/as-bumblebee-release-notes)https://developer.android.com/studio/releases/past-releases/as-bumblebee-release-notes
[^3]: https://stackoverflow.com/questions/57117338/how-to-use-view-binding-in-android
[^4]: https://developer.android.com/reference/androidx/recyclerview/widget/RecyclerView
[^5]: https://developer.android.com/reference/androidx/constraintlayout/widget/ConstraintLayout
[^6]: https://developer.android.com/reference/android/widget/EditText
[^7]: https://developer.android.com/reference/android/widget/Button
[^8]: https://developer.android.com/reference/android/widget/TextView
[^9]: https://developer.android.com/reference/android/widget/CheckBox
[^10]: https://developer.android.com/reference/kotlin/android/app/Activity
[^11]: https://developer.android.com/reference/androidx/recyclerview/widget/RecyclerView.LayoutManager
[^12]: https://developer.android.com/reference/androidx/recyclerview/widget/LinearLayoutManager
[^13]: https://kotlinlang.org/docs/data-classes.html
[^14]: https://www.baeldung.com/kotlin/adapter-pattern
[^15]: https://developer.android.com/reference/androidx/recyclerview/widget/RecyclerView.ViewHolder
[^16]: https://developer.android.com/reference/android/graphics/Paint