🦁 A Disney app using transformation motions based on MVVM (ViewModel, Coroutines, Flow, LiveData, Room, Repository, Koin) architecture.

Overview

DisneyMotions


A demo Disney app using transformation motions based on MVVM architecture.
The motion system is included in the 1.2.0-alpha05 released material version.


License API Build Status KotlinWeekly Medium Profile

Download

Go to the Releases to download the latest APK.

Screenshots

Tech stack & Open-source libraries

  • Minimum SDK level 21
  • 100% Kotlin based + Coroutines + Flow for asynchronous.
  • JetPack
    • LiveData - notify domain layer data to views.
    • Lifecycle - dispose observing data when lifecycle state changes.
    • ViewModel - UI related data holder, lifecycle aware.
    • Room Persistence - construct database.
  • Architecture
    • MVVM Architecture (View - DataBinding - ViewModel - Model)
    • Repository pattern
    • Koin - dependency injection
  • Material Design & Animations
  • Sandwich - construct lightweight network response interfaces and handling error responses.
  • Retrofit2 & Gson - constructing the REST API
  • OkHttp3 - implementing interceptor, logging and mocking web server
  • Glide - loading images
  • BaseRecyclerViewAdapter - implementing adapters and viewHolders
  • WhatIf - checking nullable object and empty collections more fluently
  • Bundler - Android Intent & Bundle extensions that insert and retrieve values elegantly.
  • Timber - logging
  • Ripple animation, Shared element container transform/transition

MAD Score

summary kotlin

Unit Testing Frameworks

Unit Tests verify the interactions of viewmodels between repositories and dao & REST api requests.

  • Robolectric - Robolectric is the industry-standard unit testing framework for Android.
  • Mockito-Kotlin - a small library that provides helper functions to work with Mockito in Kotlin.

screenshot483387955

Find this repository useful? ❤️

Support it by joining stargazers for this repository.
And follow me for my next creations! 🤩

License

Designed and developed by 2020 skydoves (Jaewoong Eum)

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Comments
  • Crash when select first item

    Crash when select first item

    Please complete the following information:

    • Library Version [e.g. v1.0.0]
    • Affected Device(s) [e.g. Nokia 6.1+ with Android 10.0]

    Describe the Bug:

    • Running the app
    • Select the first item, I have try at all tabs. All the result same.
    • The app will crash

    Crash when select first item

    This is the error log

    FATAL EXCEPTION: main
        Process: com.skydoves.disneymotions, PID: 18526
        java.lang.RuntimeException: Unable to start activity ComponentInfo{com.skydoves.disneymotions/com.skydoves.disneymotions.view.ui.details.PosterDetailActivity}: java.lang.IllegalArgumentException: Required value was null.
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3271)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3410)
            at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
            at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
            at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2017)
            at android.os.Handler.dispatchMessage(Handler.java:107)
            at android.os.Looper.loop(Looper.java:214)
            at android.app.ActivityThread.main(ActivityThread.java:7397)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:935)
         Caused by: java.lang.IllegalArgumentException: Required value was null.
            at com.skydoves.disneymotions.extensions.ActivityExtensionsKt$extraLong$1.invoke(ActivityExtensions.kt:63)
            at com.skydoves.disneymotions.extensions.ActivityExtensionsKt$extraLong$1.invoke(Unknown Source:0)
            at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
            at com.skydoves.disneymotions.view.ui.details.PosterDetailActivity.getPosterId(Unknown Source:2)
            at com.skydoves.disneymotions.view.ui.details.PosterDetailActivity.onCreate(PosterDetailActivity.kt:41)
            at android.app.Activity.performCreate(Activity.java:7802)
            at android.app.Activity.performCreate(Activity.java:7791)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1300)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3246)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3410) 
            at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83) 
            at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) 
            at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) 
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2017) 
            at android.os.Handler.dispatchMessage(Handler.java:107) 
            at android.os.Looper.loop(Looper.java:214) 
            at android.app.ActivityThread.main(ActivityThread.java:7397) 
            at java.lang.reflect.Method.invoke(Native Method) 
            at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492) 
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:935) 
    I: Sending signal. PID: 18526 SIG: 9
    
    

    Expected Behavior:

    Not crash when select first item

    opened by derohimat 2
  • How does this project compare to your other project MarvelHeroes in terms of Architecture esp MVVM side

    How does this project compare to your other project MarvelHeroes in terms of Architecture esp MVVM side

    I am little confused when comparing both your projects As both use MVVM with Repository pattern and Coroutines what is the major difference between the two setup comparing only the architecture excluding the UI.

    Thanks for sharing this great repo, It serves as a great reference point to building modern android app with good architecture implementation

    opened by rinav 2
  • Adjust the color of the status bar to match the prominent background color of image.

    Adjust the color of the status bar to match the prominent background color of image.

    Is your feature request related to a problem?

    The color of the status bar doesn't go together with the prominent background color of the selected movie.

    Describe the solution you'd like:

    The status bar color should be dynamically adjusted to the prominent background color of the selected movie.

    Describe alternatives you've considered:

    Use the Palette API to select the prominent background color of the selected movie. During runtime change the status bar color to the color selected from the palette.

    opened by cleverSheep 2
  • Type mismatch required LiveData<TypeVariable(T)> found Unit

    Type mismatch required LiveData found Unit

    I'm trying to understanding this architecture by coding example and I followed the project set up till I stuck with that compile time error

    Type mismatch required LiveData<TypeVariable(T)> found Unit

    in the viewModel I have code like that for register request

     fun postRegisterRequest(request: RegisterRequest) {
        this.registerLiveData =  launchOnViewModelScope {
                this.authRepository.postRegister ({ s -> this.toastLiveData.postValue(s) },
                    request
                )
            }
    }
    

    in the repository I have the following code

    suspend fun postRegister(error: (String) -> Unit, request: RegisterRequest) = withContext(Dispatchers.IO) {
        val liveData = MutableLiveData<ResponseWrapper<RegisterResponse>>()
        isLoading = true
        networkClient.postRegister( { response ->
            isLoading = false
            when (response) {
                is ApiResponse.Success -> {
                    response.data.whatIfNotNull {
                        liveData.postValue(it)
                    }
                }
                is ApiResponse.Failure.Error -> error(response.message())
                is ApiResponse.Failure.Exception -> error(response.message())
            }
        },request)
    }
    

    the network client request look like that

     fun postRegister(
        onResult: (response: ApiResponse<ResponseWrapper<RegisterResponse>>) -> Unit,
        request: RegisterRequest
    ) {
        this.authService.register(request).transform(onResult)
    }
    

    the authService code

      @POST(Urls.REGISTER)
    fun register(@Body request: RegisterRequest): Call<ResponseWrapper<RegisterResponse>>
    

    what I did wrong and how to make postRegister in the repository return LiveData<TypeVariable(T)> instead of Unit

    opened by abdulmalekDery 2
  • Please help me this error

    Please help me this error

    import androidx.appcompat.app.AppCompatActivity; import androidx.viewpager.widget.ViewPager;

    import android.annotation.SuppressLint; import android.os.Bundle;

    import com.example.appnhac2.Adapter.MainViewPagerAdapter; import com.example.appnhac2.Fragment.Fragment_Tim_Kiem; import com.example.appnhac2.Fragment.Fragment_Trang_Chu; import com.example.appnhac2.R; import com.google.android.material.tabs.TabLayout;

    public class MainActivity extends AppCompatActivity {

    TabLayout tabLayout;
    ViewPager viewPager;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        anhxa();
        init();
    }
    
    private void init() {
        MainViewPagerAdapter mainViewPagerAdapter = new MainViewPagerAdapter(getSupportFragmentManager());
        mainViewPagerAdapter.addFragment(new Fragment_Trang_Chu(), "Trang Chu");
        mainViewPagerAdapter.addFragment(new Fragment_Tim_Kiem(), "Tim Kiem");
        viewPager.setAdapter(mainViewPagerAdapter);
        tabLayout.setupWithViewPager(viewPager);
        tabLayout.getTabAt(0).setIcon(R.drawable.icontrangchu);
        tabLayout.getTabAt(1).setIcon(R.drawable.iconsearch);
    }
    @SuppressLint("WrongViewCast")
    private void anhxa() {
        tabLayout = findViewById(R.id.myTabLayout);
        viewPager = findViewById(R.id.myViewPager);
    }
    

    }

    E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.appnhac2, PID: 10439 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.appnhac2/com.example.appnhac2.Ativity.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void androidx.viewpager.widget.ViewPager.setAdapter(androidx.viewpager.widget.PagerAdapter)' on a null object reference at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3270) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409) at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83) at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016) at android.os.Handler.dispatchMessage(Handler.java:107) at android.os.Looper.loop(Looper.java:214) at android.app.ActivityThread.main(ActivityThread.java:7356) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930) Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void androidx.viewpager.widget.ViewPager.setAdapter(androidx.viewpager.widget.PagerAdapter)' on a null object reference at com.example.appnhac2.Ativity.MainActivity.init(MainActivity.java:32) at com.example.appnhac2.Ativity.MainActivity.onCreate(MainActivity.java:25) at android.app.Activity.performCreate(Activity.java:7802) at android.app.Activity.performCreate(Activity.java:7791) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1299) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3245) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)  at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)  at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)  at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)  at android.os.Handler.dispatchMessage(Handler.java:107)  at android.os.Looper.loop(Looper.java:214)  at android.app.ActivityThread.main(ActivityThread.java:7356)  at java.lang.reflect.Method.invoke(Native Method)  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930) 

    opened by tranminhquan536 1
  • Change the id of the navigation items

    Change the id of the navigation items

    Allows for better understanding of each nav item.

    Guidelines

    Describe the big picture of your changes here to communicate to the maintainers why we should accept this pull request. If it fixes a bug or resolves a feature request, be sure to link to that issue.

    Types of changes

    What types of changes does your code introduce? A minor refactor was made.

    opened by cleverSheep 1
  • Animation does not start

    Animation does not start

    • Affected Device(s) [Pixel 3A API 28]

    Describe the Bug:

    The navigation works when clicking a movie, but the animation does doesn't. This only occurs on API 28. I've tested API 29, 27, 26; all of which work fine.

    Expected Behavior:

    Clicking on a movie should should start the material transform animation.

    opened by cleverSheep 1
  • Tests to be added

    Tests to be added

    Is your feature request related to a problem? No

    The arch. of the app is really good, but for a developer to get more understanding on how to test such an app, tehre should be tests included.

    Describe the solution you'd like: Unit tests, integration and some UI tests

    opened by jaydeepw 1
  • Update DatabindingFragment.kt

    Update DatabindingFragment.kt

    Bugfix - A small correction for the class name in the doc comment.

    Guidelines

    Describe the big picture of your changes here to communicate to the maintainers why we should accept this pull request. If it fixes a bug or resolves a feature request, be sure to link to that issue.

    Types of changes

    What types of changes does your code introduce?

    • [ ] Bugfix (non-breaking change which fixes an issue)
    • [ ] New feature (non-breaking change which adds functionality)
    • [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)

    Preparing a pull request for review

    Ensure your change is properly formatted by running:

    $ ./gradlew spotlessApply
    

    Please correct any failures before requesting a review.

    opened by sukie2 0
Releases(1.0.4)
Owner
Jaewoong Eum
Android software engineer. Digital Nomad. Open Source Contributor. ❤️ Love coffee, music, magic tricks and writing poems. Coffee Driven Development.
Jaewoong Eum
🦄 Android Pokedex-AR using ARCore, Sceneform, Hilt, Coroutines, Flow, Jetpack (Room, ViewModel, LiveData) based on MVVM architecture.

?? Android Pokedex-AR using ARCore, Sceneform, Hilt, Coroutines, Flow, Jetpack (Room, ViewModel, LiveData) based on MVVM architecture.

Jaewoong Eum 535 Dec 9, 2022
Simple Notes app demonstrates modern Android development with Hilt, Material Motion, Coroutines, Flow, Jetpack (Room, ViewModel) based on MVVM architecture.

Simple Notes app demonstrates modern Android development with Hilt, Material Motion, Coroutines, Flow, Jetpack (Room, ViewModel) based on MVVM architecture.

Aravind Chowdary 2 Sep 3, 2022
Wallpaper app made using Hilt, Retrofit, Room, Navigation Components, MVI, Coroutines, Flows, ViewModel, LiveData, Datastore Preference.

Android Picture Engine Wallpaper app made using Hilt, Retrofit, Room, Navigation Components, MVI, Coroutines, Flows, ViewModel, LiveData, Datastore Pr

Simone Conigliaro 59 Sep 27, 2022
To Do List App is built in Kotlin using Material 3, Data Binding, Navigation Component Graphs, Room persistence library, Kotlin coroutines, LiveData, Dagger Hilt, and Notifications following MVVM Architecture.

ToDoListApp ToDoList App demonstrates modern Android development with Hilt, Coroutines, LiveData, Jetpack (Room, ViewModel), and Material 3 Design bas

Naman Garg 10 Jan 8, 2023
Simple Notes app, MVVM with Google Architectural components Room database, LiveData and ViewModel. Written in Kotlin using androidx libraries

Simple Notes app, MVVM with Google Architectural components Room database, LiveData and ViewModel. Written in Kotlin using androidx libraries. Implemented Firebase Auth and Database, and used Room database

Javokhir Jambulov 3 Aug 1, 2022
Advanced Android Weather App using MVVM Architecture Sample (ViewModel + LiveData + Kotlin + volley) = Weather App

Advanced Android Weather App using MVVM Architecture Sample (ViewModel + LiveData + Kotlin + volley) = Weather App Video Weather.-.HD.720p.mov Introdu

wykee2 4 Jul 12, 2022
Shreyas Patil 2.1k Dec 30, 2022
Patter Lock using Hilt, Coroutines, Flow and Custom View Components based on MVVM architecture.

Pattern Lock App Sample project for created Pattern Lock View using custom view. Preview Usage Step 1 Add the PatterLockView in your XML layout file.

Furkan Özcan 5 Aug 22, 2021
Note taking app using MVVM architecture with Hilt, Material Motion, Coroutines, Flow, Jetpack

Note taking app using MVVM architecture with Hilt, Material Motion, Coroutines, Flow, Jetpack (Room, ViewModel,Paging3).

Ranbir Singh 7 Apr 25, 2022
A simple Pokedex App getting API with Retrofit, maintaining data using LiveData, and Material Design based on MVVM architecture

PokedexApp Pokedex A simple Pokedex App getting API with Retrofit, maintaining data using LiveData, and Material Design based on MVVM architecture. Te

Steven Adriano 0 Apr 12, 2022
The JeTrivia is built on a modern Android Development tech stack with MVVM architecture. Kotlin, Coroutine, Flow, StateFlow, Jetpack Compose, Navigation, Room, Hilt, Retrofit2, OkHttp3, kotlinx.serialization, MockK, Truth

JeTrivia ?? In Progress ?? The JeTrivia application is sample based on MVVM architecture. Fetching data from the network via repository pattern and sa

Tolga Bolatcan 5 Mar 31, 2022
An simple image gallery app utilizing Unsplash API to showcase modern Android development architecture (MVVM + Kotlin + Retrofit2 + Hilt + Coroutines + Kotlin Flow + mockK + Espresso + Junit)

Imagine App An simple image gallery app utilizing Unsplash API. Built with ❤︎ by Wajahat Karim and contributors Features Popular photos with paginatio

Wajahat Karim 313 Jan 4, 2023
NewsApp - Modern Minimalistic Design, MVVM, Pagination, Retrofit, Coroutines, Room, Glide, Navigation Component (Clean Architecture)

NewsApp is a modern news android application which features virtually ALL recent and recommended android development tech stack and tools used

Osama Sayed 4 Dec 6, 2021
Android multimodule project based on Kotlin, MVVM, SOLID, flow, coroutines and paging3.

TVMaze David Ferrándiz Features Retrieve TVMaze shows in a grid. See more information about the show in a new screen Tech Kotlin Retrofit Modularizati

David Ferrandiz 1 Nov 18, 2022
MarsRealEstate is a simple demo app using ViewModel & LiveData with Retrofit, Glide and Moshi in Kotlin.

Android-NASA-Real-Estate-Mars Is Android app that uses Kotlin and MVVM architecture is a simple app that uses Coroutines, LiveData with Retrofit, Glid

Dmytro K 0 Nov 17, 2021
🛡️ Android security (camera/microphone dots indicators) app using Hilt, Animations, Coroutines, Material, StateFlow, Jetpack based on MVVM architecture.

??️ Android security app using Hilt, Animations, Coroutines, Material, StateFlow, Jetpack (Room, ViewModel, Paging, Security, Biometrics, Start-up) based on MVVM architecture.

null 639 Jan 6, 2023
:movie_camera: Movie discovery app showcasing Android best practices with Google's recommended architecture: MVVM + Repository + Offline support + Android Architecture Components + Paging library & Retrofit2.

Popular Movies Stage 1 + Stage 2 Discover the most popular and top rated movies playing. Movies data fetched using themoviedb.org API. ✨ Screenshots M

Yassin AJDI 189 Nov 26, 2022
🛒A Minimal Expense E-Commerce App built to demonstrate the use of modern android architecture components [Navigation, Room, MotionLayout, etc..] with MVVM Architecture. ✔

E-Store A Simple E-Commerce App ?? built to demonstrate the use of modern android architecture component with MVVM Architecture ?? . Made with love ❤️

Ameen Essa 14 Nov 3, 2022