SharedPreference usage made fun in Kotlin

Overview

PreferenceHolder

Kotlin Android Library, that makes preference usage simple and fun.

GitHub license Build Status codebeat badge Analytics Analytics

To stay up-to-date with news about library Twitter URL

This library is younger brother of KotlinPreferences.

With PreferenceHolder, you can define different preference fields this way:

object Pref: PreferenceHolder() {
    var canEatPie: Boolean by bindToPreferenceField(true)
}

And use it this way:

if(Pref.canEatPie) //...

Here are other preference definition examples: (see full example and usage)

object UserPref: PreferenceHolder() {
    var canEatPie: Boolean by bindToPreferenceField(true)
    var allPieInTheWorld: Long by bindToPreferenceField(0)

    var isMonsterKiller: Boolean? by bindToPreferenceFieldNullable()
    var monstersKilled: Int? by bindToPreferenceFieldNullable()
    
    // Property with backup is reading stored value in the first usage, 
    // and saving it, in background, each time it is changed.
    var experience: Float? by bindToPropertyWithBackup(-1.0F) 
    var className: String? by bindToPropertyWithBackupNullable()

    // Any type can used if serializer is set. See: Gson serialization
    var character: Character? by bindToPreferenceFieldNullable()
    var savedGame: Game? by bindToPreferenceFieldNullable()

    // Single level collections are also supported if serializer is set. See: Gson serialization
    var longList: Map<Int, Long> by bindToPreferenceField(mapOf(0 to 12L, 10 to 143L))
    var propTest: List<Character>? by bindToPropertyWithBackupNullable()
    var elemTest: Set<Elems> by bindToPreferenceField(setOf(Elems.Elem1, Elems.Elem3))
}

There must be application Context added to PreferenceHolder companion object. Example:

class App : Application() {

    override fun onCreate() {
        super.onCreate()
        PreferenceHolder.setContext(applicationContext)
    }
}

It it suggested to do it in project Application class. As an alternative, PreferenceHolderApplication can also be added as a name of an application in AndroidManifest: (example)

android:name="com.marcinmoskala.kotlinpreferences.PreferenceHolderApplication"

Unit testing components

Library also include test mode:

PreferenceHolder.testingMode = true

When it is turned on, then all properties are acting just like normal properties without binding to preference field. This allows to make unit tests to presenters and to use cases that are using instance of PreferenceHolder.

Install

To add PreferenceHolder to the project, add to build.gradle file:

dependencies {
    compile "com.marcinmoskala.PreferenceHolder:preferenceholder:1.51"
}

While library is located on JitPack, remember to add to module build.gradle (unless you already have it):

repositories {
    maven { url 'https://jitpack.io' }
}

Gson serialization

To use Gson serializer, we need to add following dependency:

dependencies {
    compile "com.marcinmoskala.PreferenceHolder:preferenceholder-gson-serializer:1.51"
}

And specify GsonSerializer as PreferenceHolder serializer:

PreferenceHolder.serializer = GsonSerializer(Gson())

Since then, we can use all types, even one not supported by SharedPreference (like custom objects Character and Game, or collections)

Other libraries

If you like it, remember to leave the star and check out my other libraries:

  • ActivityStarter - Simple Android Library, that provides easy way to start and save state of Activities, Fragments, Services and Receivers with arguments.
  • ArcSeekBar - Good looking curved Android SeekBar
  • VideoPlayView - Custom Android view with video player, loader and placeholder image
  • KotlinAndroidViewBindings - Bindings for properties with simple Kotlin types (Boolean, String) to layout traits (visibility, text).

License

Copyright 2017 Marcin Moskała

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Comments
  • Can you add `List<MyClass>`example to README?

    Can you add `List`example to README?

    I'm using Android Studio 3.0 + kotlin.

    // build.gradle
    compile "com.marcinmoskala.PreferenceHolder:preferenceholder:1.5"
    compile "com.marcinmoskala.PreferenceHolder:preferenceholder-gson-serializer:1.5"
    
    // class App : Application()
    override fun onCreate() {
      super.onCreate()
      PreferenceHolder.setContext(applicationContext)
      PreferenceHolder.serializer = GsonSerializer(Gson())
    }
    
    class User(name: String, age: Int = 0) {
      var name: String? = name
      var age: Int? = age
    }
    
    object AppPreference : PreferenceHolder() {
      var users: List<User>? by bindToPreferenceFieldNullable()
    }
    
    // add 
    val users: ArrayList<User> = ArrayList()
    for (i in (0..5)) {
      users.add(User("name" + i, i))
    }
    AppPreference.users = users
    
    // get
    Log.i("###", AppPreference.users.toString()) 
    // => [{age=0.0, name=name0}, {age=1.0, name=name1}, {age=2.0, name=name2}, {age=3.0, name=name3}, {age=4.0, name=name4}, {age=5.0, name=name5}]
    
    for (user in AppPreference.users!!) {
      Log.i("@@@", user.name)
    }
    // => java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap cannot be cast to kr.susemi99.testkotlin.model.User
    
    val users = Gson().fromJson<List<User>>(AppPreference.users)
    val users: List<User> = Gson().fromJson(AppPreference.users)
    // => compile error
    
    val usersType = object : TypeToken<List<User>>() {}.type
    val users = Gson().fromJson<List<User>>(AppPreference.users, usersType)
    // => compile error
    

    Please add some more detailed instructions for beginners.

    opened by susemi99 10
  • ArrayList goes empty after restarting app

    ArrayList goes empty after restarting app

    Hi, i use below line to add product (data class) to cart in sharedpreference: var CartItems: ArrayList<ResDataClass.Companion.Product> by bindToPreferenceField(arrayListOf()) when app is alive CartItems has values but after restarting app CartItems goes Empty everything except arraylist in sharedpreference has value something's wrong in saving arrays in sharedpreference plz fix it thanks

    opened by nightfury96 4
  • object changes not saved

    object changes not saved

    I use this library to save any type of object in PreferenceFieldBinder you got this line of code: override fun setValue(thisRef: PreferenceHolder, property: KProperty<*>, value: T) { if (value == field) return

    meaning that if I change object and try to save it again it not saved

    opened by duz17 2
  • Nested data classes are not parsed back correctly

    Nested data classes are not parsed back correctly

    These are my models

    data class IChapter<T>(
      var _id: String,
      var title: String,
      var picture: T,
      var createdAt: Long,
      var updatedAt: Long
    )
    
    data class IMedia(
      var _id: String,
      var name: String,
      var extension: String,
      var path: String,
      var size: Long,
      var createdAt: Long,
      var updatedAt: Long
    )
    

    I want to save this in prefrences.

    object prefs : PreferenceHolder() {
      var chapters: List<IChapter<IMedia>> by bindToPreferenceField(listOf())
    }
    

    After i populate it with objects coming from this

        fun getRemoteChapters(): List<IChapter<IMedia>> = listOf(
          IChapter("1", "در تنهایی و ...", IMedia("1", "f1", "jpg", "https://images.all-free-download.com/images/wallpapers_large/small_island_wallpaper_beaches_nature_wallpaper_1388.jpg", 0, 0, 0), 0, 0),
          IChapter("2", "پیش از جکومت", IMedia("2", "f2", "jpg", "https://besthqwallpapers.com/Uploads/22-11-2017/29941/thumb2-sea-landscape-waves-beach-sand-clouds.jpg", 0, 0, 0), 0, 0),
          IChapter("3", "تا رهایی", IMedia("3", "f3", "jpg", "https://earthporm.com/wp-content/uploads/2014/08/small-man-grand-nature-landscape-photography-62.jpg", 0, 0, 0), 0, 0)
        )
    

    If i close and open my app i get class cast error as below

        java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap cannot be cast to ir.yooneskh.alisotries.database.models.IMedia
    

    Am i doing anything wrong?

    opened by yooneskh 1
  • automatic key name

    automatic key name

    what is the key string that created automatically for declaring new preference (without specifying it)? var useTestAutoCapture: Boolean by bindToPreferenceField(false)

    I know I could put it like this and have it: var useTestAutoCapture: Boolean by bindToPreferenceField(false, "useTestAutoCapture")

    but let's say I didn't, released a version and need to know this string (to use in preferences activity for example)

    I couldn't find the answer for it, even on debug

    opened by duz17 0
  • java.lang.Error

    java.lang.Error

    My app is reporting this error.

    I have a lot of values but only in this case the problem occur.

    Could someone help me? Thsnks.

    java.lang.Error: 
      at com.marcinmoskala.kotlinpreferences.PreferenceHolder$Companion.getPreferencesOrThrowError$preferenceholder_release (PreferenceHolder.kt:86)
      at com.marcinmoskala.kotlinpreferences.bindings.PreferenceFieldBinder.readValue (PreferenceFieldBinder.kt:39)
      at com.marcinmoskala.kotlinpreferences.bindings.PreferenceFieldBinder.getValue (PreferenceFieldBinder.kt:22)
      at com.marcinmoskala.kotlinpreferences.bindings.PreferenceFieldBinder.getValue (PreferenceFieldBinder.kt:12)
      at app.package.utils.helpers.ApplicationPreference.getHomeGridElements (PreferencesHelper.kt)
      at app.package.modules.home.HomeFragment.onCreate (HomeFragment.kt:62)
      at android.support.v4.app.Fragment.performCreate (Fragment.java:2328)
      at android.support.v4.app.FragmentManagerImpl.moveToState (FragmentManager.java:1379)
      at android.support.v4.app.FragmentTransition.addToFirstInLastOut (FragmentTransition.java:1188)
      at android.support.v4.app.FragmentTransition.calculateFragments (FragmentTransition.java:1071)
      at android.support.v4.app.FragmentTransition.startTransitions (FragmentTransition.java:115)
      at android.support.v4.app.FragmentManagerImpl.executeOpsTogether (FragmentManager.java:2379)
      at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute (FragmentManager.java:2337)
      at android.support.v4.app.FragmentManagerImpl.execPendingActions (FragmentManager.java:2244)
      at android.support.v4.app.FragmentManagerImpl.dispatchStateChange (FragmentManager.java:3255)
      at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated (FragmentManager.java:3205)
      at android.support.v4.app.FragmentController.dispatchActivityCreated (FragmentController.java:195)
      at android.support.v4.app.FragmentActivity.onStart (FragmentActivity.java:597)
      at android.support.v7.app.AppCompatActivity.onStart (AppCompatActivity.java:177)
      at app.package.modules.base.BaseActivity.onStart (BaseActivity.kt:25)
      at android.app.Instrumentation.callActivityOnStart (Instrumentation.java:1270)
      at android.app.Activity.performStart (Activity.java:6689)
      at android.app.ActivityThread.performLaunchActivity (ActivityThread.java:2622)
      at android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:2724)
      at android.app.ActivityThread.-wrap12 (ActivityThread.java)
      at android.app.ActivityThread$H.handleMessage (ActivityThread.java:1473)
      at android.os.Handler.dispatchMessage (Handler.java:102)
      at android.os.Looper.loop (Looper.java:154)
      at android.app.ActivityThread.main (ActivityThread.java:6123)
      at java.lang.reflect.Method.invoke (Native Method)
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:867)
      at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:757)
    

    PreferenceHelper.kt:

    object ApplicationPreference : PreferenceHolder() {
        var homeGridElements: Int by bindToPreferenceField(2)
    }
    

    HomeFragment.kt

    override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
           ...
            gridItemDecoration = GridSpacingItemDecoration(ApplicationPreference.homeGridElements, getActivityContext()?.resources?.getDimensionPixelSize(R.dimen.dm_grid_margin) ?: 0, false)
        }
    
    opened by dsdebastiani 3
  • Preference Change Listener

    Preference Change Listener

    I love this implementation of a Preference wrapper, but I find myself using Preference change listeners sometimes and would like to know if this is something you've considered adding functionality for.

    opened by sugarmanz 2
Releases(1.52-beta.5)
Owner
Marcin Moskała
Teacher, speaker, consultant, founder of Kot. Academy, author of Android Development with Kotlin.
Marcin Moskała
Android MVVM framework write in kotlin, develop Android has never been so fun.

KBinding 中文版 Android MVVM framework write in kotlin, base on anko, simple but powerful. It depends on my another project AutoAdapter(A library for sim

Benny 413 Dec 5, 2022
Sample application to demonstrate Multi-module Clean MVVM Architecture and usage of Android Hilt, Kotlin Flow, Navigation Graph, Unit tests etc.

MoneyHeist-Chars Sample application to demonstrate Multi-module Clean MVVM Architecture and usage of Android Hilt, Kotlin Flow, Navigation Graph, Room

Hisham 20 Nov 19, 2022
Android Library to make SharedPreferences usage easier.

KotlinPreferences Kotlin Android Library, that makes preference usage simple and fun. KotlinPreferences now have a brother. With KotlinPreferences, yo

Marcin Moskała 50 Nov 6, 2022
Disk Usage/Free Utility - a better 'df' alternative

duf Disk Usage/Free Utility (Linux, BSD, macOS & Windows) Features User-friendly, colorful output Adjusts to your terminal's theme & width Sort the re

Christian Muehlhaeuser 10.3k Dec 31, 2022
Wrapper of FusedLocationProviderClient for Android to support modern usage like LiveData and Flow

FancyLocationProvider Wrapper of FusedLocationProviderClient for Android to support modern usage like LiveData or Flow. Install Add Jitpack repository

Jintin 66 Aug 15, 2022
Clean MVVM with eliminating the usage of context from view models by introducing hilt for DI and sealed classes for displaying Errors in views using shared flows (one time event), and Stateflow for data

Clean ViewModel with Sealed Classes Following are the purposes of this repo Showing how you can remove the need of context in ViewModels. I. By using

Kashif Mehmood 22 Oct 26, 2022
Account-lib - A suite of libraries to facilitate the usage of account-sdk

Usage Clone this repository (skip this step if the repo is on your local machine). The default branch is fine. git clone https://github.com/AFBlockcha

null 0 May 24, 2022
Android Kotlin paged endpoints made easy

A smart and simple way to work with paged endpoints. To see an example of how to use it, check out the introducing Fountain posts: part one and part t

xmartlabs 171 Nov 15, 2022
Dead simple EventBus for Android made with Kotlin and RxJava 2

KBus Super lightweight (13 LOC) and minimalistic (post(), subscribe(), unsubscribe()) EventBus written with idiomatic Kotlin and RxJava 2 KBus in 3 st

Adriel Café 46 Dec 6, 2022
A curated collection of splendid gradients made in Kotlin

Gradients A curated collection of splendid gradients made in Kotlin (port of https://webgradients.com for Android). Only linear gradients included for

null 51 Oct 3, 2022
Open source Crypto Currency Tracker Android App made fully in Kotlin

CoinBit CoinBit is a beautiful CryptoCurrency app, completely open sourced and 100% in kotlin. It supports following features Track prices of over 300

Pranay Airan 50 Dec 5, 2022
🚟 Lightweight, and simple scheduling library made for Kotlin (JVM)

Haru ?? Lightweight, and simple scheduling library made for Kotlin (JVM) Why did you build this? I built this library as a personal usage library to h

Noel 13 Dec 16, 2022
Server Sent Events (SSE) client multiplatform library made with Kotlin and backed by coroutines

OkSSE OkSSE is an client for Server Sent events protocol written in Kotlin Multiplatform. The implementation is written according to W3C Recommendatio

BioWink GmbH 39 Nov 4, 2022
⏰ A powerful and simple-to-use guilded wrapper made in Kotlin.

⏰ guilded-kt [WIP] A powerful yet simple-to-use guilded wrapper made entirely in Kotlin with supporting multiplatform. Take a look at an example of th

Gabriel 13 Jul 30, 2022
🎲 A powerful and simple-to-use guilded wrapper made in Kotlin.

?? deck [WIP] Deck is a powerful yet simple-to-use guilded wrapper made entirely in Kotlin with support to multiplatform. Implementating In case you'r

Gabriel 13 Jul 30, 2022
A discord bot made in Kotlin powered by JDA and Realms.

A discord bot made in Kotlin powered by JDA and Realms.

null 1 Jun 30, 2022
:octocat: Navigation toolbar is a slide-modeled UI navigation controller made by @Ramotion

NAVIGATION TOOLBAR Navigation toolbar is a Kotlin slide-modeled UI navigation controller. We specialize in the designing and coding of custom UI for M

Ramotion 804 Dec 9, 2022
Utility for developers and QAs what helps minimize time wasting on writing the same data for testing over and over again. Made by Stfalcon

Stfalcon Fixturer A Utility for developers and QAs which helps minimize time wasting on writing the same data for testing over and over again. You can

Stfalcon LLC 31 Nov 29, 2021
An android application that made as an exercise, that does 4 different conversions.

Following android studio basic course, this is my second (and bit more complicate this time) "practice on your own" project. In few words, it is an an

null 1 Dec 1, 2021