I can not get output from the seekbar - android

I wanted the seekbar value outside the onProgressChanged method use But it always gives me a value of zero. I want to take the value of two seekbars and multiply them
class BmiActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
var weight =0f
var height = 0f
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_bmi)
val seekbarHeight=findViewById<SeekBar>(R.id.seekBarHeight)
var tvResultHeight=findViewById<TextView>(R.id.textViewResultHeight)
val tvResultWeight=findViewById<TextView>(R.id.textViewResultWeight)
val seekbarWeight =findViewById<SeekBar>(R.id.seekBarWeight)
val spinnerAge=findViewById<Spinner>(R.id.spinnerAge)
val imageviewNeedle=findViewById<ImageView>(R.id.imageViewNeedle)
val tvResultBmi=findViewById<TextView>(R.id.textViewResultBmi)
seekbarHeight.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
tvResultHeight.text=" "+progress.toString()
height= progress.toFloat()
}
override fun onStartTrackingTouch(p0: SeekBar?) {
}
override fun onStopTrackingTouch(p0: SeekBar?) {
}
})
seekbarWeight.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
tvResultWeight.text=" "+progress.toString()
weight=progress.toFloat()
}
override fun onStartTrackingTouch(p0: SeekBar?) {
}
override fun onStopTrackingTouch(p0: SeekBar?) {
}
})
var result = weight/(height*height)
tvResultBmi.text=result.toString()

You can do callback/interface. And then when both triggered, the value changed.
First, you need to create interface. Create a new file named ResultInterface.kt
interface ResultInterface {
fun onValueChanged(height: Float, weight: Float)
}
And then put each of them to a function.
fun seekBarHeight(resultInterface: ResultInterface) {
seekbarHeight.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
tvResultHeight.text = " " + progress.toString()
val height = progress.toFloat()
resultInterface.onValueChanged(height, 0f)
}
override fun onStartTrackingTouch(p0: SeekBar?) {
}
override fun onStopTrackingTouch(p0: SeekBar?) {
}
})
}
fun seekBarWeight(resultInterface: ResultInterface) {
seekbarWeight.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
tvResultWeight.text = " " + progress.toString()
val weight = progress.toFloat()
resultInterface.onValueChanged(0f, weight)
}
override fun onStartTrackingTouch(p0: SeekBar?) {
}
override fun onStopTrackingTouch(p0: SeekBar?) {
}
})
}
Last, at your activity, implement the ResutInterface
class BmiActivity : AppCompatActivity(), ResultInterface {
After that you need to alt + enter . and the onValueChanged method will override.
override fun onValueChanged(height: Float, weight: Float) {
val result = weight/(height*height)
tvResultBmi.text=result.toString()
}

Related

How To get value of SeekBar and use it on another class or method

I'm new in Kotlin and I want to use three Seekbar on my app for RGB control;
I want to set seekBarManger function to manage my seekbar on SeekBarManger class and use seekbar.progress value on other class
but I cant get value of my seekbar.
the Toast is Show but I want to use the value of seekbar.progrees in other method and class.
please help me..!!!!
this is my seekbar class :
class SeekBarManager() {
}
fun seekBarManage(context: Context, seekBar: SeekBar) {
seekBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(p0: SeekBar?, p1: Int, p2: Boolean) { }
override fun onStartTrackingTouch(p0: SeekBar?) {}
override fun onStopTrackingTouch(p0: SeekBar?) {
val result = seekBar.progress
Toast.makeText(context, "Progress is: $result%", Toast.LENGTH_SHORT).show()
}
})
and this is my MainActivity :
open class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val seekRed = findViewById<SeekBar>(R.id.seekBar_red)
val seekGreen = findViewById<SeekBar>(R.id.seekBar_green)
val seekBlue = findViewById<SeekBar>(R.id.seekBar_blue)
val seekEndRed = seekBarManage(this , seekRed)
val seekEndGreen = seekBarManage(this , seekGreen)
val seekEndBlue = seekBarManage(this , seekBlue)
the Toast is Show but I want to use the value of seekbar.progrees in other method and class
the easiest way is to use a companion object in your Main class and just call a method and pass your seek bar object like below :
open class MainActivity : AppCompatActivity() {
companion object {
fun getSeekBarProgress(context: Context, seekBar: SeekBar) {
val result = seekBar.progress
Toast.makeText(context, "Progress is: $result%", Toast.LENGTH_SHORT).show()
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val seekRed = findViewById<SeekBar>(R.id.seekBar_red)
val seekGreen = findViewById<SeekBar>(R.id.seekBar_green)
val seekBlue = findViewById<SeekBar>(R.id.seekBar_blue)
val seekEndRed = seekBarManage(this, seekRed)
val seekEndGreen = seekBarManage(this, seekGreen)
val seekEndBlue = seekBarManage(this, seekBlue)
}
}
and SeekBarManager class :
class SeekBarManager() {
}
fun seekBarManage(context: Context, seekBar: SeekBar) {
seekBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(p0: SeekBar?, p1: Int, p2: Boolean) {}
override fun onStartTrackingTouch(p0: SeekBar?) {}
override fun onStopTrackingTouch(p0: SeekBar?) {
MainActivity.getSeekBarProgress(context, seekBar)
}
})
}

How to get value of ssekbar.progress and use it on another function

I want to get value from seekbar.progress of three seekbar for control RGB.
I have Red seekbar , Green seekBar and Blue seekbar and I want that when I drag red seekbar and green and blue ,
I want to set Background for an image view that use value of seekbar . I want use this values for set background that Combination of three color .
I'm write the paint function for get three values of my seekbar and set a color for my image view background;
My SeekbarManger class is this :
class SeekBarManager() {
}
fun seekBarManage(context: Context, seekBar: SeekBar) {
seekBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(p0: SeekBar?, p1: Int, p2: Boolean) { }
override fun onStartTrackingTouch(p0: SeekBar?) {}
override fun onStopTrackingTouch(p0: SeekBar?) {
MainActivity.getSeekBarProgress(context , seekBar)
}
})
}
fun paint(view: View, red: Int, green:Int, blue:Int){
fun View.getLocationOnScreen(): Point
{
val location = IntArray(2)
this.getLocationOnScreen(location)
return Point(location[0],location[1])
}
val location = view.getLocationOnScreen()
val absX = location.x
val absY = location.y
val bitmap = Bitmap.createBitmap(absX , absY , Bitmap.Config.RGB_565)
val canvas = Canvas(bitmap)
canvas.drawRGB(red , green , blue )
view.background = BitmapDrawable(view.resources , bitmap)
}
and my MainActivity is This:
open class MainActivity : AppCompatActivity() {
companion object {
fun getSeekBarProgress(context: Context , seekBar: SeekBar){
val result = seekBar.progress
Toast.makeText(context, "Progress is: $result%", Toast.LENGTH_SHORT).show()
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val seekRed = findViewById<SeekBar>(R.id.seekBar_red)
val seekGreen = findViewById<SeekBar>(R.id.seekBar_green)
val seekBlue = findViewById<SeekBar>(R.id.seekBar_blue)
val seekEndRed = seekBarManage(this , seekRed)
val seekEndGreen = seekBarManage(this , seekGreen)
val seekEndBlue = seekBarManage(this , seekBlue)
paint(color_output , seekEndRed , seekEndGreen , seekEndBlue)
}
}
You should pass seekbars and view objects to SeekbarManager Class and then pass them to Companion object like below :
open class MainActivity : AppCompatActivity() {
companion object {
fun getSeekBarProgress(
seekBarRed: SeekBar,
seekBarGreen: SeekBar,
seekBarBlue: SeekBar,
view: View
) {
paint(view, seekBarRed.progress, seekBarGreen.progress, seekBarBlue.progress)
}
private fun paint(view: View, red: Int, green: Int, blue: Int) {
fun View.getLocationOnScreen(): Point {
val location = IntArray(2)
this.getLocationOnScreen(location)
return Point(location[0], location[1])
}
val location = view.getLocationOnScreen()
val absX = location.x
val absY = location.y
val bitmap = Bitmap.createBitmap(absX, absY, Bitmap.Config.RGB_565)
val canvas = Canvas(bitmap)
canvas.drawRGB(red, green, blue)
view.background = BitmapDrawable(view.resources, bitmap)
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val colorOutput = findViewById<View>(R.id.color_output)
val seekRed = findViewById<SeekBar>(R.id.seekBar_red)
val seekGreen = findViewById<SeekBar>(R.id.seekBar_green)
val seekBlue = findViewById<SeekBar>(R.id.seekBar_blue)
seekBarManage(seekRed, seekGreen, seekBlue, colorOutput)
}
}
and
class SeekBarManager() {
}
fun seekBarManage(
seekBarRed: SeekBar,
seekBarGreen: SeekBar,
seekBarBlue: SeekBar,
view: View
) {
seekBarRed.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(p0: SeekBar?, p1: Int, p2: Boolean) {}
override fun onStartTrackingTouch(p0: SeekBar?) {}
override fun onStopTrackingTouch(p0: SeekBar?) {
MainActivity.getSeekBarProgress(seekBarRed, seekBarGreen, seekBarBlue, view)
}
})
seekBarGreen.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(p0: SeekBar?, p1: Int, p2: Boolean) {}
override fun onStartTrackingTouch(p0: SeekBar?) {}
override fun onStopTrackingTouch(p0: SeekBar?) {
MainActivity.getSeekBarProgress(seekBarRed, seekBarGreen, seekBarBlue, view)
}
})
seekBarBlue.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(p0: SeekBar?, p1: Int, p2: Boolean) {}
override fun onStartTrackingTouch(p0: SeekBar?) {}
override fun onStopTrackingTouch(p0: SeekBar?) {
MainActivity.getSeekBarProgress(seekBarRed, seekBarGreen, seekBarBlue, view)
}
})
}
and better way is to just do all these in MainActivity and there is no need for SeekBarManager Class, like below:
open class MainActivity : AppCompatActivity() {
lateinit var colorOutput: View
lateinit var seekRed: SeekBar
lateinit var seekGreen: SeekBar
lateinit var seekBlue: SeekBar
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
colorOutput = findViewById<View>(R.id.color_output)
seekRed = findViewById<SeekBar>(R.id.seekBar_red)
seekGreen = findViewById<SeekBar>(R.id.seekBar_green)
seekBlue = findViewById<SeekBar>(R.id.seekBar_blue)
seekRed.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(p0: SeekBar?, p1: Int, p2: Boolean) {}
override fun onStartTrackingTouch(p0: SeekBar?) {}
override fun onStopTrackingTouch(p0: SeekBar?) {
paint()
}
})
seekGreen.setOnSeekBarChangeListener(
object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(p0: SeekBar?, p1: Int, p2: Boolean) {}
override fun onStartTrackingTouch(p0: SeekBar?) {}
override fun onStopTrackingTouch(p0: SeekBar?) {
paint()
}
})
seekBlue.setOnSeekBarChangeListener(
object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(p0: SeekBar?, p1: Int, p2: Boolean) {}
override fun onStartTrackingTouch(p0: SeekBar?) {}
override fun onStopTrackingTouch(p0: SeekBar?) {
paint()
}
})
}
private fun paint() {
val view = colorOutput
val red = seekRed.progress
val green = seekGreen.progress
val blue = seekBlue.progress
fun View.getLocationOnScreen(): Point {
val location = IntArray(2)
this.getLocationOnScreen(location)
return Point(location[0], location[1])
}
val location = view.getLocationOnScreen()
val absX = location.x
val absY = location.y
val bitmap = Bitmap.createBitmap(absX, absY, Bitmap.Config.RGB_565)
val canvas = Canvas(bitmap)
canvas.drawRGB(red, green, blue)
view.background = BitmapDrawable(view.resources, bitmap)
}
}

How to pass a parameter to a extension function in Kotlin

I have an extension function in kotlin to check is it a valid string or not as stated below.
fun EditText.onAfterTextChanged(listener: (String) -> Unit) {
addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(editable: Editable?) {
val input = editable?.toString()
val allowedChars = context.getString(R.string.supported_digits)
val newValue = replaceInvalidCharacters(input, allowedChars)
if (newValue != input) {
setText(newValue)
setSelection(text.length)
}
listener(newValue)
}
override fun beforeTextChanged(s: CharSequence?, p1: Int, p2: Int, p3: Int) {
}
override fun onTextChanged(s: CharSequence?, p1: Int, p2: Int, p3: Int) {
}
})
}
private fun replaceInvalidCharacters(value: String?, allowedChars: String): String {
var finalValue = value ?: ""
if (finalValue.isNotEmpty()) {
val lastChar = finalValue.last()
if (!allowedChars.contains(lastChar, false)) {
finalValue = finalValue.dropLast(1)
}
}
return finalValue
}
I am using it like:
editText.onAfterTextChanged {
val length = it.length
if (length >= 250) {
activity?.toast(getString(R.string.max_limit_reached))
return#onAfterTextChanged
}
}
Here I want to pass allowedChars as a parameter to this extension as there are different strings are there for different EditText's in the application. Like 1 EditText may allow only number's but not +,- and some edit text may allow only alphanumeric, etc. Is there any way to pass a parameter to the extension?
What you can do is update the extension function signature by adding a parameter before the callback function. So, it'll look something like this
fun EditText.onAfterTextChanged(allowedChars: String, listener: (String) -> Unit) {
addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(editable: Editable?) {
val input = editable?.toString()
val allowedChars = context.getString(R.string.supported_digits)
val newValue = replaceInvalidCharacters(input, allowedChars)
if (newValue != input) {
setText(newValue)
setSelection(text.length)
}
listener(newValue)
}
override fun beforeTextChanged(s: CharSequence?, p1: Int, p2: Int, p3: Int) {
}
override fun onTextChanged(s: CharSequence?, p1: Int, p2: Int, p3: Int) {
}
})
}
And you can call it like so:
editText.onAfterTextChanged("123abc") {
val length = it.length
if (length >= 250) {
activity?.toast(getString(R.string.max_limit_reached))
return#onAfterTextChanged
}
}

Android Livedata not updating EditText

I am using Android LiveData in 3 different EditText. I have to show the result of multiplying the values of the first two EditText into the third EditText. I took advantage of an advice given to me on this site, and actually the third value is updated with the result of the multiplication of the first two. The problem is that the update does not happen live, but only happens when I leave and re-enter the activity. I am attaching the XML file, the activity, and the viewmodel.
XML:
<layout 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">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
tools:context=".MainActivity">
<EditText
android:id="#+id/num1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:backgroundTint="#color/white"
android:inputType="number" />
<EditText
android:id="#+id/num2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:backgroundTint="#color/white"
android:inputType="numberDecimal" />
<EditText
android:id="#+id/num3"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:backgroundTint="#color/white"
android:inputType="numberDecimal" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
Activity
class MainActivity: AppCompatActivity() {
private lateinit var binding: MainActivityBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main_activity)
binding = DataBindingUtil.setContentView(
this,
R.layout.main_activity
)
viewModel=
ViewModelProvider(this, factory)[MainActivityViewModel::class.java]
initView(binding)
}
private fun initView(
binding:
MainActivityBinding
) {
viewModel.num1.value = root?.num1?: 0
viewModel.num2.value = root?.num2?: 0.0
viewModel.num1.observe(lifecycleOwner, Observer { newNum1->
binding.num1.setText(
newNum1.toString()
)
})
viewModel.num2.observe(lifecycleOwner, Observer { newNum2->
binding.num2.setText(
newNum2.toString()
)
})
binding.num1.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(s: Editable?) {
viewModel.num1.value =
binding.num1.text?.toString()?.toInt()
?: 0
}
override fun beforeTextChanged(
s: CharSequence?,
start: Int,
count: Int,
after: Int
) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
})
binding.num2.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(s: Editable?) {
viewModel.num2.value =
binding.num2.text?.toString()?.toDouble()
?: 0.0
}
override fun beforeTextChanged(
s: CharSequence?,
start: Int,
count: Int,
after: Int
) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
})
fun <A, B> LiveData<A>.combineWith(b: LiveData<B>): LiveData<Pair<A?, B?>> =
MediatorLiveData<Pair<A?, B?>>().apply {
var lastA: A? = this#combineWith.value
var lastB: B? = b.value
addSource(this#combineWith) {
lastA = it
value = Pair(lastA, lastB)
}
addSource(b) {
lastB = it
value = Pair(lastA, lastB)
}
}
viewModel.num1.combineWith(viewModel.num2)
.observe(
this,
Observer { (first, second) ->
if (first != null && second != null) {
binding.num3.setText((first * second).toString())
}
}
)
}
binding.num1.isFocusableInTouchMode = true
binding.num2.isFocusableInTouchMode = true
binding.num3.isFocusableInTouchMode = true
}
}
ViewModel
class RapportiAltriCostiViewModel(private val repositoryDB: DbRepository) : ViewModel() {
var num1= MutableLiveData<Int>()
var num2= MutableLiveData<Double>()
}
Would anyone know how to solve?
Thank you for your patience and help!
UPDATE
I tried with TextWatcher but it goes in loop:
binding.num1.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(s: Editable?) {
viewModel.num1.value =
binding.num1.text?.toString()?.toInt()
?: 0
}
override fun beforeTextChanged(
s: CharSequence?,
start: Int,
count: Int,
after: Int
) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
})
binding.num2.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(s: Editable?) {
viewModel.num2.value =
binding.num2.text?.toString()?.toDouble()
?: 0.0
}
override fun beforeTextChanged(
s: CharSequence?,
start: Int,
count: Int,
after: Int
) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
})
And I can't remove the TextWatcher after assigning the value, as I read on another question on the site, because I need them to always listen.
Thanks for the patience once again!
Something similar to this. To avoid cyclic updates you may just compare new value inside onFirstChanged/onSecondChanged with value in your liveData and skip liveData.value = newValue in that way.
class MainActivity : AppCompatActivity() {
private lateinit var binding: MainActivityBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main_activity)
binding = DataBindingUtil.setContentView(
this,
R.layout.main_activity
)
viewModel =
ViewModelProvider(this, factory)[MainActivityViewModel::class.java]
initView(binding)
}
private fun initView(
binding:
MainActivityBinding
) {
binding.num1.listenChanges { viewModel.onFirstChanged(it) }
binding.num2.listenChanges { viewModel.onSecondChanged(it) }
viewModel.num1
.observe(
lifecycleOwner,
Observer { num1Value ->
binding.num1.setText(num1Value.toString())
}
)
viewModel.num2
.observe(
lifecycleOwner,
Observer { num2Value ->
binding.num2.setText(num2Value.toString())
}
)
viewModel.num3
.observe(
lifecycleOwner,
Observer { result ->
binding.num3.setText(result.toString())
}
)
}
binding.num1.isFocusableInTouchMode = true
binding.num2.isFocusableInTouchMode = true
binding.num3.isFocusableInTouchMode = true
}
private fun EditText.listenChanges(textChanged: (String) -> Unit) {
addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(s: Editable?) {
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
textChanged(s.toString())
}
})
}
class RapportiAltriCostiViewModel(private val repositoryDB: DbRepository) : ViewModel() {
val num1 = MutableLiveData<Int>(0)
val num2 = MutableLiveData<Double>(0.0)
val num3: LiveData<Double>
get() = num1.combineWith(num2) { first, second ->
(first ?: 0) * (second ?: 0.0)
}
fun onFirstChanged(newValue: Int) {
if (num1.value != newValue) {
num1.value = newValue
}
}
fun onSecondChanged(newValue: Double) {
if (num2.value != newValue) {
num2.value = newValue
}
}
private companion object {
private fun <A, B, R> LiveData<A>.combineWith(b: LiveData<B>, combine: (A?, B?) -> R?): LiveData<R> =
MediatorLiveData<R>().apply {
var lastA: A? = this#combineWith.value
var lastB: B? = b.value
addSource(this#combineWith) {
lastA = it
value = combine.invoke(lastA, lastB)
}
addSource(b) {
lastB = it
value = combine.invoke(lastA, lastB)
}
}
}
}

How to save SeekBar thumb position after setting value to its progress?

I'm trying to get worked a segmented SeekBar for font site with step of 2.
It's working, but I can't keep thumb position, it is always on 0.
private fun fontSize() {
val view = LayoutInflater.from(this).inflate(R.layout.font_size_layout, null)
size = view.findViewById(R.id.font_size_sb)
val preference = PrefManager(this)
font = view.findViewById(R.id.font_size_tv)
font.textSize = preference.getFontSize().toFloat()
font.text = preference.getFontSize().toString()
size.apply {
max = (36 - 12) / 2
progress = preference.getFontSize()
setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
updateFontSize(12 + (progress * 2))
}
override fun onStartTrackingTouch(seekBar: SeekBar?) {
}
override fun onStopTrackingTouch(seekBar: SeekBar?) {
}
})
}
AlertDialog.Builder(
this,
R.style.AlertDialogSlider
).apply {
setView(view)
create()
show()
}
}
private fun updateFontSize(i: Int) {
note.textSize = i.toFloat()
font.text = i.toString()
font.textSize = i.toFloat()
preference.saveFontSize(i)
}
My preference class PrefManager:
class PrefManager(private var context: Context) {
fun saveFontSize(size: Int) {
context.getSharedPreferences("font_size", AppCompatActivity.MODE_PRIVATE).edit().apply {
putInt("fontSize", size)
apply()
}
}
fun getFontSize(): Int {
return context.getSharedPreferences("font_size", AppCompatActivity.MODE_PRIVATE)
.getInt("fontSize", -1)
}
For example, I set the font size to 18:
That's good and works for me, but when I want to change the size one more time, the SeekBar's position does not stay there, where I left it lastly. It goes to end:
How can I keep the position?
After spending a lot of time, I finally found a solution and it's very simple:
class PrefManager(private var context: Context) {
fun saveFontSize(size: Int, progress: Int) {
context.getSharedPreferences("font_size", AppCompatActivity.MODE_PRIVATE).edit().apply {
putInt("fontSize", size)
putInt("progress", progress)
apply()
}
}
fun getFontSize(): Int {
return context.getSharedPreferences("font_size", AppCompatActivity.MODE_PRIVATE)
.getInt("fontSize", 18)
}
fun getProgress(): Int {
return context.getSharedPreferences("font_size", AppCompatActivity.MODE_PRIVATE)
.getInt("progress", 3)
}
}
And piece of code for SeekBar:
size.apply {
progress = preference.getProgress()
setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(
seekBar: SeekBar?,
progress: Int,
fromUser: Boolean
) {
val fontSize = 12 + (progress * 2)
note.textSize = fontSize.toFloat()
font.text = fontSize.toString()
preference.saveFontSize(fontSize, progress)
}
override fun onStartTrackingTouch(seekBar: SeekBar?) {
}
override fun onStopTrackingTouch(seekBar: SeekBar?) {
}
})
}
I had just to keep saved the original values of progress within the onProgressChanged(). That's all!

Categories

Resources