CIS 2237 Android Programming   Program 4 TaskList App using Kotlin   TaskLis

  
CIS 2237 Android Programming  
Program 4 TaskList App using Kotlin  
TaskList Program 100 points total
//Need to add click on item to get to edit fragment code and also the delete code.
Turn in Requirements:
• 5 pts. Name your project LastnameP4Part1, such as NelsonP4Part1. 
• 10 pts Upload your zipped project through Brightspace. Before you zip your project, delete the build folder in your in your app folder. If you project has not been reduced in size, I will not download it (or grade it).
Program Requirements:
• 5 pts. Write your name, email address and file name at the top of your source code in a comment.
• 5 pts. Put your program title in the title area of the window so it shows when your program runs. 
• 5 pts. Add comments as appropriate. Be sure that your program output is neatly presented to the user 
Project Name: LastnameP4part1
Package Name: com.cnm.cis2237.lastname.p4part1
Minimum SDK: = 26 or higher, so we can use the Database Inspector
Select Basic Views Activity in the Activity Template screen
Don’t forget to select Kotlin!
Your project will have these files:
1. MainActivity.kt
2. MainFragment.kt
3. Task.kt
4. TaskListAdapter.kt
5. activity_main.xml
6. fragment_main.xml
7. list_item_task.xml
8. navigation_graph.xml
New skills:
• Parcelize a Class
• Code in Kotlin
1. DeleteFirstFragment and SecondFragment That means FirstFragment.java, fragment_first.xml, and FirstFragment in the nav_graph.
2. Add a new fragment, MainFragment, as a blank fragment. Delete the boilerplate code
3. If you look at the nav_graph, you will see that content_main contains the nav_host_fragment already. Click + to add the MainFragment as the Home.
4. Run your project. It should show the MainFragment and say Hello blank fragment. If it doesn’t, delete your project and create another one.
5. Delete the FAB in MainActivity and activity_main.xml.
6. Create a new Kotlin class. Name it the Task class. It is a data class. It has these class members:
var taskId: Int = 0 
var taskName: String = “” 
var taskDue: Boolean = false
7. Open fragment_main.xml
a. Delete the TextView and convert the Frame layout to a Coordinator layout. Right -click on FrameLayout and select Convert view… Select Coordinator layout. Click apply.
b. Add a recyclerview. 
c. id = taskRecycler
d. layout width and height = match_parent
e. layout_margin = 16dp
8. Add a Floating Action Button(FAB) 
a. First create a Vector Asset in the drawable folder. In the Configure Vector Asset dialog, click on the clip Art button and search for Add. There are many choices. Pick on to be the icon on the FAB. Click OK, then Next, then Finish.
b. Add a FAB to the screen. Click on your selected icon in the Pick a Resource dialog, The FAB will land at the top left. Don’t worry.
c. id = addFab
d. layout_width and height = wrap_content
e. layout_gravity = bottom/right
f. layout margin_end and bottom = 10dp
g. Give the button a background color if you want.
h. Add a content Description: Add a new task. Then extract the string resource.
9. Open MainFragment.kt 
 
a. Create a list of tasks. It can be empty: private var taskList = mutableListOf()
b.  Create a class-scope variable for the adapter, the layoutManager and the recyclerView. 
private val adapter = TaskListAdapter(taskList) //This will be red.
private val taskRecycler: RecyclerView? = null
private var layoutManager: RecyclerView.LayoutManager? = null
c. Add an override method, onViewCreated.
d. Call 3 methods recyclerViewSetup(view), observerSetup() and listenerSetup(view). Let AS create them for you outside the method.
e. Code recyclerViewSetup – We’ll do this after we write the Adapter class.
i. Wire up the recycler view variable using view.findViewbyId or use viewbinding
ii. instantiate the adapter and pass it the layout id (we have not made this yet)
iii. create a linear layout manager for the recycler view
iv. set the adapter into the recycler view.
f. Code method listenerSetup : 
i. Wire up the FAB or use view binding
ii. Create an onClick listener for the fab. We’ll code it later.
g. Let AS create the observerSetup method for you and we’ll code it later.
10. We need to work on our recycler view. 
a. We need a layout for each row
a. Create a new LayoutResource File, called list_item_task. This layout will hold each line in the recycler view. Make its root element a constraint layout.
b. The layout height should be wrap_content.
c. Add a linear layout to the constraint layout or simply constrain the two items in the layout.
d.  I added a layout margin of 8dp
e. Next, add a TextView ,which will display the title or name of the task.
f.  Give it an id, txtName
g. I made the text size = 20sp
h. And added a margin to the top of 8dp
i. The text can be blank for both.
j. Add another TextView, txtDue, which will display when the task is due to be done
k. Probably make it wrap_content for height and width. 
l. Maybe center it in the layout?
11. Add a new Kotlin class called TaskListAdapter. 
a. It will have one private variable in its constructor, taskItemLayout, an Int
b. It also extends RecyclerView.Adapter and then we add the part where we say the Adapter works with theView Holder ? = null 
h. For onCreateViewHolder, break up the layout inflation and return ViewHolder(view)
i. For onBindViewHolder, add the code for the two widgets to be accessed:
val name = holder.taskName
val due= holder.chkDue
taskList.let{
  title.text = it!![position].taskName
 done.isChecked = it!![position].taskDone
  }
j. Or you can put them together for shorter code:
   holder.taskTitle.text = taskList!![position].taskName
   holder.chkDone.isChecked = taskList!![position].taskDone
k. For getItemCount(), return if(taskList == null) 0 else taskList!!.size
l. Add a method:
 setTaskList(tasks: List){
   taskList = tasks
  notifyDataSetChanged()
}
m. And another method:
fun getAllTheTasks() : List? {
return taskList
}
12. In order to see the new Task object in MainFragment, we must return the object through safeargs.
13. First, we need to make the Task class parcelable.:
a. open libs.versions.toml and add:
b. [versions]: kotlinPlugin = “1.8.10”
c. [plugins]: kotlin-parcelize = { id = “org.jetbrains.kotlin.plugin.parcelize”, version.ref = “kotlinPlugin” }
d. In build.gradle (Module), add to the plugins at the top: id(“kotlin-parcelize”)
e. Open the Task data class. 
i. Above the declaration, data class Task( add @Parcelize
ii. After the ending ) add : Parcelable
iii. You will need to import both.
14. Then, add the safeargs dependencies:
a. In libs.versions.toml: [Libraries] 
androidx-navigation-safe-args-gradle-plugin = { module = “androidx.navigation:navigation-safe-args-gradle-plugin”, version.ref = “navigationFragmentKtx” }
b. In build.gradle (Project ), add at the top of the file, before the plugins:
buildscript{
dependencies{
classpath(libs.androidx.navigation.safe.args.gradle.plugin)
}
}
c. In build.gradle (Module) add this at the top under plugins: id(“androidx.navigation.safeargs”)
d. Sync
15. Now open the nav_graph. 
a. Add an action from AddTask fragment back to MainFragment.. rename it if you want to.
b. Still in the nav_graph, select the MainFragment, which is the destination for passing the new Task object.
c. Under Arguments, press the + and see this dialog: 
d. Add the name of the class Task and select Custom Parcelable from the drop-down list of type choices. You will see this new dialog: 
e. Select the blue line with Task as one of your classes. Then you see a new dialog, where the only pertinent thing to do is press the Add button.
16. Open Add TaskFragment.java. Extract the object you want to send to MainFragment and add it to the action:
val action: AddTaskFragmentDirections.ActionAddTaskFragmentToMainFragment = 
AddTaskFragmentDirections.actionAddTaskFragmentToMainFragment(newTask)
Navigation.findNavController(it).navigate(action)
17. Open MainFragment. Either in an onStart or another method, add the required code to extract the new task from the args. 
arguments?.let{
val args = MainFragmentArgs.fromBundle(it)
val currentTask = args.task
if(currentTask != null) {
taskList.add(currentTask)
adapter.setList(taskList)
}
}
18. Run your project. You should see a blank screen with the Fab to add task. If you want to see some initial tasks. Create a couple of tasks in MainFragment and have them be in the TasklList:  private var taskList = mutableListOf(task1, task2)