Single activity approach (#30)

* CircleCI config fixes

* Implicit deeplinking via navController navigate

* Removed jacoco.exec files. Closes # 32
This commit is contained in:
Melih Aksoy
2019-08-21 17:15:01 +02:00
parent ac588ad89d
commit 2a90aba88b
36 changed files with 402 additions and 322 deletions

View File

@@ -26,19 +26,66 @@ jobs:
command: fastlane detekt
- store_artifacts: # for display in Artifacts: https://circleci.com/docs/2.0/artifacts/
path: reports/detekt
- store_test_results: # for display in Test Summary: https://circleci.com/docs/2.0/collect-test-data/
path: reports
# Tests
## App
- run:
name: Tests
name: Test App
command: |
fastlane test_all
./gradlew jacocoTestReport
fastlane test_app
./gradlew app:jacocoTestReport
bash <(curl -s https://codecov.io/bash)
- store_artifacts: # for display in Artifacts: https://circleci.com/docs/2.0/artifacts/
path: build/reports/tests
path: app/build/reports/tests
- store_test_results: # for display in Test Summary: https://circleci.com/docs/2.0/collect-test-data/
path: reports
path: app/build/test-results
## Core
- run:
name: Test Core
command: |
fastlane test_core
./gradlew core:jacocoTestReport
bash <(curl -s https://codecov.io/bash)
- store_artifacts: # for display in Artifacts: https://circleci.com/docs/2.0/artifacts/
path: core/build/reports/tests
- store_test_results: # for display in Test Summary: https://circleci.com/docs/2.0/collect-test-data/
path: core/build/test-results
## Launches
- run:
name: Test Launches
command: |
fastlane test_launches
./gradlew features:launches:jacocoTestReport
bash <(curl -s https://codecov.io/bash)
- store_artifacts: # for display in Artifacts: https://circleci.com/docs/2.0/artifacts/
path: features/launches/build/reports/tests
- store_test_results: # for display in Test Summary: https://circleci.com/docs/2.0/collect-test-data/
path: features/launches/build/test-results
## Detail
- run:
name: Test Detail
command: |
fastlane test_detail
./gradlew features:detail:jacocoTestReport
bash <(curl -s https://codecov.io/bash)
- store_artifacts: # for display in Artifacts: https://circleci.com/docs/2.0/artifacts/
path: features/detail/build/reports/tests
- store_test_results: # for display in Test Summary: https://circleci.com/docs/2.0/collect-test-data/
path: features/detail/build/test-results
## Repository
- run:
name: Test Repository
command: |
fastlane test_repository
./gradlew repository:jacocoTestReport
bash <(curl -s https://codecov.io/bash)
- store_artifacts: # for display in Artifacts: https://circleci.com/docs/2.0/artifacts/
path: repository/build/reports/tests
- store_test_results: # for display in Test Summary: https://circleci.com/docs/2.0/collect-test-data/
path: repository/build/test-results
# See https://circleci.com/docs/2.0/deployment-integrations/ for deploy examples

5
.gitignore vendored
View File

@@ -4,6 +4,8 @@
/.idea
.DS_Store
/build
/fastlane/README.md
/fastlane/report.xml
/captures
.externalNativeBuild
/projectFilesBackup
@@ -11,3 +13,6 @@
# Project reports
/reports
#jacoco.exec
jacoco.exec

159
Gemfile.lock Normal file
View File

@@ -0,0 +1,159 @@
GEM
remote: https://rubygems.org/
specs:
CFPropertyList (3.0.0)
addressable (2.6.0)
public_suffix (>= 2.0.2, < 4.0)
atomos (0.1.3)
babosa (1.0.2)
claide (1.0.3)
colored (1.2)
colored2 (3.1.2)
commander-fastlane (4.4.6)
highline (~> 1.7.2)
declarative (0.0.10)
declarative-option (0.1.0)
digest-crc (0.4.1)
domain_name (0.5.20190701)
unf (>= 0.0.5, < 1.0.0)
dotenv (2.7.5)
emoji_regex (1.0.1)
excon (0.66.0)
faraday (0.15.4)
multipart-post (>= 1.2, < 3)
faraday-cookie_jar (0.0.6)
faraday (>= 0.7.4)
http-cookie (~> 1.0.0)
faraday_middleware (0.13.1)
faraday (>= 0.7.4, < 1.0)
fastimage (2.1.5)
fastlane (2.129.0)
CFPropertyList (>= 2.3, < 4.0.0)
addressable (>= 2.3, < 3.0.0)
babosa (>= 1.0.2, < 2.0.0)
bundler (>= 1.12.0, < 3.0.0)
colored
commander-fastlane (>= 4.4.6, < 5.0.0)
dotenv (>= 2.1.1, < 3.0.0)
emoji_regex (>= 0.1, < 2.0)
excon (>= 0.45.0, < 1.0.0)
faraday (~> 0.9)
faraday-cookie_jar (~> 0.0.6)
faraday_middleware (~> 0.9)
fastimage (>= 2.1.0, < 3.0.0)
gh_inspector (>= 1.1.2, < 2.0.0)
google-api-client (>= 0.21.2, < 0.24.0)
google-cloud-storage (>= 1.15.0, < 2.0.0)
highline (>= 1.7.2, < 2.0.0)
json (< 3.0.0)
jwt (~> 2.1.0)
mini_magick (>= 4.9.4, < 5.0.0)
multi_xml (~> 0.5)
multipart-post (~> 2.0.0)
plist (>= 3.1.0, < 4.0.0)
public_suffix (~> 2.0.0)
rubyzip (>= 1.2.2, < 2.0.0)
security (= 0.1.3)
simctl (~> 1.6.3)
slack-notifier (>= 2.0.0, < 3.0.0)
terminal-notifier (>= 2.0.0, < 3.0.0)
terminal-table (>= 1.4.5, < 2.0.0)
tty-screen (>= 0.6.3, < 1.0.0)
tty-spinner (>= 0.8.0, < 1.0.0)
word_wrap (~> 1.0.0)
xcodeproj (>= 1.8.1, < 2.0.0)
xcpretty (~> 0.3.0)
xcpretty-travis-formatter (>= 0.0.3)
gh_inspector (1.1.3)
google-api-client (0.23.9)
addressable (~> 2.5, >= 2.5.1)
googleauth (>= 0.5, < 0.7.0)
httpclient (>= 2.8.1, < 3.0)
mime-types (~> 3.0)
representable (~> 3.0)
retriable (>= 2.0, < 4.0)
signet (~> 0.9)
google-cloud-core (1.3.0)
google-cloud-env (~> 1.0)
google-cloud-env (1.2.0)
faraday (~> 0.11)
google-cloud-storage (1.16.0)
digest-crc (~> 0.4)
google-api-client (~> 0.23)
google-cloud-core (~> 1.2)
googleauth (>= 0.6.2, < 0.10.0)
googleauth (0.6.7)
faraday (~> 0.12)
jwt (>= 1.4, < 3.0)
memoist (~> 0.16)
multi_json (~> 1.11)
os (>= 0.9, < 2.0)
signet (~> 0.7)
highline (1.7.10)
http-cookie (1.0.3)
domain_name (~> 0.5)
httpclient (2.8.3)
json (2.2.0)
jwt (2.1.0)
memoist (0.16.0)
mime-types (3.2.2)
mime-types-data (~> 3.2015)
mime-types-data (3.2019.0331)
mini_magick (4.9.5)
multi_json (1.13.1)
multi_xml (0.6.0)
multipart-post (2.0.0)
nanaimo (0.2.6)
naturally (2.2.0)
os (1.0.1)
plist (3.5.0)
public_suffix (2.0.5)
representable (3.0.4)
declarative (< 0.1.0)
declarative-option (< 0.2.0)
uber (< 0.2.0)
retriable (3.1.2)
rouge (2.0.7)
rubyzip (1.2.3)
security (0.1.3)
signet (0.11.0)
addressable (~> 2.3)
faraday (~> 0.9)
jwt (>= 1.5, < 3.0)
multi_json (~> 1.10)
simctl (1.6.5)
CFPropertyList
naturally
slack-notifier (2.3.2)
terminal-notifier (2.0.0)
terminal-table (1.8.0)
unicode-display_width (~> 1.1, >= 1.1.1)
tty-cursor (0.7.0)
tty-screen (0.7.0)
tty-spinner (0.9.1)
tty-cursor (~> 0.7)
uber (0.1.0)
unf (0.1.4)
unf_ext
unf_ext (0.0.7.6)
unicode-display_width (1.6.0)
word_wrap (1.0.0)
xcodeproj (1.12.0)
CFPropertyList (>= 2.3.3, < 4.0)
atomos (~> 0.1.3)
claide (>= 1.0.2, < 2.0)
colored2 (~> 3.1)
nanaimo (~> 0.2.6)
xcpretty (0.3.0)
rouge (~> 2.0.7)
xcpretty-travis-formatter (1.0.0)
xcpretty (~> 0.2, >= 0.0.7)
PLATFORMS
ruby
DEPENDENCIES
fastlane
BUNDLED WITH
2.0.1

View File

@@ -37,4 +37,7 @@ dependencies {
compileOnly libraries.retrofit
compileOnly libraries.room
compileOnly libraries.paging
// Need for proper renders in xml previews
compileOnly libraries.constraintLayout
}

View File

@@ -1,4 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.melih.rocketscience">
@@ -13,5 +14,15 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme"
tools:ignore="GoogleAppIndexingWarning" />
tools:ignore="GoogleAppIndexingWarning">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<nav-graph android:value="@navigation/nav_main" />
</activity>
</application>
</manifest>

View File

@@ -0,0 +1,31 @@
package com.melih.rocketscience
import android.os.Bundle
import androidx.databinding.DataBindingUtil
import androidx.navigation.NavController
import androidx.navigation.findNavController
import androidx.navigation.ui.NavigationUI
import com.melih.rocketscience.databinding.MainActivityBinding
import dagger.android.support.DaggerAppCompatActivity
class MainActivity : DaggerAppCompatActivity() {
private lateinit var binding: MainActivityBinding
private lateinit var navController: NavController
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
navController = findNavController(R.id.nav_host_fragment)
NavigationUI.setupWithNavController(binding.toolbar, navController)
}
override fun onSupportNavigateUp(): Boolean {
if (!NavigationUI.navigateUp(navController, null)) {
onBackPressed()
}
return true
}
}

View File

@@ -1,8 +1,6 @@
package com.melih.rocketscience.di
import com.melih.core.di.CoreComponent
import com.melih.detail.di.DetailFeatureModule
import com.melih.list.di.LaunchesFeatureModule
import com.melih.rocketscience.App
import dagger.Component
import dagger.android.AndroidInjectionModule
@@ -11,8 +9,7 @@ import dagger.android.AndroidInjector
@AppScope
@Component(
modules = [AndroidInjectionModule::class,
LaunchesFeatureModule::class,
DetailFeatureModule::class],
AppModule::class],
dependencies = [CoreComponent::class]
)

View File

@@ -0,0 +1,19 @@
package com.melih.rocketscience.di
import com.melih.detail.di.DetailContributor
import com.melih.list.di.LaunchesContributor
import com.melih.rocketscience.MainActivity
import dagger.Module
import dagger.android.ContributesAndroidInjector
@Module
abstract class AppModule {
@ContributesAndroidInjector(
modules = [
LaunchesContributor::class,
DetailContributor::class]
)
abstract fun mainActivity(): MainActivity
}

View File

@@ -1,7 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<data class="LaunchesActivityBinding" />
<data class="MainActivityBinding" />
<LinearLayout
android:layout_width="match_parent"
@@ -14,9 +16,12 @@
android:layout_height="?android:actionBarSize"
android:background="@color/colorPrimary" />
<FrameLayout
android:id="@+id/container"
<fragment
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/nav_main" />
</LinearLayout>
</layout>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<navigation
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/nav_main"
app:startDestination="@id/nav_launches">
<include app:graph="@navigation/nav_launches" />
<include app:graph="@navigation/nav_detail" />
</navigation>

View File

@@ -9,7 +9,7 @@ buildscript {
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.0-rc03'
classpath 'com.android.tools.build:gradle:3.5.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "org.jetbrains.dokka:dokka-android-gradle-plugin:0.9.18"
classpath "de.mannodermaus.gradle.plugins:android-junit5:1.5.0.0"

Binary file not shown.

View File

@@ -1,5 +1,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.melih.core">
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.melih.core">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
</manifest>

View File

@@ -1,16 +1,12 @@
package com.melih.core.actions
import android.content.Intent
const val EXTRA_LAUNCH_ID = "extras:detail:launchid"
import android.net.Uri
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.NavHostFragment
import com.melih.core.R
/**
* Navigation actions for navigation between feature activities
*/
object Actions {
fun openDetailFor(id: Long) =
Intent("action.dashboard.open")
.putExtra(EXTRA_LAUNCH_ID, id)
}
fun Fragment.openDetail(id: Long) =
NavHostFragment.findNavController(this).navigate(Uri.parse(getString(R.string.detail_uri, id)))

View File

@@ -1,56 +0,0 @@
package com.melih.core.base.lifecycle
import android.os.Bundle
import androidx.annotation.IdRes
import androidx.annotation.LayoutRes
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.ui.NavigationUI
import dagger.android.support.DaggerAppCompatActivity
const val NAV_HOST_FRAGMENT_TAG = "nav_host_fragment_tag"
/**
* Base class of all Activity classes
*/
abstract class BaseActivity<T : ViewDataBinding> : DaggerAppCompatActivity() {
protected lateinit var binding: T
protected lateinit var navHostFragment: NavHostFragment
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, getLayoutId())
binding.lifecycleOwner = this
if (savedInstanceState == null) {
navHostFragment = createNavHostFragment()
supportFragmentManager
.beginTransaction()
.add(addNavHostTo(), navHostFragment, NAV_HOST_FRAGMENT_TAG)
.commitNow()
} else {
navHostFragment = supportFragmentManager
.findFragmentByTag(NAV_HOST_FRAGMENT_TAG) as NavHostFragment
}
}
override fun onSupportNavigateUp(): Boolean {
if (!NavigationUI.navigateUp(navHostFragment.navController, null)) {
onBackPressed()
}
return true
}
@LayoutRes
abstract fun getLayoutId(): Int
abstract fun createNavHostFragment(): NavHostFragment
@IdRes
abstract fun addNavHostTo(): Int
}

View File

@@ -8,9 +8,8 @@ import androidx.annotation.LayoutRes
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.fragment.app.Fragment
import androidx.navigation.NavController
import androidx.navigation.fragment.NavHostFragment
import com.google.android.material.snackbar.Snackbar
import com.melih.core.R
import com.melih.repository.interactors.base.Reason
/**
@@ -23,7 +22,6 @@ abstract class BaseFragment<T : ViewDataBinding> : Fragment() {
// region Properties
protected lateinit var navController: NavController
protected lateinit var binding: T
// endregion
@@ -34,7 +32,6 @@ abstract class BaseFragment<T : ViewDataBinding> : Fragment() {
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
navController = NavHostFragment.findNavController(this)
binding = DataBindingUtil.inflate(inflater, getLayoutId(), container, false)
binding.lifecycleOwner = this
return binding.root
@@ -45,7 +42,7 @@ abstract class BaseFragment<T : ViewDataBinding> : Fragment() {
binding.root,
resources.getString(reason.messageRes),
Snackbar.LENGTH_INDEFINITE
).setAction(com.melih.core.R.string.retry) {
).setAction(R.string.retry) {
block()
}.show()
}

View File

@@ -1,15 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE
resources[<!ENTITY deeplinkNamespace "rocket-science://"><!ENTITY deeplinkDetailPath "&deeplinkNamespace;detail"><!ENTITY paramLaunchId "launch-id">]>
<resources>
<string name="dummy_long_text">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore
magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in
reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat
non proident, sunt in culpa qui officia
deserunt mollit anim id est laborum
</string>
<string name="retry">Retry</string>
<string name="retry">Retry</string>
<!--Actions-->
<string name="action_detail">action.detail.open</string>
<string name="detail_param_launch_id">&paramLaunchId;</string>
<string name="detail_deeplink">&deeplinkDetailPath;/{&paramLaunchId;}</string>
<string name="detail_uri">&deeplinkDetailPath;/%1d</string>
</resources>

View File

@@ -30,9 +30,29 @@ platform :android do
run_detekt()
end
desc "Runs all tests in all modules"
lane :test_all do
run_all_tests()
desc "Runs tests in app module"
lane :test_app do
run_app_tests()
end
desc "Runs tests in core module"
lane :test_core do
run_core_tests()
end
desc "Runs tests in launches module"
lane :test_launches do
run_launches_tests()
end
desc "Runs tests in detail module"
lane :test_detail do
run_detail_tests()
end
desc "Runs tests in repository module"
lane :test_repository do
run_repository_tests()
end
# ================ Gradle tasks ================
@@ -45,7 +65,23 @@ platform :android do
gradle(task: "removeReports")
end
def run_all_tests
gradle(task: "clean test --continue")
def run_app_tests
gradle(task: "app:test --continue")
end
def run_core_tests
gradle(task: "core:test --continue")
end
def run_launches_tests
gradle(task: "features:launches:test --continue")
end
def run_detail_tests
gradle(task: "features:detail:test --continue")
end
def run_repository_tests
gradle(task: "repository:test --continue")
end
end

View File

@@ -1,7 +1,6 @@
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
apply plugin: "androidx.navigation.safeargs"
apply from: "$rootProject.projectDir/scripts/feature_module.gradle"

Binary file not shown.

View File

@@ -1,14 +1 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.melih.detail">
<application>
<activity
android:name="com.melih.detail.ui.DetailActivity"
android:theme="@style/AppTheme">
<intent-filter>
<action android:name="action.dashboard.open" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
</manifest>
<manifest package="com.melih.detail" />

View File

@@ -1,24 +0,0 @@
package com.melih.detail.di
import com.melih.detail.ui.DetailActivity
import com.melih.list.di.scopes.DetailScope
import dagger.Module
import dagger.android.ContributesAndroidInjector
/**
* Contributes fragments & view models in this module
*/
@Module
abstract class DetailFeatureModule {
// region Contributes
@ContributesAndroidInjector(
modules = [
DetailContributor::class
]
)
@DetailScope
abstract fun detailActivity(): DetailActivity
// endregion
}

View File

@@ -32,7 +32,7 @@ abstract class DetailFragmentModule {
@Provides
@JvmStatic
fun provideGetLaunchDetailParams(fragment: DetailFragment): GetLaunchDetails.Params {
val args: DetailFragmentArgs by fragment.navArgs()
val args by fragment.navArgs<DetailFragmentArgs>()
return GetLaunchDetails.Params(args.launchId)
}
}

View File

@@ -1,37 +0,0 @@
package com.melih.detail.ui
import android.os.Bundle
import androidx.navigation.fragment.NavHostFragment
import com.melih.core.actions.EXTRA_LAUNCH_ID
import com.melih.core.base.lifecycle.BaseActivity
import com.melih.detail.R
import com.melih.detail.databinding.DetailActivityBinding
const val INVALID_LAUNCH_ID = -1L
class DetailActivity : BaseActivity<DetailActivityBinding>() {
// region Functions
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setSupportActionBar(binding.toolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setDisplayShowHomeEnabled(true)
}
override fun getLayoutId(): Int = R.layout.activity_detail
override fun createNavHostFragment() =
NavHostFragment.create(
R.navigation.nav_detail,
DetailFragmentArgs.Builder()
.setLaunchId(intent?.extras?.getLong(EXTRA_LAUNCH_ID) ?: INVALID_LAUNCH_ID)
.build()
.toBundle()
)
override fun addNavHostTo(): Int = R.id.container
// endregion
}

View File

@@ -1,22 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data class="DetailActivityBinding" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?android:actionBarSize"
android:background="@color/colorPrimary" />
<FrameLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</layout>

View File

@@ -1,18 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<navigation 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:id="@+id/nav_detail"
app:startDestination="@id/detailFragment">
<navigation
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:id="@+id/nav_detail"
app:startDestination="@id/detailFragment">
<fragment
android:id="@+id/detailFragment"
android:name="com.melih.detail.ui.DetailFragment"
android:label="DetailFragment"
tools:layout="@layout/fragment_detail">
<argument
android:name="launchId"
android:defaultValue="-1L"
app:argType="long" />
</fragment>
<fragment
android:id="@+id/detailFragment"
android:name="com.melih.detail.ui.DetailFragment"
android:label="DetailFragment"
tools:layout="@layout/fragment_detail">
<argument
android:name="launch-id"
android:defaultValue="0L"
app:argType="long" />
<deepLink
android:id="@+id/detailDeepLink"
app:uri="@string/detail_deeplink" />
</fragment>
</navigation>

View File

@@ -1,3 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="cd_rocket_image">Image of the rocket</string>
<string name="cd_rocket_image">Image of the rocket</string>
</resources>

Binary file not shown.

View File

@@ -1,14 +1 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.melih.list">
<application>
<activity
android:name="com.melih.list.ui.LaunchesActivity"
android:theme="@style/AppTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
<manifest package="com.melih.list" />

View File

@@ -1,24 +0,0 @@
package com.melih.list.di
import com.melih.list.di.scopes.LaunchesScope
import com.melih.list.ui.LaunchesActivity
import dagger.Module
import dagger.android.ContributesAndroidInjector
/**
* Contributes fragments & view models in this module
*/
@Module
abstract class LaunchesFeatureModule {
// region Contributes
@ContributesAndroidInjector(
modules = [
LaunchesContributor::class
]
)
@LaunchesScope
abstract fun launchesActivity(): LaunchesActivity
// endregion
}

View File

@@ -1,26 +0,0 @@
package com.melih.list.ui
import android.os.Bundle
import androidx.navigation.fragment.NavHostFragment
import com.melih.core.base.lifecycle.BaseActivity
import com.melih.list.R
import com.melih.list.databinding.LaunchesActivityBinding
class LaunchesActivity : BaseActivity<LaunchesActivityBinding>() {
// region Functions
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setSupportActionBar(binding.toolbar)
}
override fun getLayoutId(): Int = R.layout.activity_launches
override fun createNavHostFragment() =
NavHostFragment.create(R.navigation.nav_launches)
override fun addNavHostTo(): Int = R.id.container
// endregion
}

View File

@@ -3,7 +3,7 @@ package com.melih.list.ui
import android.os.Bundle
import android.view.View
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.melih.core.actions.Actions
import com.melih.core.actions.openDetail
import com.melih.core.base.lifecycle.BaseDaggerFragment
import com.melih.core.extensions.createFor
import com.melih.core.extensions.observe
@@ -36,17 +36,6 @@ class LaunchesFragment : BaseDaggerFragment<ListBinding>(), SwipeRefreshLayout.O
observeDataChanges()
}
//override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
// inflater.inflate(R.menu.menu_rocket_list, menu)
//
// with(menu.findItem(R.id.search)) {
// onExpandOrCollapse(::onSearchExpand, ::onSearchCollapse)
// setSearchQueryListener(actionView as SearchView)
// }
//
// super.onCreateOptionsMenu(menu, inflater)
//}
private fun observeDataChanges() {
// Observing state to show loading
@@ -64,30 +53,12 @@ class LaunchesFragment : BaseDaggerFragment<ListBinding>(), SwipeRefreshLayout.O
observe(viewModel.pagedList) {
launchesAdapter.submitList(it)
}
//observe(viewModel.filteredItems) {
// launchesAdapter.submitList(it)
//}
}
private fun onItemSelected(item: LaunchEntity) {
startActivity(Actions.openDetailFor(item.id))
openDetail(item.id)
}
//private fun onSearchExpand() {
// binding.swipeRefreshLayout.isEnabled = false
//}
//private fun onSearchCollapse() {
// binding.swipeRefreshLayout.isEnabled = true
//}
//private fun setSearchQueryListener(searchView: SearchView) {
// searchView.setOnQueryChangedListener {
// viewModel.filterItemListBy(it)
// }
//}
override fun onRefresh() {
viewModel.refresh()
}

View File

@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
<navigation
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:id="@+id/nav_launches"

View File

@@ -10,4 +10,8 @@ android {
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
testOptions.unitTests.all {
jvmArgs "-XX:+UnlockExperimentalVMOptions", "-XX:+UseCGroupMemoryLimitForHeap"
}
}

View File

@@ -1,3 +1,4 @@
apply plugin: "androidx.navigation.safeargs"
apply from: "$rootProject.projectDir/scripts/module.gradle"
android {

View File

@@ -1,3 +1,3 @@
apply from: "$rootProject.projectDir/scripts/default_android_config.gradle"
apply from: "$rootProject.projectDir/scripts/sources.gradle"
apply from: "$rootProject.projectDir/scripts/flavors.gradle"
apply from: "$rootProject.projectDir/scripts/flavors.gradle"