Skip to content

Commit bc872ef

Browse files
Merge pull request #6 from ImaginativeShohag/dev
Name updated, Shared Preference added, Moshi added
2 parents 99940bc + 57e3257 commit bc872ef

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+739
-217
lines changed

README.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
# Simple MVVM
22

3-
A simple Android MVVM pattern example using:
3+
A simple Android MVVM pattern example and template
4+
5+
## Used Components/Libraries
46

57
- Kotlin
68
- Kotlin Coroutines (https://developer.android.com/kotlin/coroutines)
79
- View Binding (https://developer.android.com/topic/libraries/view-binding)
810
- Data Binding (https://developer.android.com/topic/libraries/data-binding)
9-
- Retrofit (https://github.com/square/retrofit)
11+
- Retrofit (https://github.com/square/retrofit) with Moshi (https://github.com/square/moshi)
1012
- Room Persistence Library (https://developer.android.com/topic/libraries/architecture/room)
13+
- Shared Preferences (https://developer.android.com/training/data-storage/shared-preferences)
1114
- Navigation Component (https://developer.android.com/guide/navigation)
1215
- Glide (https://github.com/bumptech/glide)
1316
- Timber (https://github.com/JakeWharton/timber)
@@ -16,3 +19,7 @@ A simple Android MVVM pattern example using:
1619
- Dagger (https://github.com/google/dagger)
1720
- Paging (https://developer.android.com/topic/libraries/architecture/paging)
1821
- Dexter (https://github.com/Karumi/Dexter) **(coming soon...)**
22+
23+
## Others
24+
25+
- Build variant (https://developer.android.com/studio/build/build-variants)

app/build.gradle

Lines changed: 40 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,29 @@ android {
3131
}
3232
buildTypes {
3333
release {
34-
minifyEnabled false
35-
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
34+
minifyEnabled true
35+
shrinkResources true
36+
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
37+
}
38+
debug {
39+
debuggable true
40+
applicationIdSuffix ".debug"
41+
versionNameSuffix "-debug"
3642
}
3743
}
44+
// flavorDimensions "feature"
45+
// productFlavors {
46+
// flavorone {
47+
// dimension "feature"
48+
// applicationIdSuffix ".flavorone"
49+
// versionNameSuffix "-flavorone"
50+
// }
51+
// flavortwo {
52+
// dimension "feature"
53+
// applicationIdSuffix ".flavortwo"
54+
// versionNameSuffix "-flavortwo"
55+
// }
56+
// }
3857
compileOptions {
3958
sourceCompatibility JavaVersion.VERSION_1_8
4059
targetCompatibility JavaVersion.VERSION_1_8
@@ -59,10 +78,12 @@ dependencies {
5978
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
6079
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
6180

62-
// Retrofit and GSON
63-
implementation 'com.squareup.retrofit2:retrofit:2.6.0'
64-
implementation 'com.squareup.retrofit2:converter-gson:2.6.0'
65-
implementation 'com.squareup.okhttp3:logging-interceptor:4.0.0'
81+
// Retrofit and Moshi
82+
implementation 'com.squareup.retrofit2:retrofit:2.8.1'
83+
implementation 'com.squareup.retrofit2:converter-moshi:2.8.1'
84+
implementation 'com.squareup.okhttp3:logging-interceptor:4.4.1'
85+
implementation "com.squareup.moshi:moshi-kotlin:1.9.2"
86+
kapt "com.squareup.moshi:moshi-kotlin-codegen:1.9.2"
6687

6788
// ViewModel and LiveData
6889
implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"
@@ -72,43 +93,43 @@ dependencies {
7293
implementation 'com.google.android.material:material:1.1.0'
7394

7495
// Room Persistence Library
75-
implementation "androidx.room:room-runtime:2.2.4"
76-
kapt "androidx.room:room-compiler:2.2.4"
96+
implementation "androidx.room:room-runtime:2.2.5"
97+
kapt "androidx.room:room-compiler:2.2.5"
7798

7899
// Room: Kotlin Extensions and Coroutines support for Room
79-
implementation "androidx.room:room-ktx:2.2.4"
100+
implementation "androidx.room:room-ktx:2.2.5"
80101

81102
// Android Navigation Architecture
82-
implementation "androidx.navigation:navigation-fragment-ktx:2.2.1"
83-
implementation "androidx.navigation:navigation-ui-ktx:2.2.1"
103+
implementation "androidx.navigation:navigation-fragment-ktx:2.2.2"
104+
implementation "androidx.navigation:navigation-ui-ktx:2.2.2"
84105

85106
// Kotlin Coroutines
86-
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.0"
87-
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.0"
107+
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.5"
108+
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.5"
88109

89110
// Glide
90-
implementation 'com.github.bumptech.glide:glide:4.10.0'
111+
implementation 'com.github.bumptech.glide:glide:4.11.0'
91112
kapt 'com.github.bumptech.glide:compiler:4.10.0'
92113

93114
// Paging
94-
implementation "androidx.paging:paging-runtime-ktx:2.1.1"
115+
implementation "androidx.paging:paging-runtime-ktx:2.1.2"
95116

96117
// No Internet Library
97118
implementation 'com.github.ImaginativeShohag:Oops-No-Internet:v1.1.3'
98119

99120
// Permission
100-
implementation 'com.karumi:dexter:6.0.0'
121+
implementation 'com.karumi:dexter:6.0.2'
101122

102123
// Timber
103124
implementation 'com.jakewharton.timber:timber:4.7.1'
104125

105126
// Dagger
106-
implementation 'com.google.dagger:dagger:2.26'
127+
implementation 'com.google.dagger:dagger:2.27'
107128
kapt 'com.google.dagger:dagger-compiler:2.26'
108129

109-
implementation 'com.google.dagger:dagger-android:2.26'
130+
implementation 'com.google.dagger:dagger-android:2.27'
110131
// if you use the support libraries
111-
implementation 'com.google.dagger:dagger-android-support:2.26'
132+
// implementation 'com.google.dagger:dagger-android-support:2.26'
112133
kapt 'com.google.dagger:dagger-android-processor:2.26'
113134

114135
// Shimmer

app/src/debug/res/values/strings.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<resources>
2+
<string name="app_name">Simple MVVM Debug</string>
3+
</resources>

app/src/main/java/org/imaginativeworld/simplemvvm/adapters/PostListAdapter.kt renamed to app/src/main/java/org/imaginativeworld/simplemvvm/adapters/DemoPostListAdapter.kt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@ import android.view.ViewGroup
55
import androidx.recyclerview.widget.DiffUtil
66
import androidx.recyclerview.widget.ListAdapter
77
import androidx.recyclerview.widget.RecyclerView
8-
import org.imaginativeworld.simplemvvm.databinding.ItemPostBinding
8+
import org.imaginativeworld.simplemvvm.databinding.DemoItemPostBinding
99
import org.imaginativeworld.simplemvvm.interfaces.BindableAdapter
1010
import org.imaginativeworld.simplemvvm.interfaces.OnObjectListInteractionListener
1111
import org.imaginativeworld.simplemvvm.models.PostResult
1212

13-
class PostListAdapter(
13+
class DemoPostListAdapter(
1414
private val listener: OnObjectListInteractionListener<PostResult>
15-
) : ListAdapter<PostResult, PostListAdapter.ListViewHolder>(DIFF_CALLBACK),
15+
) : ListAdapter<PostResult, DemoPostListAdapter.ListViewHolder>(DIFF_CALLBACK),
1616
BindableAdapter<List<PostResult>> {
1717

1818
companion object {
@@ -55,7 +55,7 @@ class PostListAdapter(
5555
}
5656

5757
class ListViewHolder private constructor(
58-
private val binding: ItemPostBinding,
58+
private val binding: DemoItemPostBinding,
5959
private val listener: OnObjectListInteractionListener<PostResult>
6060
) : RecyclerView.ViewHolder(binding.root) {
6161

@@ -79,7 +79,7 @@ class PostListAdapter(
7979
listener: OnObjectListInteractionListener<PostResult>
8080
): ListViewHolder {
8181
val layoutInflater = LayoutInflater.from(parent.context)
82-
val binding = ItemPostBinding.inflate(layoutInflater, parent, false)
82+
val binding = DemoItemPostBinding.inflate(layoutInflater, parent, false)
8383
return ListViewHolder(binding, listener)
8484
}
8585
}

app/src/main/java/org/imaginativeworld/simplemvvm/adapters/PostPagedListAdapter.kt renamed to app/src/main/java/org/imaginativeworld/simplemvvm/adapters/DemoPostPagedListAdapter.kt

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,19 @@
11
package org.imaginativeworld.simplemvvm.adapters
22

3-
import android.content.Context
43
import android.view.LayoutInflater
54
import android.view.ViewGroup
65
import androidx.paging.PagedList
76
import androidx.paging.PagedListAdapter
87
import androidx.recyclerview.widget.DiffUtil
98
import androidx.recyclerview.widget.RecyclerView
10-
import org.imaginativeworld.simplemvvm.databinding.ItemPostBinding
9+
import org.imaginativeworld.simplemvvm.databinding.DemoItemPostBinding
1110
import org.imaginativeworld.simplemvvm.interfaces.BindableAdapter
1211
import org.imaginativeworld.simplemvvm.interfaces.OnObjectListInteractionListener
1312
import org.imaginativeworld.simplemvvm.models.PostResult
14-
import timber.log.Timber
1513

16-
class PostPagedListAdapter(
14+
class DemoPostPagedListAdapter(
1715
private val listener: OnObjectListInteractionListener<PostResult>
18-
) : PagedListAdapter<PostResult, PostPagedListAdapter.ListViewHolder>(DIFF_CALLBACK),
16+
) : PagedListAdapter<PostResult, DemoPostPagedListAdapter.ListViewHolder>(DIFF_CALLBACK),
1917
BindableAdapter<PagedList<PostResult>> {
2018

2119
companion object {
@@ -62,7 +60,7 @@ class PostPagedListAdapter(
6260

6361

6462
class ListViewHolder private constructor(
65-
private val binding: ItemPostBinding,
63+
private val binding: DemoItemPostBinding,
6664
private val listener: OnObjectListInteractionListener<PostResult>
6765
) : RecyclerView.ViewHolder(binding.root) {
6866

@@ -86,10 +84,10 @@ class PostPagedListAdapter(
8684
fun from(
8785
parent: ViewGroup,
8886
listener: OnObjectListInteractionListener<PostResult>
89-
): PostPagedListAdapter.ListViewHolder {
87+
): DemoPostPagedListAdapter.ListViewHolder {
9088
val layoutInflater = LayoutInflater.from(parent.context)
91-
val binding = ItemPostBinding.inflate(layoutInflater, parent, false)
92-
return PostPagedListAdapter.ListViewHolder(binding, listener)
89+
val binding = DemoItemPostBinding.inflate(layoutInflater, parent, false)
90+
return DemoPostPagedListAdapter.ListViewHolder(binding, listener)
9391
}
9492
}
9593

app/src/main/java/org/imaginativeworld/simplemvvm/adapters/UserListAdapter.kt renamed to app/src/main/java/org/imaginativeworld/simplemvvm/adapters/DemoUserListAdapter.kt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@ import android.view.ViewGroup
55
import androidx.recyclerview.widget.DiffUtil
66
import androidx.recyclerview.widget.ListAdapter
77
import androidx.recyclerview.widget.RecyclerView
8-
import org.imaginativeworld.simplemvvm.databinding.ItemUserBinding
8+
import org.imaginativeworld.simplemvvm.databinding.DemoItemUserBinding
99
import org.imaginativeworld.simplemvvm.interfaces.BindableAdapter
1010
import org.imaginativeworld.simplemvvm.interfaces.OnObjectListInteractionListener
1111
import org.imaginativeworld.simplemvvm.models.UserEntity
1212

13-
class UserListAdapter(
13+
class DemoUserListAdapter(
1414
val listener: OnObjectListInteractionListener<UserEntity>
1515
) :
16-
ListAdapter<UserEntity, UserListAdapter.ListViewHolder>(DIFF_CALLBACK),
16+
ListAdapter<UserEntity, DemoUserListAdapter.ListViewHolder>(DIFF_CALLBACK),
1717
BindableAdapter<List<UserEntity>> {
1818

1919
companion object {
@@ -58,7 +58,7 @@ class UserListAdapter(
5858

5959

6060
class ListViewHolder private constructor(
61-
private val binding: ItemUserBinding,
61+
private val binding: DemoItemUserBinding,
6262
private val listener: OnObjectListInteractionListener<UserEntity>
6363
) : RecyclerView.ViewHolder(binding.root) {
6464

@@ -81,7 +81,7 @@ class UserListAdapter(
8181
listener: OnObjectListInteractionListener<UserEntity>
8282
): ListViewHolder {
8383
val layoutInflater = LayoutInflater.from(parent.context)
84-
val binding = ItemUserBinding.inflate(layoutInflater, parent, false)
84+
val binding = DemoItemUserBinding.inflate(layoutInflater, parent, false)
8585
return ListViewHolder(binding, listener)
8686
}
8787
}

app/src/main/java/org/imaginativeworld/simplemvvm/datasource/PostPagedDataSource.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ class PostPagedDataSource(
6262
} catch (e: ApiException) {
6363
e.printStackTrace()
6464

65-
listener.onError(e)
65+
listener.onDataSourceError(e)
6666
}
6767

6868
}

app/src/main/java/org/imaginativeworld/simplemvvm/di/ApplicationGraph.kt

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ package org.imaginativeworld.simplemvvm.di
22

33
import dagger.Component
44
import org.imaginativeworld.simplemvvm.views.activities.main.MainActivity
5-
import org.imaginativeworld.simplemvvm.views.fragments.home.HomeFragment
6-
import org.imaginativeworld.simplemvvm.views.fragments.post.PostFragment
7-
import org.imaginativeworld.simplemvvm.views.fragments.user.UserFragment
8-
import org.imaginativeworld.simplemvvm.views.fragments.postpaged.PostPagedFragment
5+
import org.imaginativeworld.simplemvvm.views.fragments.demo_home.DemoHomeFragment
6+
import org.imaginativeworld.simplemvvm.views.fragments.demo_post.DemoPostFragment
7+
import org.imaginativeworld.simplemvvm.views.fragments.demo_postpaged.DemoPostPagedFragment
8+
import org.imaginativeworld.simplemvvm.views.fragments.demo_user.DemoUserFragment
99
import javax.inject.Singleton
1010

1111
@Singleton
@@ -14,12 +14,12 @@ interface ApplicationGraph {
1414

1515
fun inject(activity: MainActivity)
1616

17-
fun inject(fragment: HomeFragment)
17+
fun inject(fragment: DemoHomeFragment)
1818

19-
fun inject(fragment: PostFragment)
19+
fun inject(fragment: DemoPostFragment)
2020

21-
fun inject(fragment: UserFragment)
21+
fun inject(fragment: DemoUserFragment)
2222

23-
fun inject(fragment: PostPagedFragment)
23+
fun inject(fragment: DemoPostPagedFragment)
2424

2525
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package org.imaginativeworld.simplemvvm.interfaces
2+
3+
import org.imaginativeworld.simplemvvm.views.activities.main.MainViewModel
4+
5+
interface MainActivityExtraOnFragmentInteractionListener {
6+
fun getActivityViewModel(): MainViewModel
7+
}
Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
package org.imaginativeworld.simplemvvm.interfaces
22

3-
import java.lang.Exception
4-
53
interface OnDataSourceErrorListener {
64

7-
fun onError(exception: Exception)
5+
fun onDataSourceError(exception: Exception)
86

97
}

app/src/main/java/org/imaginativeworld/simplemvvm/interfaces/OnFragmentInteractionListener.kt

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,11 @@ import android.os.Bundle
44
import android.view.View
55
import androidx.annotation.IdRes
66
import androidx.navigation.NavDirections
7-
import org.imaginativeworld.simplemvvm.views.activities.main.MainViewModel
8-
import org.imaginativeworld.simplemvvm.views.fragments.user.UserViewModel
97

108
interface OnFragmentInteractionListener {
119

1210
fun setAppTitle(title: String)
1311

14-
fun getAppViewModel(): MainViewModel?
15-
1612
fun gotoFragment(@IdRes destinationResId: Int)
1713

1814
fun gotoFragment(@IdRes destinationResId: Int, data: Bundle)
@@ -29,5 +25,4 @@ interface OnFragmentInteractionListener {
2925

3026
fun hideLoading()
3127

32-
3328
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,24 @@
11
package org.imaginativeworld.simplemvvm.models
22

3+
import androidx.annotation.Keep
4+
import com.squareup.moshi.Json
5+
import com.squareup.moshi.JsonClass
6+
7+
@Keep
8+
@JsonClass(generateAdapter = true)
39
data class PostMeta(
10+
@Json(name = "code")
411
val code: Int,
12+
@Json(name = "currentPage")
513
val currentPage: Int,
14+
@Json(name = "message")
615
val message: String,
16+
@Json(name = "pageCount")
717
val pageCount: Int,
18+
@Json(name = "perPage")
819
val perPage: Int,
20+
@Json(name = "success")
921
val success: Boolean,
22+
@Json(name = "totalCount")
1023
val totalCount: Int
1124
)
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
package org.imaginativeworld.simplemvvm.models
22

3+
import androidx.annotation.Keep
4+
import com.squareup.moshi.Json
5+
import com.squareup.moshi.JsonClass
6+
7+
@Keep
8+
@JsonClass(generateAdapter = true)
39
data class PostResponse(
10+
@Json(name = "_meta")
411
val _meta: PostMeta,
12+
@Json(name = "result")
513
val result: List<PostResult>
614
)

0 commit comments

Comments
 (0)