Commit 5bb4ebb8 authored by shohboz's avatar shohboz

[ADD] MUS-123, Feature added pin lock screen

parent 1762fbce
......@@ -7,12 +7,17 @@ import androidx.navigation.NavController
import androidx.navigation.fragment.NavHostFragment
import dagger.hilt.android.AndroidEntryPoint
import uz.ssd.mobiuz.databinding.FragmentPinLockBinding
import uz.ssd.mobiuz.model.SharedPref
import uz.ssd.mobiuz.ui.auth.AuthViewModel
import uz.ssd.mobiuz.ui.base.BaseFragment
import javax.inject.Inject
@AndroidEntryPoint
class PinLockFragment : BaseFragment(R.layout.fragment_pin_lock) {
@Inject
lateinit var pref: SharedPref
private var _bn: FragmentPinLockBinding? = null
private val bn get() = _bn ?: throw NullPointerException("cannot inflate")
private val viewModel: AuthViewModel by viewModels()
......
package uz.ssd.mobiuz.model
data class PinData(
var count: Int = -1
)
package uz.ssd.mobiuz.ui.auth
import android.util.Log
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import uz.ssd.mobiuz.R
import uz.ssd.mobiuz.databinding.ItemPinBinding
import uz.ssd.mobiuz.model.PinData
import uz.ssd.mobiuz.utils.extensions.SingleBlock
class PinAdapter : RecyclerView.Adapter<PinAdapter.VHolder>() {
private val list = ArrayList<PinData>()
private var listener: SingleBlock<String>? = null
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VHolder {
return VHolder(ItemPinBinding.inflate(LayoutInflater.from(parent.context)))
}
override fun onBindViewHolder(holder: VHolder, position: Int) = holder.bind(position)
override fun getItemCount() = list.size
inner class VHolder(private val binding: ItemPinBinding) : RecyclerView.ViewHolder(binding.root) {
fun bind(position: Int) {
val d = list[position]
binding.imagePin.setImageResource(if (d.count == -1) R.drawable.bgn_pin_btn else R.drawable.bgn_pin_checked)
}
}
fun submitList(ls: List<PinData>) {
list.clear()
Log.e("AAA", "list $list")
list.addAll(ls)
Log.e("AAA", "list $list")
notifyDataSetChanged()
}
fun addItem(id: Int) {
val index = getAddItem()
if (index != -1) {
list[index].count = id
notifyItemChanged(index)
Log.e("AAA", "add index ${getAddItem()}")
if(index == 3) checkDone()
}
}
private fun checkDone(){
var pin = ""
list.forEach {
pin += it.count.toString()
}
if(pin.length == 4){
listener?.invoke(pin)
}
}
fun removeItem() {
val index = getCheckedItem()
if (index != -1) {
list[index].count = -1
notifyItemChanged(index)
Log.e("AAA", " remove index ${getCheckedItem()}")
}
}
private fun getCheckedItem(): Int {
var pos = -1
for (i in list.indices) {
if (list[i].count != -1)
pos = i
}
return pos
}
private fun getAddItem(): Int {
var pos = -1
for (i in list.indices) {
if (list[i].count == -1){
pos = i
return pos
}
}
return pos
}
fun setOnDoneListener(block: SingleBlock<String>){
listener = block
}
}
package uz.ssd.mobiuz.ui.auth
import android.os.Bundle
import android.view.View
import android.widget.TextView
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import androidx.navigation.NavController
import androidx.navigation.fragment.NavHostFragment
import androidx.recyclerview.widget.LinearLayoutManager
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.delay
import uz.ssd.mobiuz.R
import uz.ssd.mobiuz.databinding.FragmentPinBinding
import uz.ssd.mobiuz.model.PinData
import uz.ssd.mobiuz.model.SharedPref
import uz.ssd.mobiuz.ui.base.BaseFragment
import uz.ssd.mobiuz.utils.Utils
import uz.ssd.mobiuz.utils.extensions.showMessage
import javax.inject.Inject
@AndroidEntryPoint
class PinFragment : BaseFragment(R.layout.fragment_pin) {
@Inject
lateinit var pref: SharedPref
private var _bn: FragmentPinBinding? = null
private val bn get() = _bn ?: throw NullPointerException("cannot inflate")
private val navController: NavController by lazy(LazyThreadSafetyMode.NONE) { NavHostFragment.findNavController(this) }
var phone = ""
private var pinCode = ""
private val data = ArrayList<PinData>()
private val pinAdapter = PinAdapter()
private val viewModel: AuthViewModel by viewModels()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
_bn = FragmentPinBinding.bind(view)
setUpUI()
collects()
}
override fun setUpUI() {
bn.apply {
loadData()
rvPin.layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)
rvPin.setHasFixedSize(true)
rvPin.adapter = pinAdapter
pinAdapter.setOnDoneListener {
lifecycleScope.launchWhenCreated {
delay(500)
loadData()
if (pinCode.isEmpty()) {
pinCode = it
txtEnterPin.text = getString(R.string.confirm_pin)
showMessage(it)
} else {
if (pinCode == it) {
pref.pin_code = pinCode
navController.navigate(R.id.biometricFragment, null, Utils.navOptions())
} else {
pinCode = ""
txtEnterPin.text = getString(R.string.install_pin)
}
}
}
}
toolbar.setNavigationOnClickListener {
navController.navigateUp()
}
for (i in 0 until btnViewGroup.childCount) {
btnViewGroup.getChildAt(i).setOnClickListener {
if (it.id == R.id.btn_remove) {
pinAdapter.removeItem()
} else {
val text = it as TextView
pinAdapter.addItem(text.text.toString().toInt())
}
}
}
}
}
private fun loadData() {
data.clear()
for (i in 0..3) {
data.add(PinData(-1))
}
pinAdapter.submitList(data)
}
override fun collects() {
}
override fun onDestroy() {
_bn = null
super.onDestroy()
}
}
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<shape android:shape="oval">
<solid android:color="@color/lang_bgn_dark"/>
</shape>
</item>
<item android:state_pressed="false">
<shape android:shape="oval">
<solid android:color="@color/lang_bgn"/>
</shape>
</item>
</selector>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="oval">
<solid android:color="@color/red"/>
</shape>
</item>
</selector>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<solid android:color="@color/white"/>
<corners android:radius="4dp"/>
<stroke android:color="@color/red" android:width="1dp"/>
</shape>
</item>
</selector>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<solid android:color="@color/white"/>
<corners android:radius="2dp"/>
<stroke android:color="@color/light" android:width="1dp"/>
</shape>
</item>
</selector>
\ No newline at end of file
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="32dp"
android:height="24dp"
android:viewportWidth="32"
android:viewportHeight="24">
<path
android:pathData="M29.3333,0H9.3333C8.4,0 7.7333,0.4 7.2,1.2L0,12L7.2,22.8C7.7333,23.4667 8.4,24 9.3333,24H29.3333C30.8,24 32,22.8 32,21.3333V2.6667C32,1.2 30.8,0 29.3333,0ZM25.3333,16.8L23.4667,18.6667L18.6667,13.8667L13.8667,18.6667L12,16.8L16.8,12L12,7.2L13.8667,5.3333L18.6667,10.1333L23.4667,5.3333L25.3333,7.2L20.5333,12L25.3333,16.8Z"
android:fillColor="#D31F28"/>
</vector>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:navigationIcon="@drawable/ic_baseline_arrow_back" />
<TextView
android:id="@+id/txt_enter_pin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/_12sdp"
android:layout_marginTop="@dimen/_14sdp"
android:text="@string/install_pin"
android:textSize="@dimen/_16sdp"
android:textStyle="bold" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:gravity="center">
<com.google.android.material.card.MaterialCardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center">
<androidx.recyclerview.widget.RecyclerView
android:layout_width="wrap_content"
android:id="@+id/rv_pin"
android:paddingVertical="@dimen/_8sdp"
android:paddingHorizontal="@dimen/_6sdp"
tools:listitem="@layout/item_pin"
android:orientation="horizontal"
tools:itemCount="4"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
android:layout_height="wrap_content"/>
</com.google.android.material.card.MaterialCardView>
</LinearLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:id="@+id/btn_view_group"
android:layout_weight="3"
android:paddingHorizontal="@dimen/_48sdp">
<TextView
android:id="@+id/btn_1"
style="@style/BtnStyle"
android:text="1"
android:background="@drawable/bgn_pin_btn"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/btn_2"
style="@style/BtnStyle"
android:text="2"
android:background="@drawable/bgn_pin_btn"
app:layout_constraintEnd_toStartOf="@id/btn_3"
app:layout_constraintStart_toEndOf="@id/btn_1"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/btn_3"
style="@style/BtnStyle"
android:text="3"
android:background="@drawable/bgn_pin_btn"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/btn_4"
style="@style/BtnStyle"
android:layout_marginTop="@dimen/_16sdp"
android:text="4"
android:background="@drawable/bgn_pin_btn"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/btn_1" />
<TextView
android:id="@+id/btn_5"
style="@style/BtnStyle"
android:text="5"
android:background="@drawable/bgn_pin_btn"
app:layout_constraintEnd_toStartOf="@id/btn_3"
app:layout_constraintStart_toEndOf="@id/btn_1"
app:layout_constraintTop_toTopOf="@id/btn_4" />
<TextView
android:id="@+id/btn_6"
style="@style/BtnStyle"
android:text="6"
android:background="@drawable/bgn_pin_btn"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/btn_4" />
<TextView
android:id="@+id/btn_7"
style="@style/BtnStyle"
android:layout_marginTop="@dimen/_16sdp"
android:text="7"
android:background="@drawable/bgn_pin_btn"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/btn_4" />
<TextView
android:id="@+id/btn_8"
style="@style/BtnStyle"
android:text="8"
android:background="@drawable/bgn_pin_btn"
app:layout_constraintEnd_toStartOf="@id/btn_3"
app:layout_constraintStart_toEndOf="@id/btn_1"
app:layout_constraintTop_toTopOf="@id/btn_7" />
<TextView
android:id="@+id/btn_9"
style="@style/BtnStyle"
android:text="9"
android:background="@drawable/bgn_pin_btn"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/btn_7" />
<TextView
android:id="@+id/btn_0"
style="@style/BtnStyle"
android:layout_marginTop="@dimen/_16sdp"
android:text="0"
android:background="@drawable/bgn_pin_btn"
app:layout_constraintStart_toStartOf="@id/btn_8"
app:layout_constraintTop_toBottomOf="@id/btn_7" />
<ImageView
android:id="@+id/btn_remove"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="@dimen/_12sdp"
android:src="@drawable/ic_vector_remove"
android:text="9"
android:background="?selectableItemBackgroundBorderless"
app:layout_constraintBottom_toBottomOf="@id/btn_0"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@id/btn_9"
app:layout_constraintTop_toTopOf="@id/btn_0" />
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".VerificationFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/hello_blank_fragment" />
</FrameLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:layout_width="@dimen/_8sdp"
android:id="@+id/image_pin"
android:layout_marginHorizontal="@dimen/_4sdp"
android:background="@drawable/bgn_pin_btn"
android:layout_height="@dimen/_8sdp"/>
</FrameLayout>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment