Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
M
Magisk
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
Magisk
Commits
ebab1265
Commit
ebab1265
authored
Apr 16, 2019
by
Viktor De Pasquale
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Replaced xml navigation with self-handled
parent
0e5417a1
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
311 additions
and
67 deletions
+311
-67
build.gradle
app/build.gradle
+4
-1
MagiskNavigationEvent.kt
...opjohnwu/magisk/model/navigation/MagiskNavigationEvent.kt
+82
-0
Navigation.kt
.../java/com/topjohnwu/magisk/model/navigation/Navigation.kt
+24
-15
Navigator.kt
...n/java/com/topjohnwu/magisk/model/navigation/Navigator.kt
+13
-0
MainActivity.kt
app/src/main/java/com/topjohnwu/magisk/ui/MainActivity.kt
+20
-2
MainViewModel.kt
app/src/main/java/com/topjohnwu/magisk/ui/MainViewModel.kt
+16
-0
MagiskActivity.kt
.../main/java/com/topjohnwu/magisk/ui/base/MagiskActivity.kt
+114
-1
MagiskFragment.kt
.../main/java/com/topjohnwu/magisk/ui/base/MagiskFragment.kt
+22
-3
DataBindingAdapters.kt
...in/java/com/topjohnwu/magisk/utils/DataBindingAdapters.kt
+13
-0
activity_main.xml
app/src/main/res/layout/activity_main.xml
+1
-0
activity_main_content.xml
app/src/main/res/layout/activity_main_content.xml
+2
-5
navigation_main.xml
app/src/main/res/navigation/navigation_main.xml
+0
-39
build.gradle
build.gradle
+0
-1
No files found.
app/build.gradle
View file @
ebab1265
apply
plugin:
'com.android.application'
apply
plugin:
'kotlin-android-extensions'
apply
plugin:
'kotlin-android'
apply
plugin:
'kotlin-android-extensions'
apply
plugin:
'kotlin-kapt'
kapt
{
...
...
@@ -80,4 +80,7 @@ dependencies {
exclude
group:
'androidx.work'
,
module:
'work-runtime-ktx'
exclude
group:
'androidx.room'
,
module:
'room-runtime'
}
def
navigation
=
"3.2.0"
implementation
"com.ncapdevi:frag-nav:${navigation}"
}
app/src/main/java/com/topjohnwu/magisk/model/navigation/MagiskNavigationEvent.kt
0 → 100644
View file @
ebab1265
package
com.topjohnwu.magisk.model.navigation
import
android.os.Bundle
import
androidx.annotation.AnimRes
import
androidx.annotation.AnimatorRes
import
androidx.fragment.app.Fragment
import
com.skoumal.teanity.viewevents.NavigationDslMarker
import
com.skoumal.teanity.viewevents.ViewEvent
import
kotlin.reflect.KClass
class
MagiskNavigationEvent
(
val
navDirections
:
MagiskNavDirectionsBuilder
,
val
navOptions
:
MagiskNavOptions
,
val
animOptions
:
MagiskAnimBuilder
)
:
ViewEvent
()
{
companion
object
{
operator
fun
invoke
(
builder
:
Builder
.()
->
Unit
)
=
Builder
().
apply
(
builder
).
build
()
}
@NavigationDslMarker
class
Builder
{
private
var
animOptions
:
MagiskAnimBuilder
=
MagiskAnimBuilder
()
private
var
navOptions
:
MagiskNavOptions
=
MagiskNavOptions
()
private
val
directionsBuilder
=
MagiskNavDirectionsBuilder
()
fun
args
(
builder
:
Bundle
.()
->
Unit
)
=
directionsBuilder
.
args
(
builder
)
fun
navAnim
(
builder
:
MagiskAnimBuilder
.()
->
Unit
)
{
animOptions
=
MagiskAnimBuilder
().
apply
(
builder
)
}
fun
navOptions
(
builder
:
MagiskNavOptions
.()
->
Unit
)
{
navOptions
=
MagiskNavOptions
().
apply
(
builder
)
}
fun
navDirections
(
builder
:
MagiskNavDirectionsBuilder
.()
->
Unit
)
{
directionsBuilder
.
apply
(
builder
)
}
internal
fun
build
()
=
MagiskNavigationEvent
(
directionsBuilder
,
navOptions
,
animOptions
)
}
}
@NavigationDslMarker
class
MagiskNavDirectionsBuilder
{
var
destination
:
KClass
<
out
Fragment
>?
=
null
var
isActivity
:
Boolean
=
false
val
args
:
Bundle
=
Bundle
()
fun
args
(
builder
:
Bundle
.()
->
Unit
)
=
args
.
apply
(
builder
)
}
@NavigationDslMarker
class
MagiskNavOptions
{
var
popUpTo
:
KClass
<*>?
=
null
var
inclusive
:
Boolean
=
false
var
clearTask
:
Boolean
=
false
var
singleTop
:
Boolean
=
false
}
@NavigationDslMarker
class
MagiskAnimBuilder
{
@AnimRes
@AnimatorRes
var
enter
=
0
@AnimRes
@AnimatorRes
var
exit
=
0
@AnimRes
@AnimatorRes
var
popEnter
=
0
@AnimRes
@AnimatorRes
var
popExit
=
0
}
\ No newline at end of file
app/src/main/java/com/topjohnwu/magisk/model/navigation/Navigation.kt
View file @
ebab1265
package
com.topjohnwu.magisk.model.navigation
import
com.skoumal.teanity.viewevents.NavigationEvent
import
com.topjohnwu.magisk.R
import
com.topjohnwu.magisk.ui.hide.MagiskHideFragment
import
com.topjohnwu.magisk.ui.home.MagiskFragment
import
com.topjohnwu.magisk.ui.log.LogFragment
import
com.topjohnwu.magisk.ui.module.ModulesFragment
import
com.topjohnwu.magisk.ui.module.ReposFragment
import
com.topjohnwu.magisk.ui.settings.SettingsFragment
import
com.topjohnwu.magisk.ui.superuser.SuperuserFragment
object
Navigation
{
fun
home
()
=
NavigationEvent
{
navDirections
{
destination
=
R
.
id
.
magiskFragment
}
navOptions
{
popUpTo
=
R
.
id
.
magiskFragment
}
fun
home
()
=
Magisk
NavigationEvent
{
navDirections
{
destination
=
MagiskFragment
::
class
}
navOptions
{
popUpTo
=
MagiskFragment
::
class
}
}
fun
superuser
()
=
NavigationEvent
{
navDirections
{
destination
=
R
.
id
.
superuserFragment
}
fun
superuser
()
=
Magisk
NavigationEvent
{
navDirections
{
destination
=
SuperuserFragment
::
class
}
}
fun
modules
()
=
NavigationEvent
{
navDirections
{
destination
=
R
.
id
.
modulesFragment
}
fun
modules
()
=
Magisk
NavigationEvent
{
navDirections
{
destination
=
ModulesFragment
::
class
}
}
fun
repos
()
=
NavigationEvent
{
navDirections
{
destination
=
R
.
id
.
reposFragment
}
fun
repos
()
=
Magisk
NavigationEvent
{
navDirections
{
destination
=
R
eposFragment
::
class
}
}
fun
hide
()
=
NavigationEvent
{
navDirections
{
destination
=
R
.
id
.
magiskHideFragment
}
fun
hide
()
=
Magisk
NavigationEvent
{
navDirections
{
destination
=
MagiskHideFragment
::
class
}
}
fun
log
()
=
NavigationEvent
{
navDirections
{
destination
=
R
.
id
.
logFragment
}
fun
log
()
=
MagiskNavigationEvent
{
navDirections
{
destination
=
LogFragment
::
class
}
}
fun
settings
()
=
MagiskNavigationEvent
{
navDirections
{
destination
=
SettingsFragment
::
class
}
}
...
...
app/src/main/java/com/topjohnwu/magisk/model/navigation/Navigator.kt
0 → 100644
View file @
ebab1265
package
com.topjohnwu.magisk.model.navigation
import
androidx.fragment.app.Fragment
import
kotlin.reflect.KClass
interface
Navigator
{
//TODO Elevate Fragment to MagiskFragment<*,*> once everything is on board with it
val
baseFragments
:
List
<
KClass
<
out
Fragment
>>
fun
navigateTo
(
event
:
MagiskNavigationEvent
)
}
\ No newline at end of file
app/src/main/java/com/topjohnwu/magisk/ui/MainActivity.kt
View file @
ebab1265
...
...
@@ -3,23 +3,42 @@ package com.topjohnwu.magisk.ui
import
android.content.Intent
import
android.os.Bundle
import
androidx.core.view.GravityCompat
import
androidx.
navigation.ui.setupWithNavController
import
androidx.
fragment.app.Fragment
import
com.topjohnwu.magisk.ClassMap
import
com.topjohnwu.magisk.Config
import
com.topjohnwu.magisk.R
import
com.topjohnwu.magisk.databinding.ActivityMainBinding
import
com.topjohnwu.magisk.model.navigation.Navigation
import
com.topjohnwu.magisk.ui.base.MagiskActivity
import
com.topjohnwu.magisk.ui.hide.MagiskHideFragment
import
com.topjohnwu.magisk.ui.log.LogFragment
import
com.topjohnwu.magisk.ui.module.ModulesFragment
import
com.topjohnwu.magisk.ui.module.ReposFragment
import
com.topjohnwu.magisk.ui.settings.SettingsFragment
import
com.topjohnwu.magisk.ui.superuser.SuperuserFragment
import
com.topjohnwu.magisk.utils.Utils
import
com.topjohnwu.net.Networking
import
com.topjohnwu.superuser.Shell
import
org.koin.androidx.viewmodel.ext.android.viewModel
import
kotlin.reflect.KClass
import
com.topjohnwu.magisk.ui.home.MagiskFragment
as
HomeFragment
open
class
MainActivity
:
MagiskActivity
<
MainViewModel
,
ActivityMainBinding
>()
{
override
val
layoutRes
:
Int
=
R
.
layout
.
activity_main
override
val
viewModel
:
MainViewModel
by
viewModel
()
override
val
navHostId
:
Int
=
R
.
id
.
main_nav_host
override
val
defaultPosition
:
Int
=
0
override
val
baseFragments
:
List
<
KClass
<
out
Fragment
>>
=
listOf
(
HomeFragment
::
class
,
SuperuserFragment
::
class
,
MagiskHideFragment
::
class
,
ModulesFragment
::
class
,
ReposFragment
::
class
,
LogFragment
::
class
,
SettingsFragment
::
class
)
/*
override
fun
getDarkTheme
():
Int
{
return
R
.
style
.
AppTheme_Dark
...
...
@@ -35,7 +54,6 @@ open class MainActivity : MagiskActivity<MainViewModel, ActivityMainBinding>() {
checkHideSection
()
setSupportActionBar
(
binding
.
mainInclude
.
mainToolbar
)
binding
.
navView
.
setupWithNavController
(
navController
)
}
override
fun
onBackPressed
()
{
...
...
app/src/main/java/com/topjohnwu/magisk/ui/MainViewModel.kt
View file @
ebab1265
package
com.topjohnwu.magisk.ui
import
android.view.MenuItem
import
com.topjohnwu.magisk.R
import
com.topjohnwu.magisk.model.navigation.Navigation
import
com.topjohnwu.magisk.ui.base.MagiskViewModel
...
...
@@ -8,4 +10,18 @@ class MainViewModel : MagiskViewModel() {
fun
navPressed
()
=
Navigation
.
Main
.
OPEN_NAV
.
publish
()
fun
navigationItemPressed
(
item
:
MenuItem
):
Boolean
{
when
(
item
.
itemId
)
{
R
.
id
.
magiskFragment
->
Navigation
.
home
()
R
.
id
.
superuserFragment
->
Navigation
.
superuser
()
R
.
id
.
magiskHideFragment
->
Navigation
.
hide
()
R
.
id
.
modulesFragment
->
Navigation
.
modules
()
R
.
id
.
reposFragment
->
Navigation
.
repos
()
R
.
id
.
logFragment
->
Navigation
.
log
()
R
.
id
.
settings
->
Navigation
.
settings
()
else
->
null
}
?.
publish
()
?.
let
{
return
@navigationItemPressed
true
}
return
false
}
}
app/src/main/java/com/topjohnwu/magisk/ui/base/MagiskActivity.kt
View file @
ebab1265
package
com.topjohnwu.magisk.ui.base
import
android.content.Intent
import
android.os.Bundle
import
androidx.annotation.CallSuper
import
androidx.core.net.toUri
import
androidx.databinding.ViewDataBinding
import
androidx.fragment.app.Fragment
import
com.ncapdevi.fragnav.FragNavController
import
com.ncapdevi.fragnav.FragNavTransactionOptions
import
com.skoumal.teanity.viewevents.ViewEvent
import
com.topjohnwu.magisk.model.navigation.MagiskAnimBuilder
import
com.topjohnwu.magisk.model.navigation.MagiskNavigationEvent
import
com.topjohnwu.magisk.model.navigation.Navigator
import
com.topjohnwu.magisk.utils.Utils
import
timber.log.Timber
import
kotlin.reflect.KClass
abstract
class
MagiskActivity
<
ViewModel
:
MagiskViewModel
,
Binding
:
ViewDataBinding
>
:
MagiskLeanbackActivity
<
ViewModel
,
Binding
>()
{
MagiskLeanbackActivity
<
ViewModel
,
Binding
>(),
FragNavController
.
RootFragmentListener
,
Navigator
{
override
val
numberOfRootFragments
:
Int
get
()
=
baseFragments
.
size
override
val
baseFragments
:
List
<
KClass
<
out
Fragment
>>
=
listOf
()
protected
open
val
defaultPosition
:
Int
=
0
protected
val
navigationController
by
lazy
{
if
(
navHostId
==
0
)
throw
IllegalStateException
(
"Did you forget to override \"navHostId\"?"
)
FragNavController
(
supportFragmentManager
,
navHostId
)
}
override
fun
onCreate
(
savedInstanceState
:
Bundle
?)
{
super
.
onCreate
(
savedInstanceState
)
navigationController
.
apply
{
rootFragmentListener
=
this
@MagiskActivity
initialize
(
defaultPosition
,
savedInstanceState
)
}
}
override
fun
onSaveInstanceState
(
outState
:
Bundle
)
{
super
.
onSaveInstanceState
(
outState
)
navigationController
.
onSaveInstanceState
(
outState
)
}
@CallSuper
override
fun
onEventDispatched
(
event
:
ViewEvent
)
{
super
.
onEventDispatched
(
event
)
when
(
event
)
{
is
MagiskNavigationEvent
->
navigateTo
(
event
)
}
}
override
fun
getRootFragment
(
index
:
Int
)
=
baseFragments
[
index
].
java
.
newInstance
()
override
fun
navigateTo
(
event
:
MagiskNavigationEvent
)
{
val
directions
=
event
.
navDirections
navigationController
.
defaultTransactionOptions
=
FragNavTransactionOptions
.
newBuilder
()
.
customAnimations
(
event
.
animOptions
)
.
build
()
navigationController
.
currentStack
?.
indexOfFirst
{
it
.
javaClass
==
event
.
navOptions
.
popUpTo
}
?.
let
{
if
(
it
==
-
1
)
null
else
it
}
// invalidate if class is not found
?.
let
{
if
(
event
.
navOptions
.
inclusive
)
it
+
1
else
it
}
?.
let
{
navigationController
.
popFragments
(
it
)
}
when
(
directions
.
isActivity
)
{
true
->
navigateToActivity
(
event
)
else
->
navigateToFragment
(
event
)
}
}
private
fun
navigateToActivity
(
event
:
MagiskNavigationEvent
)
{
val
destination
=
event
.
navDirections
.
destination
?.
java
?:
let
{
Timber
.
e
(
"Cannot navigate to null destination"
)
return
}
val
options
=
event
.
navOptions
Intent
(
this
,
destination
)
.
putExtras
(
event
.
navDirections
.
args
)
.
apply
{
if
(
options
.
singleTop
)
addFlags
(
Intent
.
FLAG_ACTIVITY_SINGLE_TOP
)
if
(
options
.
clearTask
)
addFlags
(
Intent
.
FLAG_ACTIVITY_CLEAR_TASK
)
}
.
let
{
startActivity
(
it
)
}
}
private
fun
navigateToFragment
(
event
:
MagiskNavigationEvent
)
{
val
destination
=
event
.
navDirections
.
destination
?.
java
?:
let
{
Timber
.
e
(
"Cannot navigate to null destination"
)
return
}
when
(
val
index
=
baseFragments
.
indexOfFirst
{
it
.
java
.
name
==
destination
.
name
})
{
-
1
->
destination
.
newInstance
()
.
apply
{
arguments
=
event
.
navDirections
.
args
}
.
let
{
navigationController
.
pushFragment
(
it
)
}
// When it's desired that fragments of same class are put on top of one another edit this
else
->
navigationController
.
switchTab
(
index
)
}
}
override
fun
onBackPressed
()
{
val
fragment
=
navigationController
.
currentFrag
as
?
MagiskFragment
<*,
*>
if
(
fragment
?.
onBackPressed
()
==
true
)
{
return
}
try
{
navigationController
.
popFragment
()
}
catch
(
e
:
UnsupportedOperationException
)
{
super
.
onBackPressed
()
}
}
fun
openUrl
(
url
:
String
)
=
Utils
.
openLink
(
this
,
url
.
toUri
())
private
fun
FragNavTransactionOptions
.
Builder
.
customAnimations
(
options
:
MagiskAnimBuilder
)
=
customAnimations
(
options
.
enter
,
options
.
exit
,
options
.
popEnter
,
options
.
popExit
)
}
app/src/main/java/com/topjohnwu/magisk/ui/base/MagiskFragment.kt
View file @
ebab1265
package
com.topjohnwu.magisk.ui.base
import
androidx.annotation.CallSuper
import
androidx.databinding.ViewDataBinding
import
androidx.fragment.app.Fragment
import
com.skoumal.teanity.view.TeanityFragment
import
com.skoumal.teanity.viewevents.ViewEvent
import
com.topjohnwu.magisk.model.navigation.MagiskNavigationEvent
import
com.topjohnwu.magisk.model.navigation.Navigator
import
kotlin.reflect.KClass
abstract
class
MagiskFragment
<
ViewModel
:
MagiskViewModel
,
Binding
:
ViewDataBinding
>
:
TeanityFragment
<
ViewModel
,
Binding
>()
{
TeanityFragment
<
ViewModel
,
Binding
>()
,
Navigator
{
protected
val
magiskActivity
get
()
=
activity
as
MagiskActivity
<*,
*>
fun
openLink
(
url
:
String
)
{
magiskActivity
.
openUrl
(
url
)
// We don't need nested fragments
override
val
baseFragments
:
List
<
KClass
<
Fragment
>>
=
listOf
()
override
fun
navigateTo
(
event
:
MagiskNavigationEvent
)
=
magiskActivity
.
navigateTo
(
event
)
@CallSuper
override
fun
onEventDispatched
(
event
:
ViewEvent
)
{
super
.
onEventDispatched
(
event
)
when
(
event
)
{
is
MagiskNavigationEvent
->
navigateTo
(
event
)
}
}
fun
openLink
(
url
:
String
)
=
magiskActivity
.
openUrl
(
url
)
open
fun
onBackPressed
():
Boolean
=
false
}
app/src/main/java/com/topjohnwu/magisk/utils/DataBindingAdapters.kt
View file @
ebab1265
...
...
@@ -6,6 +6,8 @@ import androidx.annotation.DrawableRes
import
androidx.appcompat.widget.AppCompatImageView
import
androidx.appcompat.widget.Toolbar
import
androidx.databinding.BindingAdapter
import
androidx.drawerlayout.widget.DrawerLayout
import
com.google.android.material.navigation.NavigationView
@BindingAdapter
(
"onNavigationClick"
)
...
...
@@ -13,6 +15,17 @@ fun setOnNavigationClickedListener(view: Toolbar, listener: View.OnClickListener
view
.
setNavigationOnClickListener
(
listener
)
}
@BindingAdapter
(
"onNavigationClick"
)
fun
setOnNavigationClickedListener
(
view
:
NavigationView
,
listener
:
NavigationView
.
OnNavigationItemSelectedListener
)
{
view
.
setNavigationItemSelectedListener
{
(
view
.
parent
as
?
DrawerLayout
)
?.
closeDrawers
()
listener
.
onNavigationItemSelected
(
it
)
}
}
@BindingAdapter
(
"srcCompat"
)
fun
setImageResource
(
view
:
AppCompatImageView
,
@DrawableRes
resId
:
Int
)
{
view
.
setImageResource
(
resId
)
...
...
app/src/main/res/layout/activity_main.xml
View file @
ebab1265
...
...
@@ -29,6 +29,7 @@
android:layout_height=
"match_parent"
android:layout_gravity=
"start"
android:fitsSystemWindows=
"true"
onNavigationClick=
"@{(item) -> viewModel.navigationItemPressed(item)}"
app:menu=
"@menu/drawer"
/>
</androidx.drawerlayout.widget.DrawerLayout>
...
...
app/src/main/res/layout/activity_main_content.xml
View file @
ebab1265
...
...
@@ -31,15 +31,12 @@
</com.google.android.material.appbar.AppBarLayout>
<
fragmen
t
<
FrameLayou
t
android:id=
"@+id/main_nav_host"
android:name=
"androidx.navigation.fragment.NavHostFragment"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:background=
"?android:windowBackground"
app:defaultNavHost=
"true"
app:layout_behavior=
"@string/appbar_scrolling_view_behavior"
app:navGraph=
"@navigation/navigation_main"
/>
app:layout_behavior=
"@string/appbar_scrolling_view_behavior"
/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
...
...
app/src/main/res/navigation/navigation_main.xml
deleted
100644 → 0
View file @
0e5417a1
<?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/navigation_main"
app:startDestination=
"@id/magiskFragment"
>
<fragment
android:id=
"@+id/magiskFragment"
android:name=
"com.topjohnwu.magisk.ui.home.MagiskFragment"
android:label=
"fragment_magisk"
tools:layout=
"@layout/fragment_magisk"
/>
<fragment
android:id=
"@+id/superuserFragment"
android:name=
"com.topjohnwu.magisk.ui.superuser.SuperuserFragment"
android:label=
"fragment_superuser"
tools:layout=
"@layout/fragment_superuser"
/>
<fragment
android:id=
"@+id/modulesFragment"
android:name=
"com.topjohnwu.magisk.ui.module.ModulesFragment"
android:label=
"fragment_modules"
tools:layout=
"@layout/fragment_modules"
/>
<fragment
android:id=
"@+id/reposFragment"
android:name=
"com.topjohnwu.magisk.ui.module.ReposFragment"
android:label=
"fragment_repos"
tools:layout=
"@layout/fragment_repos"
/>
<fragment
android:id=
"@+id/magiskHideFragment"
android:name=
"com.topjohnwu.magisk.ui.hide.MagiskHideFragment"
android:label=
"fragment_magisk_hide"
tools:layout=
"@layout/fragment_magisk_hide"
/>
<fragment
android:id=
"@+id/logFragment"
android:name=
"com.topjohnwu.magisk.ui.log.LogFragment"
android:label=
"fragment_log"
tools:layout=
"@layout/fragment_log"
/>
</navigation>
build.gradle
View file @
ebab1265
...
...
@@ -17,7 +17,6 @@ buildscript {
classpath
'com.android.tools:r8:1.4.79'
classpath
'com.android.tools.build:gradle:3.3.2'
classpath
'org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.30'
classpath
'androidx.navigation:navigation-safe-args-gradle-plugin:2.0.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment