Defining application activities

To sum up, we will have three activities:

It's common practice in Android development to create an activity that will be a parent class to all other activities because, like this, we will reduce code base and share it at the same time with multiple activites. In most cases, Android developers call it BaseActivity. We will define our version of BaseActivity. Create a new class called BaseActivity; the BaseActivity.kt file is created. Make sure the newly created class is located under the Activity package of your project.

The BaseActivity class must extend the FragmentActivity class of Android SDK. We will extend FragmentActivity because we plan to use fragments inside our MainActivity class. Fragments will be used with ViewPager to navigate between different filters (Today, Next 7 Days, and so on). We plan that when the user clicks on one of those from our sliding menu, ViewPager automatically swipes to position with the fragment containing the data filtered by the chosen criteria. We will extend FragmentActivity from the package as follows--android.support.v4.app.FragmentActivity.

Android provides a way to support multiple API versions. Since we plan to do so, we will use the FragmentActivity version from the support library. Like this, we maximize our compatibility! To add support for the Android support library, include the following directive in the build.gradle configuration:

    compile 'com.android.support:appcompat-v7:26+' 

As you probably remember, we did so!

Let's continue! Since we are introducing a base class for all activities, we have to do some small refactoring to the only activity we have now. We will move the tag field from MainActivity to BaseActivity. Since it must be accessible to children of BaseActivity, we will update its visibility to protected.

We want each Activity class to have its unique tag. We will use activity concretization to choose the value for its tag. So, the tag field becomes abstract with no default value assigned:

    protected abstract val tag : String 

Beside this, we have some more common stuff in all activities. Each activity will have a layout. A layout is Android identified by the ID of the integer type. In the BaseActivity class, we will create an abstract method, as follows:

    protected abstract fun getLayout(): Int 

To optimize the code, we will move onCreate from MainActivity to BaseActivity. Instead of passing the ID of the layout from the Android generated resource directly, we will pass the result value of the getLayout() method. We will move all other lifecycle method overrides as well.

Update your classes according to these changes and build and run the application as follows:

    BasicActivity.kt:
package com.journaler.activity import android.os.Bundle import android.support.v4.app.FragmentActivity import android.util.Log abstract class BaseActivity : FragmentActivity() { protected abstract val tag : String protected abstract fun getLayout(): Int override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(getLayout()) Log.v(tag, "[ ON CREATE ]") } override fun onPostCreate(savedInstanceState: Bundle?) { super.onPostCreate(savedInstanceState) Log.v(tag, "[ ON POST CREATE ]") } override fun onRestart() { super.onRestart() Log.v(tag, "[ ON RESTART ]") } override fun onStart() { super.onStart() Log.v(tag, "[ ON START ]") } override fun onResume() { super.onResume() Log.v(tag, "[ ON RESUME ]") } override fun onPostResume() { super.onPostResume() Log.v(tag, "[ ON POST RESUME ]") } override fun onPause() { super.onPause() Log.v(tag, "[ ON PAUSE ]") } override fun onStop() { super.onStop() Log.v(tag, "[ ON STOP ]") } override fun onDestroy() { super.onDestroy() Log.v(tag, "[ ON DESTROY ]") } } MainActivity.kt:
package com.journaler.activity import com.journaler.R class MainActivity : BaseActivity() { override val tag = "Main activity" override fun getLayout() = R.layout.activity_main }

Now, we are ready to define the rest of the screens. We have to create a screen for adding and editing Notes and a screen that does the same for TODOs. There is a lot of common between these screens. The only difference for now is that the TODOs screen has buttons for date and time. We will create a common class for everything that these screens share. Each concretization will extend it. Create a class called ItemActivity. Make sure it's located in the Activity package. Create two more classes--NoteActivity and TodoActivity. ItemActivity extends our BaseActivity class and NoteActivity and TodoActivity activity classes extend ItemActivity class. You will be asked to override members. Please do so. Give some meaningful value for the tag we will use in logging. To assign a proper layout ID first we must create it!

Locate the layout we created for the main screen. Now, using the same principle, create two more layouts:

Any layout or layout member in Android gets a unique ID as integer representation in the R class that Android generates during the build. The R class for our application is as follows:

    com.journaler.R 

To access the layout, use the following line of code:

    R.layout.layout_you_are_interested_in 

We use static access. So, let's update our class concretizations to access layout IDs. Classes now look like this:

    ItemActivity.kt:
abstract class ItemActivity : BaseActivity()
For now, this class is short and simple.
NoteActivity.kt:
package com.journaler.activity
import com.journaler.R
class NoteActivity : ItemActivity(){
override val tag = "Note activity"
override fun getLayout() = R.layout.activity_note
}
Pay attention on import for R class!
TodoActivity.kt:
package com.journaler.activity
import com.journaler.Rclass TodoActivity : ItemActivity(){
override val tag = "Todo activity"
override fun getLayout() = R.layout.activity_todo
}

Last step is to register our screens (activities) in view groups. Open the manifest file and add the following:

    <activity 
      android:name=".activity.NoteActivity" 
      android:configChanges="orientation" 
      android:screenOrientation="portrait" /> 
 
      <activity 
        android:name=".activity.TodoActivity" 
        android:configChanges="orientation" 
        android:screenOrientation="portrait" /> 

Both activities are locked to portrait orientation.

We made progress! We defined our application screens. In the next section, we will populate the screens it with UI components.