Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/add mvvm architecture #2

Merged
merged 6 commits into from
Apr 16, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Next Next commit
add databinding and activitymain and adapter
  • Loading branch information
mohamedebrahim96 committed Apr 16, 2021
commit 545c1a47afda13b9b6761b44c3245d73aee2bf22
148 changes: 125 additions & 23 deletions app/build.gradle
Original file line number Diff line number Diff line change
@@ -1,56 +1,158 @@


plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-parcelize'
id 'kotlin-kapt'
id 'dagger.hilt.android.plugin'
}

apply from: "$rootDir/dependencies.gradle"

android {
compileSdkVersion 30

compileSdkVersion versions.compileSdk
defaultConfig {
applicationId "com.tahmeel.task"
minSdkVersion 21
targetSdkVersion 30
versionCode 1
versionName "0.0.1"

minSdkVersion versions.minSdk
targetSdkVersion versions.compileSdk
versionCode versions.versionCode
versionName versions.versionName
vectorDrawables.useSupportLibrary = true
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
javaCompileOptions {
annotationProcessorOptions {
arguments += ["room.schemaLocation": "$projectDir/schemas".toString()]
}
}
javaCompileOptions {
annotationProcessorOptions {
arguments["dagger.hilt.disableModulesHaveInstallInCheck"] = "true"
}
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
jvmTarget = JavaVersion.VERSION_1_8.toString()
}
buildFeatures {
dataBinding true
}
lintOptions {
abortOnError false
}
sourceSets {
androidTest.java.srcDirs += "src/test-common/java"
test.java.srcDirs += "src/test-common/java"
test.assets.srcDirs += files("$projectDir/schemas".toString())
}
testOptions {
unitTests {
includeAndroidResources = true
returnDefaultValues = true
}
}
packagingOptions {
exclude 'META-INF/DEPENDENCIES'
exclude 'META-INF/LICENSE'
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/license.txt'
exclude 'META-INF/NOTICE'
exclude 'META-INF/NOTICE.txt'
exclude 'META-INF/notice.txt'
exclude 'META-INF/ASL2.0'
exclude("META-INF/*.kotlin_module")
}
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
kotlinOptions.freeCompilerArgs += ["-Xopt-in=kotlin.time.ExperimentalTime"]
kotlinOptions.freeCompilerArgs += ["-Xopt-in=kotlinx.coroutines.ExperimentalCoroutinesApi"]
}
}

dependencies {
// android supports
implementation "com.google.android.material:material:$versions.materialVersion"
implementation "androidx.constraintlayout:constraintlayout:$versions.constraintVersion"

implementation 'androidx.core:core-ktx:1.3.2'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.3.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
// architecture components
implementation "androidx.fragment:fragment-ktx:$versions.fragmentVersion"
implementation "androidx.lifecycle:lifecycle-extensions:$versions.lifecycleVersion"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$versions.lifecycleVersion"
implementation "androidx.lifecycle:lifecycle-viewmodel-savedstate:$versions.lifecycleVersion"
implementation "androidx.room:room-runtime:$versions.roomVersion"
implementation "androidx.room:room-ktx:$versions.roomVersion"
kapt "androidx.room:room-compiler:$versions.roomVersion"
testImplementation "androidx.arch.core:core-testing:$versions.archCompomentVersion"

// binding
implementation("com.github.skydoves:bindables:$versions.bindablesVersion") {
exclude group: "com.google.android.material"
}

// startup
implementation "androidx.startup:startup-runtime:$versions.startupVersion"

// hilt
implementation "com.google.dagger:hilt-android:$versions.hiltCoreVersion"
kapt "com.google.dagger:hilt-compiler:$versions.hiltCoreVersion"
kapt "androidx.hilt:hilt-compiler:$versions.hiltVersion"
androidTestImplementation "com.google.dagger:hilt-android-testing:$versions.hiltCoreVersion"
kaptAndroidTest "com.google.dagger:hilt-compiler:$versions.hiltCoreVersion"

// network
implementation "com.github.skydoves:sandwich:$versions.sandwichVersion"
implementation "com.squareup.retrofit2:retrofit:$versions.retrofitVersion"
implementation "com.squareup.retrofit2:converter-moshi:$versions.retrofitVersion"
implementation "com.squareup.okhttp3:logging-interceptor:$versions.okhttpVersion"
testImplementation "com.squareup.okhttp3:mockwebserver:$versions.okhttpVersion"

// moshi
implementation "com.squareup.moshi:moshi-kotlin:$versions.moshiVersion"
kapt "com.squareup.moshi:moshi-kotlin-codegen:$versions.moshiVersion"

// coroutines
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$versions.coroutinesVersion"
testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$versions.coroutinesVersion"
testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$versions.coroutinesVersion"

// whatIf
implementation "com.github.skydoves:whatif:$versions.whatIfVersion"

// glide
implementation "com.github.bumptech.glide:glide:$versions.glideVersion"
implementation "com.github.florent37:glidepalette:$versions.glidePaletteVersion"
kapt "com.github.bumptech.glide:compiler:$versions.glideVersion"

// bundler
implementation "com.github.skydoves:bundler:$versions.bundlerVersion"

// transformation
implementation "com.github.skydoves:transformationlayout:$versions.transformationLayout"

// recyclerView
implementation "androidx.recyclerview:recyclerview:$versions.recyclerView"
implementation "com.github.skydoves:baserecyclerviewadapter:$versions.baseAdapter"

// gradation
implementation "com.github.skydoves:rainbow:$versions.rainbowVersion"

// custom views
implementation "com.github.skydoves:androidribbon:$versions.androidRibbonVersion"
implementation "com.github.skydoves:progressview:$versions.progressViewVersion"

// debugging
implementation "com.jakewharton.timber:timber:$versions.timberVersion"

// unit test
testImplementation "junit:junit:$versions.junitVersion"
testImplementation "androidx.test:core:$versions.androidxTest"
testImplementation "com.nhaarman.mockitokotlin2:mockito-kotlin:$versions.mockitoKotlinVersion"
testImplementation "org.mockito:mockito-inline:$versions.mockitoInlineVersion"
testImplementation "app.cash.turbine:turbine:$versions.turbineVersion"
testImplementation "org.robolectric:robolectric:$versions.robolectricVersion"
androidTestImplementation "com.google.truth:truth:$versions.truthVersion"
androidTestImplementation "androidx.test.ext:junit:$versions.androidxTestJunit"
androidTestImplementation "com.android.support.test:runner:$versions.androidTestRunner"
androidTestImplementation "androidx.test.espresso:espresso-core:$versions.espressoVersion"
}
20 changes: 17 additions & 3 deletions app/src/main/java/com/tahmeel/task/ui/main/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,26 @@ package com.tahmeel.task.ui.main

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.activity.viewModels
import androidx.annotation.VisibleForTesting
import com.skydoves.bindables.BindingActivity
import com.skydoves.transformationlayout.onTransformationStartContainer
import com.tahmeel.task.R
import dagger.hilt.android.AndroidEntryPoint

@AndroidEntryPoint
class MainActivity : BindingActivity<ActivityMainBinding>(R.layout.activity_main) {

@VisibleForTesting
val viewModel: MainViewModel by viewModels()

class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
onTransformationStartContainer()
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

binding {
lifecycleOwner = this@MainActivity
adapter = PokemonAdapter()
vm = viewModel
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package com.tahmeel.task.ui.main.adapter

import android.os.SystemClock
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import com.skydoves.bindables.BindingListAdapter
import com.skydoves.bindables.binding
import com.tahmeel.task.R

/**
* Created by @mohamedebrahim96 on 16,April,2021
* ShopiniWorld, Inc
* ebrahimm131@gmail.com
*/


class OrdersAdapter : BindingListAdapter<Pokemon, PokemonAdapter.PokemonViewHolder>(diffUtil) {

private var onClickedAt = 0L

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PokemonViewHolder {
val binding = parent.binding<ItemPokemonBinding>(R.layout.item_pokemon)
return PokemonViewHolder(binding).apply {
binding.root.setOnClickListener {
val position = bindingAdapterPosition.takeIf { it != RecyclerView.NO_POSITION }
?: return@setOnClickListener
val currentClickedAt = SystemClock.elapsedRealtime()
if (currentClickedAt - onClickedAt > binding.transformationLayout.duration) {
DetailActivity.startActivity(binding.transformationLayout, getItem(position))
onClickedAt = currentClickedAt
}
}
}
}

override fun onBindViewHolder(holder: PokemonViewHolder, position: Int) {
holder.binding.apply {
pokemon = getItem(position)
executePendingBindings()
}
}

class PokemonViewHolder(val binding: ItemPokemonBinding) :
RecyclerView.ViewHolder(binding.root)

companion object {
private val diffUtil = object : DiffUtil.ItemCallback<Pokemon>() {

override fun areItemsTheSame(oldItem: Pokemon, newItem: Pokemon): Boolean =
oldItem.name == newItem.name

override fun areContentsTheSame(oldItem: Pokemon, newItem: Pokemon): Boolean =
oldItem == newItem
}
}
}
84 changes: 67 additions & 17 deletions app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
@@ -1,18 +1,68 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.main.MainActivity">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
xmlns:tools="http://schemas.android.com/tools">

<data>

<variable
name="vm"
type="com.tahmeel.task.ui.main.MainViewModel" />

<variable
name="adapter"
type="com.tahmeel.task.ui.main.adapter.OrdersAdapter" />
</data>

<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/grey_100"
android:clipToPadding="false">

<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">

<include
android:id="@+id/main_toolbar"
layout="@layout/toolbar_home" />

</com.google.android.material.appbar.AppBarLayout>

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:clipToPadding="false"
android:fadeScrollbars="false"
android:padding="6dp"
android:scrollbarStyle="outsideOverlay"
android:scrollbars="vertical"
app:adapter="@{adapter}"
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/appBarLayout"
app:paginationPokemonList="@{vm}"
app:spanCount="2"
app:submitList="@{vm.pokemonList}"
app:toast="@{vm.toastMessage}"
tools:listitem="@layout/item_order" />

<ProgressBar
android:id="@+id/progressbar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:gone="@{!vm.loading &amp;&amp; adapter.submitted}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

</layout>
Loading