├── app ├── .gitignore ├── src │ ├── main │ │ ├── res │ │ │ ├── values │ │ │ │ ├── strings.xml │ │ │ │ ├── colors.xml │ │ │ │ └── styles.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 │ │ │ ├── mipmap-anydpi-v26 │ │ │ │ ├── ic_launcher.xml │ │ │ │ └── ic_launcher_round.xml │ │ │ ├── layout │ │ │ │ ├── activity_main.xml │ │ │ │ └── single_movie_item.xml │ │ │ ├── drawable-v24 │ │ │ │ └── ic_launcher_foreground.xml │ │ │ └── drawable │ │ │ │ └── ic_launcher_background.xml │ │ ├── java │ │ │ └── com │ │ │ │ └── spartons │ │ │ │ └── kotlincoroutinecalladapter │ │ │ │ ├── util │ │ │ │ ├── NonNullMediatorLiveData.kt │ │ │ │ ├── TopLevelFunctions.kt │ │ │ │ └── LiveDataExtensions.kt │ │ │ │ ├── di │ │ │ │ ├── qualifiers │ │ │ │ │ └── ApplicationContextQualifier.kt │ │ │ │ ├── scopes │ │ │ │ │ └── CustomApplicationScope.kt │ │ │ │ ├── modules │ │ │ │ │ ├── ApplicationContextModule.kt │ │ │ │ │ ├── PicassoModule.kt │ │ │ │ │ ├── ServiceUtilModule.kt │ │ │ │ │ └── NetworkModule.kt │ │ │ │ └── components │ │ │ │ │ └── AppComponent.kt │ │ │ │ ├── activites │ │ │ │ ├── mainActivity │ │ │ │ │ ├── di │ │ │ │ │ │ ├── MainActivityScope.kt │ │ │ │ │ │ ├── MainActivityComponent.kt │ │ │ │ │ │ └── MainActivityModule.kt │ │ │ │ │ ├── viewModel │ │ │ │ │ │ ├── MainActivityViewModelFactory.kt │ │ │ │ │ │ └── MainActivityViewModel.kt │ │ │ │ │ ├── dataSource │ │ │ │ │ │ └── MovieDataSource.kt │ │ │ │ │ └── ui │ │ │ │ │ │ └── MainActivity.kt │ │ │ │ └── BaseActivity.kt │ │ │ │ ├── response │ │ │ │ ├── Result.kt │ │ │ │ └── MovieResponse.kt │ │ │ │ ├── backend │ │ │ │ ├── ApiService.kt │ │ │ │ └── MyCustomApplicationClass.kt │ │ │ │ ├── viewHolder │ │ │ │ └── MovieViewHolder.kt │ │ │ │ └── adapter │ │ │ │ └── MovieAdapter.kt │ │ └── AndroidManifest.xml │ ├── test │ │ └── java │ │ │ └── com │ │ │ └── spartons │ │ │ └── kotlincoroutinecalladapter │ │ │ └── ExampleUnitTest.kt │ └── androidTest │ │ └── java │ │ └── com │ │ └── spartons │ │ └── kotlincoroutinecalladapter │ │ └── ExampleInstrumentedTest.kt ├── proguard-rules.pro └── build.gradle ├── settings.gradle ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── .idea ├── codeStyles │ ├── codeStyleConfig.xml │ └── Project.xml ├── vcs.xml ├── inspectionProfiles │ └── Project_Default.xml ├── runConfigurations.xml ├── gradle.xml └── misc.xml ├── .gitignore ├── README.md ├── gradle.properties ├── gradlew.bat └── gradlew /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | KotlinCoroutineCallAdapter 3 | 4 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodingInfinite/KotlinCoroutineCallAdpater/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodingInfinite/KotlinCoroutineCallAdpater/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodingInfinite/KotlinCoroutineCallAdpater/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodingInfinite/KotlinCoroutineCallAdpater/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodingInfinite/KotlinCoroutineCallAdpater/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodingInfinite/KotlinCoroutineCallAdpater/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodingInfinite/KotlinCoroutineCallAdpater/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodingInfinite/KotlinCoroutineCallAdpater/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodingInfinite/KotlinCoroutineCallAdpater/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodingInfinite/KotlinCoroutineCallAdpater/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodingInfinite/KotlinCoroutineCallAdpater/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/caches/build_file_checksums.ser 5 | /.idea/libraries 6 | /.idea/modules.xml 7 | /.idea/workspace.xml 8 | .DS_Store 9 | /build 10 | /captures 11 | .externalNativeBuild 12 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /app/src/main/java/com/spartons/kotlincoroutinecalladapter/util/NonNullMediatorLiveData.kt: -------------------------------------------------------------------------------- 1 | package com.spartons.kotlincoroutinecalladapter.util 2 | 3 | import android.arch.lifecycle.MediatorLiveData 4 | 5 | class NonNullMediatorLiveData : MediatorLiveData() 6 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #008577 4 | #00574B 5 | #D81B60 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/java/com/spartons/kotlincoroutinecalladapter/di/qualifiers/ApplicationContextQualifier.kt: -------------------------------------------------------------------------------- 1 | package com.spartons.kotlincoroutinecalladapter.di.qualifiers 2 | 3 | import javax.inject.Qualifier 4 | 5 | @Qualifier 6 | annotation class ApplicationContextQualifier -------------------------------------------------------------------------------- /app/src/main/java/com/spartons/kotlincoroutinecalladapter/di/scopes/CustomApplicationScope.kt: -------------------------------------------------------------------------------- 1 | package com.spartons.kotlincoroutinecalladapter.di.scopes 2 | 3 | import javax.inject.Scope 4 | 5 | @Scope 6 | @Retention(AnnotationRetention.RUNTIME) 7 | annotation class CustomApplicationScope 8 | -------------------------------------------------------------------------------- /app/src/main/java/com/spartons/kotlincoroutinecalladapter/activites/mainActivity/di/MainActivityScope.kt: -------------------------------------------------------------------------------- 1 | package com.spartons.kotlincoroutinecalladapter.activites.mainActivity.di 2 | 3 | import javax.inject.Scope 4 | 5 | @Scope 6 | @Retention(AnnotationRetention.RUNTIME) 7 | annotation class MainActivityScope -------------------------------------------------------------------------------- /app/src/main/java/com/spartons/kotlincoroutinecalladapter/response/Result.kt: -------------------------------------------------------------------------------- 1 | package com.spartons.kotlincoroutinecalladapter.response 2 | 3 | sealed class Result { 4 | data class Success(val data: T) : Result() 5 | data class Error(val exception: Exception) : Result() 6 | } -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /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/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # KotlinCoroutineCallAdpater 2 | 3 | In order to use Kotlin Coroutine Call Adapter, we need to add the instance of its factory when building the 4 | Retrofit instance. In this app I briefly how we can simply use Retrofit and Kotlin Coroutine Adapter 5 | together to improve our Android app networking architecture. 6 | 7 | Getting Started: 8 | ====== 9 | 10 | For getting started with this project, check out this [article](https://codinginfinite.com/kotlin-coroutine-call-adapter-retrofit/). 11 | -------------------------------------------------------------------------------- /app/src/test/java/com/spartons/kotlincoroutinecalladapter/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package com.spartons.kotlincoroutinecalladapter 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 | -------------------------------------------------------------------------------- /app/src/main/java/com/spartons/kotlincoroutinecalladapter/activites/BaseActivity.kt: -------------------------------------------------------------------------------- 1 | package com.spartons.kotlincoroutinecalladapter.activites 2 | 3 | import android.annotation.SuppressLint 4 | import android.support.v7.app.AppCompatActivity 5 | import com.spartons.kotlincoroutinecalladapter.backend.MyCustomApplicationClass 6 | 7 | @SuppressLint("Registered") 8 | open class BaseActivity : AppCompatActivity() { 9 | 10 | protected fun getAppComponent() = getApp().getAppComponent() 11 | 12 | private fun getApp() = applicationContext as MyCustomApplicationClass 13 | } -------------------------------------------------------------------------------- /app/src/main/java/com/spartons/kotlincoroutinecalladapter/util/TopLevelFunctions.kt: -------------------------------------------------------------------------------- 1 | @file:Suppress("EXPERIMENTAL_FEATURE_WARNING") 2 | 3 | package com.spartons.kotlincoroutinecalladapter.util 4 | 5 | import com.spartons.kotlincoroutinecalladapter.response.Result 6 | import java.io.IOException 7 | import java.lang.Exception 8 | 9 | suspend fun safeApiCall(call: suspend () -> Result, errorMessage: String): Result = try { 10 | call.invoke() 11 | } catch (e: Exception) { 12 | Result.Error(IOException(errorMessage, e)) 13 | } 14 | 15 | val T.exhaustive: T get() = this -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/java/com/spartons/kotlincoroutinecalladapter/di/modules/ApplicationContextModule.kt: -------------------------------------------------------------------------------- 1 | package com.spartons.kotlincoroutinecalladapter.di.modules 2 | 3 | import android.content.Context 4 | import com.spartons.kotlincoroutinecalladapter.di.qualifiers.ApplicationContextQualifier 5 | import com.spartons.kotlincoroutinecalladapter.di.scopes.CustomApplicationScope 6 | import dagger.Module 7 | import dagger.Provides 8 | 9 | @Module 10 | class ApplicationContextModule(private var context: Context) { 11 | 12 | @Provides 13 | @CustomApplicationScope 14 | @ApplicationContextQualifier 15 | fun getContext() = context 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/com/spartons/kotlincoroutinecalladapter/backend/ApiService.kt: -------------------------------------------------------------------------------- 1 | package com.spartons.kotlincoroutinecalladapter.backend 2 | 3 | import com.spartons.kotlincoroutinecalladapter.response.MovieResponse 4 | import kotlinx.coroutines.experimental.Deferred 5 | import retrofit2.Response 6 | import retrofit2.http.GET 7 | import retrofit2.http.Query 8 | 9 | interface ApiService { 10 | 11 | @GET(value = "popular") 12 | fun getPopular( 13 | @Query( 14 | value = "api_key" 15 | ) apiKey: String, @Query( 16 | value = "page" 17 | ) page: Int 18 | ): Deferred> 19 | } -------------------------------------------------------------------------------- /app/src/main/java/com/spartons/kotlincoroutinecalladapter/response/MovieResponse.kt: -------------------------------------------------------------------------------- 1 | package com.spartons.kotlincoroutinecalladapter.response 2 | 3 | import com.google.gson.annotations.Expose 4 | import com.google.gson.annotations.SerializedName 5 | 6 | class MovieResponse { 7 | 8 | @SerializedName(value = "page") 9 | @Expose 10 | var page: Int = 0 11 | @SerializedName(value = "results") 12 | @Expose 13 | var movies: List = ArrayList() 14 | 15 | class Movie constructor( 16 | val title: String, 17 | val vote_average: Double, 18 | val poster_path: String, 19 | val release_date: String 20 | ) 21 | } -------------------------------------------------------------------------------- /app/src/main/java/com/spartons/kotlincoroutinecalladapter/util/LiveDataExtensions.kt: -------------------------------------------------------------------------------- 1 | package com.spartons.kotlincoroutinecalladapter.util 2 | 3 | import android.arch.lifecycle.LifecycleOwner 4 | import android.arch.lifecycle.LiveData 5 | 6 | fun LiveData.nonNull(): NonNullMediatorLiveData { 7 | val mediator: NonNullMediatorLiveData = NonNullMediatorLiveData() 8 | mediator.addSource(this) { it?.let { mediator.value = it } } 9 | return mediator 10 | } 11 | fun NonNullMediatorLiveData.observe(owner: LifecycleOwner, observer: (t: T) -> Unit) { 12 | this.observe(owner, android.arch.lifecycle.Observer { 13 | it?.let(observer) 14 | }) 15 | } -------------------------------------------------------------------------------- /app/src/main/java/com/spartons/kotlincoroutinecalladapter/activites/mainActivity/viewModel/MainActivityViewModelFactory.kt: -------------------------------------------------------------------------------- 1 | package com.spartons.kotlincoroutinecalladapter.activites.mainActivity.viewModel 2 | 3 | import android.arch.lifecycle.ViewModel 4 | import android.arch.lifecycle.ViewModelProvider 5 | import com.spartons.kotlincoroutinecalladapter.activites.mainActivity.dataSource.MovieDataSource 6 | 7 | @Suppress("UNCHECKED_CAST") 8 | class MainActivityViewModelFactory constructor(private val movieDataSource: MovieDataSource) : 9 | ViewModelProvider.Factory { 10 | 11 | override fun create(modelClass: Class) = MainActivityViewModel(movieDataSource) as T 12 | } -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | -------------------------------------------------------------------------------- /app/src/main/java/com/spartons/kotlincoroutinecalladapter/viewHolder/MovieViewHolder.kt: -------------------------------------------------------------------------------- 1 | package com.spartons.kotlincoroutinecalladapter.viewHolder 2 | 3 | import android.support.v7.widget.RecyclerView 4 | import android.view.View 5 | import android.widget.ImageView 6 | import android.widget.TextView 7 | import com.spartons.kotlincoroutinecalladapter.R 8 | 9 | class MovieViewHolder (itemView1: View) : RecyclerView.ViewHolder(itemView1) { 10 | 11 | val moviePosterImageView: ImageView = itemView1.findViewById(R.id.moviePosterImageView) 12 | val movieRatingTextView: TextView = itemView1.findViewById(R.id.movieRatingTextView) 13 | val movieTitleTextView: TextView = itemView1.findViewById(R.id.movieTitleTextView) 14 | } -------------------------------------------------------------------------------- /app/src/main/java/com/spartons/kotlincoroutinecalladapter/di/components/AppComponent.kt: -------------------------------------------------------------------------------- 1 | package com.spartons.kotlincoroutinecalladapter.di.components 2 | 3 | import com.spartons.kotlincoroutinecalladapter.backend.ApiService 4 | import com.spartons.kotlincoroutinecalladapter.di.modules.PicassoModule 5 | import com.spartons.kotlincoroutinecalladapter.di.modules.ServiceUtilModule 6 | import com.spartons.kotlincoroutinecalladapter.di.scopes.CustomApplicationScope 7 | import com.squareup.picasso.Picasso 8 | import dagger.Component 9 | 10 | @CustomApplicationScope 11 | @Component(modules = [PicassoModule::class, ServiceUtilModule::class]) 12 | interface AppComponent { 13 | 14 | fun getPicasso(): Picasso 15 | 16 | fun getApiService(): ApiService 17 | } 18 | -------------------------------------------------------------------------------- /app/src/main/java/com/spartons/kotlincoroutinecalladapter/activites/mainActivity/di/MainActivityComponent.kt: -------------------------------------------------------------------------------- 1 | package com.spartons.kotlincoroutinecalladapter.activites.mainActivity.di 2 | 3 | import com.spartons.kotlincoroutinecalladapter.activites.mainActivity.ui.MainActivity 4 | import com.spartons.kotlincoroutinecalladapter.activites.mainActivity.viewModel.MainActivityViewModel 5 | import com.spartons.kotlincoroutinecalladapter.di.components.AppComponent 6 | import dagger.Component 7 | 8 | @MainActivityScope 9 | @Component(modules = [MainActivityModule::class], dependencies = [AppComponent::class]) 10 | interface MainActivityComponent : AppComponent { 11 | 12 | fun inject(mainActivity: MainActivity) 13 | 14 | fun viewModel(): MainActivityViewModel 15 | } -------------------------------------------------------------------------------- /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/spartons/kotlincoroutinecalladapter/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.spartons.kotlincoroutinecalladapter 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.spartons.kotlincoroutinecalladapter", appContext.packageName) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /app/src/main/java/com/spartons/kotlincoroutinecalladapter/backend/MyCustomApplicationClass.kt: -------------------------------------------------------------------------------- 1 | package com.spartons.kotlincoroutinecalladapter.backend 2 | 3 | import android.app.Application 4 | import com.spartons.kotlincoroutinecalladapter.di.components.AppComponent 5 | import com.spartons.kotlincoroutinecalladapter.di.components.DaggerAppComponent 6 | import com.spartons.kotlincoroutinecalladapter.di.modules.ApplicationContextModule 7 | import timber.log.Timber 8 | 9 | class MyCustomApplicationClass : Application() { 10 | 11 | private lateinit var applicationComponent: AppComponent 12 | 13 | override fun onCreate() { 14 | super.onCreate() 15 | Timber.plant(Timber.DebugTree()) 16 | applicationComponent = DaggerAppComponent 17 | .builder() 18 | .applicationContextModule(ApplicationContextModule(this)) 19 | .build() 20 | } 21 | 22 | fun getAppComponent() = applicationComponent 23 | } -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 14 | 15 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /app/src/main/java/com/spartons/kotlincoroutinecalladapter/di/modules/PicassoModule.kt: -------------------------------------------------------------------------------- 1 | package com.spartons.kotlincoroutinecalladapter.di.modules 2 | 3 | import android.content.Context 4 | import com.jakewharton.picasso.OkHttp3Downloader 5 | import com.spartons.kotlincoroutinecalladapter.di.qualifiers.ApplicationContextQualifier 6 | import com.spartons.kotlincoroutinecalladapter.di.scopes.CustomApplicationScope 7 | import com.squareup.picasso.Picasso 8 | import dagger.Module 9 | import dagger.Provides 10 | import okhttp3.OkHttpClient 11 | 12 | @Module(includes = [NetworkModule::class]) 13 | class PicassoModule { 14 | 15 | @Provides 16 | @CustomApplicationScope 17 | fun getOkHttp3Downloader(okHttpClient: OkHttpClient) = OkHttp3Downloader(okHttpClient) 18 | 19 | @Provides 20 | @CustomApplicationScope 21 | fun getPicasso(@ApplicationContextQualifier context: Context, okHttpDownloader: OkHttp3Downloader): Picasso { 22 | return Picasso.Builder(context) 23 | .downloader(okHttpDownloader) 24 | .build() 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /app/src/main/java/com/spartons/kotlincoroutinecalladapter/activites/mainActivity/dataSource/MovieDataSource.kt: -------------------------------------------------------------------------------- 1 | package com.spartons.kotlincoroutinecalladapter.activites.mainActivity.dataSource 2 | 3 | import com.spartons.kotlincoroutinecalladapter.backend.ApiService 4 | import com.spartons.kotlincoroutinecalladapter.response.MovieResponse 5 | import com.spartons.kotlincoroutinecalladapter.response.Result 6 | import com.spartons.kotlincoroutinecalladapter.util.safeApiCall 7 | import java.io.IOException 8 | 9 | @Suppress("EXPERIMENTAL_FEATURE_WARNING") 10 | class MovieDataSource constructor(private val apiService: ApiService) { 11 | 12 | companion object { 13 | private const val API_KEY = "e5c7041*****************0e80c7" 14 | } 15 | 16 | suspend fun getMovies(pageNumber: Int) = safeApiCall( 17 | call = { popularMovies(pageNumber) }, 18 | errorMessage = "Error occurred" 19 | ) 20 | 21 | private suspend fun popularMovies(pageNumber: Int): Result { 22 | val response = apiService.getPopular(API_KEY, pageNumber).await() 23 | if (response.isSuccessful) 24 | return Result.Success(response.body()!!) 25 | return Result.Error(IOException("Error occurred during fetching movies!")) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/com/spartons/kotlincoroutinecalladapter/activites/mainActivity/di/MainActivityModule.kt: -------------------------------------------------------------------------------- 1 | package com.spartons.kotlincoroutinecalladapter.activites.mainActivity.di 2 | 3 | import android.arch.lifecycle.ViewModelProviders 4 | import com.spartons.kotlincoroutinecalladapter.activites.mainActivity.dataSource.MovieDataSource 5 | import com.spartons.kotlincoroutinecalladapter.activites.mainActivity.ui.MainActivity 6 | import com.spartons.kotlincoroutinecalladapter.activites.mainActivity.viewModel.MainActivityViewModel 7 | import com.spartons.kotlincoroutinecalladapter.activites.mainActivity.viewModel.MainActivityViewModelFactory 8 | import com.spartons.kotlincoroutinecalladapter.backend.ApiService 9 | import dagger.Module 10 | import dagger.Provides 11 | 12 | @Module 13 | class MainActivityModule constructor(private val mainActivity: MainActivity) { 14 | 15 | @Provides 16 | @MainActivityScope 17 | fun movieDataSource(apiService: ApiService) = MovieDataSource(apiService) 18 | 19 | @Provides 20 | @MainActivityScope 21 | fun mainActivityViewModelFactory(movieDataSource: MovieDataSource) = MainActivityViewModelFactory(movieDataSource) 22 | 23 | @Provides 24 | @MainActivityScope 25 | fun mainActivityViewModel(viewModelFactory: MainActivityViewModelFactory): MainActivityViewModel = 26 | ViewModelProviders.of(mainActivity, viewModelFactory).get(MainActivityViewModel::class.java) 27 | } -------------------------------------------------------------------------------- /app/src/main/java/com/spartons/kotlincoroutinecalladapter/di/modules/ServiceUtilModule.kt: -------------------------------------------------------------------------------- 1 | package com.spartons.kotlincoroutinecalladapter.di.modules 2 | 3 | import com.google.gson.Gson 4 | import com.google.gson.GsonBuilder 5 | import com.jakewharton.retrofit2.adapter.kotlin.coroutines.experimental.CoroutineCallAdapterFactory 6 | import com.spartons.kotlincoroutinecalladapter.backend.ApiService 7 | import com.spartons.kotlincoroutinecalladapter.di.scopes.CustomApplicationScope 8 | import dagger.Module 9 | import dagger.Provides 10 | import okhttp3.OkHttpClient 11 | import retrofit2.Retrofit 12 | import retrofit2.converter.gson.GsonConverterFactory 13 | 14 | 15 | @Module(includes = [NetworkModule::class]) 16 | class ServiceUtilModule { 17 | 18 | companion object { 19 | private const val BASE_URL = "https://api.themoviedb.org/3/movie/" 20 | } 21 | 22 | @Provides 23 | @CustomApplicationScope 24 | fun getServiceUtil(retrofit: Retrofit): ApiService = retrofit.create(ApiService::class.java) 25 | 26 | @Provides 27 | @CustomApplicationScope 28 | fun getGson() = GsonBuilder().create()!! 29 | 30 | @Provides 31 | @CustomApplicationScope 32 | fun getRetrofit(okHttpClient: OkHttpClient, gson: Gson): Retrofit { 33 | return Retrofit.Builder() 34 | .addCallAdapterFactory(CoroutineCallAdapterFactory()) 35 | .addConverterFactory(GsonConverterFactory.create()) 36 | .baseUrl(BASE_URL) 37 | .client(okHttpClient) 38 | .build() 39 | } 40 | } -------------------------------------------------------------------------------- /app/src/main/java/com/spartons/kotlincoroutinecalladapter/adapter/MovieAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.spartons.kotlincoroutinecalladapter.adapter 2 | 3 | import android.content.Context 4 | import android.support.v7.widget.RecyclerView 5 | import android.view.LayoutInflater 6 | import android.view.ViewGroup 7 | import com.spartons.kotlincoroutinecalladapter.R 8 | import com.spartons.kotlincoroutinecalladapter.response.MovieResponse 9 | import com.spartons.kotlincoroutinecalladapter.viewHolder.MovieViewHolder 10 | import com.squareup.picasso.Picasso 11 | 12 | class MovieAdapter constructor( 13 | private val context: Context, 14 | private val movies: List, 15 | private val picasso: Picasso = Picasso.with(context) 16 | ) : 17 | RecyclerView.Adapter() { 18 | 19 | companion object { 20 | const val IMAGE_BASE_URL = "http://image.tmdb.org/t/p/w185" 21 | } 22 | 23 | private val layoutInflater = LayoutInflater.from(context) 24 | 25 | override fun onCreateViewHolder(p0: ViewGroup, p1: Int): MovieViewHolder = 26 | MovieViewHolder(layoutInflater.inflate(R.layout.single_movie_item, p0, false)) 27 | 28 | override fun getItemCount() = movies.size 29 | 30 | override fun onBindViewHolder(holder: MovieViewHolder, position: Int) { 31 | val movie = movies[position] 32 | val url = IMAGE_BASE_URL.plus(movie.poster_path) 33 | picasso.load(url).into(holder.moviePosterImageView) 34 | holder.movieRatingTextView.text = movie.vote_average.toString() 35 | holder.movieTitleTextView.text = movie.title 36 | 37 | } 38 | } -------------------------------------------------------------------------------- /app/src/main/java/com/spartons/kotlincoroutinecalladapter/activites/mainActivity/viewModel/MainActivityViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.spartons.kotlincoroutinecalladapter.activites.mainActivity.viewModel 2 | 3 | import android.arch.lifecycle.LiveData 4 | import android.arch.lifecycle.ViewModel 5 | import com.spartons.kotlincoroutinecalladapter.activites.mainActivity.dataSource.MovieDataSource 6 | import com.spartons.kotlincoroutinecalladapter.response.MovieResponse 7 | import com.spartons.kotlincoroutinecalladapter.response.Result 8 | import com.spartons.kotlincoroutinecalladapter.util.NonNullMediatorLiveData 9 | import kotlinx.coroutines.experimental.Job 10 | import kotlinx.coroutines.experimental.launch 11 | 12 | @Suppress("EXPERIMENTAL_FEATURE_WARNING") 13 | class MainActivityViewModel constructor(private val movieDataSource: MovieDataSource) : ViewModel() { 14 | 15 | private val _movies = NonNullMediatorLiveData>() 16 | private val _error = NonNullMediatorLiveData() 17 | 18 | private var moviesJob: Job? = null 19 | 20 | val movies: LiveData> get() = _movies 21 | val error: LiveData get() = _error 22 | 23 | init { 24 | initGetMoviesCall() 25 | } 26 | 27 | private fun initGetMoviesCall() { 28 | moviesJob = launch { 29 | val value = movieDataSource.getMovies(1) 30 | when (value) { 31 | is Result.Success -> _movies.postValue(value.data.movies) 32 | is Result.Error -> _error.postValue(value.exception.message) 33 | } 34 | } 35 | } 36 | 37 | override fun onCleared() { 38 | super.onCleared() 39 | moviesJob?.cancel() 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /app/src/main/java/com/spartons/kotlincoroutinecalladapter/di/modules/NetworkModule.kt: -------------------------------------------------------------------------------- 1 | package com.spartons.kotlincoroutinecalladapter.di.modules 2 | 3 | import android.content.Context 4 | import com.spartons.kotlincoroutinecalladapter.di.qualifiers.ApplicationContextQualifier 5 | import com.spartons.kotlincoroutinecalladapter.di.scopes.CustomApplicationScope 6 | import dagger.Module 7 | import dagger.Provides 8 | import okhttp3.Cache 9 | import okhttp3.OkHttpClient 10 | import okhttp3.logging.HttpLoggingInterceptor 11 | import timber.log.Timber 12 | import java.io.File 13 | import java.util.concurrent.TimeUnit 14 | 15 | @Module(includes = [(ApplicationContextModule::class)]) 16 | class NetworkModule { 17 | 18 | @Provides 19 | @CustomApplicationScope 20 | fun getInterceptor(): HttpLoggingInterceptor { 21 | val interceptor = HttpLoggingInterceptor { 22 | Timber.i(it) 23 | } 24 | interceptor.level = HttpLoggingInterceptor.Level.BODY 25 | return interceptor 26 | } 27 | 28 | @Provides 29 | @CustomApplicationScope 30 | fun getCache(cacheFile: File) = Cache(cacheFile, 10 * 1000 * 1000) // 10 Mib cache 31 | 32 | @Provides 33 | @CustomApplicationScope 34 | fun getFile(@ApplicationContextQualifier context: Context): File { 35 | val file = File(context.filesDir, "cache_dir") 36 | if (!file.exists()) 37 | file.mkdirs() 38 | return file 39 | } 40 | 41 | @Provides 42 | @CustomApplicationScope 43 | fun getOkHttpClient(interceptor: HttpLoggingInterceptor, cache: Cache): OkHttpClient { 44 | return OkHttpClient.Builder() 45 | .writeTimeout(15, TimeUnit.SECONDS) 46 | .connectTimeout(15, TimeUnit.SECONDS) 47 | .readTimeout(15, TimeUnit.SECONDS) 48 | .cache(cache) 49 | .addInterceptor(interceptor) 50 | .build() 51 | } 52 | } -------------------------------------------------------------------------------- /app/src/main/res/layout/single_movie_item.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 15 | 16 | 19 | 20 | 26 | 27 | 36 | 37 | 38 | 39 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 18 | 19 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 34 | 35 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 31 | 32 | 33 | 34 | 35 | 36 | 38 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | /* AUTO-GENERATED FILE. DO NOT MODIFY. 2 | * 3 | * This class was automatically generated by the 4 | * gradle plugin from the resource data it found. It 5 | * should not be modified by hand. 6 | */ 7 | package com.google.firebase.database; 8 | 9 | public final class R { 10 | private R() {} 11 | 12 | } 13 | -------------------------------------------------------------------------------- /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 28 8 | defaultConfig { 9 | applicationId "com.spartons.kotlincoroutinecalladapter" 10 | minSdkVersion 20 11 | targetSdkVersion 28 12 | versionCode 1 13 | versionName "1.0" 14 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 15 | } 16 | buildTypes { 17 | release { 18 | minifyEnabled false 19 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 20 | } 21 | } 22 | } 23 | 24 | dependencies { 25 | implementation fileTree(dir: 'libs', include: ['*.jar']) 26 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 27 | implementation 'com.android.support:appcompat-v7:28.0.0' 28 | implementation 'com.android.support.constraint:constraint-layout:1.1.3' 29 | 30 | implementation 'com.squareup.retrofit2:retrofit:2.3.0' 31 | implementation 'com.squareup.retrofit2:converter-gson:2.3.0' 32 | implementation 'com.squareup.okhttp3:logging-interceptor:3.9.1' 33 | implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-experimental-adapter:1.0.0' 34 | 35 | // Support library dependencies 36 | implementation 'com.android.support:recyclerview-v7:28.0.0' 37 | implementation 'com.android.support:cardview-v7:28.0.0' 38 | 39 | // Picasso dependency 40 | implementation 'com.squareup.picasso:picasso:2.5.2' 41 | implementation 'com.jakewharton.picasso:picasso2-okhttp3-downloader:1.1.0' 42 | 43 | 44 | // ViewModel dependencies 45 | implementation 'android.arch.lifecycle:viewmodel:1.1.1' 46 | implementation 'android.arch.lifecycle:extensions:1.1.1' 47 | 48 | // Dagger dependencies 49 | implementation 'com.google.dagger:dagger-android:2.15' 50 | implementation 'com.google.dagger:dagger:2.15' 51 | implementation 'com.google.dagger:dagger-android-support:2.15' 52 | kapt 'com.google.dagger:dagger-compiler:2.15' 53 | kapt 'com.google.dagger:dagger-android-processor:2.15' 54 | 55 | // Timber dependency 56 | implementation 'com.jakewharton.timber:timber:4.6.0' 57 | 58 | testImplementation 'junit:junit:4.12' 59 | androidTestImplementation 'com.android.support.test:runner:1.0.2' 60 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' 61 | } 62 | kotlin { 63 | experimental { 64 | coroutines "enable" 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /app/src/main/java/com/spartons/kotlincoroutinecalladapter/activites/mainActivity/ui/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.spartons.kotlincoroutinecalladapter.activites.mainActivity.ui 2 | 3 | import android.os.Bundle 4 | import android.support.v7.widget.GridLayoutManager 5 | import android.view.View 6 | import android.widget.Toast 7 | import com.spartons.kotlincoroutinecalladapter.R 8 | import com.spartons.kotlincoroutinecalladapter.activites.BaseActivity 9 | import com.spartons.kotlincoroutinecalladapter.activites.mainActivity.di.DaggerMainActivityComponent 10 | import com.spartons.kotlincoroutinecalladapter.activites.mainActivity.di.MainActivityModule 11 | import com.spartons.kotlincoroutinecalladapter.activites.mainActivity.viewModel.MainActivityViewModel 12 | import com.spartons.kotlincoroutinecalladapter.adapter.MovieAdapter 13 | import com.spartons.kotlincoroutinecalladapter.response.MovieResponse 14 | import com.spartons.kotlincoroutinecalladapter.util.nonNull 15 | import com.spartons.kotlincoroutinecalladapter.util.observe 16 | import com.squareup.picasso.Picasso 17 | import kotlinx.android.synthetic.main.activity_main.* 18 | import javax.inject.Inject 19 | 20 | class MainActivity : BaseActivity() { 21 | 22 | private lateinit var movieAdapter: MovieAdapter 23 | private val movies = mutableListOf() 24 | 25 | @Inject 26 | lateinit var picasso: Picasso 27 | @Inject 28 | lateinit var viewModel: MainActivityViewModel 29 | 30 | override fun onCreate(savedInstanceState: Bundle?) { 31 | super.onCreate(savedInstanceState) 32 | setContentView(R.layout.activity_main) 33 | DaggerMainActivityComponent.builder() 34 | .mainActivityModule(MainActivityModule(this)) 35 | .appComponent(getAppComponent()) 36 | .build() 37 | .inject(this) 38 | moviesRecyclerView.layoutManager = GridLayoutManager(this, 2, GridLayoutManager.VERTICAL, false) 39 | moviesRecyclerView.setHasFixedSize(true) 40 | movieAdapter = MovieAdapter(this, movies, picasso) 41 | moviesRecyclerView.adapter = movieAdapter 42 | startListeningToNewMovies() 43 | listenToErrors() 44 | } 45 | 46 | private fun startListeningToNewMovies() { 47 | viewModel 48 | .movies 49 | .nonNull() 50 | .observe(this) { 51 | progressBar.visibility = View.GONE 52 | this.movies.addAll(it) 53 | movieAdapter.notifyDataSetChanged() 54 | } 55 | } 56 | 57 | 58 | private fun listenToErrors() { 59 | viewModel.error 60 | .nonNull() 61 | .observe(this) { 62 | progressBar.visibility = View.GONE 63 | Toast.makeText(this, it, Toast.LENGTH_SHORT).show() 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | /* AUTO-GENERATED FILE. DO NOT MODIFY. 2 | * 3 | * This class was automatically generated by the 4 | * gradle plugin from the resource data it found. It 5 | * should not be modified by hand. 6 | */ 7 | package com.google.android.gms.base; 8 | 9 | public final class R { 10 | private R() {} 11 | 12 | public static final class attr { 13 | private attr() {} 14 | 15 | public static final int buttonSize = 0x7f04005c; 16 | public static final int circleCrop = 0x7f040088; 17 | public static final int colorScheme = 0x7f0400a4; 18 | public static final int imageAspectRatio = 0x7f040134; 19 | public static final int imageAspectRatioAdjust = 0x7f040135; 20 | public static final int scopeUris = 0x7f040210; 21 | } 22 | public static final class color { 23 | private color() {} 24 | 25 | public static final int common_google_signin_btn_text_dark = 0x7f06004c; 26 | public static final int common_google_signin_btn_text_dark_default = 0x7f06004d; 27 | public static final int common_google_signin_btn_text_dark_disabled = 0x7f06004e; 28 | public static final int common_google_signin_btn_text_dark_focused = 0x7f06004f; 29 | public static final int common_google_signin_btn_text_dark_pressed = 0x7f060050; 30 | public static final int common_google_signin_btn_text_light = 0x7f060051; 31 | public static final int common_google_signin_btn_text_light_default = 0x7f060052; 32 | public static final int common_google_signin_btn_text_light_disabled = 0x7f060053; 33 | public static final int common_google_signin_btn_text_light_focused = 0x7f060054; 34 | public static final int common_google_signin_btn_text_light_pressed = 0x7f060055; 35 | public static final int common_google_signin_btn_tint = 0x7f060056; 36 | } 37 | public static final class drawable { 38 | private drawable() {} 39 | 40 | public static final int common_full_open_on_phone = 0x7f080086; 41 | public static final int common_google_signin_btn_icon_dark = 0x7f080087; 42 | public static final int common_google_signin_btn_icon_dark_focused = 0x7f080088; 43 | public static final int common_google_signin_btn_icon_dark_normal = 0x7f080089; 44 | public static final int common_google_signin_btn_icon_dark_normal_background = 0x7f08008a; 45 | public static final int common_google_signin_btn_icon_disabled = 0x7f08008b; 46 | public static final int common_google_signin_btn_icon_light = 0x7f08008c; 47 | public static final int common_google_signin_btn_icon_light_focused = 0x7f08008d; 48 | public static final int common_google_signin_btn_icon_light_normal = 0x7f08008e; 49 | public static final int common_google_signin_btn_icon_light_normal_background = 0x7f08008f; 50 | public static final int common_google_signin_btn_text_dark = 0x7f080090; 51 | public static final int common_google_signin_btn_text_dark_focused = 0x7f080091; 52 | public static final int common_google_signin_btn_text_dark_normal = 0x7f080092; 53 | public static final int common_google_signin_btn_text_dark_normal_background = 0x7f080093; 54 | public static final int common_google_signin_btn_text_disabled = 0x7f080094; 55 | public static final int common_google_signin_btn_text_light = 0x7f080095; 56 | public static final int common_google_signin_btn_text_light_focused = 0x7f080096; 57 | public static final int common_google_signin_btn_text_light_normal = 0x7f080097; 58 | public static final int common_google_signin_btn_text_light_normal_background = 0x7f080098; 59 | public static final int googleg_disabled_color_18 = 0x7f0800b0; 60 | public static final int googleg_standard_color_18 = 0x7f0800b1; 61 | } 62 | public static final class id { 63 | private id() {} 64 | 65 | public static final int adjust_height = 0x7f09002a; 66 | public static final int adjust_width = 0x7f09002b; 67 | public static final int auto = 0x7f09003c; 68 | public static final int dark = 0x7f0900a8; 69 | public static final int icon_only = 0x7f090120; 70 | public static final int light = 0x7f090137; 71 | public static final int none = 0x7f090184; 72 | public static final int standard = 0x7f090234; 73 | public static final int wide = 0x7f090285; 74 | } 75 | public static final class string { 76 | private string() {} 77 | 78 | public static final int common_google_play_services_enable_button = 0x7f100063; 79 | public static final int common_google_play_services_enable_text = 0x7f100064; 80 | public static final int common_google_play_services_enable_title = 0x7f100065; 81 | public static final int common_google_play_services_install_button = 0x7f100066; 82 | public static final int common_google_play_services_install_text = 0x7f100067; 83 | public static final int common_google_play_services_install_title = 0x7f100068; 84 | public static final int common_google_play_services_notification_channel_name = 0x7f100069; 85 | public static final int common_google_play_services_notification_ticker = 0x7f10006a; 86 | public static final int common_google_play_services_unsupported_text = 0x7f10006c; 87 | public static final int common_google_play_services_update_button = 0x7f10006d; 88 | public static final int common_google_play_services_update_ --------------------------------------------------------------------------------