create a viewpager for switching between pattern/pin protection

This commit is contained in:
tibbi 2017-07-30 23:07:53 +02:00
parent a55943f0f0
commit 02ee4dcc03
8 changed files with 227 additions and 64 deletions

View file

@ -0,0 +1,33 @@
package com.simplemobiletools.gallery.adapters
import android.content.Context
import android.support.v4.view.PagerAdapter
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.simplemobiletools.gallery.R
import com.simplemobiletools.gallery.views.PatternTab
class PasswordTypesAdapter(val context: Context, val requiredHash: String, val hashListener: PatternTab.HashListener) : PagerAdapter() {
override fun instantiateItem(container: ViewGroup, position: Int): Any {
val view = LayoutInflater.from(context).inflate(layoutSelection(position), container, false)
container.addView(view)
if (position == 0)
(view as PatternTab).initTab(requiredHash, hashListener)
return view
}
override fun destroyItem(container: ViewGroup, position: Int, item: Any) {
container.removeView(item as View)
}
override fun getCount() = 2
override fun isViewFromObject(view: View, item: Any) = view == item
private fun layoutSelection(position: Int): Int = when (position) {
0 -> R.layout.tab_pattern
1 -> R.layout.tab_pin
else -> throw RuntimeException("Only 2 tabs allowed")
}
}

View file

@ -1,42 +1,27 @@
package com.simplemobiletools.gallery.dialogs package com.simplemobiletools.gallery.dialogs
import android.os.Handler
import android.support.v7.app.AlertDialog import android.support.v7.app.AlertDialog
import android.view.LayoutInflater import android.view.LayoutInflater
import com.andrognito.patternlockview.PatternLockView
import com.andrognito.patternlockview.listener.PatternLockViewListener
import com.andrognito.patternlockview.utils.PatternLockUtils
import com.simplemobiletools.commons.extensions.setupDialogStuff import com.simplemobiletools.commons.extensions.setupDialogStuff
import com.simplemobiletools.commons.extensions.toast
import com.simplemobiletools.gallery.R import com.simplemobiletools.gallery.R
import com.simplemobiletools.gallery.activities.SimpleActivity import com.simplemobiletools.gallery.activities.SimpleActivity
import com.simplemobiletools.gallery.adapters.PasswordTypesAdapter
import com.simplemobiletools.gallery.extensions.config import com.simplemobiletools.gallery.extensions.config
import com.simplemobiletools.gallery.views.MyDialogViewPager
import com.simplemobiletools.gallery.views.PatternTab
import kotlinx.android.synthetic.main.dialog_pattern.view.* import kotlinx.android.synthetic.main.dialog_pattern.view.*
class PatternDialog(val activity: SimpleActivity, val requiredHash: String, val callback: (hash: String) -> Unit) { class PatternDialog(val activity: SimpleActivity, val requiredHash: String, val callback: (hash: String) -> Unit) : PatternTab.HashListener {
var dialog: AlertDialog? = null var dialog: AlertDialog? = null
val view = LayoutInflater.from(activity).inflate(R.layout.dialog_pattern, null) val view = LayoutInflater.from(activity).inflate(R.layout.dialog_pattern, null)
var hash = requiredHash
init { init {
view.apply { view.apply {
pattern_lock_view.correctStateColor = activity.config.primaryColor val textColor = context.config.textColor
pattern_lock_view.normalStateColor = activity.config.textColor dialog_tab_layout.setTabTextColors(textColor, textColor)
pattern_lock_view.addPatternLockListener(object : PatternLockViewListener {
override fun onComplete(pattern: MutableList<PatternLockView.Dot>?) {
receivedHash(PatternLockUtils.patternToSha1(pattern_lock_view, pattern))
}
override fun onCleared() { val viewPager = findViewById(R.id.dialog_tab_view_pager) as MyDialogViewPager
} viewPager.adapter = PasswordTypesAdapter(context, requiredHash, this@PatternDialog)
override fun onStarted() {
}
override fun onProgress(progressPattern: MutableList<PatternLockView.Dot>?) {
}
})
} }
dialog = AlertDialog.Builder(activity) dialog = AlertDialog.Builder(activity)
@ -46,31 +31,8 @@ class PatternDialog(val activity: SimpleActivity, val requiredHash: String, val
} }
} }
private fun receivedHash(newHash: String) { override fun receivedHash(hash: String) {
view.apply { callback(hash)
if (hash.isEmpty()) { dialog!!.dismiss()
hash = newHash
pattern_lock_view.clearPattern()
pattern_dialog_title.setText(R.string.repeat_pattern)
} else {
if (hash == newHash) {
pattern_lock_view.setViewMode(PatternLockView.PatternViewMode.CORRECT)
Handler().postDelayed({
callback(hash)
dialog!!.dismiss()
}, 300)
} else {
pattern_lock_view.setViewMode(PatternLockView.PatternViewMode.WRONG)
activity.toast(R.string.wrong_pattern)
Handler().postDelayed({
pattern_lock_view.clearPattern()
if (requiredHash.isEmpty()) {
hash = ""
pattern_dialog_title.setText(R.string.insert_pattern)
}
}, 1000)
}
}
}
} }
} }

View file

@ -0,0 +1,42 @@
package com.simplemobiletools.gallery.views
import android.content.Context
import android.support.v4.view.ViewPager
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
class MyDialogViewPager : ViewPager {
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
// disable manual swiping of viewpager at the dialog
override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
return false
}
override fun onTouchEvent(ev: MotionEvent): Boolean {
try {
return super.onTouchEvent(ev)
} catch (ignored: Exception) {
}
return false
}
// https://stackoverflow.com/a/20784791/1967672
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
var height = 0
for (i in 0..childCount - 1) {
val child = getChildAt(i)
child.measure(widthMeasureSpec, View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED))
val h = child.measuredHeight
if (h > height) height = h
}
val newHeightMeasureSpec = View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY)
super.onMeasure(widthMeasureSpec, newHeightMeasureSpec)
}
}

View file

@ -0,0 +1,76 @@
package com.simplemobiletools.gallery.views
import android.content.Context
import android.os.Handler
import android.util.AttributeSet
import android.widget.RelativeLayout
import com.andrognito.patternlockview.PatternLockView
import com.andrognito.patternlockview.listener.PatternLockViewListener
import com.andrognito.patternlockview.utils.PatternLockUtils
import com.simplemobiletools.commons.extensions.toast
import com.simplemobiletools.gallery.R
import com.simplemobiletools.gallery.extensions.config
import kotlinx.android.synthetic.main.tab_pattern.view.*
class PatternTab(context: Context, attrs: AttributeSet) : RelativeLayout(context, attrs) {
var hash = ""
var requiredHash = ""
lateinit var hashListener: HashListener
override fun onFinishInflate() {
super.onFinishInflate()
val textColor = context.config.textColor
pattern_lock_title.setTextColor(textColor)
pattern_lock_view.correctStateColor = context.config.primaryColor
pattern_lock_view.normalStateColor = textColor
pattern_lock_view.addPatternLockListener(object : PatternLockViewListener {
override fun onComplete(pattern: MutableList<PatternLockView.Dot>?) {
receivedHash(PatternLockUtils.patternToSha1(pattern_lock_view, pattern))
}
override fun onCleared() {
}
override fun onStarted() {
}
override fun onProgress(progressPattern: MutableList<PatternLockView.Dot>?) {
}
})
}
fun initTab(requiredHash: String, listener: HashListener) {
this.requiredHash = requiredHash
hash = requiredHash
hashListener = listener
}
private fun receivedHash(newHash: String) {
if (hash.isEmpty()) {
hash = newHash
pattern_lock_view.clearPattern()
pattern_lock_title.setText(R.string.repeat_pattern)
} else {
if (hash == newHash) {
pattern_lock_view.setViewMode(PatternLockView.PatternViewMode.CORRECT)
Handler().postDelayed({
hashListener.receivedHash(hash)
}, 300)
} else {
pattern_lock_view.setViewMode(PatternLockView.PatternViewMode.WRONG)
context.toast(R.string.wrong_pattern)
Handler().postDelayed({
pattern_lock_view.clearPattern()
if (requiredHash.isEmpty()) {
hash = ""
pattern_lock_title.setText(R.string.insert_pattern)
}
}, 1000)
}
}
}
interface HashListener {
fun receivedHash(hash: String)
}
}

View file

@ -0,0 +1,11 @@
package com.simplemobiletools.gallery.views
import android.content.Context
import android.util.AttributeSet
import android.widget.RelativeLayout
class PinTab(context: Context, attrs: AttributeSet) : RelativeLayout(context, attrs) {
override fun onFinishInflate() {
super.onFinishInflate()
}
}

View file

@ -1,22 +1,31 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout <RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/pattern_dialog_holder" android:id="@+id/dialog_holder"
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="match_parent"> android:layout_height="wrap_content">
<com.simplemobiletools.commons.views.MyTextView <android.support.design.widget.TabLayout
android:id="@+id/pattern_dialog_title" android:id="@+id/dialog_tab_layout"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.design.widget.TabItem
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/pattern"/>
<android.support.design.widget.TabItem
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/pin"/>
</android.support.design.widget.TabLayout>
<com.simplemobiletools.gallery.views.MyDialogViewPager
android:id="@+id/dialog_tab_view_pager"
android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:padding="@dimen/activity_margin" android:layout_below="@+id/dialog_tab_layout"/>
android:text="@string/insert_pattern"/>
<com.andrognito.patternlockview.PatternLockView
android:id="@+id/pattern_lock_view"
android:layout_width="280dp"
android:layout_height="280dp"
android:layout_below="@+id/pattern_dialog_title"
android:layout_centerInParent="true"/>
</RelativeLayout> </RelativeLayout>

View file

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<com.simplemobiletools.gallery.views.PatternTab
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/pattern_lock_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/pattern_lock_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="@dimen/activity_margin"
android:text="@string/insert_pattern"/>
<com.andrognito.patternlockview.PatternLockView
android:id="@+id/pattern_lock_view"
android:layout_width="280dp"
android:layout_height="280dp"
android:layout_below="@+id/pattern_lock_title"
android:layout_centerInParent="true"/>
</com.simplemobiletools.gallery.views.PatternTab>

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<com.simplemobiletools.gallery.views.PinTab
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/pin_lock_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</com.simplemobiletools.gallery.views.PinTab>