[m] Prepare Release

This commit is contained in:
soraefir 2024-04-04 00:14:33 +02:00
parent ce2055ee97
commit 65be3526a6
Signed by: sora
GPG Key ID: A362EA0491E2EEA0
27 changed files with 468 additions and 5268 deletions

64
.github/workflow/build.yml vendored Normal file
View File

@ -0,0 +1,64 @@
#file: noinspection SpellCheckingInspection
name: CI-Android APK
env:
main_project_module: app
playstore_name: Beans
on:
push:
branches: [ main ]
tags:
- '**'
pull_request:
branches: [ main ]
workflow_dispatch:
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- name: set up secrets
run: |
echo "${{ secrets.RELEASE_KEYSTORE }}" > keystore.asc
echo "${{ secrets.RELEASE_KEY}}" > key.asc
gpg -d --passphrase "${{ secrets.RELEASE_KEYSTORE_PASSWORD }}" --batch keystore.asc > app/keystore.properties
gpg -d --passphrase "${{ secrets.RELEASE_KEYSTORE_PASSWORD }}" --batch key.asc > app/key.jks
- uses: gradle/wrapper-validation-action@v2
- name: create and checkout branch
if: github.event_name == 'pull_request'
env:
BRANCH: ${{ github.head_ref }}
run: git checkout -B "$BRANCH"
- name: set up JDK
uses: actions/setup-java@v4
with:
java-version: 17
distribution: "temurin"
cache: 'gradle'
- name: Build APK
run: ./gradlew assemble
# - name: Upload APK
# uses: actions/upload-artifact@v4
# with:
# name: app.apk
# path: app/build/outputs/apk/release/app-release.apk
- name: Release
uses: softprops/action-gh-release@v2
if: startsWith(github.ref, 'refs/tags/')
with:
files: |
app/build/outputs/apk/release/app-release.apk

8
.gitignore vendored
View File

@ -16,4 +16,12 @@ temp/
.externalNativeBuild
.cxx
.yarn
app/build/
app/debug/
app/release/
captures/
.externalNativeBuild
.cxx
local.properties
keystore.properties
key.jks

View File

@ -14,15 +14,25 @@ android {
minSdk 28
targetSdk 34
versionCode 1
versionName "1.0"
versionName "0.1a"
}
signingConfigs {
create("release") {
keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword']
storeFile file(keystoreProperties['storeFile'])
storePassword keystoreProperties['storePassword']
}
}
buildTypes {
release {
minifyEnabled true
shrinkResources false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.debug
signingConfig = signingConfigs.getByName("release")
}
}
compileOptions {
@ -49,6 +59,9 @@ android {
}
}
aboutLibraries {
exclusionPatterns = [~"androidx.*", ~"com.google.android.*", ~"org.jetbrains.*"]
}
dependencies {
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs_nio:2.0.4'

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 6.5 MiB

View File

@ -1291,7 +1291,7 @@ IRL_WD|IRL|Waterford|1857
IRL_WH|IRL|Westmeath|1835
IRL_WX|IRL|Wexford|2367
IRL_WW|IRL|Wicklow|2022
IRL_CK|IRL|NA|7488
IRL_CK|IRL|Cork|7488
IMN_AY|IMN|Ramsey|4
IMN_RU|IMN|Port Saint Mary|2
IMN_MC|IMN|Michael|34
@ -1931,7 +1931,7 @@ MMR_SA|MMR|Sagaing|96034
MMR_SH|MMR|Shan|156514
MMR_TN|MMR|Tanintharyi|41535
MMR_YA|MMR|Yangon|9607
NAM_KA|NAM|!Karas|161821
NAM_KA|NAM|Karas|161821
NAM_ER|NAM|Erongo|63918
NAM_HA|NAM|Hardap|110185
NAM_OK|NAM|Kavango|48945
@ -1968,7 +1968,7 @@ NLD_FL|NLD|Flevoland|1466
NLD_FR|NLD|Fryslân|3573
NLD_GE|NLD|Gelderland|5102
NLD_GR|NLD|Groningen|2370
NLD_NA|NLD|NA|3143
NLD_SH|NLD|Zuid-Holland|3143
NLD_LI|NLD|Limburg|2159
NLD_NB|NLD|Noord-Brabant|5082
NLD_NH|NLD|Noord-Holland|2872
@ -3532,4 +3532,4 @@ Z05_UT|IND|Uttarakhand|259
Z09_UT|IND|Uttarakhand|987
Z06_JK|PAK|Azad Kashmir|13931
Z06_NA|PAK|Gilgit-Baltistan|68053
NA_NA|GBR|NA|417
GBR_EN|GBR|England|417

View File

@ -4,36 +4,31 @@ import android.os.Bundle
import android.view.MenuItem
import androidx.activity.addCallback
import androidx.appcompat.app.AppCompatActivity
import androidx.viewpager2.widget.ViewPager2
import com.google.android.material.tabs.TabLayout
import com.google.android.material.tabs.TabLayoutMediator
import net.helcel.beans.R
import net.helcel.beans.activity.adapter.ViewPagerAdapter
import net.helcel.beans.activity.fragment.EditPlaceFragment
import net.helcel.beans.countries.World
import net.helcel.beans.databinding.ActivityEditBinding
import net.helcel.beans.helper.Theme.createActionBar
class EditActivity : AppCompatActivity() {
private lateinit var viewPager: ViewPager2
private lateinit var tabLayout: TabLayout
private lateinit var _binding: ActivityEditBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
_binding = ActivityEditBinding.inflate(layoutInflater)
setContentView(R.layout.activity_edit)
setContentView(_binding.root)
createActionBar(this, getString(R.string.action_edit))
viewPager = findViewById(R.id.pager)
tabLayout = findViewById(R.id.tab)
val adapter = ViewPagerAdapter(supportFragmentManager, lifecycle, viewPager)
viewPager.adapter = adapter
val adapter = ViewPagerAdapter(supportFragmentManager, lifecycle, _binding.pager)
_binding.pager.adapter = adapter
adapter.addFragment(null, EditPlaceFragment(World.WWW, adapter))
TabLayoutMediator(tabLayout, viewPager) { tab, position ->
TabLayoutMediator(_binding.tab, _binding.pager) { tab, position ->
tab.text = adapter.getLabel(position)
}.attach()

View File

@ -4,15 +4,13 @@ import android.content.Intent
import android.graphics.drawable.PictureDrawable
import android.os.Bundle
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.MenuProvider
import com.caverock.androidsvg.RenderOptions
import com.github.chrisbanes.photoview.PhotoView
import net.helcel.beans.R
import net.helcel.beans.countries.GeoLocImporter
import net.helcel.beans.helper.Data.loadData
import net.helcel.beans.databinding.ActivityMainBinding
import net.helcel.beans.helper.Data
import net.helcel.beans.helper.Settings
import net.helcel.beans.helper.Theme.colorWrapper
import net.helcel.beans.svg.CSSWrapper
@ -20,8 +18,7 @@ import net.helcel.beans.svg.SVGWrapper
class MainActivity : AppCompatActivity() {
private lateinit var photoView: PhotoView
private lateinit var _binding: ActivityMainBinding
private lateinit var psvg: SVGWrapper
private lateinit var css: CSSWrapper
@ -31,55 +28,36 @@ class MainActivity : AppCompatActivity() {
super.onRestart()
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.menu_main, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
val d = when (item.itemId) {
R.id.action_edit -> EditActivity::class.java
R.id.action_stats -> StatActivity::class.java
R.id.action_settings -> SettingsActivity::class.java
else -> throw Exception("Non Existent Menu Item")
}
startActivity(Intent(this@MainActivity, d))
return true
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Create action bar
_binding = ActivityMainBinding.inflate(layoutInflater)
Settings.start(this)
supportActionBar?.setBackgroundDrawable(colorWrapper(this, android.R.attr.colorPrimary))
// restore app theme & settings upon startup
Settings.start(this)
// Create menu in action bar
addMenuProvider(object : MenuProvider {
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
menuInflater.inflate(R.menu.menu_main, menu)
}
setContentView(_binding.root)
override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
return when (menuItem.itemId) {
R.id.action_edit -> {
startActivity(Intent(this@MainActivity, EditActivity::class.java))
true
}
R.id.action_stats -> {
startActivity(Intent(this@MainActivity, StatActivity::class.java))
true
}
R.id.action_settings -> {
startActivity(Intent(this@MainActivity, SettingsActivity::class.java))
true
}
else -> {
false
}
}
}
})
// Populate map from list of countries
setContentView(R.layout.activity_main)
photoView = findViewById(R.id.photo_view)
photoView.minimumScale = 1f
photoView.maximumScale = 40f
_binding.photoView.minimumScale = 1f
_binding.photoView.maximumScale = 40f
GeoLocImporter.importStates(this)
loadData(this, Int.MIN_VALUE)
Data.loadData(this, Int.MIN_VALUE)
psvg = SVGWrapper(this)
css = CSSWrapper(this)
@ -88,9 +66,8 @@ class MainActivity : AppCompatActivity() {
private fun refreshMap() {
val opt: RenderOptions = RenderOptions.create()
css.refresh()
opt.css(css.get())
photoView.setImageDrawable(PictureDrawable(psvg.get()?.renderToPicture(opt)))
_binding.photoView.setImageDrawable(PictureDrawable(psvg.get()?.renderToPicture(opt)))
}
}

View File

@ -4,32 +4,30 @@ import android.content.res.ColorStateList
import android.graphics.Color
import android.graphics.Typeface
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.fragment.app.FragmentActivity
import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.checkbox.MaterialCheckBox
import net.helcel.beans.R
import net.helcel.beans.activity.fragment.EditPlaceColorFragment
import net.helcel.beans.activity.fragment.EditPlaceFragment
import net.helcel.beans.countries.GeoLoc
import net.helcel.beans.databinding.ItemListGeolocBinding
import net.helcel.beans.helper.Data
import net.helcel.beans.helper.Settings
import net.helcel.beans.helper.Theme.colorWrapper
class GeolocListAdapter(
private val ctx: EditPlaceFragment, val l: GeoLoc, private val pager: ViewPagerAdapter
private val ctx: EditPlaceFragment, private val l: GeoLoc, private val pager: ViewPagerAdapter
) : RecyclerView.Adapter<GeolocListAdapter.FoldingListViewHolder>() {
private lateinit var view: View
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): FoldingListViewHolder {
view = LayoutInflater
.from(viewGroup.context)
.inflate(R.layout.item_list_geoloc, viewGroup, false)
return FoldingListViewHolder(ctx.requireActivity(), view)
val binding = ItemListGeolocBinding.inflate(
LayoutInflater.from(viewGroup.context),
viewGroup,
false
)
return FoldingListViewHolder(ctx.requireActivity(), binding)
}
override fun onBindViewHolder(holder: FoldingListViewHolder, position: Int) {
@ -46,56 +44,51 @@ class GeolocListAdapter(
return l.children.size
}
class FoldingListViewHolder(private val ctx: FragmentActivity, itemView: View) :
RecyclerView.ViewHolder(itemView) {
private val textView: TextView = itemView.findViewById(R.id.textView)
private val progressView: TextView = itemView.findViewById(R.id.name)
private val checkBox: MaterialCheckBox = itemView.findViewById(R.id.checkBox)
class FoldingListViewHolder(
private val ctx: FragmentActivity,
private val _binding: ItemListGeolocBinding
) : RecyclerView.ViewHolder(_binding.root) {
private val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(ctx)
private val statsPref = sharedPreferences.getString(
ctx.getString(R.string.key_stats),
ctx.getString(R.string.counters)
)
private fun bindGroup(el: GeoLoc) {
val numerator = el.children.map { Data.visits.getVisited(it) != 0 }.count { it }
val denominator = el.children.size
_binding.count.text = when (Settings.getStatPref(ctx)) {
ctx.getString(R.string.percentages) -> ctx.getString(
R.string.percentage,
(100 * (numerator.toFloat() / denominator.toFloat())).toInt()
)
else -> ctx.getString(R.string.rate, numerator, denominator)
}
_binding.textView.setTypeface(null, Typeface.BOLD)
_binding.textView.backgroundTintList = ColorStateList.valueOf(
colorWrapper(
ctx,
android.R.attr.panelColorBackground
).color
).withAlpha(64)
}
fun bind(el: GeoLoc) {
textView.text = el.fullName
if (el.shouldShowChildren(ctx)) {
textView.setTypeface(null, Typeface.BOLD)
_binding.textView.text = el.fullName
_binding.textView.backgroundTintList =
ColorStateList.valueOf(colorWrapper(ctx, android.R.attr.colorBackground).color)
val numerator = el.children.map { Data.visits.getVisited(it) != 0 }.count { it }
val denominator = el.children.size
if (el.shouldShowChildren(ctx))
bindGroup(el)
progressView.text = when (statsPref) {
ctx.getString(R.string.percentages) -> ctx.getString(
R.string.percentage,
(100 * (numerator.toFloat() / denominator.toFloat())).toInt()
)
else -> ctx.getString(R.string.rate, numerator, denominator)
}
textView.backgroundTintList = ColorStateList.valueOf(
colorWrapper(
ctx,
android.R.attr.panelColorBackground
).color
).withAlpha(128)
textView.parent.parent.requestChildFocus(textView, textView)
} else {
textView.backgroundTintList =
ColorStateList.valueOf(colorWrapper(ctx, android.R.attr.colorBackground).color)
}
refreshCheck(el)
}
fun addListeners(el: GeoLoc, expandLambda: () -> Boolean) {
if (el.shouldShowChildren(ctx)) {
textView.setOnClickListener { expandLambda() }
_binding.textView.setOnClickListener { expandLambda() }
}
checkBox.setOnClickListener {
_binding.checkBox.setOnClickListener {
Data.selected_geoloc = el
if (Data.groups.size() == 1 && Settings.isSingleGroup(ctx)) {
if (checkBox.isChecked) {
if (_binding.checkBox.isChecked) {
// If one has just checked the box (assign unique group)
Data.selected_group = Data.groups.getUniqueEntry()
onColorDialogDismiss(false)
@ -129,21 +122,20 @@ class GeolocListAdapter(
}
private fun refreshCheck(geoLoc: GeoLoc) {
var col = Data.groups.getGroupFromKey(Data.visits.getVisited(geoLoc)).color.color
if (col == Color.TRANSPARENT)
col = Color.GRAY
checkBox.checkedState =
var col = Data.groups.getGroupFromKey(Data.visits.getVisited(geoLoc)).color
if (col.color == Color.TRANSPARENT) {
col = colorWrapper(
ctx,
android.R.attr.panelColorBackground
)
col.alpha = 64
}
_binding.checkBox.checkedState =
if (Data.visits.getVisited(geoLoc) != 0) MaterialCheckBox.STATE_CHECKED
else if (geoLoc.children.any { Data.visits.getVisited(it) != 0 }) MaterialCheckBox.STATE_INDETERMINATE
else MaterialCheckBox.STATE_UNCHECKED
checkBox.buttonTintList = ColorStateList(
arrayOf(
intArrayOf(-android.R.attr.state_checked),
intArrayOf(android.R.attr.state_checked)
),
intArrayOf(col, col)
)
_binding.checkBox.buttonTintList = ColorStateList.valueOf(col.color)
}
}

View File

@ -1,15 +1,12 @@
package net.helcel.beans.activity.adapter
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.TextView
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.FragmentActivity
import androidx.recyclerview.widget.RecyclerView
import net.helcel.beans.R
import net.helcel.beans.activity.fragment.EditGroupAddFragment
import net.helcel.beans.databinding.ItemListGroupBinding
import net.helcel.beans.helper.Data
import net.helcel.beans.helper.Groups
import net.helcel.beans.helper.Theme.getContrastColor
@ -20,9 +17,9 @@ class GroupListAdapter(
) : RecyclerView.Adapter<GroupListAdapter.GroupViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): GroupViewHolder {
val view: View =
LayoutInflater.from(parent.context).inflate(R.layout.item_list_group, parent, false)
return GroupViewHolder(view, activity, selectDialog)
val binding =
ItemListGroupBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return GroupViewHolder(binding, activity, selectDialog)
}
override fun onBindViewHolder(holder: GroupViewHolder, pos: Int) {
@ -34,41 +31,39 @@ class GroupListAdapter(
}
inner class GroupViewHolder(
itemView: View,
private val _binding: ItemListGroupBinding,
private val activity: FragmentActivity,
private val selectDialog: DialogFragment
) : RecyclerView.ViewHolder(itemView) {
private val color: Button = itemView.findViewById(R.id.group_color)
private val entries: TextView = itemView.findViewById(R.id.name)
) : RecyclerView.ViewHolder(_binding.root) {
private lateinit var dialogFragment: EditGroupAddFragment
fun bind(entry: Pair<Int, Groups.Group>) {
color.text = entry.second.name
_binding.groupColor.text = entry.second.name
dialogFragment = EditGroupAddFragment(entry.first, {
val newEntry = Data.groups.getGroupFromKey(entry.first)
color.text = newEntry.name
_binding.groupColor.text = newEntry.name
val newEntryColor = newEntry.color.color
val contrastNewEntryColor =
getContrastColor(newEntryColor)
color.setBackgroundColor(newEntryColor)
color.setTextColor(contrastNewEntryColor)
entries.setTextColor(contrastNewEntryColor)
entries.text = "0"
_binding.groupColor.setBackgroundColor(newEntryColor)
_binding.groupColor.setTextColor(contrastNewEntryColor)
_binding.name.setTextColor(contrastNewEntryColor)
_binding.name.text = "0"
}, {
notifyItemRemoved(it)
})
val entryColor = entry.second.color.color
val contrastEntryColor = getContrastColor(entryColor)
color.setBackgroundColor(entryColor)
color.setTextColor(contrastEntryColor)
entries.setTextColor(contrastEntryColor)
entries.text = Data.visits.countVisited(entry.first).toString()
_binding.groupColor.setBackgroundColor(entryColor)
_binding.groupColor.setTextColor(contrastEntryColor)
_binding.name.setTextColor(contrastEntryColor)
_binding.name.text = Data.visits.countVisited(entry.first).toString()
color.setOnClickListener {
_binding.groupColor.setOnClickListener {
Data.selected_group = entry.second
selectDialog.dismiss()
}
color.setOnLongClickListener {
_binding.groupColor.setOnLongClickListener {
dialogFragment.show(
activity.supportFragmentManager,
"AddColorDialogFragment"

View File

@ -7,8 +7,6 @@ import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.view.View
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.widget.AppCompatButton
import androidx.core.graphics.blue
import androidx.core.graphics.green
import androidx.core.graphics.red
@ -17,6 +15,7 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.slider.Slider
import com.google.android.material.textfield.TextInputEditText
import net.helcel.beans.R
import net.helcel.beans.databinding.FragmentEditGroupsAddBinding
import net.helcel.beans.helper.Data
import net.helcel.beans.helper.Groups
import net.helcel.beans.helper.Theme.colorToHex6
@ -26,51 +25,28 @@ class EditGroupAddFragment(
private val key: Int = 0,
val onAddCb: (Int) -> Unit,
val onDelCb: (Int) -> Unit
) :
DialogFragment() {
private lateinit var colorNameEditText: TextInputEditText
private lateinit var colorEditText: TextInputEditText
private lateinit var colorView: View
private lateinit var colorEditR: Slider
private lateinit var colorEditG: Slider
private lateinit var colorEditB: Slider
private lateinit var btnDelete: AppCompatButton
private lateinit var btnCancel: AppCompatButton
private lateinit var btnOk: AppCompatButton
) : DialogFragment() {
private lateinit var _binding: FragmentEditGroupsAddBinding
private val grp = Data.groups.getGroupFromKey(key)
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val builder = AlertDialog.Builder(requireActivity())
val inflater = requireActivity().layoutInflater
val view: View = inflater.inflate(R.layout.fragment_edit_groups_add, null)
val builder = MaterialAlertDialogBuilder(requireContext())
_binding = FragmentEditGroupsAddBinding.inflate(layoutInflater)
colorNameEditText = view.findViewById(R.id.group_name)
colorEditText = view.findViewById(R.id.group_color)
colorView = view.findViewById(R.id.colorView)
colorEditR = view.findViewById(R.id.colorR)
colorEditG = view.findViewById(R.id.colorG)
colorEditB = view.findViewById(R.id.colorB)
setupSlider(_binding.colorR, grp.color.color.red / 255F)
setupSlider(_binding.colorG, grp.color.color.green / 255F)
setupSlider(_binding.colorB, grp.color.color.blue / 255F)
setupText(_binding.groupColor, grp)
setupSlider(colorEditR, grp.color.color.red / 255F)
setupSlider(colorEditG, grp.color.color.green / 255F)
setupSlider(colorEditB, grp.color.color.blue / 255F)
_binding.colorView.background = ColorDrawable(grp.color.color)
setupText(colorEditText, grp)
colorView.background = ColorDrawable(grp.color.color)
btnDelete = view.findViewById(R.id.btnDelete)
btnCancel = view.findViewById(R.id.btnCancel)
btnOk = view.findViewById(R.id.btnOk)
if (key == 0) {
btnDelete.visibility = View.INVISIBLE
btnDelete.isEnabled = false
_binding.btnDelete.visibility = View.INVISIBLE
_binding.btnDelete.isEnabled = false
}
btnDelete.setOnClickListener {
_binding.btnDelete.setOnClickListener {
MaterialAlertDialogBuilder(requireActivity())
.setMessage(R.string.delete_group)
.setPositiveButton(android.R.string.ok) { _, _ ->
@ -87,9 +63,9 @@ class EditGroupAddFragment(
.show()
}
btnOk.setOnClickListener {
val name = colorNameEditText.text.toString()
val color = colorEditText.text.toString()
_binding.btnOk.setOnClickListener {
val name = _binding.groupName.text.toString()
val color = _binding.groupColor.text.toString()
val key = (if (key != 0) key else Data.groups.genKey())
Data.groups.setGroup(key, name, ColorDrawable(Color.parseColor("#$color")))
Data.saveData()
@ -97,12 +73,12 @@ class EditGroupAddFragment(
dialog?.dismiss()
}
btnCancel.setOnClickListener {
_binding.btnCancel.setOnClickListener {
dialog?.cancel()
}
colorNameEditText.setText(grp.name)
builder.setView(view)
_binding.groupName.setText(grp.name)
builder.setView(_binding.root)
return builder.create()
}
@ -110,11 +86,11 @@ class EditGroupAddFragment(
s.setText(colorToHex6(ColorDrawable(grp?.color?.color ?: 0)).substring(1))
s.addTextChangedListener(
EditTextListener(
colorEditR,
colorEditG,
colorEditB,
colorEditText,
colorView
_binding.colorR,
_binding.colorG,
_binding.colorB,
_binding.groupColor,
_binding.colorView
)
)
}
@ -125,11 +101,11 @@ class EditGroupAddFragment(
s.value = v
s.addOnChangeListener(
SliderOnChangeListener(
colorEditR,
colorEditG,
colorEditB,
colorEditText,
colorView
_binding.colorR,
_binding.colorG,
_binding.colorB,
_binding.groupColor,
_binding.colorView
)
)
}

View File

@ -3,48 +3,41 @@ package net.helcel.beans.activity.fragment
import android.app.Dialog
import android.content.DialogInterface
import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.widget.AppCompatButton
import androidx.fragment.app.DialogFragment
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import net.helcel.beans.R
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import net.helcel.beans.activity.adapter.GeolocListAdapter
import net.helcel.beans.activity.adapter.GroupListAdapter
import net.helcel.beans.databinding.FragmentEditPlacesColorsBinding
import net.helcel.beans.helper.Data
class EditPlaceColorFragment(private val parent: GeolocListAdapter.FoldingListViewHolder) :
DialogFragment() {
private lateinit var _binding: FragmentEditPlacesColorsBinding
private lateinit var listAdapt: GroupListAdapter
private lateinit var list: RecyclerView
private var clear: Boolean = false
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val builder = AlertDialog.Builder(
requireActivity()
)
val inflater = requireActivity().layoutInflater
val view: View = inflater.inflate(R.layout.fragment_edit_places_colors, null)
val btnAdd: AppCompatButton = view.findViewById(R.id.btnAdd)
val btnClear: AppCompatButton = view.findViewById(R.id.btnClear)
btnAdd.setOnClickListener {
val builder = MaterialAlertDialogBuilder(requireContext())
_binding = FragmentEditPlacesColorsBinding.inflate(layoutInflater)
_binding.btnAdd.setOnClickListener {
EditGroupAddFragment(0, {
listAdapt.notifyItemInserted(Data.groups.findGroupPos(it))
}, {}).show(requireActivity().supportFragmentManager, "AddColorDialogFragment")
}
btnClear.setOnClickListener {
_binding.btnClear.setOnClickListener {
clear = true
dialog?.dismiss()
}
val dialog = builder.setView(view).create()
val dialog = builder.setView(_binding.root).create()
listAdapt = GroupListAdapter(requireActivity(), this)
list = view.findViewById(R.id.groups_color)!!
list.layoutManager = LinearLayoutManager(requireContext(), RecyclerView.VERTICAL, false)
list.adapter = listAdapt
_binding.groupsColor.layoutManager =
LinearLayoutManager(requireContext(), RecyclerView.VERTICAL, false)
_binding.groupsColor.adapter = listAdapt
return dialog
}

View File

@ -12,11 +12,12 @@ import kotlin.random.Random
private const val randSeed = 0
private val rnd = Random(randSeed)
@Serializable
class Groups(val id: Int, private val grps: HashMap<Int,Group>) {
class Groups(val id: Int, private val grps: HashMap<Int, Group>) {
fun setGroup(key: Int, name: String, col: ColorDrawable) {
grps[key] = Group(key,name,col)
grps[key] = Group(key, name, col)
}
fun deleteGroup(key: Int) {
@ -24,12 +25,12 @@ class Groups(val id: Int, private val grps: HashMap<Int,Group>) {
}
fun getGroupFromKey(key: Int): Group {
return grps.getOrDefault(key,EmptyGroup())
return grps.getOrDefault(key, EmptyGroup())
}
fun genKey(): Int {
val key = rnd.nextInt()
if(grps.containsKey(key) || key == 0) return genKey()
if (grps.containsKey(key) || key == 0) return genKey()
return key
}
@ -46,32 +47,38 @@ class Groups(val id: Int, private val grps: HashMap<Int,Group>) {
}
}
fun getGroupFromPos(pos: Int): Pair<Int,Group> {
fun getGroupFromPos(pos: Int): Pair<Int, Group> {
val key = grps.keys.toList()[pos]
return Pair(key,getGroupFromKey(key))
return Pair(key, getGroupFromKey(key))
}
fun findGroupPos(key: Int): Int {
return grps.keys.toList().indexOf(key)
}
class EmptyGroup: Group(0,"")
class EmptyGroup : Group(0, "")
@Serializable
open class Group(val key: Int, val name: String, @Serializable(with = ColorDrawableSerializer::class) val color: ColorDrawable = ColorDrawable(Color.TRANSPARENT))
open class Group(
val key: Int,
val name: String,
@Serializable(with = Theme.ColorDrawableSerializer::class) val color: ColorDrawable = ColorDrawable(
Color.TRANSPARENT
)
)
@OptIn(ExperimentalSerializationApi::class)
@Serializer(Groups::class)
class GroupsSerializer{
class GroupsSerializer {
val defaultValue: Groups
get() = Groups(Int.MIN_VALUE,hashMapOf())
get() = Groups(Int.MIN_VALUE, hashMapOf())
fun readFrom(input: InputStream): Groups {
return Json.decodeFromString(serializer(),input.readBytes().decodeToString())
return Json.decodeFromString(serializer(), input.readBytes().decodeToString())
}
fun writeTo(t: Groups): String {
return Json.encodeToString(serializer(),t).encodeToByteArray().decodeToString()
return Json.encodeToString(serializer(), t).encodeToByteArray().decodeToString()
}
}

View File

@ -30,6 +30,13 @@ object Settings {
)
}
fun getStatPref(ctx: Context): String? {
return sp.getString(
ctx.getString(R.string.key_stats),
ctx.getString(R.string.counters)
)
}
private fun getBooleanValue(ctx: Context, key: String?): Boolean {
return when (key) {
ctx.getString(R.string.on) -> true

View File

@ -6,6 +6,11 @@ import android.graphics.drawable.ColorDrawable
import android.util.TypedValue
import androidx.appcompat.app.AppCompatActivity
import androidx.core.graphics.ColorUtils
import kotlinx.serialization.KSerializer
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
object Theme {
fun colorWrapper(ctx: Context, res: Int): ColorDrawable {
@ -34,4 +39,17 @@ object Theme {
val blackContrast = ColorUtils.calculateContrast(Color.BLACK, color)
return if (whiteContrast > blackContrast) Color.WHITE else Color.BLACK
}
}
object ColorDrawableSerializer : KSerializer<ColorDrawable> {
override val descriptor = PrimitiveSerialDescriptor("ColorDrawable", PrimitiveKind.INT)
override fun deserialize(decoder: Decoder): ColorDrawable {
return ColorDrawable(decoder.decodeInt())
}
override fun serialize(encoder: Encoder, value: ColorDrawable) {
encoder.encodeInt(value.color)
}
}
}

View File

@ -1,20 +0,0 @@
package net.helcel.beans.helper
import android.graphics.drawable.ColorDrawable
import kotlinx.serialization.KSerializer
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
object ColorDrawableSerializer : KSerializer<ColorDrawable> {
override val descriptor = PrimitiveSerialDescriptor("ColorDrawable", PrimitiveKind.INT)
override fun deserialize(decoder: Decoder): ColorDrawable {
return ColorDrawable(decoder.decodeInt())
}
override fun serialize(encoder: Encoder, value: ColorDrawable) {
encoder.encodeInt(value.color)
}
}

View File

@ -0,0 +1,41 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="72dp"
android:height="72dp"
android:viewportWidth="72"
android:viewportHeight="72">
<path
android:pathData="M31,16l0,-4l10,0l0,4"
android:strokeLineJoin="round"
android:strokeWidth="4"
android:fillColor="#00000000"
android:strokeColor="#000000"
android:strokeLineCap="round"/>
<path
android:pathData="M51,25v31c0,2.209 -1.791,4 -4,4H25c-2.209,0 -4,-1.791 -4,-4V25"
android:strokeLineJoin="round"
android:strokeWidth="4"
android:fillColor="#00000000"
android:strokeColor="#000000"
android:strokeLineCap="round"/>
<path
android:pathData="M17,16h38v4h-38z"
android:strokeLineJoin="round"
android:strokeWidth="4"
android:fillColor="#00000000"
android:strokeColor="#000000"
android:strokeLineCap="round"/>
<path
android:pathData="M41,28.25L41,55"
android:strokeLineJoin="round"
android:strokeWidth="4"
android:fillColor="#00000000"
android:strokeColor="#000000"
android:strokeLineCap="round"/>
<path
android:pathData="M31,28.25L31,55"
android:strokeLineJoin="round"
android:strokeWidth="4"
android:fillColor="#00000000"
android:strokeColor="#000000"
android:strokeLineCap="round"/>
</vector>

View File

@ -1,13 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:theme="@style/Theme.Beans"
android:layout_width="match_parent"
android:layout_height="match_parent">
tools:context=".activity.EditActivity">
<com.google.android.material.tabs.TabLayout
android:id="@+id/tab"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
android:layout_height="wrap_content" />
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/pager"

View File

@ -1,13 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:theme="@style/Theme.Beans"
android:layout_width="match_parent"
android:layout_height="match_parent">
tools:context=".activity.MainActivity">
<com.github.chrisbanes.photoview.PhotoView
android:id="@+id/photo_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
android:layout_height="match_parent" />
</LinearLayout>

View File

@ -1,13 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:theme="@style/Theme.Beans"
android:layout_width="match_parent"
android:layout_height="match_parent">
tools:context=".activity.StatActivity">
<com.github.mikephil.charting.charts.PieChart
android:id="@+id/chart"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
android:layout_height="match_parent" />
</LinearLayout>

View File

@ -9,9 +9,9 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical" >
android:orientation="vertical">
<ImageView
<com.google.android.material.imageview.ShapeableImageView
android:layout_width="250dp"
android:layout_height="250dp"
android:layout_marginTop="40dp"
@ -19,46 +19,46 @@
android:contentDescription="@string/logo"
android:src="@mipmap/ic_launcher_round" />
<TextView
<com.google.android.material.textview.MaterialTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="15dp"
android:layout_marginEnd="10dp"
android:layout_marginBottom="10dp"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:text="@string/app_name"
android:textStyle="bold"
android:textAlignment="center"
android:textSize="30sp"
android:textAlignment="center" />
android:textStyle="bold" />
<TextView
<com.google.android.material.textview.MaterialTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="0dp"
android:layout_marginBottom="15dp"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:layout_marginBottom="15dp"
android:text="@string/app_version"
android:textSize="25sp"
android:textAlignment="center" />
android:textAlignment="center"
android:textSize="25sp" />
<TextView
<com.google.android.material.textview.MaterialTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:layout_marginBottom="15dp"
android:layout_marginStart="10dp"
android:layout_marginTop="15dp"
android:layout_marginEnd="10dp"
android:layout_marginBottom="15dp"
android:text="@string/beans_is_foss"
android:textAlignment="center" />
<TextView
<com.google.android.material.textview.MaterialTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:layout_marginBottom="15dp"
android:layout_marginStart="10dp"
android:layout_marginTop="15dp"
android:layout_marginEnd="10dp"
android:layout_marginBottom="15dp"
android:autoLink="web"
android:text="@string/beans_repo"
android:textAlignment="center" />

View File

@ -1,10 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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="wrap_content"
android:orientation="vertical"
android:padding="16dp">
android:padding="16dp"
tools:context=".activity.fragment.EditGroupAddFragment">
<com.google.android.material.textfield.TextInputEditText
@ -92,29 +94,39 @@
android:layout_height="match_parent"
android:layout_marginTop="10dp">
<androidx.appcompat.widget.AppCompatButton
<com.google.android.material.button.MaterialButton
android:id="@+id/btnDelete"
android:layout_width="wrap_content"
android:layout_width="52dp"
android:layout_height="wrap_content"
android:text="@string/delete"
android:paddingLeft="6dp"
android:paddingRight="6dp"
android:tooltipText="@string/delete"
app:icon="@drawable/delete"
app:iconGravity="textStart"
app:iconPadding="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.AppCompatButton
<com.google.android.material.button.MaterialButton
android:id="@+id/btnCancel"
android:layout_width="wrap_content"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:layout_marginEnd="6dp"
android:paddingLeft="6dp"
android:paddingRight="6dp"
android:text="@string/cancel"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/btnOk"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.AppCompatButton
<com.google.android.material.button.MaterialButton
android:id="@+id/btnOk"
android:layout_width="wrap_content"
android:layout_width="52dp"
android:layout_height="wrap_content"
android:paddingLeft="6dp"
android:paddingRight="6dp"
android:text="@string/ok"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"

View File

@ -1,8 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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">
android:layout_height="match_parent"
tools:context=".activity.fragment.EditPlaceFragment">
<androidx.core.widget.NestedScrollView

View File

@ -10,7 +10,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
android:padding="4dp">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/groups_color"
@ -24,20 +24,24 @@
android:layout_height="wrap_content"
android:layout_marginTop="10dp">
<androidx.appcompat.widget.AppCompatButton
<com.google.android.material.button.MaterialButton
android:id="@+id/btnAdd"
android:layout_width="wrap_content"
android:layout_width="64dp"
android:layout_height="wrap_content"
android:paddingLeft="6dp"
android:paddingRight="6dp"
android:text="@string/add"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.AppCompatButton
<com.google.android.material.button.MaterialButton
android:id="@+id/btnClear"
android:layout_width="wrap_content"
android:layout_width="64dp"
android:layout_height="wrap_content"
android:paddingLeft="6dp"
android:paddingRight="6dp"
android:text="@string/clear"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"

View File

@ -7,8 +7,7 @@
<androidx.fragment.app.FragmentContainerView
android:id="@+id/license_fragment_view"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
android:layout_height="match_parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,57 +1,52 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.button.MaterialButton
android:id="@+id/textView"
android:layout_width="0dp"
android:layout_height="50dp"
android:clickable="true"
android:focusable="true"
android:gravity="start|center_vertical"
android:insetTop="4dp"
android:insetBottom="4dp"
android:paddingStart="20dp"
android:paddingEnd="20dp"
android:textAllCaps="false"
android:textAppearance="?attr/textAppearanceBody2"
android:textColor="?attr/colorOnBackground"
<com.google.android.material.button.MaterialButton
android:id="@+id/textView"
android:layout_width="0dp"
android:layout_height="50dp"
android:clickable="true"
android:focusable="true"
android:gravity="start|center_vertical"
android:insetTop="4dp"
android:insetBottom="4dp"
android:paddingStart="20dp"
android:paddingEnd="20dp"
android:textAllCaps="false"
android:textAppearance="?attr/textAppearanceBody2"
android:textColor="?attr/colorOnBackground"
app:cornerRadius="0dp"
app:layout_constraintBottom_toBottomOf="@id/checkBox"
app:layout_constraintEnd_toStartOf="@id/checkBox"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
app:cornerRadius="4dp"
app:layout_constraintBottom_toBottomOf="@id/checkBox"
app:layout_constraintEnd_toStartOf="@id/checkBox"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:gravity="start|center_vertical"
android:paddingStart="20dp"
android:paddingEnd="20dp"
app:layout_constraintBottom_toBottomOf="@id/checkBox"
app:layout_constraintEnd_toStartOf="@id/checkBox"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/count"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:gravity="start|center_vertical"
android:paddingStart="20dp"
android:paddingEnd="20dp"
app:layout_constraintBottom_toBottomOf="@id/checkBox"
app:layout_constraintEnd_toStartOf="@id/checkBox"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.checkbox.MaterialCheckBox
android:id="@+id/checkBox"
android:layout_width="50dp"
android:layout_height="50dp"
app:checkedState="indeterminate"
app:layout_constraintBottom_toBottomOf="@id/textView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1"
app:layout_constraintStart_toEndOf="@id/textView"
app:layout_constraintTop_toTopOf="@id/textView"
app:layout_constraintVertical_bias="0.5" />
<com.google.android.material.checkbox.MaterialCheckBox
android:id="@+id/checkBox"
android:layout_width="50dp"
android:layout_height="50dp"
app:checkedState="indeterminate"
app:layout_constraintBottom_toBottomOf="@id/textView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1"
app:layout_constraintStart_toEndOf="@id/textView"
app:layout_constraintTop_toTopOf="@id/textView"
app:layout_constraintVertical_bias="0.5" />
</androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,41 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.button.MaterialButton
android:id="@+id/group_color"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginTop="2dp"
android:layout_marginEnd="32dp"
android:layout_marginBottom="2dp"
android:textAlignment="textStart"
android:textColor="?attr/colorOnPrimary"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/group_color"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginTop="2dp"
android:layout_marginEnd="32dp"
android:layout_marginBottom="2dp"
android:textAlignment="textStart"
android:textColor="?attr/colorOnPrimary"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:gravity="start|center_vertical"
android:paddingStart="20dp"
android:paddingEnd="20dp"
android:textColor="?attr/colorOnPrimary"
app:layout_constraintBottom_toBottomOf="@id/group_color"
app:layout_constraintEnd_toEndOf="@id/group_color"
app:layout_constraintTop_toTopOf="@id/group_color" />
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:gravity="start|center_vertical"
android:paddingStart="20dp"
android:paddingEnd="20dp"
android:textColor="?attr/colorOnPrimary"
app:layout_constraintTop_toTopOf="@id/group_color"
app:layout_constraintBottom_toBottomOf="@id/group_color"
app:layout_constraintEnd_toEndOf="@id/group_color" />
</androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -32,6 +32,16 @@
app:key="@string/key_stats"
app:title="@string/key_stats"
app:useSimpleSummaryProvider="true" />
<ListPreference
app:defaultValue="@string/system"
app:enabled="true"
app:entries="@array/entries_theme"
app:entryValues="@array/entries_theme"
app:icon="@drawable/palette"
app:key="@string/key_theme"
app:title="@string/key_theme"
app:useSimpleSummaryProvider="true" />
<Preference
android:summary="@string/foss_licenses"