Skip to content

Commit

Permalink
V1 (#1)
Browse files Browse the repository at this point in the history
* Minor changes
* Simplified usage of settings.
* Fixed receiver issue
* Fixed nested crashing by implementing Parcelable and base data setting class
* Refusing to register if it is an instance of SettingActivity that already has its own implementation
* Using coroutine to prevent frame freeze when building
* Component update
  • Loading branch information
bskjon authored May 12, 2023
1 parent 38d9681 commit 9bf46a0
Show file tree
Hide file tree
Showing 41 changed files with 1,324 additions and 529 deletions.
1 change: 1 addition & 0 deletions .idea/gradle.xml

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

2 changes: 1 addition & 1 deletion .idea/misc.xml

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

105 changes: 105 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,107 @@
Settings library

# Building Settings
In this library, settings are composed in Groups, then Key and Value
To keep the settings organized and easily accessible, the setting is encapsulated by a sealed class, which is the group (you can also use KeyBasedSetting as well).
In order to compose a setting using this library you will start with this:
```kotlin
sealed class MySetting(key: String) : GroupBasedSetting(group = "MyGroup", key = key)
```
This will let you access your settings by `MySetting.<your setting class>` <br />
So to create a setting that you can use, access and read:
```kotlin
sealed class MySetting(key: String) : GroupBasedSetting(group = "MyGroup", key = key) {

class FancyMode : MySetting("Enable fancy mode")

}
```
In this case we create a setting FancyMode with the `SharedPreference` key "Enable fancy mode" <br />

You can now access the setting by `MySetting.FancyMode()` </br>
From there you can decide what you want it to be. <br />
For now you can get the values directly, or you can make it return a <strong>SettingObject</strong> that you can share with the library or among your own components. This can be done by `.asReactive()` or `.asStatic()`


<br />
<br />

# Automatically generate setting components

## Setup Activity
1. Make the activity extend: SettingsRenderActivity
```kotlin
class SettingsActivity : SettingsRenderActivity()
```
SettingsRenderActivity is based on AppCompatActivity

2. Add a Linear Layout in the layout file
3. return the Linear Layout in the `getRenderContainer()` function
If you want to make the layout render your created setting components, override the function `preCreatedSettingItems()` and make it return your list of settings


## Automatic render
`preCreatedSettingItems` requires that you return an arrayListOf `SettingComponentDescriptorBase` <br>
All automatically generated and rendered settings ui components are based upon a `SettingComponentDescriptorBuilder`
and is created like this
```kotlin
SettingComponentDescriptorBuilder(this)
.setGroupName(no.iktdev.demoapplication.R.string.setting_group_title_switchy)
.setTitle("Switch 1")
.setIcon(no.iktdev.setting.R.drawable.ic_android_black_24dp)
.setType(SettingComponentType.SWITCH)
.setSetting(Settings.SwitchTest.ImFancyNoOne())
.build()
```
About `SettingComponentDescriptorBuilder`
```python
SettingComponentDescriptorBuilder(this): where "this" is context
GroupName: is String Resource
Title: is String Resource or String
Icon: is Drawable Resource Id
Type: is the type to be generated
Setting: is either StaticSetting or ReactiveSetting. default is StaticSetting
```
Current types that are supported for auto-gen is:
- Clickable
- Switch (toggle switch)
- Launch (starts external page)
- Dropdown (creates a spinner)
- Popout (creates a dropdown)
- Slider (numeric)



### Single level

```kotlin
arrayListOf<SettingComponentDescriptorBase>(
SettingComponentDescriptorBuilder(this)
.setGroupName(no.iktdev.demoapplication.R.string.setting_group_title_switchy)
.setTitle("Switch 1")
.setIcon(no.iktdev.setting.R.drawable.ic_android_black_24dp)
.setType(SettingComponentType.SWITCH)
.setSetting(Settings.SwitchTest.ImFancyNoOne())
.build()
)

```

### Multi level
```kotlin
arrayListOf<SettingComponentDescriptorBase>(
SettingComponentDescriptorBuilder(this)
.setGroupName(R.string.setting_title2)
.setTitle(R.string.setting_title2)
.setIcon(no.iktdev.setting.R.drawable.ic_android_black_24dp)
.setType(SettingComponentType.CLICKABLE)
.setPayload(ActionableComponentDataBuilder()
.setTitle("Fancy Section")
.setActivityClass(SettingActivity::class.java)
.applyPayload(componentPassKey, external)
.build()
)
.build()
)

```
12 changes: 11 additions & 1 deletion app/src/main/java/no/iktdev/demoapplication/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,25 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import no.iktdev.demoapplication.databinding.ActivityMainBinding
import no.iktdev.demoapplication.services.LockscreenWidgetActivity
import no.iktdev.setting.ReactiveSettingsReceiver
import no.iktdev.setting.access.GroupedReactiveSetting

class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = ActivityMainBinding.inflate(LayoutInflater.from(this))
setContentView(binding.root)

ReactiveSettingsReceiver(this, object : ReactiveSettingsReceiver.Listener {
override fun onReactiveGroupSettingsChanged(group: String, key: String, payload: Any?) {
super.onReactiveGroupSettingsChanged(group, key, payload)
Toast.makeText(this@MainActivity, "${this@MainActivity::class.java.simpleName} Setting group: $group got changed value for key $key with value $payload", Toast.LENGTH_LONG).show()
}
})

binding.toastMe.setOnClickListener {
Toast.makeText(this, "Potet klikka", Toast.LENGTH_LONG).show()
val group = GroupedReactiveSetting("Main", "TestMain").asReactive()
group.setBoolean(this, !group.getBoolean(this))
}

binding.launcTest.setOnClickListener(Uri.parse("https://iktdev.no"))
Expand Down
137 changes: 84 additions & 53 deletions app/src/main/java/no/iktdev/demoapplication/SettingActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,117 +3,127 @@ package no.iktdev.demoapplication
import android.os.Bundle
import android.view.LayoutInflater
import android.widget.LinearLayout
import android.widget.Toast
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import no.iktdev.demoapplication.databinding.ActivitySettingBinding
import no.iktdev.setting.access.ReactiveSettingDefined
import no.iktdev.setting.access.SettingDefined
import no.iktdev.setting.factory.ThemeType
import no.iktdev.setting.ReactiveSettingsReceiver
import no.iktdev.setting.model.*
import no.iktdev.setting.model.builder.ActionableComponentDataBuilder
import no.iktdev.setting.model.builder.LaunchableComponentDataBuilder
import no.iktdev.setting.model.builder.SettingComponentDescriptorBuilder
import no.iktdev.setting.ui.ThemeType
import no.iktdev.setting.ui.Theming
import no.iktdev.setting.ui.activities.SettingsRenderActivity

class SettingActivity : SettingsRenderActivity() {
lateinit var binding: ActivitySettingBinding
private var reactiveSettingsReceiver: ReactiveSettingsReceiver? = null

val cantKeepMeOn = SettingDefined("setting_cant_keep_me_on", "setting_cant_keep_me_on")

override fun onCreate(savedInstanceState: Bundle?) {
// super.onCreate(savedInstanceState)
binding = ActivitySettingBinding.inflate(LayoutInflater.from(this))
setContentView(binding.root)
toolbar = binding.toolbar
setCollapsingToolbar(binding.appBar, binding.toolbarLayout, binding.toolbarTitle)
super.onCreate(savedInstanceState)
reactiveSettingsReceiver = ReactiveSettingsReceiver(this, object : ReactiveSettingsReceiver.Listener {
override fun onReactiveGroupSettingsChanged(group: String, key: String, payload: Any?) {
super.onReactiveGroupSettingsChanged(group, key, payload)
Toast.makeText(this@SettingActivity, "${this@SettingActivity::class.java.simpleName} Setting group: $group got changed value for key $key with value $payload", Toast.LENGTH_LONG).show()
}
})
titleChange.observe(this) {
title = it
binding.toolbarLayout.title = title
binding.toolbarTitle.text = title
binding.toolbarTitleLarge.text = title
}
cantKeepMeOn.reader(this).registerOnSharedPreferenceChangeListener { _, _ ->
Settings.SwitchTest.ToggleMe().setObserver(this) { _, _ ->
GlobalScope.launch {
delay(1000)
if (cantKeepMeOn.getBoolean(this@SettingActivity, false)) {
cantKeepMeOn.setBoolean(this@SettingActivity,false)
if (Settings.SwitchTest.ToggleMe().getBoolean(this@SettingActivity, false)) {
Settings.SwitchTest.ToggleMe().setBoolean(this@SettingActivity, false)
}
}
}
}

override fun onReactiveSettingsChanged(group: String, key: String, payload: Any) {
super.onReactiveSettingsChanged(group, key, payload)
}

override fun preCreatedSettingItems(): List<SettingComponentDescriptorBase> {
val external = arrayListOf<SettingComponentDescriptorBase>(
SettingComponentDescriptorBuilder(this)
.setGroupName(R.string.setting_cant_keep_me_on)
.setTitle(R.string.setting_cant_keep_me_on)
.setGroupName(R.string.setting_group_title_switchy)
.setTitle("Switch One")
.setDescription(R.string.setting_description)
.setIcon(no.iktdev.setting.R.drawable.ic_android_black_24dp)
.setType(SettingComponentType.SWITCH)
.setSetting(cantKeepMeOn)
.setSetting(Settings.SwitchTest.ImFancyNoOne())
.build(),
SettingComponentDescriptorBuilder(this)
.setGroupName(R.string.setting_cant_keep_me_on)
.setTitle("PlayWithMe")
.setGroupName(R.string.setting_group_title_switchy)
.setTitle("Switch Two")
.setDescription(R.string.setting_description)
.setIcon(no.iktdev.setting.R.drawable.ic_android_black_24dp)
.setType(SettingComponentType.CLICKABLE)
.setPayload(ActionableComponentDataBuilder()
.setTitle("Im Fancy")
.setActivityClass(SettingActivity::class.java)
.applyPayload(componentPassKey, arrayListOf<SettingComponentDescriptorBase>(
SettingComponentDescriptorBuilder(this)
.setGroupName(R.string.setting_cant_keep_me_on)
.setTitle("PlayWithMe")
.setIcon(no.iktdev.setting.R.drawable.ic_android_black_24dp)
.setType(SettingComponentType.CLICKABLE)
.setPayload(ActionableComponentDataBuilder()
.setActivityClass(SettingActivity2::class.java)
.build())
.build(),
))
.build())
.setType(SettingComponentType.SWITCH)
.setSetting(Settings.SwitchTest.ImFancyNoTwo())
.build(),
SettingComponentDescriptorBuilder(this)
.setGroupName(R.string.setting_title)
.setTitle(R.string.setting_title)
.setGroupName(R.string.setting_group_title_switchy)
.setTitle("Switch Three")
.setDescription(R.string.setting_description)
.setIcon(no.iktdev.setting.R.drawable.ic_android_black_24dp)
.setType(SettingComponentType.SWITCH)
.setSetting(SettingDefined("test", "fancy"))
.setSetting(Settings.SwitchTest.ImFancyNoThree())
.build(),
SettingComponentDescriptorBuilder(this)
.setGroupName(R.string.setting_title2)
.setTitle(R.string.setting_title2)
.setGroupName(R.string.setting_group_title_switchy)
.setTitle("Don´t turn me on")
.setDescription(R.string.setting_description)
.setIcon(no.iktdev.setting.R.drawable.ic_android_black_24dp)
.setType(SettingComponentType.SWITCH)
.setSetting(SettingDefined("test2", "fancy2"))
.setSetting(Settings.SwitchTest.ToggleMe())
.build(),
SettingComponentDescriptorBuilder(this)
.setGroupName(R.string.setting_title)
.setTitle(R.string.setting_title)
.setGroupName(R.string.setting_group_title_switchy)
.setTitle("Switch Reactive")
.setDescription(R.string.setting_description)
.setIcon(no.iktdev.setting.R.drawable.ic_android_black_24dp)
.setType(SettingComponentType.SWITCH)
.setSetting(Settings.SwitchTest.ReactiveToggle().asReactive())
.build(),
SettingComponentDescriptorBuilder(this)
.setGroupName(R.string.setting_group_title_switchy)
.setTitle("Switch")
.setDescription("With no icon")
.setType(SettingComponentType.SWITCH)
.setSetting(Settings.SwitchTest.ReactiveToggle().asReactive())
.build(),


SettingComponentDescriptorBuilder(this)
.setGroupName(R.string.setting_group_title_launchy)
.setTitle(R.string.setting_group_title_launchy)
.setIcon(no.iktdev.setting.R.drawable.ic_android_black_24dp)
.setType(SettingComponentType.LAUNCH)
.setPayload(LaunchableComponentDataBuilder()
.setUri("https://iktdev.no")
.build()
)
.build(),

SettingComponentDescriptorBuilder(this)
.setGroupName(R.string.setting_title)
.setTitle(R.string.setting_title)
.setGroupName(R.string.setting_group_title_slidy)
.setTitle("Set me to fancy number")
.setType(SettingComponentType.SLIDER)
.setSetting(SettingDefined("test", "sliding"))
.setSetting(Settings.ValueSelector.PercentageIsFun())
.build()
)
return external + listOf(
SettingComponentDescriptorBuilder(this)
.setGroupName(R.string.setting_title2)
.setTitle(R.string.setting_title2)
.setGroupName(R.string.setting_group_title_launchy)
.setTitle("I will crash")
.setIcon(no.iktdev.setting.R.drawable.ic_android_black_24dp)
.setType(SettingComponentType.CLICKABLE)
.setPayload(ActionableComponentDataBuilder()
Expand All @@ -123,11 +133,32 @@ class SettingActivity : SettingsRenderActivity() {
.build()
)
.build(),
SettingComponentDescriptorBuilder(this)
.setGroupName(R.string.setting_group_title_launchy)
.setTitle("Click me")
.setIcon(no.iktdev.setting.R.drawable.ic_android_black_24dp)
.setType(SettingComponentType.CLICKABLE)
.setPayload(ActionableComponentDataBuilder()
.setTitle("Im Fancy")
.setActivityClass(SettingActivity::class.java)
.applyPayload(componentPassKey, arrayListOf<SettingComponentDescriptorBase>(
SettingComponentDescriptorBuilder(this)
.setGroupName(R.string.setting_cant_keep_me_on)
.setTitle("Click me")
.setIcon(no.iktdev.setting.R.drawable.ic_android_black_24dp)
.setType(SettingComponentType.CLICKABLE)
.setPayload(ActionableComponentDataBuilder()
.setActivityClass(SettingActivity2::class.java)
.build())
.build(),
))
.build())
.build(),
SettingComponentDescriptorBuilder(this)
.setGroupName(R.string.setting_title)
.setTitle(R.string.setting_title)
.setType(SettingComponentType.DROPDOWN)
.setSetting(ReactiveSettingDefined("slider", "fancyness"))
.setSetting(Settings.ValueSelector.SelectSomething().asReactive())
.setPayload(ComponentData(arrayListOf<DropdownItem>(
DropdownItem("Stringy", "Potatis"),
DropdownItem("Inti", 0)
Expand All @@ -138,7 +169,7 @@ class SettingActivity : SettingsRenderActivity() {
.setTitle(R.string.setting_title)
.setType(SettingComponentType.POPOUT_SELECT)
.setIcon(no.iktdev.setting.R.drawable.ic_android_black_24dp)
.setSetting(SettingDefined("popout", "fancyness"))
.setSetting(Settings.ValueSelector.SelectSomethingElse())
.setPayload(ComponentData(arrayListOf<DropdownItem>(
DropdownItem("Stringy", "Potatis"),
DropdownItem("Inti", 0),
Expand All @@ -149,17 +180,17 @@ class SettingActivity : SettingsRenderActivity() {
)
}

override fun themes(): List<ThemeItem> {
override fun themes(): List<Theming> {
return listOf(
ThemeItem(ThemeType.NORMAL, no.iktdev.setting.R.style.SettingComponents),
ThemeItem(ThemeType.START, no.iktdev.setting.R.style.SettingComponents_Top),
ThemeItem(ThemeType.END, no.iktdev.setting.R.style.SettingComponents_Bottom),
ThemeItem(ThemeType.SINGLE, no.iktdev.setting.R.style.SettingComponents_Single),
Theming(ThemeType.NORMAL, no.iktdev.setting.R.style.SettingComponents),
Theming(ThemeType.START, no.iktdev.setting.R.style.SettingComponents_Top),
Theming(ThemeType.END, no.iktdev.setting.R.style.SettingComponents_Bottom),
Theming(ThemeType.SINGLE, no.iktdev.setting.R.style.SettingComponents_Single),
)
}

override fun getRenderContainer(): LinearLayout {
return binding.content.renderContainer
return binding.content.renderContainer
}

}
Loading

0 comments on commit 9bf46a0

Please sign in to comment.