Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,11 @@ dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"

// Google Support Libraries
compile 'com.android.support:support-v4:25.1.0'
compile 'com.android.support:support-fragment:25.1.0'
compile 'com.android.support:appcompat-v7:25.1.0'
compile 'com.android.support:design:25.1.0'
compile 'com.android.support:recyclerview-v7:25.1.0'
compile 'com.android.support:support-v4:25.2.0'
compile 'com.android.support:support-fragment:25.2.0'
compile 'com.android.support:appcompat-v7:25.2.0'
compile 'com.android.support:design:25.2.0'
compile 'com.android.support:recyclerview-v7:25.2.0'

// RxJava
compile 'io.reactivex.rxjava2:rxjava:2.0.0'
Expand All @@ -118,6 +118,10 @@ dependencies {
// Databinding
kapt "com.android.databinding:compiler:$android_plugin_version"

// ActivityStarter
compile 'com.github.marcinmoskala.activitystarter:activitystarter:0.30'
kapt 'com.github.marcinmoskala.activitystarter:activitystarter-compiler:0.30'

// Unit Testing
testCompile 'junit:junit:4.12'
testCompile "org.mockito:mockito-core:1.10.19"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,6 @@ interface ApplicationComponent {
// Submodule methods
// Every screen is its own submodule of the graph and must be added here.
fun plus(module: ListModule): ListComponent

fun plus(module: DetailModule): DetailComponent
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,9 @@ class NetworkInteractorImpl @Inject constructor(
override fun hasNetworkConnection(): Boolean =
connectivityManager.activeNetworkInfo?.isConnectedOrConnecting ?: false

override fun hasNetworkConnectionCompletable(): Completable =
if (hasNetworkConnection()) {
Completable.complete()
} else {
Completable.error { NetworkInteractor.NetworkUnavailableException() }
}
override fun hasNetworkConnectionCompletable(): Completable = when {
hasNetworkConnection() -> Completable.complete()
else -> Completable.error { NetworkInteractor.NetworkUnavailableException() }
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,30 +11,22 @@ import javax.inject.Singleton
class ApiModule {

@Provides @Singleton
fun provideApiService(retrofit: Retrofit): GithubApiService {
return retrofit.create(GithubApiService::class.java)
}
fun provideApiService(retrofit: Retrofit) = retrofit.create(GithubApiService::class.java)!!
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is !! needed here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To avoid phantom type that is returned by create function, while it is Java function. It can be either solved by not null assertion (!!) or by setting function type. In situations like this, where it is obvious for all experienced Android developers that this will return GithubApiService I prefer to use !! because it is shorter. But I can change to:

fun provideApiService(retrofit: Retrofit): GithubApiService =
        retrofit.create(GithubApiService::class.java)

what is also totally reasonable.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the explicit return type is better.


@Provides @Singleton
fun provideRetrofit(
rxJavaCallAdapterFactory: RxJava2CallAdapterFactory,
gsonConverterFactory: GsonConverterFactory
): Retrofit {
return Retrofit.Builder()
.baseUrl(ApiConstants.GITHUB_API_BASE_ENDPOINT)
.addCallAdapterFactory(rxJavaCallAdapterFactory)
.addConverterFactory(gsonConverterFactory)
.build()
}
) = Retrofit.Builder()
.baseUrl(ApiConstants.GITHUB_API_BASE_ENDPOINT)
.addCallAdapterFactory(rxJavaCallAdapterFactory)
.addConverterFactory(gsonConverterFactory)
.build()!!

@Provides @Singleton
fun provideGsonConverterFactory(): GsonConverterFactory {
return GsonConverterFactory.create()
}
fun provideGsonConverterFactory() = GsonConverterFactory.create()!!

@Provides @Singleton
fun provideRxJavaCallAdapter(): RxJava2CallAdapterFactory {
return RxJava2CallAdapterFactory.create()
}
fun provideRxJavaCallAdapter() = RxJava2CallAdapterFactory.create()!!

}
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@ interface DefaultParcelable : Parcelable {
override fun describeContents(): Int = 0

companion object {
fun <T> generateCreator(create: (source: Parcel) -> T): Parcelable.Creator<T> = object: Parcelable.Creator<T> {
fun <T> generateCreator(create: (source: Parcel) -> T): Parcelable.Creator<T> = object : Parcelable.Creator<T> {
override fun createFromParcel(source: Parcel): T = create(source)

override fun newArray(size: Int): Array<out T>? = newArray(size)
}

}
}

inline fun <reified T> Parcel.read(): T = readValue(T::class.javaClass.classLoader) as T
fun Parcel.write(vararg values: Any?) = values.forEach { writeValue(it) }

Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.content.Context
import android.support.annotation.ColorInt
import android.support.annotation.StringRes
import android.support.design.widget.Snackbar
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
Expand All @@ -13,41 +14,50 @@ import com.squareup.picasso.Picasso
var View.isVisible: Boolean
get() = visibility == View.VISIBLE
set(value) {
visibility = if(value) View.VISIBLE else View.GONE
visibility = if (value) View.VISIBLE else View.GONE
}

fun Context.inflateLayout(layoutResId: Int): View {
return inflateView(this, layoutResId, null, false)
}

fun Context.inflateLayout(layoutResId: Int, parent: ViewGroup): View {
return inflateLayout(layoutResId, parent, true)
}

fun Context.inflateLayout(layoutResId: Int, parent: ViewGroup, attachToRoot: Boolean): View {
return inflateView(this, layoutResId, parent, attachToRoot)
}

private fun inflateView(context: Context, layoutResId: Int, parent: ViewGroup?, attachToRoot: Boolean): View {
return LayoutInflater.from(context).inflate(layoutResId, parent, attachToRoot)
}
fun Context.inflateLayout(
layoutResId: Int,
parent: ViewGroup? = null,
attachToRoot: Boolean = parent != null
): View =
LayoutInflater.from(this).inflate(layoutResId, parent, attachToRoot)

fun ImageView.loadImage(url: String) {
Picasso.with(context).load(url).into(this)
}

fun View.showSnackbar(message: String, length: Int = Snackbar.LENGTH_LONG, f: (Snackbar.() -> Unit) = {}) {
val snack = Snackbar.make(this, message, length)
snack.f()
snack.show()
fun View.showSnackbar(
message: String,
length: Int = Snackbar.LENGTH_LONG,
f: (Snackbar.() -> Unit) = {}
) {
Snackbar.make(this, message, length).apply {
f()
show()
}
}

fun View.showSnackbar(@StringRes message: Int, length: Int = Snackbar.LENGTH_LONG, f: (Snackbar.() -> Unit) = {}) {
fun View.showSnackbar(
@StringRes message: Int,
length: Int = Snackbar.LENGTH_LONG,
f: (Snackbar.() -> Unit) = {}
) {
showSnackbar(resources.getString(message), length, f)
}

fun Snackbar.action(action: String, @ColorInt color: Int? = null, listener: (View) -> Unit) {
fun Snackbar.action(
action: String,
@ColorInt color: Int? = null,
listener: (View) -> Unit
) {
setAction(action, listener)
color?.let { setActionTextColor(color) }
}

val RecyclerView.childList: List<View>
get() = (0..childCount - 1).map { getChildAt(it) }

val View.recyclerParams: RecyclerView.LayoutParams
get() = layoutParams as RecyclerView.LayoutParams
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package io.github.plastix.kotlinboilerplate.ui.base

import android.databinding.BaseObservable

abstract class AbstractViewModel : BaseObservable(), ViewModel {
abstract class AbstractViewModel : BaseObservable(), ViewModel {

override fun bind() {
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
package io.github.plastix.kotlinboilerplate.ui.base

import activitystarter.ActivityStarter
import android.os.Bundle
import android.support.annotation.CallSuper
import android.support.v7.app.AppCompatActivity
import io.github.plastix.kotlinboilerplate.ApplicationComponent
import io.github.plastix.kotlinboilerplate.KotlinBoilerplateApp

abstract class BaseActivity: AppCompatActivity() {
abstract class BaseActivity : AppCompatActivity() {

@CallSuper
override fun onCreate(savedInstanceState: Bundle?){
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
ActivityStarter.fill(this)
injectDependencies(KotlinBoilerplateApp.graph)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.github.plastix.kotlinboilerplate.ui.base

interface ViewModel {
interface
ViewModel {

fun bind()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ class ViewModelLoader<T : ViewModel> @Inject constructor(

override fun onReset() {
super.onReset()

viewModel?.onDestroy()
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package io.github.plastix.kotlinboilerplate.ui.detail

import android.content.Context
import android.content.Intent
import activitystarter.Arg
import android.databinding.DataBindingUtil
import android.os.Bundle
import io.github.plastix.kotlinboilerplate.ApplicationComponent
Expand All @@ -13,17 +12,7 @@ import io.github.plastix.kotlinboilerplate.ui.base.ViewModelActivity

open class DetailActivity : ViewModelActivity<DetailViewModel, ActivityDetailBinding>() {

companion object {
val EXTRA_REPO_OBJECT = "REPO_ITEM"

fun newIntent(context: Context, repo: Repo): Intent {
val intent = Intent(context, DetailActivity::class.java)
intent.putExtra(EXTRA_REPO_OBJECT, repo)
return intent
}
}

private val repo by lazy { intent.getParcelableExtra<Repo>(EXTRA_REPO_OBJECT) }
@Arg lateinit var repo: Repo

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Expand All @@ -36,9 +25,8 @@ open class DetailActivity : ViewModelActivity<DetailViewModel, ActivityDetailBin
binding.viewModel = viewModel
}

override fun getViewBinding(): ActivityDetailBinding {
return DataBindingUtil.setContentView(this, R.layout.activity_detail)
}
override fun getViewBinding(): ActivityDetailBinding
= DataBindingUtil.setContentView(this, R.layout.activity_detail)

override fun injectDependencies(graph: ApplicationComponent) {
graph.plus(DetailModule(this, repo))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ import android.widget.ImageView
import io.github.plastix.kotlinboilerplate.extensions.loadImage

@BindingAdapter("android:src")
fun setImageBinding(view: ImageView, url: String){
fun setImageBinding(view: ImageView, url: String) {
view.loadImage(url)
}
Loading