├── .gitignore
├── .idea
├── codeStyles
│ ├── Project.xml
│ └── codeStyleConfig.xml
├── encodings.xml
├── gradle.xml
├── jarRepositories.xml
├── misc.xml
├── runConfigurations.xml
└── vcs.xml
├── README.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── nextus
│ │ └── baseapp
│ │ └── ExampleInstrumentedTest.kt
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── nextus
│ │ │ └── baseapp
│ │ │ ├── MyApplication.kt
│ │ │ ├── data
│ │ │ ├── RemoteClient.kt
│ │ │ ├── api
│ │ │ │ └── GitApi.kt
│ │ │ ├── datasource
│ │ │ │ ├── GitDataSource.kt
│ │ │ │ └── GitRemoteDataSource.kt
│ │ │ └── repository
│ │ │ │ └── GitRepositoryImpl.kt
│ │ │ ├── di
│ │ │ └── AppModules.kt
│ │ │ ├── domain
│ │ │ ├── core
│ │ │ │ └── Result.kt
│ │ │ ├── model
│ │ │ │ └── GistsPublic.kt
│ │ │ ├── repository
│ │ │ │ └── GitRepository.kt
│ │ │ └── usecase
│ │ │ │ └── GetGistsPublicUseCase.kt
│ │ │ ├── ui
│ │ │ ├── base
│ │ │ │ ├── BaseActivity.kt
│ │ │ │ ├── BaseFragment.kt
│ │ │ │ ├── BaseRecyclerAdapter.kt
│ │ │ │ ├── BaseViewHolder.kt
│ │ │ │ └── BaseViewModel.kt
│ │ │ ├── home
│ │ │ │ ├── GistsAdapter.kt
│ │ │ │ ├── HomeFragment.kt
│ │ │ │ └── HomeViewModel.kt
│ │ │ ├── main
│ │ │ │ ├── MainActivity.kt
│ │ │ │ └── MainViewModel.kt
│ │ │ └── mypage
│ │ │ │ ├── MyPageFragment.kt
│ │ │ │ └── MyPageViewModel.kt
│ │ │ └── utils
│ │ │ ├── AppLogger.kt
│ │ │ ├── BindingUtils.kt
│ │ │ ├── CommonUtils.kt
│ │ │ └── ViewUtils.kt
│ └── res
│ │ ├── drawable-v24
│ │ └── ic_launcher_foreground.xml
│ │ ├── drawable
│ │ ├── ic_apps_black_24dp.xml
│ │ ├── ic_description_black_24dp.xml
│ │ ├── ic_directions_run_black_24dp.xml
│ │ ├── ic_launcher_background.xml
│ │ └── selector_bottom_navigation.xml
│ │ ├── layout
│ │ ├── activity_main.xml
│ │ ├── fragment_home.xml
│ │ ├── fragment_mypage.xml
│ │ ├── item_empty.xml
│ │ └── item_gists.xml
│ │ ├── menu
│ │ └── menu_bottom_navigation_view.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
│ │ ├── navigation
│ │ └── navigation_graph.xml
│ │ └── values
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── com
│ └── nextus
│ └── baseapp
│ └── ExampleUnitTest.kt
├── build.gradle
├── dependency.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 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | xmlns:android
18 |
19 | ^$
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | xmlns:.*
29 |
30 | ^$
31 |
32 |
33 | BY_NAME
34 |
35 |
36 |
37 |
38 |
39 |
40 | .*:id
41 |
42 | http://schemas.android.com/apk/res/android
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 | .*:name
52 |
53 | http://schemas.android.com/apk/res/android
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 | name
63 |
64 | ^$
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 | style
74 |
75 | ^$
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 | .*
85 |
86 | ^$
87 |
88 |
89 | BY_NAME
90 |
91 |
92 |
93 |
94 |
95 |
96 | .*
97 |
98 | http://schemas.android.com/apk/res/android
99 |
100 |
101 | ANDROID_ATTRIBUTE_ORDER
102 |
103 |
104 |
105 |
106 |
107 |
108 | .*
109 |
110 | .*
111 |
112 |
113 | BY_NAME
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
--------------------------------------------------------------------------------
/.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/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 | # Kotlin_MVVM
2 |
3 | Android Design Pattern 중 하나인 MVVM Pattern 을 적용한 예제입니다.
4 |
5 | ## 라이브러리
6 | > Android Databinding
7 | > Android Navigation
8 | > RxJava2 + Retrofit2
9 | > Koin
10 | > Coroutine ( Flow )
11 | > Android LiveData
12 |
13 | ## 업데이트 예정
14 | > Android Navigation 심화 ( BackStack 관련 )
15 | > 비동기 처리 방식 변경 ( 기존 Rx 에서 Coroutine 으로 )
16 | > Room 예제 추가
17 | > 기존 ObservableField 에서 LiveData 이용으로
18 |
19 | ## 업데이트 내용
20 |
21 | * 2020.07.28
22 | > 일부 필요 없는 코드 제거
23 | > Coroutine Flow 적용
24 | > ExperimentalCoroutinesApi 관련 어노테이션 제거
25 |
26 | * 2020.06.25
27 | > Gradle Version 변경
28 | > Base 클래스들( BaseViewModel, BaseActivity, BaseFragment, BaseRecyclerAdapter, BaseViewHolder) 의 구조적 변화로 인한 전체 코드 수정
29 | > 네트워크 라이브러리 변경 (~~Android Fast Networking~~ => Retrofit2)
30 | > Clean Architecture 적용 ( Google Architecture Sample 참조 )
31 |
32 |
33 | 블로그
34 |
--------------------------------------------------------------------------------
/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 | apply plugin: "androidx.navigation.safeargs.kotlin"
6 |
7 | android {
8 | compileSdkVersion build_versions.compile_sdk
9 | buildToolsVersion build_versions.build_tools
10 | defaultConfig {
11 | applicationId "com.nextus.baseapp"
12 | minSdkVersion build_versions.min_sdk
13 | targetSdkVersion build_versions.target_sdk
14 | versionCode 1
15 | versionName "1.0"
16 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
17 | vectorDrawables.useSupportLibrary true
18 | }
19 | buildTypes {
20 | release {
21 | minifyEnabled false
22 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
23 | }
24 | }
25 |
26 | compileOptions {
27 | sourceCompatibility JavaVersion.VERSION_1_8
28 | targetCompatibility JavaVersion.VERSION_1_8
29 | }
30 |
31 | kotlinOptions {
32 | jvmTarget = JavaVersion.VERSION_1_8.toString()
33 | freeCompilerArgs += [
34 | "-Xuse-experimental=kotlinx.coroutines.ExperimentalCoroutinesApi",
35 | "-Xuse-experimental=kotlinx.coroutines.ObsoleteCoroutinesApi"
36 | ]
37 | }
38 |
39 | dataBinding {
40 | enabled = true
41 | }
42 | }
43 |
44 | dependencies {
45 |
46 | implementation deps.kotlin.stdlib
47 |
48 | // Jetpack
49 | implementation deps.androidx.appcompat
50 | implementation deps.androidx.core_ktx
51 | implementation deps.androidx.constraintlayout
52 | implementation deps.androidx.lifecycle.runtime_ktx
53 | implementation deps.androidx.lifecycle.extensions
54 | implementation deps.androidx.lifecycle.viewmodel_ktx
55 | implementation deps.androidx.lifecycle.livedata_ktx
56 | implementation deps.androidx.navigation.fragment_ktx
57 | implementation deps.androidx.navigation.ui_ktx
58 | implementation deps.androidx.material
59 | implementation deps.androidx.swiperefresh
60 |
61 | // coroutine
62 | implementation deps.kotlin.coroutines.core
63 | implementation deps.kotlin.coroutines.android
64 | implementation deps.kotlin.coroutines.play_services
65 |
66 | // retrofit
67 | implementation deps.retrofit.core
68 | implementation deps.retrofit.converter_gson
69 | implementation deps.retrofit.adapter_rxjava2
70 |
71 | // koin
72 | implementation deps.koin.core
73 | implementation deps.koin.viewModel
74 |
75 | // okhttp
76 | implementation deps.okhttp.core
77 | implementation deps.okhttp.logging_interceptor
78 |
79 | // debugging
80 | implementation deps.debugging.timber
81 |
82 | // test
83 | testImplementation deps.atsl.junit
84 | androidTestImplementation deps.atsl.ext_junit
85 | androidTestImplementation deps.atsl.espresso_core
86 | testImplementation deps.kotlin.coroutines.test
87 | /*
88 |
89 |
90 | //implementation fileTree(dir: 'libs', include: ['*.jar'])
91 | kapt "androidx.room:room-compiler:$rootProject.roomVersion"
92 | kapt "com.github.bumptech.glide:compiler:$rootProject.glideVersion"
93 | //kapt "com.android.databinding:compiler:$rootProject.gradleVersion"
94 |
95 | implementation "androidx.appcompat:appcompat:$rootProject.supportLibraryVersion"
96 | implementation "androidx.constraintlayout:constraintlayout:$rootProject.constraintLayoutVersion"
97 | implementation "androidx.core:core-ktx:$rootProject.ktxVersion"
98 | implementation "androidx.fragment:fragment-ktx:$rootProject.fragmentVersion"
99 | implementation "androidx.lifecycle:lifecycle-extensions:$rootProject.lifecycleVersion"
100 | implementation "androidx.lifecycle:lifecycle-livedata-ktx:$rootProject.lifecycleVersion"
101 | implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$rootProject.lifecycleVersion"
102 | //annotationProcessor "androidx.lifecycle:lifecycle-compiler:$rootProject.lifecycleVersion"
103 | implementation "androidx.navigation:navigation-fragment-ktx:$rootProject.navigationVersion"
104 | implementation "androidx.navigation:navigation-ui-ktx:$rootProject.navigationVersion"
105 | implementation "androidx.recyclerview:recyclerview:$rootProject.recyclerViewVersion"
106 | implementation "androidx.room:room-runtime:$rootProject.roomVersion"
107 |
108 | implementation "com.amitshekhar.android:rx2-android-networking:$rootProject.rx2FastAndroidNetworking"
109 | implementation "com.github.bumptech.glide:glide:$rootProject.glideVersion"
110 | implementation "com.google.android.material:material:$rootProject.materialVersion"
111 | implementation "com.jakewharton.timber:timber:$rootProject.timberVersion"
112 |
113 | implementation "io.reactivex.rxjava2:rxjava:$rootProject.rxjava2Version"
114 | implementation "io.reactivex.rxjava2:rxandroid:$rootProject.rxandroidVersion"
115 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$rootProject.kotlinVersion"
116 | implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$rootProject.coroutinesVersion"
117 | implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$rootProject.coroutinesVersion"
118 | implementation "org.koin:koin-androidx-scope:$rootProject.koinVersion"
119 | implementation "org.koin:koin-androidx-viewmodel:$rootProject.koinVersion"
120 |
121 | implementation "com.squareup.retrofit2:retrofit:$rootProject.retrofitVersion"
122 | implementation "com.squareup.retrofit2:converter-gson:$rootProject.retrofitVersion"
123 | implementation "com.squareup.retrofit2:converter-jackson:$rootProject.retrofitVersion"
124 | implementation "com.squareup.retrofit2:adapter-rxjava2:$rootProject.retrofitVersion"
125 |
126 |
127 | testImplementation 'junit:junit:4.12'
128 | androidTestImplementation 'androidx.test:runner:1.2.0'
129 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'*/
130 | }
131 |
--------------------------------------------------------------------------------
/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/src/androidTest/java/com/nextus/baseapp/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package com.nextus.baseapp
2 |
3 | import androidx.test.InstrumentationRegistry
4 | import androidx.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.nextus.baseapp", 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 |
--------------------------------------------------------------------------------
/app/src/main/java/com/nextus/baseapp/MyApplication.kt:
--------------------------------------------------------------------------------
1 | package com.nextus.baseapp
2 |
3 | import android.app.Application
4 | import com.nextus.baseapp.di.appModules
5 | import com.nextus.baseapp.utils.AppLogger
6 | import org.koin.android.ext.koin.androidContext
7 | import org.koin.core.context.startKoin
8 | import timber.log.Timber
9 |
10 | class MyApplication : Application() {
11 |
12 | override fun onCreate() {
13 | super.onCreate()
14 |
15 | if (BuildConfig.DEBUG) {
16 | AppLogger.init()
17 | Timber.plant(Timber.DebugTree())
18 | }
19 |
20 | // start Koin!
21 | startKoin {
22 | // Android context
23 | androidContext(this@MyApplication)
24 | // modules
25 | modules(appModules)
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/nextus/baseapp/data/RemoteClient.kt:
--------------------------------------------------------------------------------
1 | package com.nextus.baseapp.data
2 |
3 | import okhttp3.OkHttpClient
4 | import okhttp3.logging.HttpLoggingInterceptor
5 | import retrofit2.Retrofit
6 | import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
7 | import retrofit2.converter.gson.GsonConverterFactory
8 |
9 | object RemoteClient {
10 |
11 | private const val baseUrl = "http://api.github.com/"
12 |
13 | fun createRetrofit(debug: Boolean): Retrofit {
14 | return Retrofit.Builder()
15 | .baseUrl(baseUrl)
16 | .client(
17 | provideOkHttpClient(
18 | provideLoggingInterceptor(debug)
19 | )
20 | )
21 | .addCallAdapterFactory(RxJava2CallAdapterFactory.createAsync())
22 | .addConverterFactory(GsonConverterFactory.create())
23 | .build()
24 | }
25 |
26 | // 네트워크 통신에 사용할 클라이언트 객체를 생성합니다.
27 | private fun provideOkHttpClient(interceptor: HttpLoggingInterceptor): OkHttpClient {
28 | val b = OkHttpClient.Builder()
29 | // 이 클라이언트를 통해 오고 가는 네트워크 요청/응답을 로그로 표시하도록 합니다.
30 | b.addInterceptor(interceptor)
31 | /* // header 에 정보를 추가해 준다.
32 | b.addInterceptor(AddHeaderInterceptor())*/
33 | return b.build()
34 | }
35 |
36 | // 네트워크 요청/응답을 로그에 표시하는 Interceptor 객체를 생성합니다.
37 | private fun provideLoggingInterceptor(debug: Boolean): HttpLoggingInterceptor {
38 | val logging = HttpLoggingInterceptor()
39 | logging.level = if (debug)
40 | HttpLoggingInterceptor.Level.BODY
41 | else
42 | HttpLoggingInterceptor.Level.NONE
43 | return logging
44 | }
45 |
46 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/nextus/baseapp/data/api/GitApi.kt:
--------------------------------------------------------------------------------
1 | package com.nextus.baseapp.data.api
2 |
3 | import com.nextus.baseapp.domain.model.GistsPublic
4 | import retrofit2.Call
5 | import retrofit2.http.POST
6 |
7 | interface GitApi {
8 |
9 | @POST("gists/public")
10 | fun getGistsPublic(): Call>
11 |
12 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/nextus/baseapp/data/datasource/GitDataSource.kt:
--------------------------------------------------------------------------------
1 | package com.nextus.baseapp.data.datasource
2 |
3 | import com.nextus.baseapp.domain.core.Result
4 | import com.nextus.baseapp.domain.model.GistsPublic
5 |
6 | interface GitDataSource {
7 | suspend fun getGistsPublic(): Result>
8 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/nextus/baseapp/data/datasource/GitRemoteDataSource.kt:
--------------------------------------------------------------------------------
1 | package com.nextus.baseapp.data.datasource
2 |
3 | import com.nextus.baseapp.data.api.GitApi
4 | import com.nextus.baseapp.domain.core.Result
5 | import com.nextus.baseapp.domain.model.GistsPublic
6 |
7 | class GitRemoteDataSource(private val gitApi: GitApi): GitDataSource {
8 |
9 | override suspend fun getGistsPublic(): Result> {
10 | val response = gitApi.getGistsPublic().execute()
11 |
12 | return if(response.isSuccessful) {
13 | Result.Success(response.body() ?: ArrayList())
14 | } else {
15 | Result.Error(Exception("Network Error"))
16 | }
17 | }
18 |
19 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/nextus/baseapp/data/repository/GitRepositoryImpl.kt:
--------------------------------------------------------------------------------
1 | package com.nextus.baseapp.data.repository
2 |
3 | import com.nextus.baseapp.data.datasource.GitDataSource
4 | import com.nextus.baseapp.domain.core.Result
5 | import com.nextus.baseapp.domain.model.GistsPublic
6 | import com.nextus.baseapp.domain.repository.GitRepository
7 | import kotlinx.coroutines.delay
8 | import kotlinx.coroutines.flow.Flow
9 | import kotlinx.coroutines.flow.flow
10 |
11 | class GitRepositoryImpl(private val gitDataSource: GitDataSource): GitRepository {
12 | override fun getGistsPublic() = flow {
13 | emit(Result.Loading)
14 | delay(1000)
15 | emit(gitDataSource.getGistsPublic())
16 | }
17 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/nextus/baseapp/di/AppModules.kt:
--------------------------------------------------------------------------------
1 | package com.nextus.baseapp.di
2 |
3 | import com.nextus.baseapp.data.RemoteClient
4 | import com.nextus.baseapp.data.api.GitApi
5 | import com.nextus.baseapp.data.datasource.GitDataSource
6 | import com.nextus.baseapp.data.datasource.GitRemoteDataSource
7 | import com.nextus.baseapp.domain.repository.GitRepository
8 | import com.nextus.baseapp.data.repository.GitRepositoryImpl
9 | import com.nextus.baseapp.ui.home.HomeViewModel
10 | import com.nextus.baseapp.ui.main.MainViewModel
11 | import com.nextus.baseapp.ui.mypage.MyPageViewModel
12 | import com.nextus.baseapp.domain.usecase.GetGistsPublicUseCase
13 | import org.koin.androidx.viewmodel.dsl.viewModel
14 | import org.koin.dsl.module
15 |
16 | val viewModelModule = module {
17 | viewModel { MainViewModel(get()) }
18 | viewModel { HomeViewModel(get(), get()) }
19 | viewModel { MyPageViewModel(get()) }
20 | }
21 |
22 | val remoteModule = module {
23 | single { RemoteClient }
24 | }
25 |
26 | val dataSourceModule = module {
27 | single { GitRemoteDataSource(get()) as GitDataSource}
28 | }
29 |
30 | val apiModule = module {
31 | single { gitApi }
32 | }
33 |
34 | val repositoryModule = module {
35 | single { GitRepositoryImpl(get()) as GitRepository }
36 | }
37 |
38 | val useCaseModule = module {
39 | single { GetGistsPublicUseCase(get()) }
40 | }
41 |
42 | val retrofit = RemoteClient.createRetrofit(true)
43 | private val gitApi = retrofit.create(GitApi::class.java)
44 |
45 | val appModules = listOf(
46 | remoteModule,
47 | dataSourceModule,
48 | viewModelModule,
49 | apiModule,
50 | repositoryModule,
51 | useCaseModule
52 | )
--------------------------------------------------------------------------------
/app/src/main/java/com/nextus/baseapp/domain/core/Result.kt:
--------------------------------------------------------------------------------
1 | package com.nextus.baseapp.domain.core
2 |
3 | /**
4 | * @author ReStartAllKill
5 | * @created on 2020-02-12
6 | * @modified by
7 | * @updated on
8 | */
9 | /**
10 | * A generic class that holds a value with its loading status.
11 | * @param
12 | */
13 | sealed class Result {
14 |
15 | data class Success(val data: T) : Result()
16 | data class Error(val exception: Exception) : Result()
17 | object Loading : Result()
18 |
19 | override fun toString(): String {
20 | return when (this) {
21 | is Success<*> -> "Success[data=$data]"
22 | is Error -> "Error[exception=$exception]"
23 | Loading -> "Loading"
24 | }
25 | }
26 | }
27 |
28 | /**
29 | * `true` if [Result] is of type [Success] & holds non-null [Success.data].
30 | */
31 | val Result<*>.succeeded
32 | get() = this is Result.Success && data != null
--------------------------------------------------------------------------------
/app/src/main/java/com/nextus/baseapp/domain/model/GistsPublic.kt:
--------------------------------------------------------------------------------
1 | package com.nextus.baseapp.domain.model
2 |
3 | data class GistsPublic(val url: String, val forks_url: String)
--------------------------------------------------------------------------------
/app/src/main/java/com/nextus/baseapp/domain/repository/GitRepository.kt:
--------------------------------------------------------------------------------
1 | package com.nextus.baseapp.domain.repository
2 |
3 | import com.nextus.baseapp.domain.core.Result
4 | import com.nextus.baseapp.domain.model.GistsPublic
5 | import kotlinx.coroutines.flow.Flow
6 |
7 | interface GitRepository {
8 | fun getGistsPublic(): Flow>>
9 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/nextus/baseapp/domain/usecase/GetGistsPublicUseCase.kt:
--------------------------------------------------------------------------------
1 | package com.nextus.baseapp.domain.usecase
2 |
3 | import com.nextus.baseapp.domain.repository.GitRepository
4 |
5 | class GetGistsPublicUseCase(private val gitRepository: GitRepository) {
6 | operator fun invoke() = gitRepository.getGistsPublic()
7 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/nextus/baseapp/ui/base/BaseActivity.kt:
--------------------------------------------------------------------------------
1 | package com.nextus.baseapp.ui.base
2 |
3 | import android.os.Bundle
4 | import androidx.annotation.LayoutRes
5 | import androidx.appcompat.app.AppCompatActivity
6 | import androidx.databinding.DataBindingUtil
7 | import androidx.databinding.ViewDataBinding
8 | import androidx.lifecycle.ViewModel
9 | import org.koin.androidx.viewmodel.ext.android.viewModel
10 | import kotlin.reflect.KClass
11 | import com.nextus.baseapp.BR
12 |
13 | abstract class BaseActivity(
14 | @LayoutRes private val layoutResId: Int,
15 | clazz: KClass
16 | ) : AppCompatActivity(), BaseFragment.CallBack {
17 |
18 | protected lateinit var mViewDataBinding: B
19 | protected val viewModel : VM by viewModel(clazz)
20 |
21 | abstract fun onCreate()
22 |
23 | override fun onCreate(savedInstanceState: Bundle?) {
24 | super.onCreate(savedInstanceState)
25 | performDataBinding()
26 | onCreate()
27 | }
28 |
29 | private fun performDataBinding() {
30 | mViewDataBinding = DataBindingUtil.setContentView(this, layoutResId)
31 | mViewDataBinding.lifecycleOwner = this
32 | mViewDataBinding.setVariable(BR.viewModel, viewModel)
33 | mViewDataBinding.executePendingBindings()
34 | }
35 |
36 | override fun onFragmentAttached() {
37 |
38 | }
39 |
40 | override fun onFragmentDetached(tag: String) {
41 |
42 | }
43 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/nextus/baseapp/ui/base/BaseFragment.kt:
--------------------------------------------------------------------------------
1 | package com.nextus.baseapp.ui.base
2 |
3 | import android.content.Context
4 | import android.os.Bundle
5 | import android.view.LayoutInflater
6 | import android.view.View
7 | import android.view.ViewGroup
8 | import androidx.annotation.LayoutRes
9 | import androidx.databinding.DataBindingUtil
10 | import androidx.databinding.ViewDataBinding
11 | import androidx.fragment.app.Fragment
12 | import androidx.lifecycle.ViewModel
13 | import com.nextus.baseapp.BR
14 | import org.koin.androidx.viewmodel.ext.android.viewModel
15 | import kotlin.reflect.KClass
16 |
17 | /**
18 | * @author ReStartAllKill
19 | * @created on 2019-05-27
20 | * @modified by
21 | * @updated on
22 | */
23 | abstract class BaseFragment(
24 | @LayoutRes private val layoutResId: Int,
25 | clazz: KClass
26 | ) : Fragment() {
27 |
28 | private lateinit var mViewDataBinding: B
29 | protected val viewModel : VM by viewModel(clazz)
30 | private var mActivity: BaseActivity<*, *>? = null
31 |
32 | override fun onAttach(context: Context) {
33 | super.onAttach(context)
34 | if(context is BaseActivity<*, *>) {
35 | mActivity = context
36 | mActivity?.onFragmentAttached()
37 | }
38 | }
39 |
40 | abstract fun onCreate()
41 |
42 | override fun onCreate(savedInstanceState: Bundle?) {
43 | super.onCreate(savedInstanceState)
44 | setHasOptionsMenu(true) // Fragment Option Menu 사용
45 | }
46 |
47 | override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
48 | mViewDataBinding = DataBindingUtil.inflate(inflater, layoutResId, container, false)
49 | return mViewDataBinding.root
50 | }
51 |
52 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
53 | super.onViewCreated(view, savedInstanceState)
54 | mViewDataBinding.setVariable(BR.viewModel, viewModel)
55 | mViewDataBinding.lifecycleOwner = this
56 | mViewDataBinding.executePendingBindings()
57 |
58 | onCreate()
59 | }
60 |
61 | fun getBaseActivity() : BaseActivity<*, *>? {
62 | return mActivity
63 | }
64 |
65 | override fun onDetach() {
66 | mActivity = null
67 | super.onDetach()
68 | }
69 |
70 | interface CallBack {
71 | fun onFragmentAttached()
72 | fun onFragmentDetached(tag: String)
73 | }
74 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/nextus/baseapp/ui/base/BaseRecyclerAdapter.kt:
--------------------------------------------------------------------------------
1 | package com.nextus.baseapp.ui.base
2 |
3 | import android.view.LayoutInflater
4 | import android.view.View
5 | import android.view.ViewGroup
6 | import androidx.databinding.DataBindingUtil
7 | import androidx.databinding.ViewDataBinding
8 | import androidx.recyclerview.widget.DiffUtil
9 | import androidx.recyclerview.widget.ListAdapter
10 |
11 | abstract class BaseRecyclerAdapter(diffCallBack: DiffUtil.ItemCallback)
12 | : ListAdapter>(diffCallBack) {
13 |
14 | interface ItemClickListener {
15 | fun onClickItem(view: View, item: T, position: Int)
16 | }
17 |
18 | private var onItemClickListener : ItemClickListener? = null
19 |
20 | fun setOnItemClickListener(listener: (view: View, T, position: Int) -> Unit) {
21 | onItemClickListener = object: ItemClickListener {
22 | override fun onClickItem(view: View, item: T, position: Int) {
23 | listener(view, item, position)
24 | }
25 | }
26 | }
27 |
28 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder {
29 | val layoutInflater = LayoutInflater.from(parent.context)
30 | val binding = DataBindingUtil.inflate(layoutInflater, viewType, parent, false)
31 | return BaseViewHolder(binding)
32 | }
33 |
34 | override fun onBindViewHolder(holder: BaseViewHolder, position: Int) {
35 | holder.itemView.setOnClickListener {
36 | onItemClickListener?.onClickItem(holder.itemView, getItem(position), position)
37 | }
38 | return holder.bind(getItem(position))
39 | }
40 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/nextus/baseapp/ui/base/BaseViewHolder.kt:
--------------------------------------------------------------------------------
1 | package com.nextus.baseapp.ui.base
2 |
3 | import androidx.databinding.ViewDataBinding
4 | import androidx.recyclerview.widget.RecyclerView
5 | import com.nextus.baseapp.BR
6 |
7 | class BaseViewHolder(private val binding: ViewDataBinding): RecyclerView.ViewHolder(binding.root) {
8 |
9 | fun bind(item: T) {
10 | binding.setVariable(BR.item, item)
11 | binding.executePendingBindings()
12 | }
13 |
14 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/nextus/baseapp/ui/base/BaseViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.nextus.baseapp.ui.base
2 |
3 | import android.app.Application
4 | import androidx.lifecycle.AndroidViewModel
5 |
6 | abstract class BaseViewModel(application: Application) : AndroidViewModel(application) {
7 |
8 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/nextus/baseapp/ui/home/GistsAdapter.kt:
--------------------------------------------------------------------------------
1 | package com.nextus.baseapp.ui.home
2 |
3 | import androidx.recyclerview.widget.DiffUtil
4 | import com.nextus.baseapp.R
5 | import com.nextus.baseapp.domain.model.GistsPublic
6 | import com.nextus.baseapp.ui.base.BaseRecyclerAdapter
7 |
8 | class GistsAdapter : BaseRecyclerAdapter(DiffCallback()) {
9 |
10 | class DiffCallback : DiffUtil.ItemCallback() {
11 | override fun areItemsTheSame(oldItem: GistsPublic, newItem: GistsPublic): Boolean {
12 | return oldItem.url == newItem.url
13 | }
14 |
15 | override fun areContentsTheSame(oldItem: GistsPublic, newItem: GistsPublic): Boolean {
16 | return oldItem == newItem
17 | }
18 | }
19 |
20 | override fun getItemViewType(position: Int) = R.layout.item_gists
21 |
22 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/nextus/baseapp/ui/home/HomeFragment.kt:
--------------------------------------------------------------------------------
1 | package com.nextus.baseapp.ui.home
2 |
3 | import android.widget.Toast
4 | import androidx.lifecycle.Observer
5 | import androidx.navigation.findNavController
6 | import androidx.recyclerview.widget.LinearLayoutManager
7 | import androidx.recyclerview.widget.RecyclerView
8 | import com.nextus.baseapp.R
9 | import com.nextus.baseapp.databinding.FragmentHomeBinding
10 | import com.nextus.baseapp.ui.base.BaseFragment
11 | import kotlinx.android.synthetic.main.fragment_home.*
12 | import kotlinx.coroutines.ExperimentalCoroutinesApi
13 |
14 | /**
15 | * @author ReStartAllKill
16 | * @created on 2019-05-28
17 | * @modified by
18 | * @updated on
19 | */
20 |
21 | class HomeFragment : BaseFragment(
22 | R.layout.fragment_home,
23 | HomeViewModel::class
24 | ) {
25 |
26 | private val gistsAdapter = GistsAdapter()
27 |
28 | override fun onCreate() {
29 | initView()
30 | initGistsObserve()
31 | }
32 |
33 | private fun initView() {
34 | gistsAdapter.apply {
35 | setOnItemClickListener { view, gistsPublic, i ->
36 | Toast.makeText(view.context, "$i) $gistsPublic", Toast.LENGTH_SHORT).show()
37 |
38 | val directions = HomeFragmentDirections.actionHomeFragmentToMyPageFragment(gistsPublic.url)
39 | view.findNavController().navigate(directions)
40 | }
41 | }
42 |
43 | gistsPublicRecycler.apply {
44 | adapter = gistsAdapter
45 | layoutManager = LinearLayoutManager(requireContext(), RecyclerView.VERTICAL, false)
46 | }
47 | }
48 |
49 | private fun initGistsObserve() {
50 | viewModel.gistsPublicDataList.observe(this, Observer {
51 | it.let(gistsAdapter::submitList)
52 | })
53 | }
54 |
55 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/nextus/baseapp/ui/home/HomeViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.nextus.baseapp.ui.home
2 |
3 | import android.app.Application
4 | import androidx.lifecycle.*
5 | import com.nextus.baseapp.domain.core.Result
6 | import com.nextus.baseapp.domain.model.GistsPublic
7 | import com.nextus.baseapp.domain.usecase.GetGistsPublicUseCase
8 | import com.nextus.baseapp.ui.base.BaseViewModel
9 | import kotlinx.coroutines.Dispatchers
10 | import kotlinx.coroutines.flow.flowOn
11 | import kotlinx.coroutines.flow.map
12 |
13 | /**
14 | * @author ReStartAllKill
15 | * @created on 2019-05-28
16 | * @modified by
17 | * @updated on
18 | */
19 |
20 | class HomeViewModel(
21 | application: Application,
22 | private val getGistsPublicUseCase: GetGistsPublicUseCase
23 | ): BaseViewModel(application) {
24 |
25 | private val _refreshEvent = MutableLiveData()
26 | val refreshEvent: LiveData = _refreshEvent
27 |
28 | private val _gistsPublicDataList = refreshEvent.switchMap {
29 | getGistsPublicUseCase()
30 | .flowOn(Dispatchers.IO)
31 | .map {
32 | when (it) {
33 | is Result.Success -> it.data
34 | is Result.Loading -> ArrayList()
35 | is Result.Error -> ArrayList()
36 | }
37 | }
38 | .asLiveData()
39 | }
40 |
41 | var gistsPublicDataList: LiveData> = _gistsPublicDataList
42 |
43 | val isRefreshing: LiveData = gistsPublicDataList.map { it.isEmpty() }
44 |
45 | init {
46 | _refreshEvent.value = Unit
47 | }
48 |
49 | fun getGistsPublic() {
50 | _refreshEvent.value = Unit
51 | }
52 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/nextus/baseapp/ui/main/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.nextus.baseapp.ui.main
2 |
3 | import androidx.navigation.fragment.NavHostFragment
4 | import androidx.navigation.ui.NavigationUI
5 | import com.nextus.baseapp.R
6 | import com.nextus.baseapp.databinding.ActivityMainBinding
7 | import com.nextus.baseapp.ui.base.BaseActivity
8 | import kotlinx.android.synthetic.main.activity_main.*
9 |
10 | class MainActivity : BaseActivity(
11 | R.layout.activity_main,
12 | MainViewModel::class
13 | ) {
14 |
15 | override fun onCreate() {
16 | val host = supportFragmentManager.findFragmentById(R.id.navHostfragment) as NavHostFragment
17 | NavigationUI.setupWithNavController(bottomNavigation, host.navController)
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/app/src/main/java/com/nextus/baseapp/ui/main/MainViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.nextus.baseapp.ui.main
2 |
3 | import android.app.Application
4 | import com.nextus.baseapp.data.RemoteClient
5 | import com.nextus.baseapp.ui.base.BaseViewModel
6 |
7 | class MainViewModel(application: Application): BaseViewModel(application) {
8 |
9 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/nextus/baseapp/ui/mypage/MyPageFragment.kt:
--------------------------------------------------------------------------------
1 | package com.nextus.baseapp.ui.mypage
2 |
3 | import com.nextus.baseapp.R
4 | import com.nextus.baseapp.databinding.FragmentMypageBinding
5 | import com.nextus.baseapp.ui.base.BaseFragment
6 | import kotlinx.android.synthetic.main.fragment_mypage.*
7 |
8 | /**
9 | * @author ReStartAllKill
10 | * @created on 2019-05-28
11 | * @modified by
12 | * @updated on
13 | */
14 |
15 | class MyPageFragment : BaseFragment(
16 | R.layout.fragment_mypage,
17 | MyPageViewModel::class
18 | ) {
19 |
20 | override fun onCreate() {
21 | arguments?.let {
22 | val arguments = MyPageFragmentArgs.fromBundle(it)
23 | text.text = arguments.testString
24 | }
25 | }
26 |
27 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/nextus/baseapp/ui/mypage/MyPageViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.nextus.baseapp.ui.mypage
2 |
3 | import android.app.Application
4 | import com.nextus.baseapp.data.RemoteClient
5 | import com.nextus.baseapp.ui.base.BaseViewModel
6 |
7 | /**
8 | * @author ReStartAllKill
9 | * @created on 2019-05-28
10 | * @modified by
11 | * @updated on
12 | */
13 | class MyPageViewModel(application: Application) : BaseViewModel(application) {
14 |
15 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/nextus/baseapp/utils/AppLogger.kt:
--------------------------------------------------------------------------------
1 | package com.nextus.baseapp.utils
2 |
3 | import com.nextus.baseapp.BuildConfig
4 | import timber.log.Timber
5 |
6 | /**
7 | * @author ReStartAllKill
8 | * @created on 2018-09-20
9 | * @modified by
10 | * @updated on
11 | */
12 |
13 | object AppLogger {
14 | fun d(s: String, vararg objects: Any) {
15 | Timber.d(s, objects)
16 | }
17 |
18 | fun d(throwable: Throwable, s: String, vararg objects: Any) {
19 | Timber.d(throwable, s, objects)
20 | }
21 |
22 | fun e(s: String, vararg objects: Any) {
23 | Timber.e(s, objects)
24 | }
25 |
26 | fun e(throwable: Throwable, s: String, vararg objects: Any) {
27 | Timber.e(throwable, s, objects)
28 | }
29 |
30 | fun i(s: String, vararg objects: Any) {
31 | Timber.i(s, objects)
32 | }
33 |
34 | fun i(throwable: Throwable, s: String, vararg objects: Any) {
35 | Timber.i(throwable, s, objects)
36 | }
37 |
38 | fun init() {
39 | Timber.plant(Timber.DebugTree())
40 | }
41 |
42 | fun w(s: String, vararg objects: Any) {
43 | Timber.w(s, objects)
44 | }
45 |
46 | fun w(throwable: Throwable, s: String, vararg objects: Any) {
47 | Timber.w(throwable, s, objects)
48 | }
49 | }
50 |
51 |
--------------------------------------------------------------------------------
/app/src/main/java/com/nextus/baseapp/utils/BindingUtils.kt:
--------------------------------------------------------------------------------
1 | package com.nextus.baseapp.utils
2 |
3 | import androidx.databinding.BindingAdapter
4 | import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
5 |
6 | /**
7 | * @author ReStartAllKill
8 | * @created on 2019-05-27
9 | * @modified by
10 | * @updated on
11 | */
12 | object BindingUtils {
13 | @JvmStatic
14 | @BindingAdapter("isRefreshing")
15 | fun SwipeRefreshLayout.bindRefreshing(isRefreshing: Boolean) {
16 | this.isRefreshing = isRefreshing
17 | }
18 |
19 | @JvmStatic
20 | @BindingAdapter("onRefresh")
21 | fun SwipeRefreshLayout.bindRefreshListener(onRefreshListener: SwipeRefreshLayout.OnRefreshListener) =
22 | setOnRefreshListener(onRefreshListener)
23 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/nextus/baseapp/utils/CommonUtils.kt:
--------------------------------------------------------------------------------
1 | package com.nextus.baseapp.utils
2 |
3 | import android.util.Patterns
4 | import java.text.SimpleDateFormat
5 | import java.util.*
6 |
7 | /**
8 | * @author ReStartAllKill
9 | * @created on 2019-05-27
10 | * @modified by
11 | * @updated on
12 | */
13 | object CommonUtils {
14 |
15 | fun getTimeStamp(format: String) : String {
16 | return SimpleDateFormat(format, Locale.KOREA).format(Date())
17 | }
18 |
19 | fun getTime() : Long {
20 | return System.currentTimeMillis()
21 | }
22 |
23 | fun isEmailValid(email: String) : Boolean {
24 | return Patterns.EMAIL_ADDRESS.matcher(email).matches()
25 | }
26 |
27 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/nextus/baseapp/utils/ViewUtils.kt:
--------------------------------------------------------------------------------
1 | package com.nextus.baseapp.utils
2 |
3 | import android.content.res.Resources
4 |
5 | /**
6 | * @author ReStartAllKill
7 | * @created on 2019-05-27
8 | * @modified by
9 | * @updated on
10 | */
11 | object ViewUtils {
12 |
13 | fun dpToPx(dp: Float) : Int {
14 | val density = Resources.getSystem().displayMetrics.density
15 | return Math.round(dp * density)
16 | }
17 |
18 | fun pxToDp(px: Float) : Float {
19 | val densityDpi = Resources.getSystem().displayMetrics.densityDpi
20 | return px / (densityDpi / 160f)
21 | }
22 |
23 | }
--------------------------------------------------------------------------------
/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/ic_apps_black_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_description_black_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_directions_run_black_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
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/selector_bottom_navigation.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
15 |
16 |
23 |
24 |
27 |
28 |
29 |
38 |
39 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_home.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
9 |
10 |
13 |
14 |
20 |
21 |
26 |
27 |
28 |
29 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_mypage.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
12 |
13 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_empty.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
8 |
9 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_gists.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
11 |
12 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_bottom_navigation_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/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/chosw1029/Kotlin_MVVM/c54db6b4e877b8f71fcc1eedd850b2050a53e4b0/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chosw1029/Kotlin_MVVM/c54db6b4e877b8f71fcc1eedd850b2050a53e4b0/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chosw1029/Kotlin_MVVM/c54db6b4e877b8f71fcc1eedd850b2050a53e4b0/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chosw1029/Kotlin_MVVM/c54db6b4e877b8f71fcc1eedd850b2050a53e4b0/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chosw1029/Kotlin_MVVM/c54db6b4e877b8f71fcc1eedd850b2050a53e4b0/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chosw1029/Kotlin_MVVM/c54db6b4e877b8f71fcc1eedd850b2050a53e4b0/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chosw1029/Kotlin_MVVM/c54db6b4e877b8f71fcc1eedd850b2050a53e4b0/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chosw1029/Kotlin_MVVM/c54db6b4e877b8f71fcc1eedd850b2050a53e4b0/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chosw1029/Kotlin_MVVM/c54db6b4e877b8f71fcc1eedd850b2050a53e4b0/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chosw1029/Kotlin_MVVM/c54db6b4e877b8f71fcc1eedd850b2050a53e4b0/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/navigation/navigation_graph.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
12 |
15 |
16 |
17 |
22 |
26 |
27 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FFC107
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | My Application
3 |
4 | TAB1
5 | TAB2
6 | TAB3
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/test/java/com/nextus/baseapp/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package com.nextus.baseapp
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 | apply from: 'dependency.gradle'
5 | addRepos(repositories)
6 |
7 | dependencies {
8 | classpath gradlePlugin.android
9 | classpath gradlePlugin.kotlin
10 | classpath gradlePlugin.navigation_safe_args
11 | }
12 | /*ext {
13 | constraintLayoutVersion = '2.0.0-beta4'
14 | coroutinesVersion = "1.3.5"
15 |
16 | fragmentVersion = '1.2.5'
17 |
18 | gradleVersion = '4.0.0'
19 | glideVersion = '4.11.0'
20 |
21 | kotlinVersion = '1.3.72'
22 | koinVersion = '2.1.0-alpha-3'
23 | ktxVersion = '1.2.0'
24 |
25 | lifecycleVersion = '2.2.0'
26 |
27 | materialVersion = '1.1.0'
28 |
29 | navigationVersion = '2.3.0-alpha01'
30 |
31 | recyclerViewVersion = '1.2.0-alpha01'
32 | retrofitVersion = '2.7.1'
33 | rxandroidVersion = '2.1.1'
34 | rxjava2Version = '2.2.13'
35 | rx2FastAndroidNetworking = '1.0.2'
36 | roomVersion = '2.2.5'
37 |
38 | supportLibraryVersion = '1.2.0-alpha02'
39 |
40 | timberVersion = '4.7.1'
41 | }
42 |
43 | dependencies {
44 | classpath "com.android.tools.build:gradle:$gradleVersion"
45 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
46 | classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$navigationVersion"
47 | // NOTE: Do not place your application dependencies here; they belong
48 | // in the individual module build.gradle files
49 | }*/
50 | }
51 |
52 | allprojects {
53 | addRepos(repositories)
54 | }
55 |
56 | task clean(type: Delete) {
57 | delete rootProject.buildDir
58 | }
59 |
--------------------------------------------------------------------------------
/dependency.gradle:
--------------------------------------------------------------------------------
1 | /**
2 | * Shared file between builds so that they can all use the same dependencies and
3 | * maven repositories.
4 | **/
5 | ext.deps = [:]
6 |
7 | // version
8 | def versions = [:]
9 | versions.kotlin = "1.3.72"
10 | versions.lifecycle = "2.2.0"
11 | versions.coroutine = "1.3.5"
12 | versions.navigation = "2.3.0-alpha01"
13 | versions.timber = "4.7.1"
14 | versions.retrofit = "2.7.1"
15 | versions.koin = "2.1.0-alpha-3"
16 | versions.okhttp = "4.4.0"
17 | deps.versions = versions
18 |
19 | // dependency
20 | def deps = [:]
21 |
22 | // androidx
23 | def androidx = [:]
24 | androidx.appcompat = "androidx.appcompat:appcompat:1.2.0-alpha02"
25 | androidx.core_ktx = "androidx.core:core-ktx:1.2.0"
26 | androidx.constraintlayout = "androidx.constraintlayout:constraintlayout:2.0.0-beta4"
27 | androidx.lifecycle = [
28 | runtime_ktx : "androidx.lifecycle:lifecycle-runtime-ktx:$versions.lifecycle",
29 | extensions : "androidx.lifecycle:lifecycle-extensions:$versions.lifecycle",
30 | viewmodel_ktx: "androidx.lifecycle:lifecycle-viewmodel-ktx:$versions.lifecycle",
31 | livedata_ktx : "androidx.lifecycle:lifecycle-livedata-ktx:$versions.lifecycle"
32 | ]
33 | androidx.navigation = [
34 | fragment_ktx: "androidx.navigation:navigation-fragment-ktx:$versions.navigation",
35 | ui_ktx : "androidx.navigation:navigation-ui-ktx:$versions.navigation"
36 | ]
37 | androidx.material = "com.google.android.material:material:1.1.0"
38 | androidx.swiperefresh = "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0"
39 | deps.androidx = androidx
40 |
41 | // kotlin
42 | def kotlin = [:]
43 | kotlin.stdlib = "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$versions.kotlin"
44 | kotlin.coroutines = [
45 | core : "org.jetbrains.kotlinx:kotlinx-coroutines-core:$versions.coroutine",
46 | android : "org.jetbrains.kotlinx:kotlinx-coroutines-android:$versions.coroutine",
47 | play_services: "org.jetbrains.kotlinx:kotlinx-coroutines-play-services:$versions.coroutine",
48 | test : "org.jetbrains.kotlinx:kotlinx-coroutines-test:$versions.coroutine"
49 | ]
50 | deps.kotlin = kotlin
51 |
52 | // koin
53 | deps.koin = [
54 | core : "org.koin:koin-androidx-scope:$versions.koin",
55 | viewModel: "org.koin:koin-androidx-viewmodel:$versions.koin"
56 | ]
57 |
58 | // okhttp
59 | deps.okhttp = [
60 | core : "com.squareup.okhttp3:okhttp:$versions.okhttp",
61 | logging_interceptor : "com.squareup.okhttp3:logging-interceptor:$versions.okhttp"
62 | ]
63 |
64 | // retrofit
65 | deps.retrofit = [
66 | core : "com.squareup.retrofit2:retrofit:$versions.retrofit",
67 | converter_gson : "com.squareup.retrofit2:converter-gson:$versions.retrofit",
68 | adapter_rxjava2 : "com.squareup.retrofit2:adapter-rxjava2:$versions.retrofit"
69 | ]
70 |
71 | deps.google = [
72 | gson: 'com.google.code.gson:gson:2.8.6'
73 | ]
74 |
75 | // debugging
76 | deps.debugging = [
77 | timber : "com.jakewharton.timber:timber:$versions.timber"
78 | ]
79 |
80 | // test
81 | deps.atsl = [
82 | junit : "junit:junit:4.12",
83 | ext_junit : "androidx.test.ext:junit:1.1.1",
84 | espresso_core: "androidx.test.espresso:espresso-core:3.2.0"
85 | ]
86 |
87 | ext.deps = deps
88 |
89 | // build gradle plugin
90 | def gradlePlugin = [
91 | android : "com.android.tools.build:gradle:4.0.1",
92 | kotlin : "org.jetbrains.kotlin:kotlin-gradle-plugin:$versions.kotlin",
93 | play_services: "com.google.gms:google-services:4.3.3",
94 | navigation_safe_args: "androidx.navigation:navigation-safe-args-gradle-plugin:$versions.navigation"
95 | ]
96 | ext.gradlePlugin = gradlePlugin
97 |
98 | // build_versions
99 | ext.build_versions = [
100 | compile_sdk: 29,
101 | build_tools: "29.0.2",
102 | min_sdk : 15,
103 | target_sdk : 29
104 | ]
105 |
106 | // repository
107 | def static addRepos(RepositoryHandler handler) {
108 | handler.google()
109 | handler.jcenter()
110 | }
111 |
112 | ext.addRepos = this.&addRepos
--------------------------------------------------------------------------------
/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 | # AndroidX package structure to make it clearer which packages are bundled with the
15 | # Android operating system, and which are packaged with your app's APK
16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
17 | android.useAndroidX=true
18 | # Automatically convert third-party libraries to use AndroidX
19 | android.enableJetifier=true
20 | # Kotlin code style for this project: "official" or "obsolete":
21 | kotlin.code.style=official
22 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chosw1029/Kotlin_MVVM/c54db6b4e877b8f71fcc1eedd850b2050a53e4b0/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Jun 24 15:30:07 KST 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 |
--------------------------------------------------------------------------------