Git Product home page Git Product logo

andfun-kotlin-sleep-tracker-with-recyclerview's Introduction

RecyclerView - SleepQualityTracker with RecyclerView app

This is the toy app for Lesson 7 of the Android App Development in Kotlin course on Udacity.

SleepQualityTracker with RecyclerView

This app builds on the SleepQualityTracker you developed in Lesson 6. In this lesson you'll learn how to display a list of results in a RecyclerView instead of a static ScrollView. You'll also learn how you can refactor your code to make it more efficient so it will be easier to maintain and test.

Screenshots

Screenshot1 Screenshot2

How to use this repo while taking the course

Each code repository in this class has a chain of commits that looks like this:

listofcommits

These commits show every step you'll take to create the app. Each commit contains instructions for completing the that step.

Each commit also has a branch associated with it of the same name as the commit message, as seen below:

branches Access all branches from this tab.

listofbranches

branchesdropdown

The branches are also accessible from the drop-down in the "Code" tab.

Working with the Course Code

Here are the basic steps for working with and completing exercises in the repo.

The basic steps are:

  1. Clone the repo.
  2. Check out the branch corresponding to the step you want to attempt.
  3. Find and complete the TODOs.
  4. Optionally commit your code changes.
  5. Compare your code with the solution.
  6. Repeat steps 2-5 until you've gone trough all the steps to complete the toy app.

Step 1: Clone the repo

As you go through the course, you'll be instructed to clone the different exercise repositories, so you don't need to set these up now. You can clone a repository from github in a folder of your choice with the command:

git clone https://github.com/udacity/REPOSITORY_NAME.git

Step 2: Check out the step branch

As you go through different steps in the code, you'll be told which step you're on, as well as a link to the corresponding branch.

You'll want to check out the branch associated with that step. The command to check out a branch would be:

git checkout BRANCH_NAME

Step 3: Find and complete the TODOs

Once you've checked out the branch, you'll have the code in the exact state you need. You'll even have TODOs, which are special comments that tell you all the steps you need to complete the exercise. You can easily navigate to all the TODOs using Android Studio's TODO tool. To open the TODO tool, click the button at the bottom of the screen that says TODO. This will display a list of all comments with TODO in the project.

We've numbered the TODO steps so you can do them in order: todos

Step 4: Commit your code changes

After You've completed the TODOs, you can optionally commit your changes. This will allow you to see the code you wrote whenever you return to the branch. The following git code will add and save all your changes.

git add .
git commit -m "Your commit message"

Step 5: Compare with the solution

Most exercises will have a list of steps for you to check off in the classroom. Once you've checked these off, you'll see a pop up window with a link to the solution code. Note the Diff link:

solutionwindow

The Diff link will take you to a Github diff as seen below: diff

All of the code that was added in the solution is in green, and the removed code (which will usually be the TODO comments) is in red.

You can also compare your code locally with the branch of the following step.

Report Issues

Notice any issues with a repository? Please file a github issue in the repository.

andfun-kotlin-sleep-tracker-with-recyclerview's People

Contributors

iambryanwho avatar maxim-yudin avatar sudkul avatar yenerm avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

andfun-kotlin-sleep-tracker-with-recyclerview's Issues

DiffUtil.ItemCallback areContentsTheSame() shows linter warning when comparing sealed classes

It looks like this issue will be patched in Android Studio 3.6, but the linter throws a warning when checking instance equality of two subclasses of a sealed class. This pops up in DiffUtil.ItemCallback method areContentsTheSame() in Step 13 of the lesson.

Thought it might be good to mention in the instructor notes, or add @SuppressLint("DiffUtilEquals"), since I though the solution was to override DataItem.equals().

TextItemViewHolder class not found

I am getting an error in TextItemViewHolder class not found, when I try to extend it, I am not getting what mistake I am doing, so if anyone can help me to find what wrong I am doing here.

When using DiffUtils, I noticed that the recycler view does not auto scroll to top anymore.

It works initially, but when you add a certain number of elements that go off the recycler view height, and then you click "start," it will add a new item to the list, but you would have to scroll up to see it! I tried to force the recyclerview to scroll to position 0 manually in:

sleepTrackerViewModel.nights.observe(viewLifecycleOwner, Observer { list -> list?.let { sleepNightAdapter.submitList(list) binding.rvSleepList.scrollToPosition(0) } })

But this does not work. Any suggestions?

BottomNavigation resets AppStats

Hi guys,
This is a problem I'm facing for a couple of days now but I couldn't find a good solution so far.

The problem
I've implemented a bottom navigation bar in my Main activity, I have 3 fragments and they are all using viewModels to save the app state but even doing that whenever I switch between fragments, my recycler views get reset to the top of the list, and that is not the behavior I wish.

What do you guys recommend to me?

Thanks!

night or night.nightId ?

In SleepTrackerFragment.kt, I think that:

  sleepTrackerViewModel.navigateToSleepDataQuality.observe(this, Observer { night ->
        night?.let {

            this.findNavController().navigate(
                    SleepTrackerFragmentDirections
                            .actionSleepTrackerFragmentToSleepDetailFragment(night))
            sleepTrackerViewModel.onSleepDataQualityNavigated()
        }
    })

Should instead be:

  sleepTrackerViewModel.navigateToSleepDataQuality.observe(this, Observer { night ->
        night?.let {

            this.findNavController().navigate(
                    SleepTrackerFragmentDirections
                            .actionSleepTrackerFragmentToSleepDetailFragment(night.nightId))
            sleepTrackerViewModel.onSleepDataQualityNavigated()
        }
    })

App crashes on navigation after orientation change

When user tries to navigate after rotating the phone, app crashes.
The following error is shown in the logcat:

com.example.android.trackmysleepqualityrecyclerview E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.android.trackmysleepqualityrecyclerview, PID: 11450
    java.lang.IllegalStateException: no current navigation node
        at androidx.navigation.NavController.navigate(NavController.java:765)
        at androidx.navigation.NavController.navigate(NavController.java:745)
        at androidx.navigation.NavController.navigate(NavController.java:731)
        at androidx.navigation.NavController.navigate(NavController.java:863)
        at com.example.android.trackmysleepquality.sleeptracker.SleepTrackerFragment$onCreateView$2.onChanged(SleepTrackerFragment.kt:93)
        at com.example.android.trackmysleepquality.sleeptracker.SleepTrackerFragment$onCreateView$2.onChanged(SleepTrackerFragment.kt:39)
        at androidx.lifecycle.LiveData.considerNotify(LiveData.java:131)
        at androidx.lifecycle.LiveData.dispatchingValue(LiveData.java:149)
        at androidx.lifecycle.LiveData.setValue(LiveData.java:307)
        at androidx.lifecycle.MutableLiveData.setValue(MutableLiveData.java:50)
        at com.example.android.trackmysleepquality.sleeptracker.SleepTrackerViewModel$onStopTracking$1.invokeSuspend(SleepTrackerViewModel.kt:224)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
        at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:56)
        at android.os.Handler.handleCallback(Handler.java:790)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6494)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)

java.lang.RuntimeException: Failed to call observer method

Getting this error after implementing click listener for RecyclerView. When clicked on any sleep quality image, the app force closes.

Caused by: java.lang.IllegalArgumentException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull, parameter item at com.example.android.trackmysleepquality.BindingUtilKt.setSleepImage(Unknown Source:7) at com.example.android.trackmysleepquality.databinding.FragmentSleepDetailBindingImpl.executeBindings(FragmentSleepDetailBindingImpl.java:145)

Step 03 Solution Crashes

Start, then rotate the screen then click stop. Crash.

2023-05-11 10:35:33.339 16812-16812/com.example.android.trackmysleepqualityrecyclerview E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.android.trackmysleepqualityrecyclerview, PID: 16812
    java.lang.IllegalStateException: no current navigation node
        at androidx.navigation.NavController.navigate(NavController.java:765)
        at androidx.navigation.NavController.navigate(NavController.java:745)
        at androidx.navigation.NavController.navigate(NavController.java:731)
        at androidx.navigation.NavController.navigate(NavController.java:863)
        at com.example.android.trackmysleepquality.sleeptracker.SleepTrackerFragment$onCreateView$2.onChanged(SleepTrackerFragment.kt:91)
        at com.example.android.trackmysleepquality.sleeptracker.SleepTrackerFragment$onCreateView$2.onChanged(SleepTrackerFragment.kt:38)
        at androidx.lifecycle.LiveData.considerNotify(LiveData.java:131)
        at androidx.lifecycle.LiveData.dispatchingValue(LiveData.java:149)
        at androidx.lifecycle.LiveData.setValue(LiveData.java:307)
        at androidx.lifecycle.MutableLiveData.setValue(MutableLiveData.java:50)
        at com.example.android.trackmysleepquality.sleeptracker.SleepTrackerViewModel$onStopTracking$1.invokeSuspend(SleepTrackerViewModel.kt:224)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
        at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:56)
        at android.os.Handler.handleCallback(Handler.java:942)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loopOnce(Looper.java:201)
        at android.os.Looper.loop(Looper.java:288)
        at android.app.ActivityThread.main(ActivityThread.java:7884)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)

A couple questions about Step 9

Hello,

Couldn't find a better place to ask, so might as well do it here.

In step 9, we add data binding to our app. I have two questions about the code here:

  1. Why do we use context.resources instead of just resources in BindingUtils.kt lines 45 and 52?

  2. In list_item_sleep_night.xml, why do we use, for example, app:sleepImage instead of just sleepImage?

I was not looking at the video while following the audio instructions and for both examples typed in the latter version, yet my app is still working as intended, so I was wondering what the difference there was and why I would want to do it as is provided in the lesson.

java.lang.RuntimeException: Failed to call observer method

Could anyone here to help how to solve this exception ?

E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.android.trackmysleepquality, PID: 4117
java.lang.RuntimeException: Failed to call observer method
at androidx.lifecycle.ClassesInfoCache$MethodReference.invokeCallback(ClassesInfoCache.java:226)
at androidx.lifecycle.ClassesInfoCache$CallbackInfo.invokeMethodsForEvent(ClassesInfoCache.java:194)
at androidx.lifecycle.ClassesInfoCache$CallbackInfo.invokeCallbacks(ClassesInfoCache.java:185)
at androidx.lifecycle.ReflectiveGenericLifecycleObserver.onStateChanged(ReflectiveGenericLifecycleObserver.java:37)
at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry.java:361)
at androidx.lifecycle.LifecycleRegistry.forwardPass(LifecycleRegistry.java:300)
at androidx.lifecycle.LifecycleRegistry.sync(LifecycleRegistry.java:339)
at androidx.lifecycle.LifecycleRegistry.moveToState(LifecycleRegistry.java:145)
at androidx.lifecycle.LifecycleRegistry.handleLifecycleEvent(LifecycleRegistry.java:131)
at androidx.fragment.app.Fragment.performStart(Fragment.java:2735)
at androidx.fragment.app.FragmentStateManager.start(FragmentStateManager.java:355)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1192)
at androidx.fragment.app.FragmentManager.addAddedFragments(FragmentManager.java:2222)
at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1995)
at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1951)
at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1847)
at androidx.fragment.app.FragmentManager$4.run(FragmentManager.java:413)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:201)
at android.app.ActivityThread.main(ActivityThread.java:6810)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873)
Caused by: java.lang.IllegalArgumentException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull, parameter item
at com.example.android.trackmysleepquality.sleeptracker.BindingUtilsKt.setSleepImage(Unknown Source:7)
at com.example.android.trackmysleepquality.databinding.FragmentSleepDetailBindingImpl.executeBindings(FragmentSleepDetailBindingImpl.java:145)
at androidx.databinding.ViewDataBinding.executeBindingsInternal(ViewDataBinding.java:473)
at androidx.databinding.ViewDataBinding.executePendingBindings(ViewDataBinding.java:445)
at androidx.databinding.ViewDataBinding$OnStartListener.onStart(ViewDataBinding.java:1687)
at java.lang.reflect.Method.invoke(Native Method)
at androidx.lifecycle.ClassesInfoCache$MethodReference.invokeCallback(ClassesInfoCache.java:216)
at androidx.lifecycle.ClassesInfoCache$CallbackInfo.invokeMethodsForEvent(ClassesInfoCache.java:194) 
at androidx.lifecycle.ClassesInfoCache$CallbackInfo.invokeCallbacks(ClassesInfoCache.java:185) 
at androidx.lifecycle.ReflectiveGenericLifecycleObserver.onStateChanged(ReflectiveGenericLifecycleObserver.java:37) 
at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry.java:361) 
at androidx.lifecycle.LifecycleRegistry.forwardPass(LifecycleRegistry.java:300) 
at androidx.lifecycle.LifecycleRegistry.sync(LifecycleRegistry.java:339) 
at androidx.lifecycle.LifecycleRegistry.moveToState(LifecycleRegistry.java:145) 
at androidx.lifecycle.LifecycleRegistry.handleLifecycleEvent(LifecycleRegistry.java:131) 
at androidx.fragment.app.Fragment.performStart(Fragment.java:2735) 
at androidx.fragment.app.FragmentStateManager.start(FragmentStateManager.java:355) 
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1192) 
at androidx.fragment.app.FragmentManager.addAddedFragments(FragmentManager.java:2222) 
at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1995) 
at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1951) 
at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1847) 
at androidx.fragment.app.FragmentManager$4.run(FragmentManager.java:413) 
at android.os.Handler.handleCallback(Handler.java:873) 
at android.os.Handler.dispatchMessage(Handler.java:99) 
at android.os.Looper.loop(Looper.java:201) 
at android.app.ActivityThread.main(ActivityThread.java:6810) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873) 

TextItemViewHolder is not found in androidx

Hi Team

Can someone please look into as this holder type is pivotal to create the Adapter for RecyclerView for this Lesson, but don't see that as is probably from support library

Gradle Errors

I tried to run the program with the step one changes but keep running into gradle errors. When attempting to update the gradle file to more current versions, we still get crashes due to uneditable files needing edits.

RecycledView, item list change animation

After introducing data binding to the application (RecycledView with LinearLayoutManage), animation of adding new items to the list has a strange behavior. It works properly until the list expands beyond the height of the screen, and after that adding new items does not make the list scroll down.

Update: the same is with GridLayout. It seems that when the list of items it too big to fit the screen, animation ignores the constraints of the RecycledView and plays as if there is no buttons on the screen and the RecycleView fills the entire space of the ConstraintLayout.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.