Home > Software engineering >  Password circle in kotlin simplified
Password circle in kotlin simplified

Time:09-23

I currently do this to make my custom password circle:

val pinIcon0 = "◇ ◇ ◇ ◇"
val pinIcon1 = "◆ ◇ ◇ ◇"
val pinIcon2 = "◆ ◆ ◇ ◇"
val pinIcon3 = "◆ ◆ ◆ ◇"
val pinIcon4 = "◆ ◆ ◆ ◆"

And then do this:

listOf(num0,num1,num2,num3,num4,num5,num6,num7,num8,num9)
            .withIndex()
            .forEach { (index, view) ->
                view.setOnClickListener {
                    pinCount  
                    pinCodeNew.append("$index")

                    if(pinCount == 0){ newPinCircle.text = pinIcon0 }
                    if(pinCount == 1 || pinCount == 5){ newPinCircle.text = pinIcon1 }
                    if(pinCount == 2 || pinCount == 6){ newPinCircle.text = pinIcon2 }
                    if(pinCount == 3 || pinCount == 7){ newPinCircle.text = pinIcon3 }
                    if(pinCount == 4 || pinCount == 8){ newPinCircle.text = pinIcon4 }

                    if(pinCount == 8){
                        savePin()
                        newPinTxt.text = "NEW PIN"
                        newPinCircle.text = pinIcon0
                    }
                    if(pinCount == 9){
                        pinCount = 0
                        newPinCircle.text = pinIcon0
                    }
                    if(pinCount == 4){
                        if(pinCodeNew.text.toString() == "1234"){
                            Toast.makeText(this,"PIN cannot be 1234", Toast.LENGTH_SHORT).show()
                            pinCodeNew.text?.clear()
                            pinCount = 0
                            newPinCircle.text = pinIcon0
                        }else {
                            if(pinCodeNew.text.toString() == getEncryptedSharedPrefs().getString("pinSettingsLogin", "")){
                                Toast.makeText(this,"PIN cannot be current PIN", Toast.LENGTH_SHORT).show()
                                pinCodeNew.text?.clear()
                                pinCount = 0
                                newPinCircle.text = pinIcon0
                            }else{
                                getEncryptedSharedPrefs().edit()
                                    .putString("pinSettingsNew", pinCodeNew.text.toString())
                                    .apply()
                                pinCodeNew.text?.clear()
                                newPinTxt.text = "CONFIRM PIN"
                                newPinCircle.text = pinIcon0
                            }
                        }
                    }
                }
            }
        }

This is the current code I use to make my stuff happen good, but not optimal. The part that needs some work is the 5 "if" statements to change my pinIcon.

See image below here on what It looks like: enter image description here

CodePudding user response:

This way you can loop through the list endlessly no need to worry about index getting out of range of list

var pinCount = 0
val pins = listOf("◇ ◇ ◇ ◇","◆ ◇ ◇ ◇","◆ ◆ ◇ ◇","◆ ◆ ◆ ◇","◆ ◆ ◆ ◆")

And in your click listener

newPinCircle.text = pins[pinCount]
pinCount = (pinCount  1) % pins.size

CodePudding user response:

you can exchange pinCount == 1 || pinCount == 5 to pinCount % 4 == 1 and also use else for preventing unnecessary if conditions checks (as they are excluding in fact). also in Kotlin you may use

newPinCircle.text = 
    if(pinCount % 4 == 1) pinIcon1
    else if(pinCount % 4 == 2) pinIcon2
    else if(pinCount % 4 == 3) pinIcon3
    else pinIcon4 // can pinCount be > 8?

besides these "improvements" you've posted veeery little code for more suggestions

I would suggest to make "beautiful" app and showing filled dots with text/characters won't be pretty for shure ;) Would look better with ImageViews with exchanging their images, even better it would be to use checkable attribute and some "filling" anims. But who knows how your layout looks like, what contains, for what it is used

CodePudding user response:

Basically you'd need the maximum length of the pin number and basically use some functional operators

fun onPinTyped() {
  editText.value = List<String>(MAX_PIN_LENGTH) { i ->  if(i <= pinCount) "◆" else "◇" }.joinToString(separator=" ")
}

What this bit of code is doing is essentially creating a list of strings with as many elements as a outer variable named MAX_PIN_LENGTH.

It then executes the function for each of the elements (ie, characters) that are going to compose your text.

The function returns for all characters that have already been typed and for the missing ones.

Lastly it joins each of the separater characters into a single string separating each character with a whitespace.

This code is not the most efficient one due to unneeded string allocations but hey, it's a one-liner.


A more optimal approach is to use the buildString utility from the kotlin.text package:

fun onPinTyped() {
  editText.value = buildString {
    (0..MAX_PIN_LENGTH).forEach { i ->
       append(if(i<=pinCount) '◆' else '◇')
    }
  }
}
  • Related