Code Monkey home page Code Monkey logo

pokedex's Introduction

Pokedex

License API Build Status
Google Medium Profile Profile

🗡️ Pokedex demonstrates modern Android development with Hilt, Coroutines, Flow, Jetpack (Room, ViewModel), and Material Design based on MVVM architecture.

Tip

If you want to see the Jetpack Compose version of Pokedex, check out the Pokedex Compose repository.

Download

Go to the Releases to download the latest APK.

Tech stack & Open-source libraries

  • Minimum SDK level 21
  • Kotlin based, Coroutines + Flow for asynchronous.
  • Jetpack
    • Lifecycle: Observe Android lifecycles and handle UI states upon the lifecycle changes.
    • ViewModel: Manages UI-related data holder and lifecycle aware. Allows data to survive configuration changes such as screen rotations.
    • DataBinding: Binds UI components in your layouts to data sources in your app using a declarative format rather than programmatically.
    • Room: Constructs Database by providing an abstraction layer over SQLite to allow fluent database access.
    • Hilt: for dependency injection.
  • Architecture
    • MVVM Architecture (View - DataBinding - ViewModel - Model)
    • Bindables: Android DataBinding kit for notifying data changes to UI layers.
    • Repository Pattern
  • Retrofit2 & OkHttp3: Construct the REST APIs and paging network data.
  • Sandwich: Construct a lightweight and modern response interface to handle network payload for Android.
  • Moshi: A modern JSON library for Kotlin and Java.
  • WhatIf: Check nullable objects and empty collections more fluently.
  • Bundler: Android Intent & Bundle extensions, which insert and retrieve values elegantly.
  • ksp: Kotlin Symbol Processing API.
  • Turbine: A small testing library for kotlinx.coroutines Flow.
  • Material-Components: Material design components for building ripple animation, and CardView.
  • Glide, GlidePalette: Loading images from network.
  • TransformationLayout: Implementing transformation motion animations.
  • Custom Views
    • Rainbow: An easy way to apply gradations and tinting for Android.
    • AndroidRibbon: A simple way to implement a beautiful ribbon with the shimmering on Android.
    • ProgressView: A polished and flexible ProgressView, fully customizable with animations.
  • Timber: A logger with a small, extensible API.

Architecture

Pokedex is based on the MVVM architecture and the Repository pattern, which follows the Google's official architecture guidance.

architecture

The overall architecture of Pokedex is composed of two layers; the UI layer and the data layer. Each layer has dedicated components and they have each different responsibilities, as defined below:

Pokedex was built with Guide to app architecture, so it would be a great sample to show how the architecture works in real-world projects.

Architecture Overview

architecture

  • Each layer follows unidirectional event/data flow; the UI layer emits user events to the data layer, and the data layer exposes data as a stream to other layers.
  • The data layer is designed to work independently from other layers and must be pure, which means it doesn't have any dependencies on the other layers.

With this loosely coupled architecture, you can increase the reusability of components and scalability of your app.

UI Layer

architecture

The UI layer consists of UI elements to configure screens that could interact with users and ViewModel that holds app states and restores data when configuration changes.

  • UI elements observe the data flow via DataBinding, which is the most essential part of the MVVM architecture.
  • With Bindables, which is an Android DataBinding kit for notifying data changes, you can implement two-way binding, and data observation in XML very clean.

Data Layer

architecture

The data Layer consists of repositories, which include business logic, such as querying data from the local database and requesting remote data from the network. It is implemented as an offline-first source of business logic and follows the single source of truth principle.

Pokedex is an offline-first app is an app that is able to perform all, or a critical subset of its core functionality without access to the internet. So users don't need to be up-to-date on the network resources every time and it will decrease users' data consumption. For further information, you can check out Build an offline-first app.

Modularization

architecture

Pokedex adopted modularization strategies below:

  • Reusability: Modulizing reusable codes properly enable opportunities for code sharing and limits code accessibility in other modules at the same time.
  • Parallel Building: Each module can be run in parallel and it reduces the build time.
  • Strict visibility control: Modules restrict to expose dedicated components and access to other layers, so it prevents they're being used outside the module
  • Decentralized focusing: Each developer team can assign their dedicated module and they can focus on their own modules.

For more information, check out the Guide to Android app modularization.

MAD Score

summary kotlin

Open API

Pokedex using the PokeAPI for constructing RESTful API.
PokeAPI provides a RESTful API interface to highly detailed objects built from thousands of lines of data related to Pokémon.

Find this repository useful? ❤️

Support it by joining stargazers for this repository. ⭐
Also, follow me on GitHub for my next creations! 🤩

License

Designed and developed by 2022 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.

pokedex's People

Contributors

androiddevnotes avatar efhemo avatar eoqkrskfk94 avatar freedomchuks avatar ganadist avatar halilozel1903 avatar huixingwong avatar lorenzovngl avatar lucasnlm avatar mhdabbaghy avatar mhzdev avatar necatisozer avatar piloudu avatar renovate[bot] avatar shahnoor-khan avatar skydoves avatar yehezkiell avatar zjunior06 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  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

pokedex's Issues

App build failure by circular dependency between kapt and ksp

Please complete the following information:

  • Build failure

Describe the Bug:

$ git clone https://github.com/skydoves/Pokedex

$ cd Pokedex

$ ./gradlew :app:aR

FAILURE: Build failed with an exception.

* What went wrong:
Circular dependency between the following tasks:
:app:kaptGenerateStubsReleaseKotlin
\--- :app:kspReleaseKotlin
     \--- :app:kaptReleaseKotlin
          \--- :app:kaptGenerateStubsReleaseKotlin (*)

(*) - details omitted (listed previously)

Here is gradle scan result : https://scans.gradle.com/s/2xsbxrhuos4b4

Expected Behavior:

How to provide savedstateHandle in DetailViewModel?

how to provide private val savedStateHandle: SavedStateHandle in DetailViewModel for ViewModel with AssistedInject?
because if I change into this

class DetailViewModel @AssistedInject constructor(
  detailRepository: DetailRepository,
  savedstateHandle: SavedstateHandle ,
  @Assisted private val pokemonName: String
) : LiveCoroutinesViewModel() {

it will give me error, because i didnt proved savedstateHandle in injection

Filter pokemon.

Is your feature request related to a problem?

no.

Describe the solution you'd like:

A menu where you could filter pokemon by generation, name, type, etc.

Describe alternatives you've considered:

A search bar.

pokemon types are not displayed properly

Please complete the following information:

  • App Version: v1.0.0
  • Affected Device(s): LG G5 with Android 8.0

Describe the Bug:

The pokemon types are not being displayed properly on my device. Here's a screenshot:

screenshot_vertical

Also, after rotating the device to landscape mode, the types are duplicated: (See comment bellow)

screenshot_horizontal

Expected Behavior:

Expected pokemon types to be displayed exactly like the screenshots on the repo.

找不到符号 hilt注解编译时

/Users/admin/Desktop/移动开发/android/mydemo/Pokedex/app/build/generated/source/kapt/debug/com/skydoves/pokedex/test/hilt/HiltTestModule_GetHiltTestObjectFactory.java:23: 错误: 找不到符号
public final class HiltTestModule_GetHiltTestObjectFactory implements Factory {
^
符号: 类 HiltTestObject

其实这些东西都存在,都编译生成了, 就是爆红

Pokémon caught list.

Is your feature request related to a problem?
No

A clear and concise description of what the problem is.

Describe the solution you'd like:
There would be another drawer or some menu where you would see the list of pokémons you have caught. You could add pokémons to the list manually by clicking on the specific pokédex entry and clicking on a specific button.

A clear and concise description of what you want to happen.

Describe alternatives you've considered:
If you could find a Pokémon GO API you could even do it automatically.

A clear description of any alternative solutions you've considered.

how to refresh when page=0

i add SwipeRefreshLayout for MainActivity ,and try to refresh but when page=0 nothing happened,Can you add refresh for this project?

ListAdapter reset RecyclerView after submitList(Edit)->If you direclty fetch from the network and submit list that will cause this issue

Please complete the following information:

  • Library-Version Current Main Branch
  • Affected Device(s) [Redmi Note 8]

Describe the Bug:
After submitting the list previous list is cleared and new is replacing it. Pagination is not working
Add a clear description of the problem.
I am using an API when I got a response from the server and submit the result it is resetting the recycler view and moving to position 0 in UI Edit)->If you direclty fetch from the network and submit list that will cause this issue
Expected Behavior:
pagination should work
A clear description of what you expected to happen.
I want to paginate data from the API and add data to the list and smooth scroll to the end

5 type arguments expected for interface CommonExtension in build.gradle.kts

Please complete the following information:

  • Version: v0.0.1
  • Device : OnePlus 6T

Describe the Bug:

private typealias AndroidExtension = com.android.build.api.dsl.CommonExtension<*, *, *, *, *, *>

5 type arguments expected for interface CommonExtension<BuildFeaturesT : BuildFeatures, BuildTypeT : BuildType, DefaultConfigT : DefaultConfig, ProductFlavorT : ProductFlavor, AndroidResourcesT : AndroidResources>

Expected Behavior:

The project will build perfectly

Add menu with About page

In About page should be
Author name and contact
Source code - Github link
Licence
App version

ViewModel tests always asserting true

If you change any value inside verify statement testing still asserting everything it's OK. Seems that there's some issue related with coroutines

My feedback :D

First of all I want to congratulate you, the animations when opening a pokemon are beautiful!

Here are my fb:

1 - It is difficult to access pokemon with high numbers, for example #318 (random number). A search bar can help solve this problem.

2 - It would be great to be able to have a list of favorite pokemon.

3 - I don't remember what the lateral scroll is called to quickly access in alphabetical or by number order in list order (a, b, c, d, e, f, etc.) but it can help to get a quick scroll. Hope to be clear.

Cheers!

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Detected dependencies

github-actions
.github/workflows/android.yml
  • actions/checkout v4
  • actions/setup-java v4
  • actions/cache v4
gradle
buildSrc/src/main/kotlin/com/skydoves/pokedex/Configuration.kt
gradle.properties
settings.gradle.kts
  • com.android.settings 8.3.2
build.gradle.kts
app/build.gradle.kts
benchmark/build.gradle.kts
buildSrc/build.gradle.kts
core-data/build.gradle.kts
core-database/build.gradle.kts
core-model/build.gradle.kts
core-network/build.gradle.kts
core-test/build.gradle.kts
gradle/libs.versions.toml
  • com.google.android.material:material 1.11.0
  • androidx.fragment:fragment-ktx 1.6.2
  • androidx.lifecycle:lifecycle-viewmodel-ktx 2.7.0
  • androidx.room:room-runtime 2.6.1
  • androidx.room:room-ktx 2.6.1
  • androidx.room:room-compiler 2.6.1
  • androidx.arch.core:core-testing 2.2.0
  • androidx.startup:startup-runtime 1.1.1
  • androidx.test:core 1.5.0
  • androidx.test.ext:junit 1.1.5
  • androidx.test.espresso:espresso-core 3.5.1
  • com.github.skydoves:bindables 1.1.0
  • com.google.dagger:hilt-android 2.51.1
  • com.google.dagger:hilt-compiler 2.51.1
  • com.google.dagger:hilt-android-testing 2.51.1
  • com.google.dagger:hilt-android-gradle-plugin 2.51.1
  • com.github.skydoves:sandwich-retrofit 2.0.6
  • com.squareup.retrofit2:converter-gson 2.11.0
  • com.squareup.retrofit2:converter-moshi 2.11.0
  • com.squareup.okhttp3:logging-interceptor 4.12.0
  • com.squareup.okhttp3:mockwebserver 4.12.0
  • com.squareup.moshi:moshi-kotlin 1.15.1
  • com.squareup.moshi:moshi-kotlin-codegen 1.15.1
  • org.jetbrains.kotlinx:kotlinx-coroutines-android 1.8.0
  • org.jetbrains.kotlinx:kotlinx-coroutines-test 1.8.0
  • com.github.skydoves:whatif 1.1.4
  • com.github.bumptech.glide:glide 4.16.0
  • com.github.florent37:glidepalette 2.1.2
  • com.github.skydoves:bundler 1.0.4
  • com.github.skydoves:transformationlayout 1.1.3
  • androidx.recyclerview:recyclerview 1.3.2
  • com.github.skydoves:baserecyclerviewadapter 1.0.4
  • com.github.skydoves:rainbow 1.0.4
  • com.github.skydoves:androidribbon 1.0.4
  • com.github.skydoves:progressview 1.1.3
  • com.jakewharton.timber:timber 5.0.1
  • junit:junit 4.13.2
  • org.mockito:mockito-core 5.11.0
  • org.mockito.kotlin:mockito-kotlin 5.3.1
  • app.cash.turbine:turbine 1.1.0
  • org.robolectric:robolectric 4.12.1
  • com.google.truth:truth 1.4.2
  • com.android.support.test:runner 1.3.0-beta01
  • androidx.profileinstaller:profileinstaller 1.3.1
  • androidx.benchmark:benchmark-macro-junit4 1.2.3
  • androidx.test.uiautomator:uiautomator 2.3.0
  • com.android.application 8.3.2
  • com.android.library 8.3.2
  • com.android.test 8.3.2
  • org.jetbrains.kotlin.android 1.9.23
  • org.jetbrains.kotlin.kapt 1.9.23
  • com.google.devtools.ksp 1.9.23-1.0.20
  • org.jetbrains.kotlin.plugin.parcelize 1.9.23
  • com.diffplug.spotless 6.25.0
  • com.google.dagger.hilt.android 2.51.1
gradle-wrapper
gradle/wrapper/gradle-wrapper.properties
  • gradle 8.7

  • Check this box to trigger a request for Renovate to run again on this repository

# of Downloads?

How many downloads does your app have? For a university class I need to find a kotlin open source app with a lot of downloads.
And really nice project by the way, it is really good

Add to F-Droid

Hey, I noticed that this app is licensed by a free license and I'd like to see this app in the F-Droid cataolgue, a store of FOSS Android apps. Take a look to the request here

Could not find fragment-1.2.4.jar

I come across following error when syncing and building the project

Could not find fragment-1.2.4.jar (androidx.fragment:fragment:1.2.4).
Searched in the following locations:
https://dl.google.com/dl/android/maven2/androidx/fragment/fragment/1.2.4/fragment-1.2.4.jar

Repository Interface not used?

Hi! excellent work 👍
I'm wondering if the implementation of the repository interface in the MainRepository and DetailsRepository is necessary as it is empty.

failed to load pokemon images

Please complete the following information:

  • Library Version [e.g. v1.0.5]
  • Affected Device(s) [e.g. Samsung Galaxy s21 with Android 11]

Describe the Bug:

currently the app cannot load the pokemon images

error:
W/Glide: Load failed for https://pokeres.bastionbot.org/images/pokemon/7.png with size [330x330]
class com.bumptech.glide.load.engine.GlideException: Failed to load resource
There was 1 root cause:
com.bumptech.glide.load.HttpException(Failed to connect or obtain data, status code: -1)

it seems the url (rest api) https://pokeres.bastionbot.org/images/pokemon/ does not work anymore.

Expected Behavior:
it should show the images of the pokemons

Bug causing test to not run properly

Please complete the following information:

  • Library Version [e.g. v1.0.0]
  • Affected Device(s) [e.g. Samsung Galaxy s10 with Android 9.0]

Describe the Bug:
Any class that uses MainCoroutinesRule doesn't actually run the test. If you put the line assertThat(-1, `is`(0)) in any class that uses MainCoroutinesRule it would pass.

Expected Behavior:
assertThat(-1, `is`(0)) should assert and fail

Proposed Solution:
The following code should change from:

@ExperimentalCoroutinesApi
class MainCoroutinesRule : TestRule, TestCoroutineScope by TestCoroutineScope() {

  private val testCoroutinesDispatcher = TestCoroutineDispatcher()

  override fun apply(base: Statement?, description: Description?) = object : Statement() {
    override fun evaluate() {
      Dispatchers.setMain(testCoroutinesDispatcher)
      cleanupTestCoroutines()
      Dispatchers.resetMain()
    }
  }
}

to this:

@ExperimentalCoroutinesApi
class MainCoroutinesRule : TestRule, TestCoroutineScope by TestCoroutineScope() {

  private val testCoroutinesDispatcher = TestCoroutineDispatcher()

  override fun apply(base: Statement?, description: Description?) = object : Statement() {
    override fun evaluate() {
      Dispatchers.setMain(testCoroutinesDispatcher)
      try {
        base?.evaluate()
      } finally {
        cleanupTestCoroutines()
        Dispatchers.resetMain()
      }
    }
  }
}

Better Offline mode

Could be there option to download all the data by one button?

If I get it correctly data is cached only after you look at it in online mode and wait for it to be cached. Specif info about Pokemons are hard to be cached, because its on different page.

Adapter items disappear on double tap and back press

Noticed this strange bug when I accidentally double tapped a Pokémon adapter item and immediately press the system back button. The adapter item disappears from the list when the animation finishes. Might be an issue with TransformationLayout?

Screen_Recording_20200601-133143_1_1

InvalidTestClassError on unit tests

Hi, I followed your implementation on my project. In unit test part, I have an error.

org.junit.runners.model.InvalidTestClassError: Invalid test class 'myApplicationID.repository.LoginRegisterServiceTest':

  1. Method sendTokenTest() should be void

My test fun like below;

@Test
fun sendTokenTest() = runBlocking {
    val mockData = Response<ResponseBody>(
        error = false,
        message = "OK",
        result = null,
        statusCode = 200,
        errorCode = 0
    )
    val tokenRequest = TokenRequest("+905554443322")
    whenever(service.sendToken(tokenRequest)).thenReturn(mockData)
    repository.sendToken("+905554443322").test {
        assertEquals(expectItem().message, "OK")
        assertNull(expectItem().result)
        assertFalse(expectItem().error)
        assertEquals(expectItem().statusCode, 200)
        assertEquals(expectItem().errorCode, 0)
        expectComplete()
    }

    verify(service, atLeastOnce()).sendToken(tokenRequest)
}

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.