Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9e1436a223 | |||
| bd9ac36efc | |||
| 2dc6fca41c | |||
| e210e45c36 | |||
| f1a5881a9e | |||
| af396eb974 | |||
| b37a6c979d | |||
| 701feee394 | |||
| b399dd3173 | |||
| 2a4969d756 | |||
| 8521b7e19d | |||
| 8b2eab847b | |||
| cbaabaf0bc |
@@ -31,27 +31,27 @@
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
Cicerone (means - a guide, one who conducts sightseers) is a lightweight library that makes the navigation in an Android app easy.
|
||||
Cicerone (a guide who gives information about antiquities and places of interest to sightseers) is a lightweight library that makes the navigation in an Android app easy.
|
||||
It was designed to be used with the MVP/MVVM/MVI patterns but will work great with any architecture.
|
||||
|
||||
## Main advantages
|
||||
+ is not tied to Fragments
|
||||
+ not a framework (very lightweight)
|
||||
+ short navigation calls (no builders)
|
||||
+ static typed checks for screen parameters!
|
||||
+ lifecycle-safe!
|
||||
+ functionality is simple to extend
|
||||
+ suitable for Unit Testing
|
||||
+ Is not tied to Fragments
|
||||
+ Not a framework (very lightweight)
|
||||
+ Short navigation calls (no builders)
|
||||
+ Static typed checks for screen parameters!
|
||||
+ Lifecycle-safe!
|
||||
+ Functionality is simple to extend
|
||||
+ Suitable for Unit Testing
|
||||
|
||||
## Additional features
|
||||
+ opening several screens inside single call (for example: deeplink)
|
||||
+ provides `FragmentFactory` if it needed
|
||||
+ Opening several screens inside single call (for example: deeplink)
|
||||
+ Provides `FragmentFactory` if it needed
|
||||
+ `add` or `replace` strategy for opening next screen (see `router.navigateTo` last parameter)
|
||||
+ implementation of parallel navigation (Instagram like)
|
||||
+ predefined navigator ready for Single-Activity apps
|
||||
+ predefined navigator ready for setup transition animation
|
||||
+ Implementation of parallel navigation (Instagram like)
|
||||
+ Predefined navigator ready for Single-Activity apps
|
||||
+ Predefined navigator ready for setup transition animation
|
||||
|
||||
## How to add
|
||||
## How to add Cicerone to your application
|
||||
Add the dependency in your build.gradle:
|
||||
```kotlin
|
||||
dependencies {
|
||||
@@ -79,10 +79,10 @@ class App : Application() {
|
||||
}
|
||||
```
|
||||
|
||||
## How it works?
|
||||
## How does it work?
|
||||
<img src="https://github.com/terrakok/Cicerone/blob/master/media/CiceroneDiagram.png" alt="CiceroneDiagram.png" width="800"/>
|
||||
|
||||
Presenter calls navigation method of Router.
|
||||
The `Presenter` calls the navigation method of `Router`.
|
||||
|
||||
```kotlin
|
||||
class SamplePresenter(
|
||||
@@ -99,11 +99,11 @@ class SamplePresenter(
|
||||
}
|
||||
```
|
||||
|
||||
Router converts the navigation call to the set of Commands and sends them to CommandBuffer.
|
||||
`Router` converts the navigation call to the set of commands and sends them to `CommandBuffer`.
|
||||
|
||||
CommandBuffer checks whether there are _"active"_ Navigator:
|
||||
- If yes, it passes the commands to the Navigator. Navigator will process them to achive the desired transition.
|
||||
- If no, then CommandBuffer saves the commands in a queue, and will apply them as soon as new _"active"_ Navigator will appear.
|
||||
`CommandBuffer` checks whether there are the `_"active"_ Navigator`:
|
||||
- If yes, it passes the commands to the Navigator. `Navigator` will process them to achive the desired transition.
|
||||
- If no, then `CommandBuffer` saves the commands in a queue, and will apply them as soon as a new `_"active"_ Navigator` will appear.
|
||||
|
||||
```kotlin
|
||||
fun executeCommands(commands: Array<out Command>) {
|
||||
@@ -111,10 +111,10 @@ fun executeCommands(commands: Array<out Command>) {
|
||||
}
|
||||
```
|
||||
|
||||
Navigator processes the navigation commands. Usually it is an anonymous class inside the Activity.
|
||||
Activity provides Navigator to the CommandBuffer in _onResume_ and removes it in _onPause_.
|
||||
`Navigator` processes the navigation commands. Usually it is an anonymous class inside `Activity`.
|
||||
`Activity` provides `Navigator` to the `CommandBuffer` in `_onResume_` and removes it in `_onPause_`.
|
||||
|
||||
**Attention**: Use _onResumeFragments()_ with FragmentActivity ([more info](https://developer.android.com/reference/android/support/v4/app/FragmentActivity.html#onResume()))
|
||||
**Attention**: Use `_onResumeFragments()_` with `FragmentActivity` ([more info](https://developer.android.com/reference/android/support/v4/app/FragmentActivity.html#onResume()))
|
||||
|
||||
```kotlin
|
||||
private val navigator = AppNavigator(this, R.id.container)
|
||||
@@ -131,7 +131,7 @@ override fun onPause() {
|
||||
```
|
||||
|
||||
## Navigation commands
|
||||
This commands set will fulfill the needs of the most applications. But if you need something special - just add it!
|
||||
These commands will fulfill the needs of the most applications. But if you need something special - just add it!
|
||||
+ Forward - Opens new screen
|
||||

|
||||
+ Back - Rolls back the last transition
|
||||
@@ -148,16 +148,16 @@ To use, just provide it with the container and _FragmentManager_.
|
||||
private val navigator = AppNavigator(this, R.id.container)
|
||||
```
|
||||
|
||||
Custom navigator can be useful sometimes:
|
||||
A custom navigator can be useful sometimes:
|
||||
```kotlin
|
||||
private val navigator = object : AppNavigator(this, R.id.container) {
|
||||
override fun setupFragmentTransaction(
|
||||
screen: FragmentScreen,
|
||||
fragmentTransaction: FragmentTransaction,
|
||||
currentFragment: Fragment?,
|
||||
nextFragment: Fragment?
|
||||
nextFragment: Fragment
|
||||
) {
|
||||
super.setupFragmentTransaction(fragmentTransaction, currentFragment, nextFragment)
|
||||
fragmentTransaction.setReorderingAllowed(true)
|
||||
//setup your animation
|
||||
}
|
||||
|
||||
override fun applyCommands(commands: Array<out Command>) {
|
||||
@@ -168,7 +168,7 @@ private val navigator = object : AppNavigator(this, R.id.container) {
|
||||
```
|
||||
|
||||
## Screens
|
||||
Describe your screens as you like e.g. create Kotlin `object` with all application screens:
|
||||
Describe your screens as you like e.g. create a Kotlin `object` with all application screens:
|
||||
```kotlin
|
||||
object Screens {
|
||||
fun Main() = FragmentScreen { MainFragment() }
|
||||
@@ -208,13 +208,16 @@ fun onPhotoClick(photo: Bitmap) {
|
||||
```
|
||||
|
||||
## Sample
|
||||
To see how to add, initialize and use the library and predefined navigators see **sample project**
|
||||
To see how to add, initialize and use the library and predefined navigators see the **sample project**
|
||||
(thank you [@Javernaut](https://github.com/Javernaut) for support new library version and migrate sample project to Kotlin!)
|
||||
|
||||
For more complex use case check out the [GitFox (Android GitLab client)](https://gitlab.com/terrakok/gitlab-client)
|
||||
|
||||
## Applications with Cicerone inside
|
||||
## Applications that use Cicerone
|
||||
<a href="https://play.google.com/store/apps/details?id=ru.foodfox.client"><img src="https://play-lh.googleusercontent.com/gWYedIqy8QujCQOn0kzEIBEkGLBSpuKvFm-fMcfkWnJ1Oirtv847xAE4OyhAaohdcp5V=s360" width="64" /> Яндекс.Еда — доставка еды/продуктов. Food delivery</a><br>
|
||||
<a href="https://play.google.com/store/apps/details?id=com.kms.me"><img src="https://play-lh.googleusercontent.com/IBzu0tlHd_amw2HbjBLOZiCfK-0tn0CnwkMdOd1toP23rdHUV-i7L2ViNKgIg687=s360" width="64" /> Kaspersky Internet Security</a><br>
|
||||
<a href="https://play.google.com/store/apps/details?id=com.deliveryclub"><img src="https://play-lh.googleusercontent.com/m6-gFunvj7aQD5fdv8EdJZBN5M4REIobTaPZPYS0K5Td7CNYnazN7fOKiPwwaY3hJw=s360" width="64" /> Delivery Club – Доставка еды и продуктов</a><br>
|
||||
<a href="https://play.google.com/store/apps/details?id=ru.hh.android"><img src="https://play-lh.googleusercontent.com/YpAV7Q-ZJhI5tzFk_wEX-7-x2BydtnCtFTVUrmq0zAO6jLCLA4nNcfem3p_Pyowg9w=s360" width="64" /> Поиск работы на hh. Вакансии рядом с домом</a><br>
|
||||
<a href="https://play.google.com/store/apps/details?id=com.foodient.whisk"><img src="https://play-lh.googleusercontent.com/eKotZjJcZOU2_L9t2l34EEY7aGl5zhvKVuEbF0Kc4MRs_pAC2SJgOnWMkMTFjR_e9EY=s360" width="64" /> Whisk: Recipe Saver, Meal Planner & Grocery List</a><br>
|
||||
<a href="https://play.google.com/store/apps/details?id=kz.beeline.odp"><img src="https://play-lh.googleusercontent.com/hzgjpQQpy6Z-Byye0aVKSv9P7h8yx58i6pVkQtiM6jB99iWFXjYfKeaPqJ3wm6Rtb38=s360" width="64" /> Мой Beeline (Казахстан)</a><br>
|
||||
<a href="https://play.google.com/store/apps/details?id=com.mercuryo.app"><img src="https://play-lh.googleusercontent.com/FKulXdc15r5PWX6hTZi2i3iaJjcQHwd9xParp6YPiQ2KiBqza7jwEt_b_tqLwXpyEHg=s360" width="64" /> Mercuryo Bitcoin Cryptowallet</a><br>
|
||||
@@ -225,8 +228,8 @@ For more complex use case check out the [GitFox (Android GitLab client)](https:/
|
||||
<a href="https://play.google.com/store/apps/details?id=ru.zakaz.android"><img src="https://play-lh.googleusercontent.com/jj18yK2dB2MHZ_QdO21aXyznGXteIF2q4mgxY4ubLhFv9gwZqHVDeu1i2FmanS-0Furm=s360" width="64" /> Zakaz.ru</a><br>
|
||||
|
||||
## Participants
|
||||
+ idea and code - Konstantin Tskhovrebov (@terrakok)
|
||||
+ architecture advice, documentation and publication - Vasili Chyrvon (@Jeevuz)
|
||||
+ Idea and code - Konstantin Tskhovrebov (@terrakok)
|
||||
+ Architecture advice, documentation and publication - Vasili Chyrvon (@Jeevuz)
|
||||
|
||||
## License
|
||||
```
|
||||
|
||||
+4
-7
@@ -1,24 +1,21 @@
|
||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
|
||||
buildscript {
|
||||
ext.kotlin_version = '1.4.10'
|
||||
ext.kotlin_version = '1.5.21'
|
||||
repositories {
|
||||
jcenter()
|
||||
mavenCentral()
|
||||
google()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:4.1.0'
|
||||
classpath 'com.android.tools.build:gradle:4.2.2'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
|
||||
// For the library uploading to the Bintray
|
||||
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4'
|
||||
classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5'
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
jcenter()
|
||||
mavenCentral()
|
||||
google()
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.1.1-bin.zip
|
||||
|
||||
@@ -14,7 +14,7 @@ dependencies {
|
||||
ext {
|
||||
publishedGroupId = 'com.github.terrakok'
|
||||
artifact = 'cicerone'
|
||||
libraryVersion = '7.0'
|
||||
libraryVersion = '7.1'
|
||||
}
|
||||
|
||||
project.archivesBaseName = artifact // to fix that project name different from artifact name
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
package com.github.terrakok.cicerone
|
||||
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
|
||||
/**
|
||||
* Passes navigation command to an active [Navigator]
|
||||
* or stores it in the pending commands queue to pass it later.
|
||||
@@ -7,6 +10,7 @@ package com.github.terrakok.cicerone
|
||||
internal class CommandBuffer : NavigatorHolder {
|
||||
private var navigator: Navigator? = null
|
||||
private val pendingCommands = mutableListOf<Array<out Command>>()
|
||||
private val mainHandler = Handler(Looper.getMainLooper())
|
||||
|
||||
override fun setNavigator(navigator: Navigator) {
|
||||
this.navigator = navigator
|
||||
@@ -24,6 +28,8 @@ internal class CommandBuffer : NavigatorHolder {
|
||||
* @param commands navigation command array
|
||||
*/
|
||||
fun executeCommands(commands: Array<out Command>) {
|
||||
navigator?.applyCommands(commands) ?: pendingCommands.add(commands)
|
||||
mainHandler.post {
|
||||
navigator?.applyCommands(commands) ?: pendingCommands.add(commands)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,6 @@ package com.github.terrakok.cicerone.androidx
|
||||
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.Intent
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import androidx.fragment.app.*
|
||||
import com.github.terrakok.cicerone.*
|
||||
|
||||
@@ -22,15 +20,8 @@ open class AppNavigator @JvmOverloads constructor(
|
||||
) : Navigator {
|
||||
|
||||
protected val localStackCopy = mutableListOf<String>()
|
||||
private val mainHandler = Handler(Looper.getMainLooper())
|
||||
|
||||
override fun applyCommands(commands: Array<out Command>) {
|
||||
mainHandler.post {
|
||||
applyCommandsSync(commands)
|
||||
}
|
||||
}
|
||||
|
||||
protected open fun applyCommandsSync(commands: Array<out Command>) {
|
||||
fragmentManager.executePendingTransactions()
|
||||
|
||||
//copy stack before apply commands
|
||||
|
||||
+6
-6
@@ -3,7 +3,7 @@ apply plugin: 'kotlin-android'
|
||||
apply plugin: 'kotlin-kapt'
|
||||
|
||||
repositories {
|
||||
jcenter()
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
android {
|
||||
@@ -42,10 +42,10 @@ android {
|
||||
}
|
||||
|
||||
ext {
|
||||
androidXVersion = "1.2.0"
|
||||
materialVersion = "1.2.1"
|
||||
moxyVersion = "2.2.0"
|
||||
daggerVersion = "2.29.1"
|
||||
androidXVersion = "1.3.0"
|
||||
materialVersion = "1.4.0"
|
||||
moxyVersion = "2.2.2"
|
||||
daggerVersion = "2.38"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
@@ -69,5 +69,5 @@ dependencies {
|
||||
implementation ('com.ashokvarma.android:bottom-navigation-bar:1.3.0') {
|
||||
exclude group: "com.android.support", module: "design"
|
||||
}
|
||||
implementation "androidx.core:core-ktx:1.3.2"
|
||||
implementation "androidx.core:core-ktx:1.6.0"
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import com.github.terrakok.cicerone.sample.ui.bottom.ForwardFragment
|
||||
import com.github.terrakok.cicerone.sample.ui.bottom.TabContainerFragment
|
||||
import com.github.terrakok.cicerone.sample.ui.main.MainActivity
|
||||
import com.github.terrakok.cicerone.sample.ui.main.SampleFragment
|
||||
import com.github.terrakok.cicerone.sample.ui.main.SemiTransparentFragment
|
||||
import com.github.terrakok.cicerone.sample.ui.start.StartActivity
|
||||
|
||||
/**
|
||||
@@ -59,4 +60,8 @@ object Screens {
|
||||
fun SelectPhoto(resultKey: String) = FragmentScreen {
|
||||
SelectPhotoFragment.getNewInstance(resultKey)
|
||||
}
|
||||
|
||||
fun SemiTransparent() = FragmentScreen(clearContainer = false) {
|
||||
SemiTransparentFragment()
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import com.github.terrakok.cicerone.sample.ui.bottom.BottomNavigationActivity
|
||||
import com.github.terrakok.cicerone.sample.ui.bottom.TabContainerFragment
|
||||
import com.github.terrakok.cicerone.sample.ui.main.MainActivity
|
||||
import com.github.terrakok.cicerone.sample.ui.main.SampleFragment
|
||||
import com.github.terrakok.cicerone.sample.ui.main.SemiTransparentFragment
|
||||
import com.github.terrakok.cicerone.sample.ui.start.StartActivity
|
||||
import dagger.Component
|
||||
import javax.inject.Singleton
|
||||
@@ -37,4 +38,6 @@ interface AppComponent {
|
||||
fun inject(fragment: SelectPhotoFragment)
|
||||
|
||||
fun inject(activity: ProfileActivity)
|
||||
|
||||
fun inject(fragment: SemiTransparentFragment)
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package com.github.terrakok.cicerone.sample.mvp.main
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import com.github.terrakok.cicerone.Router
|
||||
import com.github.terrakok.cicerone.sample.Screens
|
||||
import com.github.terrakok.cicerone.sample.Screens.Sample
|
||||
import moxy.InjectViewState
|
||||
import moxy.MvpPresenter
|
||||
@@ -56,6 +57,10 @@ class SamplePresenter(
|
||||
router.finishChain()
|
||||
}
|
||||
|
||||
fun onForwardNccCommandClick() {
|
||||
router.navigateTo(Screens.SemiTransparent())
|
||||
}
|
||||
|
||||
fun onNewRootCommandClick() {
|
||||
router.newRootScreen(Sample(screenNumber + 1))
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import androidx.fragment.app.Fragment
|
||||
import moxy.MvpAppCompatFragment
|
||||
import java.lang.ref.WeakReference
|
||||
|
||||
abstract class BaseFragment : MvpAppCompatFragment() {
|
||||
abstract class BaseFragment : MvpAppCompatFragment(), ChainScreen {
|
||||
override fun onAttach(context: Context) {
|
||||
super.onAttach(context)
|
||||
|
||||
|
||||
@@ -5,4 +5,9 @@ import java.lang.ref.WeakReference
|
||||
|
||||
interface ChainHolder {
|
||||
val chain: MutableList<WeakReference<Fragment>>
|
||||
}
|
||||
|
||||
interface ChainScreen {
|
||||
val name: String
|
||||
val creationTime: Long
|
||||
}
|
||||
@@ -33,8 +33,8 @@ class MainActivity : MvpAppCompatActivity(), ChainHolder {
|
||||
|
||||
private val navigator: Navigator = object : AppNavigator(this, R.id.main_container) {
|
||||
|
||||
override fun applyCommandsSync(commands: Array<out Command>) {
|
||||
super.applyCommandsSync(commands)
|
||||
override fun applyCommands(commands: Array<out Command>) {
|
||||
super.applyCommands(commands)
|
||||
supportFragmentManager.executePendingTransactions()
|
||||
printScreensScheme()
|
||||
}
|
||||
@@ -75,10 +75,10 @@ class MainActivity : MvpAppCompatActivity(), ChainHolder {
|
||||
}
|
||||
|
||||
private fun printScreensScheme() {
|
||||
val fragments = ArrayList<SampleFragment>()
|
||||
val fragments = ArrayList<ChainScreen>()
|
||||
for (fragmentReference in chain) {
|
||||
val fragment = fragmentReference.get()
|
||||
if (fragment != null && fragment is SampleFragment) {
|
||||
if (fragment != null && fragment is ChainScreen) {
|
||||
fragments.add(fragment)
|
||||
}
|
||||
}
|
||||
@@ -86,9 +86,9 @@ class MainActivity : MvpAppCompatActivity(), ChainHolder {
|
||||
val t = f1.creationTime - f2.creationTime
|
||||
if (t > 0) 1 else if (t < 0) -1 else 0
|
||||
}
|
||||
val keys = ArrayList<Int>()
|
||||
val keys = ArrayList<String>()
|
||||
for (fragment in fragments) {
|
||||
keys.add(fragment.number)
|
||||
keys.add(fragment.name)
|
||||
}
|
||||
screensSchemeTV.text = "Chain: $keys"
|
||||
}
|
||||
|
||||
@@ -31,9 +31,9 @@ class SampleFragment : BaseFragment(), SampleView, BackButtonListener {
|
||||
@ProvidePresenter
|
||||
fun createSamplePresenter() = SamplePresenter(router, arguments!!.getInt(EXTRA_NUMBER))
|
||||
|
||||
val number: Int
|
||||
get() = arguments!!.getInt(EXTRA_NUMBER)
|
||||
val creationTime: Long
|
||||
override val name: String
|
||||
get() = arguments!!.getInt(EXTRA_NUMBER).toString()
|
||||
override val creationTime: Long
|
||||
get() = arguments!!.getLong(EXTRA_TIME, 0L)
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
@@ -59,6 +59,7 @@ class SampleFragment : BaseFragment(), SampleView, BackButtonListener {
|
||||
binding.forwardDelayCommand.setOnClickListener { presenter.onForwardWithDelayCommandClick() }
|
||||
binding.backToCommand.setOnClickListener { presenter.onBackToCommandClick() }
|
||||
binding.finishChainCommand.setOnClickListener { presenter.onFinishChainCommandClick() }
|
||||
binding.forwardNccCommand.setOnClickListener { presenter.onForwardNccCommandClick() }
|
||||
}
|
||||
|
||||
override fun setTitle(title: String) {
|
||||
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
package com.github.terrakok.cicerone.sample.ui.main
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Button
|
||||
import com.github.terrakok.cicerone.Router
|
||||
import com.github.terrakok.cicerone.sample.R
|
||||
import com.github.terrakok.cicerone.sample.SampleApplication
|
||||
import com.github.terrakok.cicerone.sample.databinding.FragmentSampleBinding
|
||||
import com.github.terrakok.cicerone.sample.databinding.FragmentSemitransparentBinding
|
||||
import com.github.terrakok.cicerone.sample.ui.common.BackButtonListener
|
||||
import moxy.MvpAppCompatFragment
|
||||
import javax.inject.Inject
|
||||
|
||||
class SemiTransparentFragment : BaseFragment(), BackButtonListener {
|
||||
lateinit var binding: FragmentSemitransparentBinding
|
||||
|
||||
@Inject
|
||||
lateinit var router: Router
|
||||
|
||||
override val name: String = "D"
|
||||
override val creationTime: Long = System.currentTimeMillis()
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
SampleApplication.INSTANCE.appComponent.inject(this)
|
||||
super.onCreate(savedInstanceState)
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
binding = FragmentSemitransparentBinding.inflate(inflater)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
binding.background.setOnClickListener { onBackPressed() }
|
||||
binding.backButton.setOnClickListener { onBackPressed() }
|
||||
}
|
||||
|
||||
override fun onBackPressed(): Boolean {
|
||||
router.exit()
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -121,11 +121,21 @@
|
||||
android:layout_margin="4dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_rowWeight="1"
|
||||
android:layout_columnSpan="2"
|
||||
android:background="@color/greensea"
|
||||
android:gravity="center"
|
||||
android:text="Finish chain"
|
||||
android:textSize="28sp"/>
|
||||
<TextView
|
||||
android:id="@+id/forward_ncc_command"
|
||||
android:layout_width="0dp"
|
||||
android:layout_columnWeight="1"
|
||||
android:layout_margin="4dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_rowWeight="1"
|
||||
android:background="@color/nephritis"
|
||||
android:gravity="center"
|
||||
android:text="Forward not clearing container"
|
||||
android:textSize="28sp"/>
|
||||
|
||||
</GridLayout>
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/background"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/semitransparent"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
tools:ignore="HardcodedText">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_margin="40dp"
|
||||
android:background="@color/accent"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:text="This is not a dialog.\n This is a regular screen."
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/back_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginTop="16dp"
|
||||
android:minWidth="100dp"
|
||||
android:text="Back"
|
||||
android:textSize="20sp" />
|
||||
</LinearLayout>
|
||||
</FrameLayout>
|
||||
@@ -4,6 +4,8 @@
|
||||
<color name="primary_dark">#c0392b</color>
|
||||
<color name="accent">#e67e22</color>
|
||||
|
||||
<color name="semitransparent">#99000000</color>
|
||||
|
||||
|
||||
<color name="alizarin">#e74c3c</color>
|
||||
<color name="carrot">#e67e22</color>
|
||||
|
||||
Reference in New Issue
Block a user