Skip to content

Commit c9d09e6

Browse files
authored
Replace com.andrognito.pinlockview (#78)
* Replace com.andrognito.pinlockview (jcenter only dependency) with custom implementation * Fix lint issue by using requireContext()
1 parent 5a61c32 commit c9d09e6

11 files changed

Lines changed: 444 additions & 62 deletions

File tree

pretixscan/app/build.gradle

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,6 @@ dependencies {
129129
implementation 'com.louiscad.splitties:splitties-toast:3.0.0'
130130
implementation 'com.github.traex.rippleeffect:library:1.3'
131131
implementation 'me.dm7.barcodescanner:zxing:1.9.8'
132-
implementation 'com.andrognito.pinlockview:pinlockview:2.1.0'
133132
implementation 'com.github.kizitonwose:CalendarView:1.0.4'
134133

135134
implementation 'com.squareup.okhttp3:okhttp:4.9.3'
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
package eu.pretix.pretixscan.droid.ui
2+
3+
import android.content.Context
4+
import android.os.Build
5+
import android.util.AttributeSet
6+
import android.view.LayoutInflater
7+
import android.view.MotionEvent
8+
import android.view.View
9+
import android.widget.ImageView
10+
import android.widget.RelativeLayout
11+
import android.widget.TextView
12+
import eu.pretix.pretixscan.droid.R
13+
14+
15+
// (c) 2015 OrangeGangsters
16+
// MIT License
17+
// https://github.com/omadahealth/LolliPin/blob/0c523dfb7e9ee5dfcf37ad047cbb970ccd8794fb/lib/src/main/java/com/github/omadahealth/lollipin/lib/views/KeyboardButtonView.java
18+
19+
interface KeyboardButtonClickedListener {
20+
21+
}
22+
23+
class KeyboardButtonView @JvmOverloads constructor(private val mContext: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : RelativeLayout(mContext, attrs, defStyleAttr) {
24+
25+
private var mKeyboardButtonClickedListener: KeyboardButtonClickedListener? = null
26+
private var mRippleView: View? = null
27+
28+
init {
29+
initializeView(attrs, defStyleAttr)
30+
}
31+
32+
private fun initializeView(attrs: AttributeSet?, defStyleAttr: Int) {
33+
if (attrs != null && !isInEditMode) {
34+
val attributes = mContext.getTheme().obtainStyledAttributes(attrs, R.styleable.KeyboardButtonView,
35+
defStyleAttr, 0)
36+
val text = attributes.getString(R.styleable.KeyboardButtonView_lp_keyboard_button_text)
37+
val image = attributes.getDrawable(R.styleable.KeyboardButtonView_lp_keyboard_button_image)
38+
val rippleEnabled = attributes.getBoolean(R.styleable.KeyboardButtonView_lp_keyboard_button_ripple_enabled, true)
39+
40+
attributes.recycle()
41+
42+
val inflater = mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
43+
val view = inflater.inflate(R.layout.view_keyboard_button, this) as KeyboardButtonView
44+
45+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
46+
view.focusable = NOT_FOCUSABLE
47+
}
48+
49+
if (text != null) {
50+
val textView = view.findViewById(R.id.keyboard_button_textview) as TextView
51+
textView?.setText(text)
52+
}
53+
if (image != null) {
54+
val imageView = view.findViewById(R.id.keyboard_button_imageview) as ImageView
55+
if (imageView != null) {
56+
imageView!!.setImageDrawable(image)
57+
imageView!!.setVisibility(View.VISIBLE)
58+
}
59+
}
60+
61+
mRippleView = view.findViewById(R.id.pin_code_keyboard_button_ripple) as View
62+
//mRippleView!!.setRippleAnimationListener(this)
63+
if (mRippleView != null) {
64+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
65+
mRippleView!!.focusable = NOT_FOCUSABLE
66+
}
67+
if (!rippleEnabled) {
68+
mRippleView!!.setVisibility(View.INVISIBLE)
69+
}
70+
}
71+
}
72+
}
73+
74+
fun setOnRippleAnimationEndListener(keyboardButtonClickedListener: KeyboardButtonClickedListener) {
75+
mKeyboardButtonClickedListener = keyboardButtonClickedListener
76+
}
77+
78+
fun onRippleAnimationEnd() {
79+
if (mKeyboardButtonClickedListener != null) {
80+
//mKeyboardButtonClickedListener!!.onRippleAnimationEnd()
81+
}
82+
}
83+
84+
override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
85+
onTouchEvent(event)
86+
return false
87+
}
88+
}

pretixscan/app/src/main/java/eu/pretix/pretixscan/droid/ui/MainActivity.kt

Lines changed: 12 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,6 @@ import androidx.databinding.DataBindingUtil
4949
import androidx.databinding.ObservableField
5050
import androidx.preference.PreferenceManager
5151
import androidx.recyclerview.widget.LinearLayoutManager
52-
import com.andrognito.pinlockview.IndicatorDots
53-
import com.andrognito.pinlockview.PinLockListener
54-
import com.andrognito.pinlockview.PinLockView
5552
import com.fasterxml.jackson.databind.DeserializationFeature
5653
import com.fasterxml.jackson.databind.ObjectMapper
5754
import com.fasterxml.jackson.databind.module.SimpleModule
@@ -180,6 +177,8 @@ class MainActivity : AppCompatActivity(), ReloadableActivity, ZXingScannerView.R
180177

181178
private var syncMessage = ""
182179

180+
private var pendingPinAction: ((pin: String) -> Unit)? = null
181+
183182
companion object {
184183
const val PERMISSIONS_REQUEST_CAMERA = 1337
185184
const val PERMISSIONS_REQUEST_WRITE_STORAGE = 1338
@@ -501,6 +500,14 @@ class MainActivity : AppCompatActivity(), ReloadableActivity, ZXingScannerView.R
501500

502501
binding.recyclerViewSearch.layoutManager = LinearLayoutManager(this)
503502
binding.recyclerViewSearch.addItemDecoration(androidx.recyclerview.widget.DividerItemDecoration(binding.recyclerViewSearch.context, androidx.recyclerview.widget.DividerItemDecoration.VERTICAL))
503+
504+
supportFragmentManager.setFragmentResultListener(PinDialog.RESULT_PIN, this) { _, bundle ->
505+
val pin = bundle.getString(PinDialog.RESULT_PIN)
506+
if (pin != null && conf.verifyPin(pin)) {
507+
(supportFragmentManager.findFragmentByTag(PinDialog.TAG) as? PinDialog)?.dismiss()
508+
pendingPinAction?.let { it(pin) }
509+
}
510+
}
504511
}
505512

506513
private fun eventButtonText(): String {
@@ -1367,35 +1374,8 @@ class MainActivity : AppCompatActivity(), ReloadableActivity, ZXingScannerView.R
13671374
valid("")
13681375
return
13691376
}
1370-
val view = layoutInflater.inflate(R.layout.dialog_pin, null)
1371-
val dialog = AlertDialog.Builder(this)
1372-
.setView(view)
1373-
.create()
1374-
dialog.setOnShowListener {
1375-
val mPinLockListener: PinLockListener = object : PinLockListener {
1376-
override fun onComplete(pin: String) {
1377-
this.onPinChange(pin.length, pin)
1378-
}
1379-
1380-
override fun onEmpty() {
1381-
}
1382-
1383-
override fun onPinChange(pinLength: Int, intermediatePin: String) {
1384-
if (conf.verifyPin(intermediatePin)) {
1385-
dialog.dismiss()
1386-
valid(intermediatePin)
1387-
}
1388-
}
1389-
}
1390-
1391-
val lockView = view.findViewById(R.id.pin_lock_view) as PinLockView
1392-
lockView.pinLength = conf.getPinLength()
1393-
lockView.setPinLockListener(mPinLockListener)
1394-
val idots = view.findViewById(R.id.indicator_dots) as IndicatorDots
1395-
idots.pinLength = conf.getPinLength()
1396-
lockView.attachIndicatorDots(idots);
1397-
}
1398-
dialog.show()
1377+
pendingPinAction = valid
1378+
PinDialog().show(supportFragmentManager)
13991379
}
14001380

14011381
fun startWithPIN(intent: Intent, key: String, resultCode: Int? = null, bundle: Bundle? = null) {
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
package eu.pretix.pretixscan.droid.ui
2+
3+
import android.app.Dialog
4+
import android.content.DialogInterface
5+
import android.os.Bundle
6+
import android.view.KeyEvent
7+
import android.view.View
8+
import androidx.core.os.bundleOf
9+
import androidx.databinding.ObservableField
10+
import androidx.fragment.app.DialogFragment
11+
import androidx.fragment.app.FragmentManager
12+
import androidx.fragment.app.setFragmentResult
13+
import com.google.android.material.dialog.MaterialAlertDialogBuilder
14+
import eu.pretix.pretixscan.droid.databinding.DialogPinBinding
15+
import java.util.Collections
16+
17+
18+
class PINInputDataHolder() {
19+
val input = ObservableField("")
20+
val text = ObservableField("")
21+
}
22+
23+
class PinDialog : DialogFragment() {
24+
companion object {
25+
const val TAG = "PinDialogFragment"
26+
const val RESULT_PIN = "pin"
27+
const val RESULT_DISMISS = "dismiss"
28+
}
29+
30+
val data = PINInputDataHolder()
31+
32+
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
33+
data.input.set("")
34+
35+
val binding = DialogPinBinding.inflate(layoutInflater)
36+
binding.data = data
37+
38+
binding.keyboardButtonView0.setOnClickListener { pushDigit("0") }
39+
binding.keyboardButtonView00.visibility = View.INVISIBLE
40+
binding.keyboardButtonView1.setOnClickListener { pushDigit("1") }
41+
binding.keyboardButtonView2.setOnClickListener { pushDigit("2") }
42+
binding.keyboardButtonView3.setOnClickListener { pushDigit("3") }
43+
binding.keyboardButtonView4.setOnClickListener { pushDigit("4") }
44+
binding.keyboardButtonView5.setOnClickListener { pushDigit("5") }
45+
binding.keyboardButtonView6.setOnClickListener { pushDigit("6") }
46+
binding.keyboardButtonView7.setOnClickListener { pushDigit("7") }
47+
binding.keyboardButtonView8.setOnClickListener { pushDigit("8") }
48+
binding.keyboardButtonView9.setOnClickListener { pushDigit("9") }
49+
binding.keyboardButtonViewBackspace.setOnClickListener { pushBackspace() }
50+
51+
return MaterialAlertDialogBuilder(requireContext())
52+
.setView(binding.root)
53+
.setOnKeyListener { _, keyCode, event ->
54+
if (event.action != KeyEvent.ACTION_DOWN) return@setOnKeyListener false
55+
56+
if (event.displayLabel.toString().matches(Regex("^[0-9]$"))) {
57+
pushDigit(event.displayLabel.toString())
58+
return@setOnKeyListener true
59+
}
60+
if (keyCode == KeyEvent.KEYCODE_DEL) {
61+
pushBackspace()
62+
return@setOnKeyListener true
63+
}
64+
if (keyCode == KeyEvent.KEYCODE_ESCAPE) {
65+
dismiss()
66+
return@setOnKeyListener true
67+
}
68+
69+
return@setOnKeyListener false
70+
}
71+
.create()
72+
}
73+
74+
protected fun pushBackspace() {
75+
val current = data.input.get()!!
76+
if (current.isNotBlank()) {
77+
data.input.set(current.substring(0, current.length - 1))
78+
}
79+
data.text.set(Collections.nCopies(data.input.get()!!.length, "*").joinToString(""))
80+
}
81+
82+
protected fun pushDigit(digit: String) {
83+
val current = data.input.get()!!
84+
data.input.set(current + digit)
85+
data.text.set(Collections.nCopies(data.input.get()!!.length, "*").joinToString(""))
86+
setFragmentResult(RESULT_PIN, bundleOf(RESULT_PIN to data.input.get()!!))
87+
}
88+
89+
override fun onDismiss(dialog: DialogInterface) {
90+
setFragmentResult(RESULT_DISMISS, bundleOf())
91+
super.onDismiss(dialog)
92+
}
93+
94+
fun show(manager: FragmentManager) {
95+
super.show(manager, TAG)
96+
}
97+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
2+
android:width="24dp"
3+
android:height="24dp"
4+
android:viewportWidth="24.0"
5+
android:viewportHeight="24.0">
6+
<path
7+
android:fillColor="#FF000000"
8+
android:pathData="M22,3L7,3c-0.69,0 -1.23,0.35 -1.59,0.88L0,12l5.41,8.11c0.36,0.53 0.9,0.89 1.59,0.89h15c1.1,0 2,-0.9 2,-2L24,5c0,-1.1 -0.9,-2 -2,-2zM19,15.59L17.59,17 14,13.41 10.41,17 9,15.59 12.59,12 9,8.41 10.41,7 14,10.59 17.59,7 19,8.41 15.41,12 19,15.59z"/>
9+
</vector>

0 commit comments

Comments
 (0)