Some small projects to practice Android Basics with Kotlin for beginners. Every project in this repository is simplest. Besides making your own project following this, you should improve the UI for better look and feel, or maybe add more functionalities to upgrade your skill. Happy coding !
How to use:
- CLone this repo to your local machine then choose one to open with Android Studio
- For each project, you should overview the code inside the activity first, if there is something unclear, get back here then read the References part of each project
-
Simple layout design with TableLayout
-
Handle click event to change button's attributes
-
Handle simple logic for game playing
References:
- Simple layout design with TableLayout, LinearLayout
- Support multiple screens sizes
- Handle calculating operations "+ - * /". The +/- and % is your part
Multiple screens Instruction: These are some kind of screens that you have to support: ldpi, mdpi, hdpi, xhdpi, xxhdpi, xxxhdpi You have to do this for every Ativity that you need it to be supported.
Follow these steps:
-
Add new resource file in layout folder
-
Name that new file by the name of the root activity. And the directory shoud follow this convention: layout-ldpi or layout-xxxhdpi
-
Use Design tab and choose the device with suitable kind of screen to see your layout in that screen
-
Change the layout if needed
References:
- Play with Google Map SDK Android: change map types, view angle
- Add toolbar menu to perform some actions
- Use Thread, GPS service to get location continuously
References:
- Request App Permission
- BitMapDescriptorFactory
- BitMapDescriptor
- LocationListener
- LocationManager
- Marker
- Map Types
- Menu
- Toolbar
- Multithread Kotlin
- Nested and Inner Class Kotlin
- Classes and Inheritance Kotlin
- Interfaces Kotlin
- Exceptions: try, catch Kotlin
Not completed yet
- Model: data - Bean classes, database, Content Provider
- View: user interface - define how to display the data
- Controller: event handling, navigation, communicator between Model and View
References:
- Code - Android Architecture Blueprints
- Blog - Android Architecture Pattern
- Blog - Android Architecture MVP
- Doc - Guide Android Architecture
- Talk Android Architecture Component
- Talk Droidcon A Journey Through MV Wonderland
- Blog - Android Architecture Pattern
- Simple layout with LinearLayout
- Data binding basic technique
Problem with findViewById()
When our app has complex view hierarchies, findViewById()
function will slow down the app. Why? Given that you need to access to a View, which is nested in a nested nested nested ViewGroup...Uh ohh...
Android need to traverse all over the view herrachies from the root until get the needed one. If our app has so complex view, it is expensive to find a desired view. Is there a way for the View to update whenever the data changes and we don't need to go so far with expensive findViewById()
? Use Data Binding
Benefits from Data Binding
- Code is shorter, easier to read, maintain
- Data and Views are separated, make it easier for Unit Test
- Android system only traverses once to get view, during app start up, not at runtime
- Type safty when access views. We can get exception while compiling and fix it earlier
Follow these steps:
- Go to
build.gradle
, add this block
buildFeatures {
dataBinding true
}
- Wrap the whole layout with
<layout>
as a root view - Define a binding varialbe:
private lateint var binding:ActivityMainBinding
- Replace
setContentView()
withbinding = DataBindingUtil.setContentView(this, R.layout.activity_main)
- Replace
findViewById()
with references to the view in binding object.findViewById<Button>(R.id.done_button)
=>binding.doneButton
(Note: name of the view will be theid
in XML but is defined as camel case) - Create a class for data
- Add
<data>
block inside<layout>
tag - Define
<variable>
with name and type to the data class
<data>
<variable
name="myName"
type="com.example.android.aboutme.MyName" />
</data>
- Back at
MainActivity
, create value for our binding variable. Ex:private val myName: MyName = MyName("Hieu Vu")
- Bind your data with the variable
binding.myName = myName
- Change the content of the View to display our data with the name in the
<data>
block.android:text="@={myName.name}"
Note: Whenever you change your data, remember to callinvalidateAll()
method to notify the UI to refresh with new data.
References:
-
When
onPause()
is called, the app no longer has focus. AfteronStop()
, the app is no longer visible on screen -
onCreate()
andonDestroy()
only run once -
onCreate()
: where all your first-time initialization goes, where you set up the layout for the first time by inflating it, and where you initialize your variables, data binding... -
onRestart()
method is a place to put code that you only want to call if your activity is not being started for the first time. -
When our application starts, the
onCreate()
,onStart()
andonResume()
run orderly -
At the very first Activity, if we press
Physical Back button
and move to the home screen of the device ,onPause()
,onStop()
,onDestroy()
run orderly -
If we reopen the app, it will call three methods
onCreate()
,onStart()
andonResume()
again -
If we press
Home button
,onPause()
andonStop()
are called -
If we reopen our app, the
onRestart()
,onStart()
,onResume()
will be called -
When we press the
Tabs button
,onPause()
andonStop()
will be called -
Then if we go back to our app,
onRestart()
,onStart()
,onResume()
wil be called -
Whatever code runs in
onPause()
blocks other things from displaying, so keep the code inonPause()
lightweight. For example, if a phone call comes in, the code inonPause()
may delay the incoming-call notification. -
onAttach()
: Called when the fragment is associated with its owner activity. -
onCreate()
: Similarly to onCreate() for the activity, onCreate() for the fragment is called to do initial fragment creation (other than layout). -
onCreateView()
: Called to inflate the fragment's layout. -
onViewCreated()
: Called immediately after onCreateView() has returned, but before any saved state has been restored into the view. -
onStart()
: Called when the fragment becomes visible; parallel to the activity's onStart(). -
onResume()
: Called when the fragment gains the user focus; parallel to the activity's onResume() -
onPause()
: Called when the fragment loses the user focus; parallel to the activity's onPause(). -
onStop()
: Called when the fragment is no longer visible on screen; parallel to the activity's onStop(). -
onDestroyView()
: Called when the fragment's view is no longer needed, to clean up the resources associated with that view. -
To add skeleton override methods to your classes in Android Studio, select Code > Override Methods or press
Control+o
. Logging with Timber A logging library better thant the default one. Benefits: -
Generates the log tag for you based on the class name.
-
Helps avoid showing logs in a release version of your Android app.
-
Allows for integration with crash reporting libraries.
Steps to add Timber:
- Add dependencies to
gradle.build
- Create a class extends the
Application
class - In the
onCreate()
of new class, addTimber.plant(Timber.DebugTree())
- Add
android:name
with your new application class to<application>
tag - Call with this syntax
Timber.i("Log example")
Kotlin Android Practice is licensed under a Creative Commons Attribution 4.0 International License. .
Based on a work at https://github.com/hieuwu/kotlin-android-practice.