From d60d3987f4d8b05532e5cb35b51677437f51c4e0 Mon Sep 17 00:00:00 2001 From: liemvo Date: Fri, 31 Aug 2018 10:50:32 +1200 Subject: [PATCH 1/7] - Update spek version --- app/build.gradle | 23 +++--- .../com/droidcba/kedditbysteps/KedditApp.kt | 2 - .../commons/extensions/Extensions.kt | 4 +- .../kedditbysteps/NewsManagerSpekTest.kt | 71 ++++++++++--------- .../droidcba/kedditbysteps/NewsManagerTest.kt | 1 + build.gradle | 1 + gradle.properties | 6 +- 7 files changed, 62 insertions(+), 46 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 2fca47c..1620705 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -5,7 +5,6 @@ apply plugin: 'kotlin-kapt' android { compileSdkVersion 27 - buildToolsVersion '27.0.3' defaultConfig { applicationId "com.droidcba.kedditbysteps" @@ -31,11 +30,13 @@ android { dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) - implementation 'com.android.support:appcompat-v7:27.1.1' - implementation 'com.android.support:design:27.1.1' + implementation 'com.android.support:appcompat-v7:27.1.0' + implementation 'com.android.support.constraint:constraint-layout:1.1.2' + implementation 'com.android.support:recyclerview-v7:27.1.0' + implementation 'com.android.support:design:27.1.0' implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" - implementation 'com.squareup.picasso:picasso:2.5.2' + implementation 'com.squareup.picasso:picasso:2.71828' // Retrofit @@ -43,21 +44,25 @@ dependencies { implementation 'com.squareup.retrofit2:converter-moshi:2.0.0' // Dagger 2 - implementation 'com.google.dagger:dagger:2.11' - kapt 'com.google.dagger:dagger-compiler:2.11' + implementation "com.google.dagger:dagger:$dagger2Version" + kapt "com.google.dagger:dagger-compiler:$dagger2Version" compileOnly 'org.glassfish:javax.annotation:10.0-b28' // Coroutines - implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:0.23.0" - implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:0.23.0" + implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:0.24.0" + implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:0.24.0" // Coroutines - Retrofit extention implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-experimental-adapter:1.0.0' // Tests testImplementation 'junit:junit:4.12' testImplementation 'com.nhaarman.mockitokotlin2:mockito-kotlin:2.0.0-alpha04' - testImplementation 'org.jetbrains.spek:spek:1.0.25' + testImplementation "org.jetbrains.spek:spek-api:$spekVersion" + testImplementation "org.jetbrains.spek:spek-junit-platform-engine:$spekVersion" + testImplementation "org.junit.platform:junit-platform-runner:$junitPlatformVersion" + testImplementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" + implementation "org.jetbrains.kotlin:kotlin-test:1.2.51" } repositories { mavenCentral() diff --git a/app/src/main/java/com/droidcba/kedditbysteps/KedditApp.kt b/app/src/main/java/com/droidcba/kedditbysteps/KedditApp.kt index 2ab6bad..74a5d07 100644 --- a/app/src/main/java/com/droidcba/kedditbysteps/KedditApp.kt +++ b/app/src/main/java/com/droidcba/kedditbysteps/KedditApp.kt @@ -18,8 +18,6 @@ class KedditApp : Application() { override fun onCreate() { super.onCreate() newsComponent = DaggerNewsComponent.builder() - .appModule(AppModule(this)) - //.newsModule(NewsModule()) Module with empty constructor is implicitly created by dagger. .build() } } \ No newline at end of file diff --git a/app/src/main/java/com/droidcba/kedditbysteps/commons/extensions/Extensions.kt b/app/src/main/java/com/droidcba/kedditbysteps/commons/extensions/Extensions.kt index 10d9bc7..7bb48ac 100644 --- a/app/src/main/java/com/droidcba/kedditbysteps/commons/extensions/Extensions.kt +++ b/app/src/main/java/com/droidcba/kedditbysteps/commons/extensions/Extensions.kt @@ -17,9 +17,9 @@ fun ViewGroup.inflate(layoutId: Int, attachToRoot: Boolean = false): View { fun ImageView.loadImg(imageUrl: String) { if (TextUtils.isEmpty(imageUrl)) { - Picasso.with(context).load(R.mipmap.ic_launcher).into(this) + Picasso.get().load(R.mipmap.ic_launcher).into(this) } else { - Picasso.with(context).load(imageUrl).into(this) + Picasso.get().load(imageUrl).into(this) } } diff --git a/app/src/test/java/com/droidcba/kedditbysteps/NewsManagerSpekTest.kt b/app/src/test/java/com/droidcba/kedditbysteps/NewsManagerSpekTest.kt index eb7faa7..cd93207 100644 --- a/app/src/test/java/com/droidcba/kedditbysteps/NewsManagerSpekTest.kt +++ b/app/src/test/java/com/droidcba/kedditbysteps/NewsManagerSpekTest.kt @@ -7,42 +7,50 @@ import com.nhaarman.mockitokotlin2.any import com.nhaarman.mockitokotlin2.doAnswer import com.nhaarman.mockitokotlin2.doReturn import com.nhaarman.mockitokotlin2.mock +import junit.framework.Assert.assertNotNull import kotlinx.coroutines.experimental.runBlocking import org.jetbrains.spek.api.Spek +import org.jetbrains.spek.api.dsl.given +import org.jetbrains.spek.api.dsl.it +import org.jetbrains.spek.api.dsl.on +import org.junit.platform.runner.JUnitPlatform +import org.junit.runner.RunWith import java.util.* import kotlin.test.assertFailsWith -import kotlin.test.assertNotNull /** * Unit Tests for NewsManager using Spek * * @author juancho. + * @update liemvo */ + +@RunWith(JUnitPlatform::class) class NewsManagerSpekTest : Spek({ given("a NewsManager") { var redditNews: RedditNews? = null var apiMock: NewsAPI - beforeEach { + beforeEachTest { redditNews = null } on("service returns something") { - beforeEach { - // prepare - val redditNewsResponse = RedditNewsResponse(RedditDataResponse(listOf(), null, null)) - apiMock = mock { - onBlocking { getNews(any(), any()) } doReturn redditNewsResponse - } - // call - val newsManager = NewsManager(apiMock) - runBlocking { - redditNews = newsManager.getNews("") - } + // prepare + val redditNewsResponse = RedditNewsResponse(RedditDataResponse(listOf(), null, null)) + apiMock = mock { + onBlocking { getNews(any(), any()) } doReturn redditNewsResponse } + // call + val newsManager = NewsManager(apiMock) + runBlocking { + redditNews = newsManager.getNews("") + } + + it("should receive something and no errors") { assertNotNull(redditNews) } @@ -57,20 +65,20 @@ class NewsManagerSpekTest : Spek({ "thumbnail", "url" ) - beforeEach { - // prepare - val newsResponse = RedditChildrenResponse(newsData) - val redditNewsResponse = RedditNewsResponse(RedditDataResponse(listOf(newsResponse), null, null)) - apiMock = mock { - onBlocking { getNews(any(), any()) } doReturn redditNewsResponse - } - // call - val newsManager = NewsManager(apiMock) - runBlocking { - redditNews = newsManager.getNews("") - } + + // prepare + val newsResponse = RedditChildrenResponse(newsData) + val redditNewsResponse = RedditNewsResponse(RedditDataResponse(listOf(newsResponse), null, null)) + apiMock = mock { + onBlocking { getNews(any(), any()) } doReturn redditNewsResponse + } + // call + val newsManager = NewsManager(apiMock) + runBlocking { + redditNews = newsManager.getNews("") } + it("should process only one news successfully") { assertNotNull(redditNews) assert(redditNews!!.news[0].author == newsData.author) @@ -81,16 +89,15 @@ class NewsManagerSpekTest : Spek({ on("service returns a 500 error") { var newsManager: NewsManager? = null - beforeEach { - // prepare - apiMock = mock { - onBlocking { getNews(any(), any()) } doAnswer { throw Throwable() } - } - // call - newsManager = NewsManager(apiMock) + // prepare + apiMock = mock { + onBlocking { getNews(any(), any()) } doAnswer { throw Throwable() } } + // call + newsManager = NewsManager(apiMock) + it("should receive an exception") { assertFailsWith { runBlocking { diff --git a/app/src/test/java/com/droidcba/kedditbysteps/NewsManagerTest.kt b/app/src/test/java/com/droidcba/kedditbysteps/NewsManagerTest.kt index 54e7ddf..7b38881 100644 --- a/app/src/test/java/com/droidcba/kedditbysteps/NewsManagerTest.kt +++ b/app/src/test/java/com/droidcba/kedditbysteps/NewsManagerTest.kt @@ -39,6 +39,7 @@ class NewsManagerTest { // assert assertNotNull(redditNews) + assert(redditNews.news.count() > 0) } @Test diff --git a/build.gradle b/build.gradle index 1a6b93a..458e007 100644 --- a/build.gradle +++ b/build.gradle @@ -5,6 +5,7 @@ buildscript { repositories { jcenter() google() + maven { url "http://dl.bintray.com/jetbrains/spek" } } dependencies { classpath 'com.android.tools.build:gradle:3.1.3' diff --git a/gradle.properties b/gradle.properties index e810bad..4a118d5 100644 --- a/gradle.properties +++ b/gradle.properties @@ -19,4 +19,8 @@ # Kotlin kotlin.incremental=true -kotlin.coroutines=enable \ No newline at end of file +kotlin.coroutines=enable + +spekVersion=1.2.0 +junitPlatformVersion=1.0.1 +dagger2Version=2.17 \ No newline at end of file From 6525022a4b47c586b38082dc5f5b3cbbd86c5277 Mon Sep 17 00:00:00 2001 From: Liem Vo Date: Fri, 31 May 2019 16:19:07 +1200 Subject: [PATCH 2/7] WIP: Update to date library - Android build - Constraint Layout - Coroutines - Retrofit --- app/build.gradle | 22 ++++++++-------- .../droidcba/kedditbysteps/api/RedditApi.kt | 2 +- .../kedditbysteps/commons/RxBaseFragment.kt | 25 +++++++++++-------- .../features/news/NewsFragment.kt | 13 +++++----- .../features/news/adapter/NewsAdapter.kt | 4 +-- .../kedditbysteps/NewsManagerSpekTest.kt | 2 +- .../droidcba/kedditbysteps/NewsManagerTest.kt | 6 ++--- build.gradle | 4 +-- gradle/wrapper/gradle-wrapper.properties | 4 +-- 9 files changed, 44 insertions(+), 38 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 1620705..ca8afbe 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -4,12 +4,12 @@ apply plugin: 'kotlin-android-extensions' apply plugin: 'kotlin-kapt' android { - compileSdkVersion 27 + compileSdkVersion 28 defaultConfig { applicationId "com.droidcba.kedditbysteps" minSdkVersion 16 - targetSdkVersion 27 + targetSdkVersion 28 versionCode 1 versionName "1.0" } @@ -30,18 +30,18 @@ android { dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) - implementation 'com.android.support:appcompat-v7:27.1.0' - implementation 'com.android.support.constraint:constraint-layout:1.1.2' - implementation 'com.android.support:recyclerview-v7:27.1.0' - implementation 'com.android.support:design:27.1.0' + implementation 'com.android.support:appcompat-v7:28.0.0' + implementation 'com.android.support.constraint:constraint-layout:1.1.3' + implementation 'com.android.support:recyclerview-v7:28.0.0' + implementation 'com.android.support:design:28.0.0' implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" implementation 'com.squareup.picasso:picasso:2.71828' // Retrofit - implementation 'com.squareup.retrofit2:retrofit:2.4.0' - implementation 'com.squareup.retrofit2:converter-moshi:2.0.0' + implementation 'com.squareup.retrofit2:retrofit:2.5.0' + implementation 'com.squareup.retrofit2:converter-moshi:2.5.0' // Dagger 2 implementation "com.google.dagger:dagger:$dagger2Version" @@ -49,14 +49,14 @@ dependencies { compileOnly 'org.glassfish:javax.annotation:10.0-b28' // Coroutines - implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:0.24.0" - implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:0.24.0" + implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.2.1" + implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.2.1" // Coroutines - Retrofit extention implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-experimental-adapter:1.0.0' // Tests testImplementation 'junit:junit:4.12' - testImplementation 'com.nhaarman.mockitokotlin2:mockito-kotlin:2.0.0-alpha04' + testImplementation 'com.nhaarman.mockitokotlin2:mockito-kotlin:2.1.0' testImplementation "org.jetbrains.spek:spek-api:$spekVersion" testImplementation "org.jetbrains.spek:spek-junit-platform-engine:$spekVersion" testImplementation "org.junit.platform:junit-platform-runner:$junitPlatformVersion" diff --git a/app/src/main/java/com/droidcba/kedditbysteps/api/RedditApi.kt b/app/src/main/java/com/droidcba/kedditbysteps/api/RedditApi.kt index 88714ed..aaffd33 100644 --- a/app/src/main/java/com/droidcba/kedditbysteps/api/RedditApi.kt +++ b/app/src/main/java/com/droidcba/kedditbysteps/api/RedditApi.kt @@ -1,6 +1,6 @@ package com.droidcba.kedditbysteps.api -import kotlinx.coroutines.experimental.Deferred +import kotlinx.coroutines.Deferred import retrofit2.Call import retrofit2.http.GET import retrofit2.http.Query diff --git a/app/src/main/java/com/droidcba/kedditbysteps/commons/RxBaseFragment.kt b/app/src/main/java/com/droidcba/kedditbysteps/commons/RxBaseFragment.kt index 11507f9..24f06c5 100644 --- a/app/src/main/java/com/droidcba/kedditbysteps/commons/RxBaseFragment.kt +++ b/app/src/main/java/com/droidcba/kedditbysteps/commons/RxBaseFragment.kt @@ -1,20 +1,25 @@ package com.droidcba.kedditbysteps.commons +import android.os.Bundle import android.support.v4.app.Fragment -import kotlinx.coroutines.experimental.Job +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import kotlin.coroutines.CoroutineContext -open class RxBaseFragment : Fragment() { +open class RxBaseFragment : Fragment(), CoroutineScope { + override val coroutineContext: CoroutineContext + get() = job + Dispatchers.Main - protected var job: Job? = null + protected lateinit var job: Job - override fun onResume() { - super.onResume() - job = null + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + job = Job() } - override fun onPause() { - super.onPause() - job?.cancel() - job = null + override fun onDestroy() { + job.cancel() + super.onDestroy() } } \ No newline at end of file diff --git a/app/src/main/java/com/droidcba/kedditbysteps/features/news/NewsFragment.kt b/app/src/main/java/com/droidcba/kedditbysteps/features/news/NewsFragment.kt index e9aad8c..faba57c 100644 --- a/app/src/main/java/com/droidcba/kedditbysteps/features/news/NewsFragment.kt +++ b/app/src/main/java/com/droidcba/kedditbysteps/features/news/NewsFragment.kt @@ -18,8 +18,8 @@ import com.droidcba.kedditbysteps.commons.extensions.inflate import com.droidcba.kedditbysteps.features.news.adapter.NewsAdapter import com.droidcba.kedditbysteps.features.news.adapter.NewsDelegateAdapter import kotlinx.android.synthetic.main.news_fragment.* -import kotlinx.coroutines.experimental.android.UI -import kotlinx.coroutines.experimental.launch +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch import javax.inject.Inject class NewsFragment : RxBaseFragment(), NewsDelegateAdapter.onViewSelectedListener { @@ -38,7 +38,8 @@ class NewsFragment : RxBaseFragment(), NewsDelegateAdapter.onViewSelectedListene private val KEY_REDDIT_NEWS = "redditNews" } - @Inject lateinit var newsManager: NewsManager + @Inject + lateinit var newsManager: NewsManager private var redditNews: RedditNews? = null private val newsAdapter by androidLazy { NewsAdapter(this) } @@ -86,7 +87,7 @@ class NewsFragment : RxBaseFragment(), NewsDelegateAdapter.onViewSelectedListene * Next time we will have redditNews set with the next page to * navigate with the 'after' param. */ - job = launch(UI) { + launch { try { val retrievedNews = newsManager.getNews(redditNews?.after.orEmpty()) redditNews = retrievedNews @@ -94,8 +95,8 @@ class NewsFragment : RxBaseFragment(), NewsDelegateAdapter.onViewSelectedListene } catch (e: Throwable) { if (isVisible) { Snackbar.make(news_list, e.message.orEmpty(), Snackbar.LENGTH_INDEFINITE) - .setAction("RETRY") { requestNews() } - .show() + .setAction("RETRY") { requestNews() } + .show() } } } diff --git a/app/src/main/java/com/droidcba/kedditbysteps/features/news/adapter/NewsAdapter.kt b/app/src/main/java/com/droidcba/kedditbysteps/features/news/adapter/NewsAdapter.kt index c7f7685..fbc8d1a 100644 --- a/app/src/main/java/com/droidcba/kedditbysteps/features/news/adapter/NewsAdapter.kt +++ b/app/src/main/java/com/droidcba/kedditbysteps/features/news/adapter/NewsAdapter.kt @@ -27,11 +27,11 @@ class NewsAdapter(listener: NewsDelegateAdapter.onViewSelectedListener) : Recycl override fun getItemCount(): Int = items.size override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = - delegateAdapters.get(viewType).onCreateViewHolder(parent) + delegateAdapters.get(viewType)!!.onCreateViewHolder(parent) override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { - delegateAdapters.get(getItemViewType(position)).onBindViewHolder(holder, items[position]) + delegateAdapters.get(getItemViewType(position))!!.onBindViewHolder(holder, items[position]) } override fun getItemViewType(position: Int) = items[position].getViewType() diff --git a/app/src/test/java/com/droidcba/kedditbysteps/NewsManagerSpekTest.kt b/app/src/test/java/com/droidcba/kedditbysteps/NewsManagerSpekTest.kt index cd93207..4925908 100644 --- a/app/src/test/java/com/droidcba/kedditbysteps/NewsManagerSpekTest.kt +++ b/app/src/test/java/com/droidcba/kedditbysteps/NewsManagerSpekTest.kt @@ -8,7 +8,7 @@ import com.nhaarman.mockitokotlin2.doAnswer import com.nhaarman.mockitokotlin2.doReturn import com.nhaarman.mockitokotlin2.mock import junit.framework.Assert.assertNotNull -import kotlinx.coroutines.experimental.runBlocking +import kotlinx.coroutines.runBlocking import org.jetbrains.spek.api.Spek import org.jetbrains.spek.api.dsl.given import org.jetbrains.spek.api.dsl.it diff --git a/app/src/test/java/com/droidcba/kedditbysteps/NewsManagerTest.kt b/app/src/test/java/com/droidcba/kedditbysteps/NewsManagerTest.kt index 7b38881..e7eee00 100644 --- a/app/src/test/java/com/droidcba/kedditbysteps/NewsManagerTest.kt +++ b/app/src/test/java/com/droidcba/kedditbysteps/NewsManagerTest.kt @@ -6,9 +6,9 @@ package com.droidcba.kedditbysteps import com.droidcba.kedditbysteps.api.* import com.droidcba.kedditbysteps.features.news.NewsManager import com.nhaarman.mockitokotlin2.* -import kotlinx.coroutines.experimental.CoroutineScope -import kotlinx.coroutines.experimental.Unconfined -import kotlinx.coroutines.experimental.runBlocking +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers.Unconfined +import kotlinx.coroutines.runBlocking import org.junit.Test import java.util.* import kotlin.test.assertEquals diff --git a/build.gradle b/build.gradle index 458e007..2cbaa9f 100644 --- a/build.gradle +++ b/build.gradle @@ -1,14 +1,14 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - ext.kotlin_version = '1.2.41' + ext.kotlin_version = '1.3.31' repositories { jcenter() google() maven { url "http://dl.bintray.com/jetbrains/spek" } } dependencies { - classpath 'com.android.tools.build:gradle:3.1.3' + classpath 'com.android.tools.build:gradle:3.4.1' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // NOTE: Do not place your application dependencies here; they belong diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 63b97f1..547b3d4 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Fri Jun 08 17:01:54 EDT 2018 +#Fri May 31 15:51:31 NZST 2019 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip From 9919b340252fa1a9aa6f7d7396c77abf64da3933 Mon Sep 17 00:00:00 2001 From: Vo Nguyen Date: Sat, 1 Jun 2019 21:47:19 +1200 Subject: [PATCH 3/7] Done --- app/build.gradle | 2 +- .../java/com/droidcba/kedditbysteps/di/NetworkModule.kt | 2 +- .../droidcba/kedditbysteps/features/news/NewsFragment.kt | 7 +++++-- .../java/com/droidcba/kedditbysteps/NewsManagerTest.kt | 1 - 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index ca8afbe..d24d81b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -52,7 +52,7 @@ dependencies { implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.2.1" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.2.1" // Coroutines - Retrofit extention - implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-experimental-adapter:1.0.0' + implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2' // Tests testImplementation 'junit:junit:4.12' diff --git a/app/src/main/java/com/droidcba/kedditbysteps/di/NetworkModule.kt b/app/src/main/java/com/droidcba/kedditbysteps/di/NetworkModule.kt index 0ca116f..111a8f3 100644 --- a/app/src/main/java/com/droidcba/kedditbysteps/di/NetworkModule.kt +++ b/app/src/main/java/com/droidcba/kedditbysteps/di/NetworkModule.kt @@ -1,6 +1,6 @@ package com.droidcba.kedditbysteps.di -import com.jakewharton.retrofit2.adapter.kotlin.coroutines.experimental.CoroutineCallAdapterFactory +import com.jakewharton.retrofit2.adapter.kotlin.coroutines.CoroutineCallAdapterFactory import dagger.Module import dagger.Provides import retrofit2.Retrofit diff --git a/app/src/main/java/com/droidcba/kedditbysteps/features/news/NewsFragment.kt b/app/src/main/java/com/droidcba/kedditbysteps/features/news/NewsFragment.kt index faba57c..cd77c6d 100644 --- a/app/src/main/java/com/droidcba/kedditbysteps/features/news/NewsFragment.kt +++ b/app/src/main/java/com/droidcba/kedditbysteps/features/news/NewsFragment.kt @@ -20,6 +20,7 @@ import com.droidcba.kedditbysteps.features.news.adapter.NewsDelegateAdapter import kotlinx.android.synthetic.main.news_fragment.* import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import javax.inject.Inject class NewsFragment : RxBaseFragment(), NewsDelegateAdapter.onViewSelectedListener { @@ -87,11 +88,13 @@ class NewsFragment : RxBaseFragment(), NewsDelegateAdapter.onViewSelectedListene * Next time we will have redditNews set with the next page to * navigate with the 'after' param. */ - launch { + launch(Dispatchers.IO) { try { val retrievedNews = newsManager.getNews(redditNews?.after.orEmpty()) redditNews = retrievedNews - newsAdapter.addNews(retrievedNews.news) + withContext(Dispatchers.Main) { + newsAdapter.addNews(retrievedNews.news) + } } catch (e: Throwable) { if (isVisible) { Snackbar.make(news_list, e.message.orEmpty(), Snackbar.LENGTH_INDEFINITE) diff --git a/app/src/test/java/com/droidcba/kedditbysteps/NewsManagerTest.kt b/app/src/test/java/com/droidcba/kedditbysteps/NewsManagerTest.kt index e7eee00..e7af8fd 100644 --- a/app/src/test/java/com/droidcba/kedditbysteps/NewsManagerTest.kt +++ b/app/src/test/java/com/droidcba/kedditbysteps/NewsManagerTest.kt @@ -39,7 +39,6 @@ class NewsManagerTest { // assert assertNotNull(redditNews) - assert(redditNews.news.count() > 0) } @Test From 363a69b34223552c98b11235bff746214d92dec1 Mon Sep 17 00:00:00 2001 From: Liem Vo Date: Thu, 25 Jul 2019 16:31:12 +1200 Subject: [PATCH 4/7] Migrate to Androidx Reformat code --- app/build.gradle | 20 +++--- .../com/droidcba/kedditbysteps/KedditApp.kt | 5 -- .../droidcba/kedditbysteps/MainActivity.kt | 14 ++--- .../com/droidcba/kedditbysteps/api/NewsAPI.kt | 5 -- .../droidcba/kedditbysteps/api/NewsRestAPI.kt | 1 - .../commons/InfiniteScrollListener.kt | 13 ++-- .../droidcba/kedditbysteps/commons/Models.kt | 63 ++++--------------- .../kedditbysteps/commons/RxBaseFragment.kt | 4 +- .../commons/adapter/AdapterConstants.kt | 2 +- .../kedditbysteps/commons/adapter/ViewType.kt | 2 +- .../adapter/ViewTypeDelegateAdapter.kt | 9 +-- .../commons/extensions/Extensions.kt | 3 +- .../commons/extensions/TimeExt.kt | 2 +- .../droidcba/kedditbysteps/di/AppModule.kt | 4 -- .../kedditbysteps/di/NetworkModule.kt | 4 -- .../kedditbysteps/di/news/NewsComponent.kt | 14 ++--- .../kedditbysteps/di/news/NewsModule.kt | 8 --- .../features/news/NewsFragment.kt | 6 +- .../features/news/NewsManager.kt | 5 -- .../news/adapter/LoadingDelegateAdapter.kt | 11 ++-- .../features/news/adapter/NewsAdapter.kt | 10 +-- .../news/adapter/NewsDelegateAdapter.kt | 8 +-- app/src/main/res/layout/activity_main.xml | 10 +-- app/src/main/res/layout/news_fragment.xml | 2 +- build.gradle | 2 +- gradle.properties | 4 +- 26 files changed, 78 insertions(+), 153 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index d24d81b..0528d2a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -26,18 +26,24 @@ android { packagingOptions { exclude 'META-INF/main.kotlin_module' } + + androidExtensions { + experimental = true + } } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) - implementation 'com.android.support:appcompat-v7:28.0.0' - implementation 'com.android.support.constraint:constraint-layout:1.1.3' - implementation 'com.android.support:recyclerview-v7:28.0.0' - implementation 'com.android.support:design:28.0.0' + implementation 'androidx.appcompat:appcompat:1.0.2' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + implementation 'androidx.recyclerview:recyclerview:1.0.0' + implementation 'com.google.android.material:material:1.0.0' implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" - implementation 'com.squareup.picasso:picasso:2.71828' + def nav_version_ktx = "2.1.0-beta02" + implementation "androidx.navigation:navigation-fragment-ktx:$nav_version_ktx" + implementation "androidx.navigation:navigation-ui-ktx:$nav_version_ktx" // Retrofit implementation 'com.squareup.retrofit2:retrofit:2.5.0' @@ -49,8 +55,8 @@ dependencies { compileOnly 'org.glassfish:javax.annotation:10.0-b28' // Coroutines - implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.2.1" - implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.2.1" + implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.2.2" + implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.2.2" // Coroutines - Retrofit extention implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2' diff --git a/app/src/main/java/com/droidcba/kedditbysteps/KedditApp.kt b/app/src/main/java/com/droidcba/kedditbysteps/KedditApp.kt index 74a5d07..19e52c2 100644 --- a/app/src/main/java/com/droidcba/kedditbysteps/KedditApp.kt +++ b/app/src/main/java/com/droidcba/kedditbysteps/KedditApp.kt @@ -4,11 +4,6 @@ import android.app.Application import com.droidcba.kedditbysteps.di.AppModule import com.droidcba.kedditbysteps.di.news.DaggerNewsComponent import com.droidcba.kedditbysteps.di.news.NewsComponent - -/** - * - * @author juancho. - */ class KedditApp : Application() { companion object { diff --git a/app/src/main/java/com/droidcba/kedditbysteps/MainActivity.kt b/app/src/main/java/com/droidcba/kedditbysteps/MainActivity.kt index b22dcf1..96ac233 100644 --- a/app/src/main/java/com/droidcba/kedditbysteps/MainActivity.kt +++ b/app/src/main/java/com/droidcba/kedditbysteps/MainActivity.kt @@ -1,10 +1,10 @@ package com.droidcba.kedditbysteps import android.os.Bundle -import android.support.v4.app.Fragment -import android.support.v4.app.FragmentManager -import android.support.v7.app.AppCompatActivity -import android.support.v7.widget.Toolbar +import androidx.fragment.app.Fragment +import androidx.fragment.app.FragmentManager +import androidx.appcompat.app.AppCompatActivity +import androidx.appcompat.widget.Toolbar import com.droidcba.kedditbysteps.features.news.NewsFragment class MainActivity : AppCompatActivity() { @@ -20,7 +20,7 @@ class MainActivity : AppCompatActivity() { } } - fun changeFragment(f: Fragment, cleanStack: Boolean = false) { + private fun changeFragment(f: Fragment, cleanStack: Boolean = false) { val ft = supportFragmentManager.beginTransaction() if (cleanStack) { clearBackStack() @@ -32,11 +32,11 @@ class MainActivity : AppCompatActivity() { ft.commit() } - fun clearBackStack() { + private fun clearBackStack() { val manager = supportFragmentManager if (manager.backStackEntryCount > 0) { val first = manager.getBackStackEntryAt(0) - manager.popBackStack(first.id, FragmentManager.POP_BACK_STACK_INCLUSIVE) + manager.popBackStack(first.id, androidx.fragment.app.FragmentManager.POP_BACK_STACK_INCLUSIVE) } } diff --git a/app/src/main/java/com/droidcba/kedditbysteps/api/NewsAPI.kt b/app/src/main/java/com/droidcba/kedditbysteps/api/NewsAPI.kt index b4ad82a..6372a37 100644 --- a/app/src/main/java/com/droidcba/kedditbysteps/api/NewsAPI.kt +++ b/app/src/main/java/com/droidcba/kedditbysteps/api/NewsAPI.kt @@ -2,11 +2,6 @@ package com.droidcba.kedditbysteps.api import retrofit2.Call -/** - * News API - * - * @author juancho. - */ interface NewsAPI { fun getNewsOldApi(after: String, limit: String): Call suspend fun getNews(after: String, limit: String): RedditNewsResponse diff --git a/app/src/main/java/com/droidcba/kedditbysteps/api/NewsRestAPI.kt b/app/src/main/java/com/droidcba/kedditbysteps/api/NewsRestAPI.kt index b206f8d..1facb25 100644 --- a/app/src/main/java/com/droidcba/kedditbysteps/api/NewsRestAPI.kt +++ b/app/src/main/java/com/droidcba/kedditbysteps/api/NewsRestAPI.kt @@ -4,7 +4,6 @@ import retrofit2.Call import javax.inject.Inject class NewsRestAPI @Inject constructor(private val redditApi: RedditApi) : NewsAPI { - override suspend fun getNews(after: String, limit: String): RedditNewsResponse { return redditApi.getDeferredTop(after, limit).await() } diff --git a/app/src/main/java/com/droidcba/kedditbysteps/commons/InfiniteScrollListener.kt b/app/src/main/java/com/droidcba/kedditbysteps/commons/InfiniteScrollListener.kt index 63dc3d6..a0681ce 100644 --- a/app/src/main/java/com/droidcba/kedditbysteps/commons/InfiniteScrollListener.kt +++ b/app/src/main/java/com/droidcba/kedditbysteps/commons/InfiniteScrollListener.kt @@ -1,12 +1,12 @@ package com.droidcba.kedditbysteps.commons -import android.support.v7.widget.LinearLayoutManager -import android.support.v7.widget.RecyclerView import android.util.Log +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView class InfiniteScrollListener( - val func: () -> Unit, - val layoutManager: LinearLayoutManager) : RecyclerView.OnScrollListener() { + val func: () -> Unit, + private val layoutManager: LinearLayoutManager) : RecyclerView.OnScrollListener() { private var previousTotal = 0 private var loading = true @@ -30,7 +30,7 @@ class InfiniteScrollListener( } } if (!loading && (totalItemCount - visibleItemCount) - <= (firstVisibleItem + visibleThreshold)) { + <= (firstVisibleItem + visibleThreshold)) { // End has been reached Log.i("InfiniteScrollListener", "End reached") func() @@ -38,5 +38,4 @@ class InfiniteScrollListener( } } } - -} \ No newline at end of file +} diff --git a/app/src/main/java/com/droidcba/kedditbysteps/commons/Models.kt b/app/src/main/java/com/droidcba/kedditbysteps/commons/Models.kt index 2dfa151..9b2f4f0 100644 --- a/app/src/main/java/com/droidcba/kedditbysteps/commons/Models.kt +++ b/app/src/main/java/com/droidcba/kedditbysteps/commons/Models.kt @@ -1,61 +1,24 @@ package com.droidcba.kedditbysteps.commons -import android.os.Parcel import android.os.Parcelable import com.droidcba.kedditbysteps.commons.adapter.AdapterConstants import com.droidcba.kedditbysteps.commons.adapter.ViewType +import kotlinx.android.parcel.Parcelize +@Parcelize data class RedditNews( - val after: String, - val before: String, - val news: List) : Parcelable { - companion object { - @Suppress("unused") - @JvmField val CREATOR: Parcelable.Creator = object : Parcelable.Creator { - override fun createFromParcel(source: Parcel): RedditNews = RedditNews(source) - override fun newArray(size: Int): Array = arrayOfNulls(size) - } - } - - constructor(source: Parcel) : this(source.readString(), source.readString(), source.createTypedArrayList(RedditNewsItem.CREATOR)) - - override fun describeContents() = 0 - - override fun writeToParcel(dest: Parcel?, flags: Int) { - dest?.writeString(after) - dest?.writeString(before) - dest?.writeTypedList(news) - } -} + val after: String, + val before: String, + val news: List) : Parcelable +@Parcelize data class RedditNewsItem( - val author: String, - val title: String, - val numComments: Int, - val created: Long, - val thumbnail: String, - val url: String? + val author: String, + val title: String, + val numComments: Int, + val created: Long, + val thumbnail: String, + val url: String? ) : ViewType, Parcelable { - override fun getViewType() = AdapterConstants.NEWS - - companion object { - @JvmField val CREATOR: Parcelable.Creator = object : Parcelable.Creator { - override fun createFromParcel(source: Parcel): RedditNewsItem = RedditNewsItem(source) - override fun newArray(size: Int): Array = arrayOfNulls(size) - } - } - - constructor(source: Parcel) : this(source.readString(), source.readString(), source.readInt(), source.readLong(), source.readString(), source.readString()) - - override fun describeContents() = 0 - - override fun writeToParcel(dest: Parcel?, flags: Int) { - dest?.writeString(author) - dest?.writeString(title) - dest?.writeInt(numComments) - dest?.writeLong(created) - dest?.writeString(thumbnail) - dest?.writeString(url) - } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/droidcba/kedditbysteps/commons/RxBaseFragment.kt b/app/src/main/java/com/droidcba/kedditbysteps/commons/RxBaseFragment.kt index 24f06c5..bf9ea0b 100644 --- a/app/src/main/java/com/droidcba/kedditbysteps/commons/RxBaseFragment.kt +++ b/app/src/main/java/com/droidcba/kedditbysteps/commons/RxBaseFragment.kt @@ -1,13 +1,13 @@ package com.droidcba.kedditbysteps.commons import android.os.Bundle -import android.support.v4.app.Fragment +import androidx.fragment.app.Fragment import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job import kotlin.coroutines.CoroutineContext -open class RxBaseFragment : Fragment(), CoroutineScope { +open class RxBaseFragment : androidx.fragment.app.Fragment(), CoroutineScope { override val coroutineContext: CoroutineContext get() = job + Dispatchers.Main diff --git a/app/src/main/java/com/droidcba/kedditbysteps/commons/adapter/AdapterConstants.kt b/app/src/main/java/com/droidcba/kedditbysteps/commons/adapter/AdapterConstants.kt index c171452..7d8757a 100644 --- a/app/src/main/java/com/droidcba/kedditbysteps/commons/adapter/AdapterConstants.kt +++ b/app/src/main/java/com/droidcba/kedditbysteps/commons/adapter/AdapterConstants.kt @@ -3,4 +3,4 @@ package com.droidcba.kedditbysteps.commons.adapter object AdapterConstants { val NEWS = 1 val LOADING = 2 -} \ No newline at end of file +} diff --git a/app/src/main/java/com/droidcba/kedditbysteps/commons/adapter/ViewType.kt b/app/src/main/java/com/droidcba/kedditbysteps/commons/adapter/ViewType.kt index c67d66a..f175147 100644 --- a/app/src/main/java/com/droidcba/kedditbysteps/commons/adapter/ViewType.kt +++ b/app/src/main/java/com/droidcba/kedditbysteps/commons/adapter/ViewType.kt @@ -2,4 +2,4 @@ package com.droidcba.kedditbysteps.commons.adapter interface ViewType { fun getViewType(): Int -} \ No newline at end of file +} diff --git a/app/src/main/java/com/droidcba/kedditbysteps/commons/adapter/ViewTypeDelegateAdapter.kt b/app/src/main/java/com/droidcba/kedditbysteps/commons/adapter/ViewTypeDelegateAdapter.kt index 2467ea7..fe1bf9e 100644 --- a/app/src/main/java/com/droidcba/kedditbysteps/commons/adapter/ViewTypeDelegateAdapter.kt +++ b/app/src/main/java/com/droidcba/kedditbysteps/commons/adapter/ViewTypeDelegateAdapter.kt @@ -1,11 +1,8 @@ package com.droidcba.kedditbysteps.commons.adapter -import android.support.v7.widget.RecyclerView import android.view.ViewGroup interface ViewTypeDelegateAdapter { - - fun onCreateViewHolder(parent: ViewGroup): RecyclerView.ViewHolder - - fun onBindViewHolder(holder: RecyclerView.ViewHolder, item: ViewType) -} \ No newline at end of file + fun onCreateViewHolder(parent: ViewGroup): androidx.recyclerview.widget.RecyclerView.ViewHolder + fun onBindViewHolder(holder: androidx.recyclerview.widget.RecyclerView.ViewHolder, item: ViewType) +} diff --git a/app/src/main/java/com/droidcba/kedditbysteps/commons/extensions/Extensions.kt b/app/src/main/java/com/droidcba/kedditbysteps/commons/extensions/Extensions.kt index 7bb48ac..831348c 100644 --- a/app/src/main/java/com/droidcba/kedditbysteps/commons/extensions/Extensions.kt +++ b/app/src/main/java/com/droidcba/kedditbysteps/commons/extensions/Extensions.kt @@ -10,7 +10,6 @@ import android.widget.ImageView import com.droidcba.kedditbysteps.R import com.squareup.picasso.Picasso - fun ViewGroup.inflate(layoutId: Int, attachToRoot: Boolean = false): View { return LayoutInflater.from(context).inflate(layoutId, this, attachToRoot) } @@ -23,4 +22,4 @@ fun ImageView.loadImg(imageUrl: String) { } } -fun androidLazy(initializer: () -> T) : Lazy = lazy(LazyThreadSafetyMode.NONE, initializer) \ No newline at end of file +fun androidLazy(initializer: () -> T) : Lazy = lazy(LazyThreadSafetyMode.NONE, initializer) diff --git a/app/src/main/java/com/droidcba/kedditbysteps/commons/extensions/TimeExt.kt b/app/src/main/java/com/droidcba/kedditbysteps/commons/extensions/TimeExt.kt index dd75b50..a15ebae 100644 --- a/app/src/main/java/com/droidcba/kedditbysteps/commons/extensions/TimeExt.kt +++ b/app/src/main/java/com/droidcba/kedditbysteps/commons/extensions/TimeExt.kt @@ -90,4 +90,4 @@ fun Long.getFriendlyTime(): String { sb.append(" ago") return sb.toString() -} \ No newline at end of file +} diff --git a/app/src/main/java/com/droidcba/kedditbysteps/di/AppModule.kt b/app/src/main/java/com/droidcba/kedditbysteps/di/AppModule.kt index cab7f9e..6ad9a4a 100644 --- a/app/src/main/java/com/droidcba/kedditbysteps/di/AppModule.kt +++ b/app/src/main/java/com/droidcba/kedditbysteps/di/AppModule.kt @@ -7,10 +7,6 @@ import dagger.Module import dagger.Provides import javax.inject.Singleton -/** - * - * @author juancho. - */ @Module class AppModule(val app: KedditApp) { diff --git a/app/src/main/java/com/droidcba/kedditbysteps/di/NetworkModule.kt b/app/src/main/java/com/droidcba/kedditbysteps/di/NetworkModule.kt index 111a8f3..0d3a2b7 100644 --- a/app/src/main/java/com/droidcba/kedditbysteps/di/NetworkModule.kt +++ b/app/src/main/java/com/droidcba/kedditbysteps/di/NetworkModule.kt @@ -7,10 +7,6 @@ import retrofit2.Retrofit import retrofit2.converter.moshi.MoshiConverterFactory import javax.inject.Singleton -/** - * - * @author juancho. - */ @Module class NetworkModule { diff --git a/app/src/main/java/com/droidcba/kedditbysteps/di/news/NewsComponent.kt b/app/src/main/java/com/droidcba/kedditbysteps/di/news/NewsComponent.kt index 0cc3a0c..d37c319 100644 --- a/app/src/main/java/com/droidcba/kedditbysteps/di/news/NewsComponent.kt +++ b/app/src/main/java/com/droidcba/kedditbysteps/di/news/NewsComponent.kt @@ -6,18 +6,12 @@ import com.droidcba.kedditbysteps.features.news.NewsFragment import dagger.Component import javax.inject.Singleton -/** - * - * @author juancho. - */ @Singleton @Component(modules = arrayOf( - AppModule::class, - NewsModule::class, - NetworkModule::class) + AppModule::class, + NewsModule::class, + NetworkModule::class) ) interface NewsComponent { - fun inject(newsFragment: NewsFragment) - -} \ No newline at end of file +} diff --git a/app/src/main/java/com/droidcba/kedditbysteps/di/news/NewsModule.kt b/app/src/main/java/com/droidcba/kedditbysteps/di/news/NewsModule.kt index 7e3dd56..d61adf5 100644 --- a/app/src/main/java/com/droidcba/kedditbysteps/di/news/NewsModule.kt +++ b/app/src/main/java/com/droidcba/kedditbysteps/di/news/NewsModule.kt @@ -8,10 +8,6 @@ import dagger.Provides import retrofit2.Retrofit import javax.inject.Singleton -/** - * - * @author juancho. - */ @Module class NewsModule { @@ -23,8 +19,4 @@ class NewsModule { @Singleton fun provideRedditApi(retrofit: Retrofit): RedditApi = retrofit.create(RedditApi::class.java) - /** - * NewsManager is automatically provided by Dagger as we set the @Inject annotation in the - * constructor, so we can avoid adding a 'provider method' here. - */ } diff --git a/app/src/main/java/com/droidcba/kedditbysteps/features/news/NewsFragment.kt b/app/src/main/java/com/droidcba/kedditbysteps/features/news/NewsFragment.kt index cd77c6d..a0e161d 100644 --- a/app/src/main/java/com/droidcba/kedditbysteps/features/news/NewsFragment.kt +++ b/app/src/main/java/com/droidcba/kedditbysteps/features/news/NewsFragment.kt @@ -3,8 +3,8 @@ package com.droidcba.kedditbysteps.features.news import android.content.Intent import android.net.Uri import android.os.Bundle -import android.support.design.widget.Snackbar -import android.support.v7.widget.LinearLayoutManager +import com.google.android.material.snackbar.Snackbar +import androidx.recyclerview.widget.LinearLayoutManager import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -58,7 +58,7 @@ class NewsFragment : RxBaseFragment(), NewsDelegateAdapter.onViewSelectedListene news_list.apply { setHasFixedSize(true) - val linearLayout = LinearLayoutManager(context) + val linearLayout = androidx.recyclerview.widget.LinearLayoutManager(context) layoutManager = linearLayout clearOnScrollListeners() addOnScrollListener(InfiniteScrollListener({ requestNews() }, linearLayout)) diff --git a/app/src/main/java/com/droidcba/kedditbysteps/features/news/NewsManager.kt b/app/src/main/java/com/droidcba/kedditbysteps/features/news/NewsManager.kt index 53b74f1..2096ed9 100644 --- a/app/src/main/java/com/droidcba/kedditbysteps/features/news/NewsManager.kt +++ b/app/src/main/java/com/droidcba/kedditbysteps/features/news/NewsManager.kt @@ -7,11 +7,6 @@ import com.droidcba.kedditbysteps.commons.RedditNewsItem import javax.inject.Inject import javax.inject.Singleton -/** - * News Manager allows you to request news from Reddit API. - * - * @author juancho - */ @Singleton class NewsManager @Inject constructor(private val api: NewsAPI) { diff --git a/app/src/main/java/com/droidcba/kedditbysteps/features/news/adapter/LoadingDelegateAdapter.kt b/app/src/main/java/com/droidcba/kedditbysteps/features/news/adapter/LoadingDelegateAdapter.kt index 8e4be25..d473a25 100644 --- a/app/src/main/java/com/droidcba/kedditbysteps/features/news/adapter/LoadingDelegateAdapter.kt +++ b/app/src/main/java/com/droidcba/kedditbysteps/features/news/adapter/LoadingDelegateAdapter.kt @@ -1,19 +1,16 @@ package com.droidcba.kedditbysteps.features.news.adapter -import android.support.v7.widget.RecyclerView import android.view.ViewGroup +import com.droidcba.kedditbysteps.R import com.droidcba.kedditbysteps.commons.adapter.ViewType import com.droidcba.kedditbysteps.commons.adapter.ViewTypeDelegateAdapter -import com.droidcba.kedditbysteps.R import com.droidcba.kedditbysteps.commons.extensions.inflate class LoadingDelegateAdapter : ViewTypeDelegateAdapter { - override fun onCreateViewHolder(parent: ViewGroup) = LoadingViewHolder(parent) - - override fun onBindViewHolder(holder: RecyclerView.ViewHolder, item: ViewType) { + override fun onBindViewHolder(holder: androidx.recyclerview.widget.RecyclerView.ViewHolder, item: ViewType) { } - class LoadingViewHolder(parent: ViewGroup) : RecyclerView.ViewHolder( - parent.inflate(R.layout.news_item_loading)) + class LoadingViewHolder(parent: ViewGroup) : androidx.recyclerview.widget.RecyclerView.ViewHolder( + parent.inflate(R.layout.news_item_loading)) } \ No newline at end of file diff --git a/app/src/main/java/com/droidcba/kedditbysteps/features/news/adapter/NewsAdapter.kt b/app/src/main/java/com/droidcba/kedditbysteps/features/news/adapter/NewsAdapter.kt index fbc8d1a..0cfbf4a 100644 --- a/app/src/main/java/com/droidcba/kedditbysteps/features/news/adapter/NewsAdapter.kt +++ b/app/src/main/java/com/droidcba/kedditbysteps/features/news/adapter/NewsAdapter.kt @@ -1,7 +1,7 @@ package com.droidcba.kedditbysteps.features.news.adapter -import android.support.v4.util.SparseArrayCompat -import android.support.v7.widget.RecyclerView +import androidx.collection.SparseArrayCompat +import androidx.recyclerview.widget.RecyclerView import android.view.ViewGroup import com.droidcba.kedditbysteps.commons.RedditNewsItem import com.droidcba.kedditbysteps.commons.adapter.AdapterConstants @@ -9,10 +9,10 @@ import com.droidcba.kedditbysteps.commons.adapter.ViewType import com.droidcba.kedditbysteps.commons.adapter.ViewTypeDelegateAdapter import java.util.* -class NewsAdapter(listener: NewsDelegateAdapter.onViewSelectedListener) : RecyclerView.Adapter() { +class NewsAdapter(listener: NewsDelegateAdapter.onViewSelectedListener) : androidx.recyclerview.widget.RecyclerView.Adapter() { private var items: ArrayList - private var delegateAdapters = SparseArrayCompat() + private var delegateAdapters = androidx.collection.SparseArrayCompat() private val loadingItem = object : ViewType { override fun getViewType() = AdapterConstants.LOADING } @@ -30,7 +30,7 @@ class NewsAdapter(listener: NewsDelegateAdapter.onViewSelectedListener) : Recycl delegateAdapters.get(viewType)!!.onCreateViewHolder(parent) - override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { + override fun onBindViewHolder(holder: androidx.recyclerview.widget.RecyclerView.ViewHolder, position: Int) { delegateAdapters.get(getItemViewType(position))!!.onBindViewHolder(holder, items[position]) } diff --git a/app/src/main/java/com/droidcba/kedditbysteps/features/news/adapter/NewsDelegateAdapter.kt b/app/src/main/java/com/droidcba/kedditbysteps/features/news/adapter/NewsDelegateAdapter.kt index 320bf8e..483cbda 100644 --- a/app/src/main/java/com/droidcba/kedditbysteps/features/news/adapter/NewsDelegateAdapter.kt +++ b/app/src/main/java/com/droidcba/kedditbysteps/features/news/adapter/NewsDelegateAdapter.kt @@ -1,6 +1,6 @@ package com.droidcba.kedditbysteps.features.news.adapter -import android.support.v7.widget.RecyclerView +import androidx.recyclerview.widget.RecyclerView import android.view.ViewGroup import com.droidcba.kedditbysteps.R import com.droidcba.kedditbysteps.commons.RedditNewsItem @@ -17,16 +17,16 @@ class NewsDelegateAdapter(val viewActions: onViewSelectedListener) : ViewTypeDel fun onItemSelected(url: String?) } - override fun onCreateViewHolder(parent: ViewGroup): RecyclerView.ViewHolder { + override fun onCreateViewHolder(parent: ViewGroup): androidx.recyclerview.widget.RecyclerView.ViewHolder { return NewsViewHolder(parent) } - override fun onBindViewHolder(holder: RecyclerView.ViewHolder, item: ViewType) { + override fun onBindViewHolder(holder: androidx.recyclerview.widget.RecyclerView.ViewHolder, item: ViewType) { holder as NewsViewHolder holder.bind(item as RedditNewsItem) } - inner class NewsViewHolder(parent: ViewGroup) : RecyclerView.ViewHolder( + inner class NewsViewHolder(parent: ViewGroup) : androidx.recyclerview.widget.RecyclerView.ViewHolder( parent.inflate(R.layout.news_item)) { private val imgThumbnail = itemView.img_thumbnail diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index db69cfd..df961d0 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,5 +1,5 @@ - - - - + - + diff --git a/app/src/main/res/layout/news_fragment.xml b/app/src/main/res/layout/news_fragment.xml index d539635..f81883a 100644 --- a/app/src/main/res/layout/news_fragment.xml +++ b/app/src/main/res/layout/news_fragment.xml @@ -2,7 +2,7 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - diff --git a/build.gradle b/build.gradle index 2cbaa9f..61ab099 100644 --- a/build.gradle +++ b/build.gradle @@ -8,7 +8,7 @@ buildscript { maven { url "http://dl.bintray.com/jetbrains/spek" } } dependencies { - classpath 'com.android.tools.build:gradle:3.4.1' + classpath 'com.android.tools.build:gradle:3.4.2' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // NOTE: Do not place your application dependencies here; they belong diff --git a/gradle.properties b/gradle.properties index 4a118d5..9100816 100644 --- a/gradle.properties +++ b/gradle.properties @@ -23,4 +23,6 @@ kotlin.coroutines=enable spekVersion=1.2.0 junitPlatformVersion=1.0.1 -dagger2Version=2.17 \ No newline at end of file +dagger2Version=2.17 +android.useAndroidX=true +android.enableJetifier=true \ No newline at end of file From 09f7deef030c528f383bc8b079b4829ce103c7ac Mon Sep 17 00:00:00 2001 From: Liem Vo Date: Thu, 25 Jul 2019 17:17:11 +1200 Subject: [PATCH 5/7] Set theme jekyll-theme-time-machine --- _config.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 _config.yml diff --git a/_config.yml b/_config.yml new file mode 100644 index 0000000..ddeb671 --- /dev/null +++ b/_config.yml @@ -0,0 +1 @@ +theme: jekyll-theme-time-machine \ No newline at end of file From 6f11bb44237901e8cbeb4c869c78d2bc29e5c7c1 Mon Sep 17 00:00:00 2001 From: Liem Vo Date: Thu, 25 Jul 2019 19:45:37 +1200 Subject: [PATCH 6/7] Use lifecycle aware. --- app/build.gradle | 27 +++++++----- app/src/main/AndroidManifest.xml | 2 +- .../kedditbysteps/{ => app}/KedditApp.kt | 3 +- .../kedditbysteps/commons/RxBaseFragment.kt | 25 ----------- .../droidcba/kedditbysteps/di/AppModule.kt | 5 +-- .../kedditbysteps/di/NetworkModule.kt | 30 +++++++++---- .../kedditbysteps/di/news/NewsComponent.kt | 6 +-- .../features/news/NewsFragment.kt | 42 ++++++++++--------- app/src/main/res/layout/news_item.xml | 12 +++--- gradle.properties | 13 ++++-- 10 files changed, 82 insertions(+), 83 deletions(-) rename app/src/main/java/com/droidcba/kedditbysteps/{ => app}/KedditApp.kt (83%) delete mode 100644 app/src/main/java/com/droidcba/kedditbysteps/commons/RxBaseFragment.kt diff --git a/app/build.gradle b/app/build.gradle index 0528d2a..ce52ef5 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -8,7 +8,7 @@ android { defaultConfig { applicationId "com.droidcba.kedditbysteps" - minSdkVersion 16 + minSdkVersion 17 targetSdkVersion 28 versionCode 1 versionName "1.0" @@ -41,19 +41,26 @@ dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" implementation 'com.squareup.picasso:picasso:2.71828' - def nav_version_ktx = "2.1.0-beta02" - implementation "androidx.navigation:navigation-fragment-ktx:$nav_version_ktx" - implementation "androidx.navigation:navigation-ui-ktx:$nav_version_ktx" + // livedata & viewmodel + implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version" + + // lifecycle + implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version" + annotationProcessor "android.arch.lifecycle:compiler:$lifecycle_version" // Retrofit - implementation 'com.squareup.retrofit2:retrofit:2.5.0' - implementation 'com.squareup.retrofit2:converter-moshi:2.5.0' + implementation "com.squareup.retrofit2:retrofit:$retrofit_version" + implementation "com.squareup.retrofit2:converter-moshi:$retrofit_version" // Dagger 2 - implementation "com.google.dagger:dagger:$dagger2Version" - kapt "com.google.dagger:dagger-compiler:$dagger2Version" + implementation "com.google.dagger:dagger:$dagger2_version" + kapt "com.google.dagger:dagger-compiler:$dagger2_version" compileOnly 'org.glassfish:javax.annotation:10.0-b28' + // okhttp + implementation "com.squareup.okhttp3:okhttp:$okhttp_version" + implementation 'com.squareup.okhttp3:logging-interceptor:3.10.0' + // Coroutines implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.2.2" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.2.2" @@ -63,8 +70,8 @@ dependencies { // Tests testImplementation 'junit:junit:4.12' testImplementation 'com.nhaarman.mockitokotlin2:mockito-kotlin:2.1.0' - testImplementation "org.jetbrains.spek:spek-api:$spekVersion" - testImplementation "org.jetbrains.spek:spek-junit-platform-engine:$spekVersion" + testImplementation "org.jetbrains.spek:spek-api:$spek_version" + testImplementation "org.jetbrains.spek:spek-junit-platform-engine:$spek_version" testImplementation "org.junit.platform:junit-platform-runner:$junitPlatformVersion" testImplementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index beec06b..467fba2 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -5,7 +5,7 @@ + android:layout_marginTop="10dp" + tools:ignore="ContentDescription" /> @@ -24,7 +25,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignTop="@+id/img_thumbnail" - android:layout_toRightOf="@+id/img_thumbnail" + android:layout_toEndOf="@+id/img_thumbnail" android:textColor="#040404" android:textSize="15sp" android:textStyle="bold" @@ -37,7 +38,6 @@ android:id="@+id/author" android:layout_width="fill_parent" android:layout_height="wrap_content" - android:layout_alignLeft="@+id/description" android:layout_alignStart="@+id/description" android:layout_below="@+id/description" android:textColor="#343434" @@ -52,9 +52,8 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignEnd="@+id/author" - android:layout_alignRight="@+id/author" android:layout_below="@+id/description" - android:gravity="right" + android:gravity="end" android:textColor="#10bcc9" android:textSize="10sp" android:textStyle="bold" @@ -67,7 +66,6 @@ android:id="@+id/time" android:layout_width="fill_parent" android:layout_height="wrap_content" - android:layout_alignLeft="@+id/author" android:layout_alignStart="@+id/author" android:layout_below="@+id/author" android:textColor="#343434" @@ -75,4 +73,4 @@ tools:ignore="SmallSp" tools:text="12 hours ago" /> - \ No newline at end of file + diff --git a/gradle.properties b/gradle.properties index 9100816..16d5486 100644 --- a/gradle.properties +++ b/gradle.properties @@ -20,9 +20,14 @@ # Kotlin kotlin.incremental=true kotlin.coroutines=enable +android.useAndroidX=true +android.enableJetifier=true -spekVersion=1.2.0 +spek_version=1.2.0 junitPlatformVersion=1.0.1 -dagger2Version=2.17 -android.useAndroidX=true -android.enableJetifier=true \ No newline at end of file +dagger2_version=2.17 +retrofit_version=2.6.0 +okhttp_version=4.0.1 + +navigation_version=2.1.0-beta02 +lifecycle_version=2.2.0-alpha02 \ No newline at end of file From a022b90b29880fa2b52502662a446cee494b2fb2 Mon Sep 17 00:00:00 2001 From: Liem Vo Date: Thu, 25 Jul 2019 19:49:56 +1200 Subject: [PATCH 7/7] Update README.md --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index aa8244d..ca68049 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ A small Reddit Android client developed using Kotlin ## Tutorial -https://android.jlelse.eu/learn-kotlin-while-developing-an-android-app-introduction-567e21ff9664 +Original from this tutorial: https://android.jlelse.eu/learn-kotlin-while-developing-an-android-app-introduction-567e21ff9664 ## Libraries used: - Retrofit 2.0 @@ -11,3 +11,7 @@ https://android.jlelse.eu/learn-kotlin-while-developing-an-android-app-introduct - Picasso - Dagger 2 - Kotlin Android Extensions + +## Update +- Lifecycle aware +- TODO: Use ViewModel, Paging