├── .gitignore
├── .idea
├── codeStyles
│ ├── Project.xml
│ └── codeStyleConfig.xml
├── encodings.xml
├── gradle.xml
├── jarRepositories.xml
├── misc.xml
├── render.experimental.xml
├── runConfigurations.xml
└── vcs.xml
├── README.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
├── schemas
│ └── com.sevenpeakssoftware.zubair.model.database.AppDatabase
│ │ └── 1.json
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── sevenpeakssoftware
│ │ └── zubair
│ │ └── ExampleInstrumentedTest.kt
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── sevenpeakssoftware
│ │ │ └── zubair
│ │ │ ├── base
│ │ │ ├── BaseViewModel.kt
│ │ │ └── CustomBindingAdapter.kt
│ │ │ ├── injection
│ │ │ ├── ViewModelFactory.kt
│ │ │ ├── component
│ │ │ │ └── ViewModelInjector.kt
│ │ │ └── module
│ │ │ │ └── NetworkModule.kt
│ │ │ ├── model
│ │ │ ├── Article.kt
│ │ │ ├── ArticleDao.kt
│ │ │ ├── ArticleResponse.kt
│ │ │ └── database
│ │ │ │ └── AppDatabase.kt
│ │ │ ├── network
│ │ │ └── ArticleApi.kt
│ │ │ ├── ui
│ │ │ └── cars
│ │ │ │ ├── ArticleListActivity.kt
│ │ │ │ ├── ArticleListAdapter.kt
│ │ │ │ ├── ArticleListViewModel.kt
│ │ │ │ └── ArticleViewModel.kt
│ │ │ └── utils
│ │ │ ├── BindingAdapters.kt
│ │ │ ├── Constants.kt
│ │ │ ├── Utility.kt
│ │ │ └── extension
│ │ │ └── ViewExtension.kt
│ └── res
│ │ ├── drawable-v24
│ │ └── ic_launcher_foreground.xml
│ │ ├── drawable
│ │ ├── gradiant.xml
│ │ ├── ic_launcher_background.xml
│ │ └── poster.jpg
│ │ ├── font
│ │ ├── appfont.xml
│ │ └── roboto_medium.ttf
│ │ ├── layout
│ │ ├── activity_article_list.xml
│ │ ├── activity_main.xml
│ │ └── item_article.xml
│ │ ├── mipmap-anydpi-v26
│ │ ├── ic_launcher.xml
│ │ └── ic_launcher_round.xml
│ │ ├── mipmap-hdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ └── values
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── com
│ └── sevenpeakssoftware
│ └── zubair
│ └── ExampleUnitTest.kt
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/caches
5 | /.idea/libraries
6 | /.idea/modules.xml
7 | /.idea/workspace.xml
8 | /.idea/navEditor.xml
9 | /.idea/assetWizardSettings.xml
10 | .DS_Store
11 | /build
12 | /captures
13 | .externalNativeBuild
14 |
--------------------------------------------------------------------------------
/.idea/codeStyles/Project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
11 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | xmlns:android
30 |
31 | ^$
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 | xmlns:.*
41 |
42 | ^$
43 |
44 |
45 | BY_NAME
46 |
47 |
48 |
49 |
50 |
51 |
52 | .*:id
53 |
54 | http://schemas.android.com/apk/res/android
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 | .*:name
64 |
65 | http://schemas.android.com/apk/res/android
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 | name
75 |
76 | ^$
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 | style
86 |
87 | ^$
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 | .*
97 |
98 | ^$
99 |
100 |
101 | BY_NAME
102 |
103 |
104 |
105 |
106 |
107 |
108 | .*
109 |
110 | http://schemas.android.com/apk/res/android
111 |
112 |
113 | ANDROID_ATTRIBUTE_ORDER
114 |
115 |
116 |
117 |
118 |
119 |
120 | .*
121 |
122 | .*
123 |
124 |
125 | BY_NAME
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
--------------------------------------------------------------------------------
/.idea/codeStyles/codeStyleConfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
19 |
20 |
--------------------------------------------------------------------------------
/.idea/jarRepositories.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/render.experimental.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Android-with-Kotlin-MVVM-Dagger-2-RxJava-Retrofit
2 |
3 |
4 | ## Example’s Feature:
5 | * Load data from server Using Retrofit2.
6 | * Use Livedata with Room.
7 |
8 |
9 |
10 |
11 | ***
12 | ## Technology Stack
13 | * Kotlin
14 | * Android
15 |
16 | DB
17 | * Firebase LiveData
18 | * Offline Storage Using Room
19 |
20 |
21 | Architectural Pattern
22 | * MVVM
23 |
24 | Libraries
25 | * RxJava
26 | * Dagger2
27 | * Firestore
28 | * Room
29 |
30 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 | apply plugin: 'kotlin-android'
3 | apply plugin: 'kotlin-android-extensions'
4 | apply plugin: 'kotlin-kapt'
5 |
6 | android {
7 | compileSdkVersion 30
8 | dataBinding {
9 | enabled = true
10 | }
11 | defaultConfig {
12 | applicationId "com.sevenpeakssoftware.zubair"
13 | minSdkVersion 16
14 | targetSdkVersion 30
15 | versionCode 1
16 | versionName "1.0"
17 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
18 |
19 | kapt {
20 | arguments {
21 | arg("room.schemaLocation", "$projectDir/schemas".toString())
22 | }
23 | }
24 |
25 | }
26 | buildTypes {
27 | release {
28 | minifyEnabled false
29 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
30 | }
31 | }
32 | sourceSets {
33 | main.java.srcDirs += 'src/main/kotlin'
34 | test.java.srcDirs = ['src/test/kotlin']
35 | androidTest.java.srcDirs = ['src/androidTest/kotlin']
36 | }
37 |
38 | }
39 |
40 | dependencies {
41 | implementation fileTree(dir: 'libs', include: ['*.jar'])
42 | implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
43 | implementation "com.android.support:appcompat-v7:$android_support_version"
44 |
45 | // Support Design
46 | implementation "com.android.support:design:$android_support_version"
47 |
48 |
49 | // RecyclerView
50 | implementation "com.android.support:recyclerview-v7:$android_support_version"
51 |
52 | // Room
53 | implementation "android.arch.persistence.room:runtime:$room_version"
54 | kapt "android.arch.persistence.room:compiler:$room_version"
55 |
56 |
57 | // LiveData & ViewModel
58 | implementation"android.arch.lifecycle:extensions:$lifecycle_version"
59 |
60 |
61 | implementation 'com.squareup.okhttp3:logging-interceptor:4.5.0'
62 |
63 | implementation 'com.android.support.constraint:constraint-layout:2.0.1'
64 | testImplementation 'junit:junit:4.12'
65 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
66 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
67 |
68 | // Retrofit
69 | implementation "com.squareup.retrofit2:retrofit:$retrofit_version"
70 | implementation "com.squareup.retrofit2:adapter-rxjava2:$retrofit_version"
71 | implementation "com.squareup.retrofit2:converter-moshi:$retrofit_version"
72 |
73 | // Dagger 2
74 | implementation "com.google.dagger:dagger:$dagger2_version"
75 | kapt "com.google.dagger:dagger-compiler:$dagger2_version"
76 | compileOnly "org.glassfish:javax.annotation:3.1.1"
77 |
78 | implementation 'com.google.code.gson:gson:2.8.6'
79 | implementation "com.squareup.picasso:picasso:$picasso_version"
80 |
81 |
82 | //Rx
83 | implementation "io.reactivex.rxjava2:rxjava:2.2.13"
84 | implementation "io.reactivex.rxjava2:rxandroid:2.1.1"
85 |
86 | }
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/app/schemas/com.sevenpeakssoftware.zubair.model.database.AppDatabase/1.json:
--------------------------------------------------------------------------------
1 | {
2 | "formatVersion": 1,
3 | "database": {
4 | "version": 1,
5 | "identityHash": "ab8bf0688bc3964c8fb2e76394875173",
6 | "entities": [
7 | {
8 | "tableName": "Article",
9 | "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `title` TEXT NOT NULL, `dateTime` TEXT NOT NULL, `ingress` TEXT NOT NULL, `image` TEXT NOT NULL, `created` REAL NOT NULL, `changed` REAL NOT NULL, PRIMARY KEY(`id`))",
10 | "fields": [
11 | {
12 | "fieldPath": "id",
13 | "columnName": "id",
14 | "affinity": "INTEGER",
15 | "notNull": true
16 | },
17 | {
18 | "fieldPath": "title",
19 | "columnName": "title",
20 | "affinity": "TEXT",
21 | "notNull": true
22 | },
23 | {
24 | "fieldPath": "dateTime",
25 | "columnName": "dateTime",
26 | "affinity": "TEXT",
27 | "notNull": true
28 | },
29 | {
30 | "fieldPath": "ingress",
31 | "columnName": "ingress",
32 | "affinity": "TEXT",
33 | "notNull": true
34 | },
35 | {
36 | "fieldPath": "image",
37 | "columnName": "image",
38 | "affinity": "TEXT",
39 | "notNull": true
40 | },
41 | {
42 | "fieldPath": "created",
43 | "columnName": "created",
44 | "affinity": "REAL",
45 | "notNull": true
46 | },
47 | {
48 | "fieldPath": "changed",
49 | "columnName": "changed",
50 | "affinity": "REAL",
51 | "notNull": true
52 | }
53 | ],
54 | "primaryKey": {
55 | "columnNames": [
56 | "id"
57 | ],
58 | "autoGenerate": false
59 | },
60 | "indices": [],
61 | "foreignKeys": []
62 | }
63 | ],
64 | "setupQueries": [
65 | "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
66 | "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"ab8bf0688bc3964c8fb2e76394875173\")"
67 | ]
68 | }
69 | }
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/sevenpeakssoftware/zubair/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package com.sevenpeakssoftware.zubair
2 |
3 | import android.support.test.InstrumentationRegistry
4 | import android.support.test.runner.AndroidJUnit4
5 |
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | import org.junit.Assert.*
10 |
11 | /**
12 | * Instrumented test, which will execute on an Android device.
13 | *
14 | * See [testing documentation](http://d.android.com/tools/testing).
15 | */
16 | @RunWith(AndroidJUnit4::class)
17 | class ExampleInstrumentedTest {
18 | @Test
19 | fun useAppContext() {
20 | // Context of the app under test.
21 | val appContext = InstrumentationRegistry.getTargetContext()
22 | assertEquals("com.sevenpeakssoftware.zubair", appContext.packageName)
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sevenpeakssoftware/zubair/base/BaseViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.sevenpeakssoftware.zubair.base
2 |
3 | import android.arch.lifecycle.ViewModel
4 | import com.sevenpeakssoftware.zubair.injection.component.DaggerViewModelInjector
5 | import com.sevenpeakssoftware.zubair.injection.component.ViewModelInjector
6 | import com.sevenpeakssoftware.zubair.injection.module.NetworkModule
7 | import com.sevenpeakssoftware.zubair.ui.cars.ArticleListViewModel
8 | import com.sevenpeakssoftware.zubair.ui.cars.ArticleViewModel
9 |
10 | abstract class BaseViewModel : ViewModel() {
11 | private val injector: ViewModelInjector = DaggerViewModelInjector
12 | .builder()
13 | .networkModule(NetworkModule)
14 | .build()
15 |
16 | init {
17 | inject()
18 | }
19 |
20 | /**
21 | * Injects the required dependencies
22 | */
23 | private fun inject() {
24 | when (this) {
25 | is ArticleListViewModel -> injector.inject(this)
26 | is ArticleViewModel -> injector.inject(this)
27 | }
28 | }
29 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sevenpeakssoftware/zubair/base/CustomBindingAdapter.kt:
--------------------------------------------------------------------------------
1 | package mvvm.sample.foods.ui.base
2 |
3 | import android.databinding.BindingAdapter
4 | import android.widget.ImageView
5 | import com.squareup.picasso.Picasso
6 |
7 | object CustomBindingAdapter {
8 |
9 | @JvmStatic
10 | @BindingAdapter("bind:image_url")
11 | fun loadImage(imageView: ImageView, url: String) {
12 | Picasso.with(imageView.context).load(url).into(imageView)
13 | }
14 |
15 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sevenpeakssoftware/zubair/injection/ViewModelFactory.kt:
--------------------------------------------------------------------------------
1 | package com.sevenpeakssoftware.zubair.injection
2 |
3 | import android.arch.lifecycle.ViewModel
4 | import android.arch.lifecycle.ViewModelProvider
5 | import android.arch.persistence.room.Room
6 | import android.support.v7.app.AppCompatActivity
7 | import com.sevenpeakssoftware.zubair.model.database.AppDatabase
8 | import com.sevenpeakssoftware.zubair.ui.cars.ArticleListViewModel
9 |
10 | class ViewModelFactory(private val activity: AppCompatActivity) : ViewModelProvider.Factory {
11 | override fun create(modelClass: Class): T {
12 | if (modelClass.isAssignableFrom(ArticleListViewModel::class.java)) {
13 | val db = Room.databaseBuilder(
14 | activity.applicationContext,
15 | AppDatabase::class.java,
16 | "articles"
17 | ).build()
18 | @Suppress("UNCHECKED_CAST")
19 | return ArticleListViewModel(db.articleDao()) as T
20 | }
21 | throw IllegalArgumentException("Unknown ViewModel class")
22 |
23 | }
24 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sevenpeakssoftware/zubair/injection/component/ViewModelInjector.kt:
--------------------------------------------------------------------------------
1 | package com.sevenpeakssoftware.zubair.injection.component
2 |
3 | import com.sevenpeakssoftware.zubair.injection.module.NetworkModule
4 | import com.sevenpeakssoftware.zubair.ui.cars.ArticleListViewModel
5 | import com.sevenpeakssoftware.zubair.ui.cars.ArticleViewModel
6 | import dagger.Component
7 |
8 | import javax.inject.Singleton
9 |
10 | /**
11 | * Component providing inject() methods for presenters.
12 | */
13 | @Singleton
14 | @Component(modules = [(NetworkModule::class)])
15 | interface ViewModelInjector {
16 | /**
17 | * Injects required dependencies into the specified ArticleListViewModel.
18 | * @param articleListViewModel ArticleListViewModel in which to inject the dependencies
19 | */
20 | fun inject(articleListViewModel: ArticleListViewModel)
21 |
22 | /**
23 | * Injects required dependencies into the specified ArticleViewModel.
24 | * @param articleViewModel ArticleViewModel in which to inject the dependencies
25 | */
26 | fun inject(articleViewModel: ArticleViewModel)
27 |
28 | @Component.Builder
29 | interface Builder {
30 | fun build(): ViewModelInjector
31 |
32 | fun networkModule(networkModule: NetworkModule): Builder
33 | }
34 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sevenpeakssoftware/zubair/injection/module/NetworkModule.kt:
--------------------------------------------------------------------------------
1 | package com.sevenpeakssoftware.zubair.injection.module
2 |
3 | import com.sevenpeakssoftware.zubair.BuildConfig
4 | import com.sevenpeakssoftware.zubair.network.ArticleApi
5 | import com.sevenpeakssoftware.zubair.utils.BASE_URL
6 | import dagger.Module
7 | import dagger.Provides
8 | import dagger.Reusable
9 | import io.reactivex.schedulers.Schedulers
10 | import okhttp3.Cache
11 | import okhttp3.OkHttpClient
12 | import okhttp3.logging.HttpLoggingInterceptor
13 |
14 | import retrofit2.Retrofit
15 | import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
16 | import retrofit2.converter.moshi.MoshiConverterFactory
17 | import java.util.concurrent.TimeUnit
18 |
19 | /**
20 | * Module which provides all required dependencies about network
21 | */
22 |
23 | @Module
24 | // Safe here as we are dealing with a Dagger 2 module
25 | @Suppress("unused")
26 | object NetworkModule {
27 |
28 | private const val NETWORK_CALL_TIMEOUT = 60
29 |
30 | /**
31 | * Provides the Article service implementation.
32 | * @param retrofit the Retrofit object used to instantiate the service
33 | * @return the Article service implementation.
34 | */
35 | @Provides
36 | @Reusable
37 | @JvmStatic
38 | internal fun provideArticleApi(retrofit: Retrofit): ArticleApi {
39 | return retrofit.create(ArticleApi::class.java)
40 | }
41 |
42 |
43 | /**
44 | * Provides the Retrofit object.
45 | * @return the Retrofit object
46 | */
47 | @Provides
48 | @Reusable
49 | @JvmStatic
50 | internal fun provideRetrofitInterface(): Retrofit {
51 | return Retrofit.Builder()
52 | .baseUrl(BASE_URL)
53 | .client(
54 | OkHttpClient.Builder()
55 | .addInterceptor(HttpLoggingInterceptor()
56 | .apply {
57 | level = if (BuildConfig.DEBUG)
58 | HttpLoggingInterceptor.Level.BODY
59 | else
60 | HttpLoggingInterceptor.Level.NONE
61 | })
62 | .readTimeout(NETWORK_CALL_TIMEOUT.toLong(), TimeUnit.SECONDS)
63 | .writeTimeout(NETWORK_CALL_TIMEOUT.toLong(), TimeUnit.SECONDS)
64 | .build()
65 | )
66 | .addConverterFactory(MoshiConverterFactory.create())
67 | .addCallAdapterFactory(RxJava2CallAdapterFactory.createWithScheduler(Schedulers.io()))
68 | .build()
69 | }
70 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sevenpeakssoftware/zubair/model/Article.kt:
--------------------------------------------------------------------------------
1 | package com.sevenpeakssoftware.zubair.model
2 |
3 | import android.arch.persistence.room.Entity
4 | import android.arch.persistence.room.PrimaryKey
5 |
6 | @Entity
7 | data class Article(
8 | @field:PrimaryKey
9 | val id: Int,
10 | val title: String,
11 | val dateTime: String,
12 | val ingress: String,
13 | val image: String,
14 | val created: Double,
15 | val changed: Double
16 | )
--------------------------------------------------------------------------------
/app/src/main/java/com/sevenpeakssoftware/zubair/model/ArticleDao.kt:
--------------------------------------------------------------------------------
1 | package com.sevenpeakssoftware.zubair.model
2 |
3 | import android.arch.persistence.room.Dao
4 | import android.arch.persistence.room.Insert
5 | import android.arch.persistence.room.Query
6 | import android.arch.persistence.room.Transaction
7 |
8 | @Dao
9 | interface ArticleDao {
10 | @get:Query("SELECT * FROM Article")
11 | val all: List
12 |
13 | @Insert
14 | fun insert(vararg users: Article)
15 |
16 | @Transaction
17 | @Insert
18 | fun insertAll(articles: List)
19 |
20 | // @Insert
21 | // fun insertAll(vararg users: ArticleResponse)
22 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sevenpeakssoftware/zubair/model/ArticleResponse.kt:
--------------------------------------------------------------------------------
1 | package com.sevenpeakssoftware.zubair.model
2 |
3 | import com.google.gson.annotations.SerializedName
4 |
5 |
6 | import android.arch.persistence.room.Entity
7 | import android.arch.persistence.room.PrimaryKey
8 |
9 | data class ArticleResponse(
10 | @SerializedName("status_code") var statusCode: String,
11 | @SerializedName("content") var content: List
12 | )
--------------------------------------------------------------------------------
/app/src/main/java/com/sevenpeakssoftware/zubair/model/database/AppDatabase.kt:
--------------------------------------------------------------------------------
1 | package com.sevenpeakssoftware.zubair.model.database
2 |
3 | import android.arch.persistence.room.Database
4 | import android.arch.persistence.room.RoomDatabase
5 | import com.sevenpeakssoftware.zubair.model.Article
6 | import com.sevenpeakssoftware.zubair.model.ArticleDao
7 |
8 | @Database(entities = [Article::class], version = 1)
9 | abstract class AppDatabase : RoomDatabase() {
10 | abstract fun articleDao(): ArticleDao
11 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sevenpeakssoftware/zubair/network/ArticleApi.kt:
--------------------------------------------------------------------------------
1 | package com.sevenpeakssoftware.zubair.network
2 |
3 | import com.sevenpeakssoftware.zubair.model.ArticleResponse
4 | import io.reactivex.Observable
5 | import retrofit2.http.GET
6 |
7 | /**
8 | * The interface which provides methods to get result of webservices
9 | */
10 | interface ArticleApi {
11 | /**
12 | * Get the list of the Article from the API
13 | */
14 | @GET("article/get_articles_list")
15 | fun getArticles(): Observable
16 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sevenpeakssoftware/zubair/ui/cars/ArticleListActivity.kt:
--------------------------------------------------------------------------------
1 | package com.sevenpeakssoftware.zubair.ui.cars
2 |
3 | import android.arch.lifecycle.Observer
4 | import android.databinding.DataBindingUtil
5 | import android.os.Bundle
6 | import android.support.annotation.StringRes
7 | import android.support.design.widget.Snackbar
8 | import android.support.v7.app.AppCompatActivity
9 | import android.support.v7.widget.LinearLayoutManager
10 | import android.arch.lifecycle.ViewModelProviders
11 | import com.sevenpeakssoftware.zubair.R
12 | import com.sevenpeakssoftware.zubair.databinding.ActivityArticleListBinding
13 | import com.sevenpeakssoftware.zubair.injection.ViewModelFactory
14 |
15 | class ArticleListActivity : AppCompatActivity() {
16 | private lateinit var binding: ActivityArticleListBinding
17 | private lateinit var viewModel: ArticleListViewModel
18 | private var errorSnackbar: Snackbar? = null
19 |
20 | override fun onCreate(savedInstanceState: Bundle?) {
21 | super.onCreate(savedInstanceState)
22 |
23 | binding = DataBindingUtil.setContentView(this, R.layout.activity_article_list)
24 | binding.articleList.layoutManager =
25 | LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
26 |
27 | viewModel = ViewModelProviders.of(this, ViewModelFactory(this))
28 | .get(ArticleListViewModel::class.java)
29 | viewModel.errorMessage.observe(this, Observer { errorMessage ->
30 | if (errorMessage != null) showError(errorMessage) else hideError()
31 | })
32 | binding.viewModel = viewModel
33 | }
34 |
35 | private fun showError(@StringRes errorMessage: Int) {
36 | errorSnackbar = Snackbar.make(binding.root, errorMessage, Snackbar.LENGTH_INDEFINITE)
37 | errorSnackbar?.setAction(R.string.retry, viewModel.errorClickListener)
38 | errorSnackbar?.show()
39 | }
40 |
41 | private fun hideError() {
42 | errorSnackbar?.dismiss()
43 | }
44 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sevenpeakssoftware/zubair/ui/cars/ArticleListAdapter.kt:
--------------------------------------------------------------------------------
1 | package com.sevenpeakssoftware.zubair.ui.cars
2 |
3 | import android.databinding.DataBindingUtil
4 | import android.support.v7.widget.RecyclerView
5 | import android.view.LayoutInflater
6 | import android.view.ViewGroup
7 | import com.sevenpeakssoftware.zubair.R
8 | import com.sevenpeakssoftware.zubair.databinding.ItemArticleBinding
9 | import com.sevenpeakssoftware.zubair.model.Article
10 |
11 | class ArticleListAdapter : RecyclerView.Adapter() {
12 | private lateinit var articleList: List
13 |
14 | override fun onCreateViewHolder(
15 | parent: ViewGroup,
16 | viewType: Int
17 | ): ArticleListAdapter.ViewHolder {
18 | val binding: ItemArticleBinding = DataBindingUtil.inflate(
19 | LayoutInflater.from(parent.context),
20 | R.layout.item_article,
21 | parent,
22 | false
23 | )
24 | return ViewHolder(binding)
25 | }
26 |
27 | override fun onBindViewHolder(holder: ArticleListAdapter.ViewHolder, position: Int) {
28 | holder.bind(articleList[position])
29 | }
30 |
31 | override fun getItemCount(): Int {
32 | return if (::articleList.isInitialized) articleList.size else 0
33 | }
34 |
35 | fun updateArticleList(postList: List) {
36 | this.articleList = postList
37 | notifyDataSetChanged()
38 | }
39 |
40 | class ViewHolder(private val binding: ItemArticleBinding) :
41 | RecyclerView.ViewHolder(binding.root) {
42 | private val viewModel = ArticleViewModel()
43 |
44 | fun bind(article: Article) {
45 | viewModel.bind(article)
46 | binding.viewModel = viewModel
47 | }
48 | }
49 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sevenpeakssoftware/zubair/ui/cars/ArticleListViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.sevenpeakssoftware.zubair.ui.cars
2 |
3 | import android.arch.lifecycle.MutableLiveData
4 | import android.view.View
5 | import com.sevenpeakssoftware.zubair.R
6 | import com.sevenpeakssoftware.zubair.base.BaseViewModel
7 | import com.sevenpeakssoftware.zubair.model.Article
8 | import com.sevenpeakssoftware.zubair.model.ArticleDao
9 | import com.sevenpeakssoftware.zubair.network.ArticleApi
10 | import io.reactivex.Observable
11 | import io.reactivex.android.schedulers.AndroidSchedulers
12 | import io.reactivex.disposables.Disposable
13 | import io.reactivex.schedulers.Schedulers
14 | import javax.inject.Inject
15 |
16 | class ArticleListViewModel(private val articleDao: ArticleDao) : BaseViewModel() {
17 | @Inject
18 | lateinit var articleApi: ArticleApi
19 | val articleListAdapter: ArticleListAdapter = ArticleListAdapter()
20 |
21 | val loadingVisibility: MutableLiveData = MutableLiveData()
22 | val errorMessage: MutableLiveData = MutableLiveData()
23 | val errorClickListener = View.OnClickListener { loadArticles() }
24 |
25 | private lateinit var subscription: Disposable
26 |
27 | init {
28 | loadArticles()
29 | }
30 |
31 | override fun onCleared() {
32 | super.onCleared()
33 | subscription.dispose()
34 | }
35 |
36 |
37 | private fun loadArticles() {
38 | subscription = Observable.fromCallable { articleDao.all }
39 | .concatMap { dbArticleList ->
40 | if (dbArticleList.isEmpty())
41 | articleApi.getArticles().concatMap { apiArticleResponse ->
42 | articleDao.insertAll(apiArticleResponse.content)
43 | Observable.just(apiArticleResponse)
44 | }
45 | else
46 | Observable.just(dbArticleList)
47 | }
48 | .subscribeOn(Schedulers.io())
49 | .observeOn(AndroidSchedulers.mainThread())
50 | .doOnSubscribe { onRetrieveArticleListStart() }
51 | .doOnTerminate { onRetrieveArticleListFinish() }
52 | .subscribe(
53 | { result -> onRetrieveArticleListSuccess(result as List) },
54 | { onRetrieveArticleListError() }
55 | )
56 | }
57 |
58 | private fun onRetrieveArticleListStart() {
59 | loadingVisibility.value = View.VISIBLE
60 | errorMessage.value = null
61 | }
62 |
63 | private fun onRetrieveArticleListFinish() {
64 | loadingVisibility.value = View.GONE
65 | }
66 |
67 |
68 | private fun onRetrieveArticleListSuccess(articleList: List) {
69 |
70 |
71 | articleListAdapter.updateArticleList(articleList)
72 | }
73 |
74 | private fun onRetrieveArticleListError() {
75 | errorMessage.value = R.string.post_error
76 | }
77 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sevenpeakssoftware/zubair/ui/cars/ArticleViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.sevenpeakssoftware.zubair.ui.cars
2 |
3 | import android.arch.lifecycle.MutableLiveData
4 | import android.os.Build
5 | import android.support.annotation.RequiresApi
6 | import android.util.Log
7 | import com.sevenpeakssoftware.zubair.base.BaseViewModel
8 | import com.sevenpeakssoftware.zubair.model.Article
9 | import com.sevenpeakssoftware.zubair.utils.getFormatedDate
10 |
11 |
12 | class ArticleViewModel : BaseViewModel() {
13 | private val title = MutableLiveData()
14 | private val ingress = MutableLiveData()
15 | private val image = MutableLiveData()
16 | private val date = MutableLiveData()
17 |
18 | fun bind(article: Article) {
19 | title.value = article.title
20 | ingress.value = article.ingress
21 | image.value = article.image
22 | date.value = article.dateTime
23 | }
24 |
25 | fun getTitle(): MutableLiveData {
26 | return title
27 | }
28 |
29 | fun getIngress(): MutableLiveData {
30 | return ingress
31 | }
32 |
33 | fun getImage(): MutableLiveData {
34 | return image
35 | }
36 |
37 | @RequiresApi(Build.VERSION_CODES.O)
38 | fun getDate(): MutableLiveData {
39 |
40 | val modifiedDate = getFormatedDate(date.value.toString())
41 | date.value = modifiedDate;
42 |
43 | return date
44 | }
45 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sevenpeakssoftware/zubair/utils/BindingAdapters.kt:
--------------------------------------------------------------------------------
1 | package com.sevenpeakssoftware.zubair.utils
2 |
3 | import android.arch.lifecycle.MutableLiveData
4 | import android.arch.lifecycle.Observer
5 | import android.databinding.BindingAdapter
6 | import android.support.v7.widget.RecyclerView
7 | import android.support.v7.app.AppCompatActivity
8 | import android.view.View
9 | import android.widget.TextView
10 | import com.sevenpeakssoftware.zubair.utils.extension.getParentActivity
11 |
12 | @BindingAdapter("adapter")
13 | fun setAdapter(view: RecyclerView, adapter: RecyclerView.Adapter<*>) {
14 | view.adapter = adapter
15 | }
16 |
17 | @BindingAdapter("mutableVisibility")
18 | fun setMutableVisibility(view: View, visibility: MutableLiveData?) {
19 | val parentActivity: AppCompatActivity? = view.getParentActivity()
20 | if (parentActivity != null && visibility != null) {
21 | visibility.observe(
22 | parentActivity,
23 | Observer { value -> view.visibility = value ?: View.VISIBLE })
24 | }
25 | }
26 |
27 |
28 | @BindingAdapter("mutableText")
29 | fun setMutableText(view: TextView, text: MutableLiveData?) {
30 | val parentActivity: AppCompatActivity? = view.getParentActivity()
31 | if (parentActivity != null && text != null) {
32 | text.observe(parentActivity, Observer { value -> view.text = value ?: "" })
33 | }
34 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sevenpeakssoftware/zubair/utils/Constants.kt:
--------------------------------------------------------------------------------
1 | package com.sevenpeakssoftware.zubair.utils
2 |
3 | /**Base URL */
4 | const val BASE_URL: String = "https://www.apphusetreach.no/application/119267/"
--------------------------------------------------------------------------------
/app/src/main/java/com/sevenpeakssoftware/zubair/utils/Utility.kt:
--------------------------------------------------------------------------------
1 | package com.sevenpeakssoftware.zubair.utils
2 |
3 | import android.os.Build
4 | import android.support.annotation.RequiresApi
5 | import java.time.LocalDateTime
6 | import java.time.format.DateTimeFormatter
7 | import java.util.Calendar
8 |
9 |
10 | @RequiresApi(Build.VERSION_CODES.O)
11 | fun getFormatedDate(serverDate: String): String {
12 |
13 | var formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm")
14 | var postedDate = LocalDateTime.parse(serverDate, formatter)
15 |
16 | var currentYearDateFormat = DateTimeFormatter.ofPattern("d MMMM, HH:mm")
17 | var otherYearDateFormate = DateTimeFormatter.ofPattern("d MMMM yyyy, HH:mm")
18 | val today = Calendar.getInstance()
19 | val currentYear = today.get(Calendar.YEAR);
20 |
21 | if (currentYear.equals(postedDate.year)) {
22 | return LocalDateTime.parse(serverDate, formatter).format(currentYearDateFormat);
23 | } else {
24 | return LocalDateTime.parse(serverDate, formatter).format(otherYearDateFormate);
25 | }
26 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sevenpeakssoftware/zubair/utils/extension/ViewExtension.kt:
--------------------------------------------------------------------------------
1 | package com.sevenpeakssoftware.zubair.utils.extension
2 |
3 | import android.content.ContextWrapper
4 | import android.support.v7.app.AppCompatActivity
5 | import android.view.View
6 |
7 |
8 | fun View.getParentActivity(): AppCompatActivity? {
9 | var context = this.context
10 | while (context is ContextWrapper) {
11 | if (context is AppCompatActivity) {
12 | return context
13 | }
14 | context = context.baseContext
15 | }
16 | return null
17 | }
18 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/gradiant.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
10 |
12 |
14 |
16 |
18 |
20 |
22 |
24 |
26 |
28 |
30 |
32 |
34 |
36 |
38 |
40 |
42 |
44 |
46 |
48 |
50 |
52 |
54 |
56 |
58 |
60 |
62 |
64 |
66 |
68 |
70 |
72 |
74 |
75 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/poster.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zubyf09/Android-with-Kotlin-MVVM-Dagger-2-RxJava-Retrofit/43f45656c72756f138a1c4c83c32d63485efa54b/app/src/main/res/drawable/poster.jpg
--------------------------------------------------------------------------------
/app/src/main/res/font/appfont.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/font/roboto_medium.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zubyf09/Android-with-Kotlin-MVVM-Dagger-2-RxJava-Retrofit/43f45656c72756f138a1c4c83c32d63485efa54b/app/src/main/res/font/roboto_medium.ttf
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_article_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
8 |
9 |
12 |
13 |
21 |
22 |
31 |
32 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
18 |
19 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_article.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
9 |
10 |
11 |
12 |
18 |
19 |
20 |
34 |
35 |
46 |
47 |
53 |
66 |
67 |
68 |
81 |
82 |
83 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
111 |
112 |
113 |
114 |
115 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zubyf09/Android-with-Kotlin-MVVM-Dagger-2-RxJava-Retrofit/43f45656c72756f138a1c4c83c32d63485efa54b/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zubyf09/Android-with-Kotlin-MVVM-Dagger-2-RxJava-Retrofit/43f45656c72756f138a1c4c83c32d63485efa54b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zubyf09/Android-with-Kotlin-MVVM-Dagger-2-RxJava-Retrofit/43f45656c72756f138a1c4c83c32d63485efa54b/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zubyf09/Android-with-Kotlin-MVVM-Dagger-2-RxJava-Retrofit/43f45656c72756f138a1c4c83c32d63485efa54b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zubyf09/Android-with-Kotlin-MVVM-Dagger-2-RxJava-Retrofit/43f45656c72756f138a1c4c83c32d63485efa54b/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zubyf09/Android-with-Kotlin-MVVM-Dagger-2-RxJava-Retrofit/43f45656c72756f138a1c4c83c32d63485efa54b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zubyf09/Android-with-Kotlin-MVVM-Dagger-2-RxJava-Retrofit/43f45656c72756f138a1c4c83c32d63485efa54b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zubyf09/Android-with-Kotlin-MVVM-Dagger-2-RxJava-Retrofit/43f45656c72756f138a1c4c83c32d63485efa54b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zubyf09/Android-with-Kotlin-MVVM-Dagger-2-RxJava-Retrofit/43f45656c72756f138a1c4c83c32d63485efa54b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zubyf09/Android-with-Kotlin-MVVM-Dagger-2-RxJava-Retrofit/43f45656c72756f138a1c4c83c32d63485efa54b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #212121
4 | #212121
5 | #D81B60
6 | #ffffff
7 | #d2000000
8 | #000000
9 | #acacac
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Cars
3 | Retry
4 | An error occurred while loading the data
5 |
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/test/java/com/sevenpeakssoftware/zubair/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package com.sevenpeakssoftware.zubair
2 |
3 | import org.junit.Test
4 |
5 | import org.junit.Assert.*
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * See [testing documentation](http://d.android.com/tools/testing).
11 | */
12 | class ExampleUnitTest {
13 | @Test
14 | fun addition_isCorrect() {
15 | assertEquals(4, 2 + 2)
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | ext.kotlin_version = '1.3.41'
5 |
6 | ext.lifecycle_version = '1.1.1'
7 | ext.retrofit_version = '2.4.0'
8 | ext.dagger2_version = '2.16'
9 | ext.android_support_version = '28.0.0'
10 | ext.room_version = '1.1.1'
11 | ext.gradle_version = '3.1.0'
12 | ext.picasso_version = '2.5.2'
13 |
14 | repositories {
15 | google()
16 | jcenter()
17 |
18 | }
19 | dependencies {
20 | classpath 'com.android.tools.build:gradle:4.0.1'
21 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
22 | // NOTE: Do not place your application dependencies here; they belong
23 | // in the individual module build.gradle files
24 | }
25 | }
26 |
27 | allprojects {
28 | repositories {
29 | google()
30 | jcenter()
31 |
32 | }
33 | }
34 |
35 | task clean(type: Delete) {
36 | delete rootProject.buildDir
37 | }
38 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx1536m
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 | # Kotlin code style for this project: "official" or "obsolete":
15 | kotlin.code.style=official
16 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zubyf09/Android-with-Kotlin-MVVM-Dagger-2-RxJava-Retrofit/43f45656c72756f138a1c4c83c32d63485efa54b/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Sep 11 20:25:22 PKT 2020
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn () {
37 | echo "$*"
38 | }
39 |
40 | die () {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save () {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------