Skip to content

Commit

Permalink
Cars loader test project
Browse files Browse the repository at this point in the history
  • Loading branch information
Denis Komissarov authored and Denis Komissarov committed Apr 21, 2019
0 parents commit 5edd420
Show file tree
Hide file tree
Showing 68 changed files with 1,763 additions and 0 deletions.
13 changes: 13 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
*.iml
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
/build
/captures
.externalNativeBuild
35 changes: 35 additions & 0 deletions .idea/codeStyles/Project.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions .idea/codeStyles/codeStyleConfig.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 18 additions & 0 deletions .idea/gradle.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions .idea/runConfigurations.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions app/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
44 changes: 44 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
apply plugin: 'com.android.application'

apply plugin: 'kotlin-android'

apply plugin: 'kotlin-android-extensions'

android {
compileSdkVersion 27
defaultConfig {
applicationId "com.cars"
minSdkVersion 16
targetSdkVersion 27
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
testOptions {
unitTests.returnDefaultValues = true
}
}

dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support:recyclerview-v7:27.1.1'
testImplementation 'junit:junit:4.12'
testImplementation 'org.json:json:20180130'
testImplementation 'org.assertj:assertj-core:3.11.1'
testImplementation 'org.mockito:mockito-core:2.23.0'
testImplementation "com.nhaarman.mockitokotlin2:mockito-kotlin:2.1.0"
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'

implementation "io.reactivex.rxjava2:rxandroid:2.1.1"
implementation "io.reactivex.rxjava2:rxjava:2.2.8"
implementation "com.squareup.okhttp3:okhttp:3.12.1"
}
21 changes: 21 additions & 0 deletions app/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
23 changes: 23 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.cars">

<uses-permission android:name="android.permission.INTERNET"/>

<application
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>

<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>

</manifest>
28 changes: 28 additions & 0 deletions app/src/main/java/com/cars/Contract.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.cars

import android.content.Context
import com.cars.model.DataModel

interface Contract {
interface Presenter<T> {
fun reload()
fun loadNext()
fun canLoadMore(): Boolean
fun isLoading(): Boolean
fun getDataSet(): List<T>

fun onCreate()
fun onDestroy()
fun onViewCreated(view: View<T>)
fun onDestroyView()

fun onItemClicked(context: Context, item: DataModel)
}

interface View<T> {
fun updateGlobalLoader(loading: Boolean)
fun updatePageLoader(loading: Boolean)
fun onError(throwable: Throwable)
fun onNewDataSet()
}
}
69 changes: 69 additions & 0 deletions app/src/main/java/com/cars/MainActivity.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.cars

import android.content.Intent
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.view.MenuItem
import com.cars.view.CarFragment
import com.cars.view.ManufacturerFragment
import com.cars.view.ModelFragment
import com.cars.view.YearFragment

class MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
setContentView(R.layout.activity_main)
if (savedInstanceState == null) {
supportFragmentManager
.beginTransaction()
.replace(R.id.content_view, ManufacturerFragment())
.commit()
}
}

override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (item.itemId == android.R.id.home) {
if (supportFragmentManager.backStackEntryCount > 0) {
supportFragmentManager.popBackStack()
} else {
super.onBackPressed()
}
}
return true
}

override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
intent?.apply {
val fragment = when (getIntExtra(FRAGMENT, 0)) {
MODEL_FRAGMENT -> ModelFragment()
YEAR_FRAGMENT -> YearFragment()
CAR_FRAGMENT -> CarFragment()
else -> return
}

getBundleExtra(DATA_BUNDLE)?.let { data ->
fragment.arguments = data
supportFragmentManager
.beginTransaction()
.setCustomAnimations(
R.animator.right_in, R.animator.right_out,
R.animator.left_in, R.animator.left_out
)
.replace(R.id.content_view, fragment)
.addToBackStack(null)
.commit()
}
}
}

companion object {
const val DATA_BUNDLE = "data"
const val FRAGMENT = "fragment"
const val MODEL_FRAGMENT = 100
const val YEAR_FRAGMENT = 101
const val CAR_FRAGMENT = 102
}
}
52 changes: 52 additions & 0 deletions app/src/main/java/com/cars/adapter/Adapter.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.cars.adapter

import android.support.v7.widget.RecyclerView
import android.view.View
import android.view.ViewGroup
import com.cars.R
import com.cars.holder.CarsItemViewHolder
import com.cars.holder.ProgressItemViewHolder
import com.cars.model.DataModel

class Adapter<T: DataModel>(private val clickListener: View.OnClickListener)
: RecyclerView.Adapter<RecyclerView.ViewHolder>() {

val dataSet = ArrayList<T>()
private var loadingMode = false

fun setLoadingMode(loading: Boolean) {
if (loadingMode != loading) {
loadingMode = loading
notifyItemChanged(itemCount)
}
}

override fun getItemViewType(position: Int): Int {
return if (loadingMode && position == itemCount - 1) VIEW_TYPE_PROGRESS
else if (position % 2 == 0) VIEW_TYPE_EVEN else VIEW_TYPE_ODD
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return when (viewType) {
VIEW_TYPE_ODD -> CarsItemViewHolder(parent, clickListener, R.color.cars_view_item_background_transparent)
VIEW_TYPE_EVEN -> CarsItemViewHolder(parent, clickListener, R.color.cars_view_item_background_colored)
else -> ProgressItemViewHolder(parent)
}
}

override fun getItemCount(): Int = dataSet.size + (if (loadingMode) 1 else 0)

override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (holder.itemViewType) {
VIEW_TYPE_ODD,
VIEW_TYPE_EVEN -> (holder as CarsItemViewHolder).bind(dataSet[position])
else -> {}
}
}

companion object {
const val VIEW_TYPE_PROGRESS = 0
const val VIEW_TYPE_ODD = 1
const val VIEW_TYPE_EVEN = 2
}
}
20 changes: 20 additions & 0 deletions app/src/main/java/com/cars/adapter/DataDiffUtilCallback.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.cars.adapter

import android.support.v7.util.DiffUtil
import com.cars.model.DataModel

class DataDiffUtilCallback(private val old: List<DataModel>,
private val new: List<DataModel>) : DiffUtil.Callback() {

override fun getOldListSize(): Int = old.size

override fun getNewListSize(): Int = new.size

override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
return old[oldItemPosition].getDataId() == new[newItemPosition].getDataId()
}

override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
return old[oldItemPosition].getDisplayData() == new[newItemPosition].getDisplayData()
}
}
Loading

0 comments on commit 5edd420

Please sign in to comment.