Improved Code

This commit is contained in:
mohamedkaif356
2023-07-25 12:22:57 +05:30
parent 46ee7b55be
commit e2e9c28efb
5 changed files with 147 additions and 193 deletions

View File

@@ -1,6 +1,7 @@
package com.example.hpostesting.data package com.example.hpostesting.data
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import com.example.hpostesting.data.model.patient.HemoCubeTestData
import com.example.hpostesting.data.model.patient.UserData import com.example.hpostesting.data.model.patient.UserData
import com.example.hpostesting.data.model.test.TestRightDeviceConstants import com.example.hpostesting.data.model.test.TestRightDeviceConstants
import com.example.hpostesting.data.model.test.TestType import com.example.hpostesting.data.model.test.TestType

View File

@@ -65,7 +65,8 @@ class MainActivity : AppCompatActivity() {
locationCallback = object : LocationCallback() { locationCallback = object : LocationCallback() {
override fun onLocationResult(locationResult: LocationResult) { override fun onLocationResult(locationResult: LocationResult) {
locationResult.lastLocation?.let { location -> locationResult.lastLocation?.let { location ->
DataHolder.selectedTest!!.location = UserData.Location(location.latitude, location.longitude) DataHolder.selectedTest!!.location =
UserData.Location(location.latitude, location.longitude)
Log.i("Location", DataHolder.location.toString()) Log.i("Location", DataHolder.location.toString())
} }
} }
@@ -87,6 +88,7 @@ class MainActivity : AppCompatActivity() {
DataHolder.usbConnected.value = true DataHolder.usbConnected.value = true
DataHolder.deviceType.postValue(Constants.DEVICE_TYPE_HOMOCUBE) DataHolder.deviceType.postValue(Constants.DEVICE_TYPE_HOMOCUBE)
} }
"Test" -> { "Test" -> {
} }
@@ -103,29 +105,33 @@ class MainActivity : AppCompatActivity() {
"Device matched -> product = ${availableDrivers[0].device.productId}, vendor = ${availableDrivers[0].device.vendorId}" "Device matched -> product = ${availableDrivers[0].device.productId}, vendor = ${availableDrivers[0].device.vendorId}"
) )
// Log.d("mariya", availableDrivers[0].device.toString()) // Log.d("mariya", availableDrivers[0].device.toString())
if (availableDrivers.isNotEmpty() && availableDrivers[0].device.productId == Constants.HOMO_CUBE_ID && availableDrivers[0].device.vendorId == Constants.VENDOR_ID) { if (availableDrivers.isNotEmpty() && availableDrivers[0].device.productId == Constants.HOMO_CUBE_ID && availableDrivers[0].device.vendorId == Constants.VENDOR_ID) {
Log.e("HomoCube", "product1") Log.e("HomoCube", "product1")
binding.cvItem1.visibility = View.VISIBLE binding.cvItem1.visibility = View.VISIBLE
binding.cvItem3.visibility = View.VISIBLE binding.cvItem3.visibility = View.VISIBLE
binding.cvItem2.visibility = View.GONE binding.cvItem2.visibility = View.GONE
binding.cvItem4.visibility = View.GONE binding.cvItem4.visibility = View.GONE
Toast.makeText(this, "HomoCube Connected", Toast.LENGTH_SHORT).show() Toast.makeText(this, "HomoCube Connected", Toast.LENGTH_SHORT).show()
DataHolder.usbConnected.value = true DataHolder.usbConnected.value = true
DataHolder.deviceType.postValue(Constants.DEVICE_TYPE_HOMOCUBE) DataHolder.deviceType.postValue(Constants.DEVICE_TYPE_HOMOCUBE)
}else if (availableDrivers.isNotEmpty() && availableDrivers[0].device.productId == Constants.DEVICE_PRODUCT_ID && availableDrivers[0].device.vendorId == Constants.DEVICE_VENDOR_ID) { } else if (availableDrivers.isNotEmpty() && availableDrivers[0].device.productId == Constants.DEVICE_PRODUCT_ID && availableDrivers[0].device.vendorId == Constants.DEVICE_VENDOR_ID) {
Log.d(TAG, "Device matched -> product = ${availableDrivers[0].device.productId}, vendor = ${availableDrivers[0].device.vendorId}") Log.d(
DataHolder.usbConnected.value = true TAG,
} else if (availableDrivers.isNotEmpty()) { "Device matched -> product = ${availableDrivers[0].device.productId}, vendor = ${availableDrivers[0].device.vendorId}"
Log.d( )
TAG, DataHolder.usbConnected.value = true
"Device NOT matched -> product = ${availableDrivers[0].device.productId}, vendor = ${availableDrivers[0].device.vendorId}" } else if (availableDrivers.isNotEmpty()) {
) Log.d(
Toast.makeText(this, "Device Not Compatible", Toast.LENGTH_SHORT).show() TAG,
DataHolder.usbConnected.value = false "Device NOT matched -> product = ${availableDrivers[0].device.productId}, vendor = ${availableDrivers[0].device.vendorId}"
} else { )
Log.d(TAG, "Device NOT Connected") Toast.makeText(this, "Device Not Compatible", Toast.LENGTH_SHORT).show()
Toast.makeText(this, "Device Not Connected", Toast.LENGTH_SHORT).show() DataHolder.usbConnected.value = false
DataHolder.usbConnected.value = false } else {
Log.d(TAG, "Device NOT Connected")
Toast.makeText(this, "Device Not Connected", Toast.LENGTH_SHORT).show()
DataHolder.usbConnected.value = false
}
} }
} }
@@ -210,15 +216,15 @@ class MainActivity : AppCompatActivity() {
} }
fusedLocationClient.lastLocation.addOnSuccessListener { location: Location? -> fusedLocationClient.lastLocation.addOnSuccessListener { location: Location? ->
location?.let { location?.let {
DataHolder.selectedTest!!.location = DataHolder.selectedTest!!.location =
UserData.Location(location.latitude, location.longitude) UserData.Location(location.latitude, location.longitude)
} ?: run { } ?: run {
requestLocationUpdates() requestLocationUpdates()
}
}.addOnFailureListener { exception: Exception ->
exception.printStackTrace()
} }
}.addOnFailureListener { exception: Exception ->
exception.printStackTrace()
}
} }
private fun requestLocationUpdates() { private fun requestLocationUpdates() {

View File

@@ -1,63 +1,90 @@
package com.example.hpostesting.presentation.hemocube package com.example.hpostesting.presentation.hemocube
import android.content.Context import android.content.Context
import android.content.SharedPreferences import android.content.SharedPreferences
import android.os.Bundle import android.os.Bundle
import android.util.Log
import androidx.fragment.app.Fragment
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.Toast import android.widget.Toast
import androidx.fragment.app.activityViewModels import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.presentation.UsbServiceListener import com.example.hpostesting.presentation.UsbServiceListener
import `in`.sminnovations.hpostesting.databinding.FragmentHemoCubeReferenceBinding import `in`.sminnovations.hpostesting.databinding.FragmentHemoCubeReferenceBinding
private const val ARG_PARAM1 = "param1"
private const val ARG_PARAM2 = "param2"
class HemoCubeFragment : Fragment() { class HemoCubeFragment : Fragment() {
private var testTime: String? = ""
private var resultRatio: String? = "" private var testTime: String? = null
private var kitSerial: String? = "" private var resultRatio: String? = null
private var kitSerial: String? = null
private lateinit var binding: FragmentHemoCubeReferenceBinding private lateinit var binding: FragmentHemoCubeReferenceBinding
private val viewModel: HemoCubeViewModel by activityViewModels() private val viewModel: HemoCubeViewModel by viewModels()
private lateinit var sharedPreference: SharedPreferences private lateinit var sharedPreference: SharedPreferences
private val TAG = "HemocubeReference" private var isOnline = false
val testDetails = DataHolder.SelectTestType
var isOnline = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
savedInstanceState: Bundle?
): View { ): View {
binding = FragmentHemoCubeReferenceBinding.inflate(inflater, container, false) binding = FragmentHemoCubeReferenceBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupButtonClickListeners()
binding.btnShowResult.setOnClickListener {
fetchHemoCubeResult()
}
sharedPreference = sharedPreference =
requireContext().getSharedPreferences("PREFERENCE_NAME", Context.MODE_PRIVATE) requireContext().getSharedPreferences("PREFERENCE_NAME", Context.MODE_PRIVATE)
viewModel.fireBaseUpload.observe(viewLifecycleOwner) { viewModel.fireBaseUpload.observe(viewLifecycleOwner) {
if (it == "Success") { if (it == "Success") {
Toast.makeText( Toast.makeText(
requireContext(), "Test Results Upload Successfully", Toast.LENGTH_SHORT requireContext(),
"Test Results Uploaded Successfully",
Toast.LENGTH_SHORT
).show() ).show()
} }
binding.progressBar.visibility = View.GONE binding.progressBar.visibility = View.GONE
} }
binding.btnSubmit.setOnClickListener(View.OnClickListener {
Log.e("upload","db") viewModel.networkStatusLiveData.observe(viewLifecycleOwner) { isNetworkAvailable ->
apply {
kitSerial = DataHolder.SelectTestType?.kitSerial
testTime = DataHolder.SelectTestType?.testTime
isOnline = isNetworkAvailable
}
}
}
private fun setupButtonClickListeners() {
binding.btnShowResult.setOnClickListener {
fetchHemoCubeResult()
}
binding.btnSubmit.setOnClickListener {
if (isOnline) { if (isOnline) {
if (resultRatio != null) { resultRatio?.let { ratio ->
Log.e("uploadData","resultdb") viewModel.uploadHemocubeResultToDatabase(
viewModel.uploadHemocubeResultToDatabase(requireContext(), true,true, kitSerial, resultRatio!!,testTime) requireContext(),
isOnline,
true,
kitSerial,
ratio,
testTime
)
} }
binding.progressBar.visibility = View.VISIBLE binding.progressBar.visibility = View.VISIBLE
} else { } else {
if (resultRatio != null) { resultRatio?.let { ratio ->
viewModel.uploadHemocubeResultToDatabase(requireContext(), true,true, kitSerial, resultRatio!!,testTime) viewModel.uploadHemocubeResultToDatabase(
requireContext(),
isOnline,
true,
kitSerial,
ratio,
testTime
)
} }
Toast.makeText( Toast.makeText(
requireContext(), requireContext(),
@@ -65,49 +92,27 @@ class HemoCubeFragment : Fragment() {
Toast.LENGTH_SHORT Toast.LENGTH_SHORT
).show() ).show()
} }
})
viewModel.networkStatusLiveData.observe(viewLifecycleOwner) { isNetworkAvailable ->
kitSerial = testDetails?.kitSerial
testTime = testDetails?.testTime
isOnline = isNetworkAvailable
} }
return binding.root
} }
private fun fetchHemoCubeResult() { private fun fetchHemoCubeResult() {
viewModel.progressBar.postValue(true) viewModel.progressBar.postValue(true)
val fullReadOutput = StringBuilder() val fullReadOutput = StringBuilder()
(activity as HemocubeActivity).mService.eventDrivenWriteHemoCube( (activity as HemocubeActivity).mService.eventDrivenWriteHemoCube(object :
object : UsbServiceListener { UsbServiceListener {
override fun onUsbRead(data: ByteArray?) { override fun onUsbRead(data: ByteArray?) {
data?.let { data?.let {
val stringData = String(it) val stringData = String(it)
fullReadOutput.append(stringData) fullReadOutput.append(stringData)
binding.tvSubtitle4.text = fullReadOutput binding.tvSubtitle4.text = fullReadOutput
resultRatio = fullReadOutput.toString() resultRatio = fullReadOutput.toString()
Log.d(
TAG,
"onUsbRead() called in sendCmdToFetchDeviceConstant() found OK"
)
viewModel.progressBar.postValue(false)
}
}
override fun onUsbError(e: Exception?) {
Log.e(TAG, "onUsbIoError() called in sendCmdToFetchDeviceConstant() -> $e")
viewModel.progressBar.postValue(false) viewModel.progressBar.postValue(false)
} }
})
}
companion object {
@JvmStatic
fun newInstance(param1: String, param2: String) =
HemoCubeFragment().apply {
arguments = Bundle().apply {
putString(ARG_PARAM1, param1)
putString(ARG_PARAM2, param2)
}
} }
override fun onUsbError(e: Exception?) {
viewModel.progressBar.postValue(false)
}
})
} }
} }

View File

@@ -18,7 +18,6 @@ import com.example.hpostesting.presentation.UsbServiceListener
import com.example.hpostesting.presentation.utils.MyDialogListener import com.example.hpostesting.presentation.utils.MyDialogListener
import com.example.hpostesting.presentation.utils.UIUtils import com.example.hpostesting.presentation.utils.UIUtils
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import dagger.hilt.android.qualifiers.ApplicationContext
import `in`.sminnovations.hpostesting.R import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.FragmentTestRightExpReferenceBinding import `in`.sminnovations.hpostesting.databinding.FragmentTestRightExpReferenceBinding
@@ -32,8 +31,7 @@ class TestRightExpReference : Fragment() {
private val TAG = "TestRightExpReference" private val TAG = "TestRightExpReference"
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
savedInstanceState: Bundle?
): View { ): View {
// Inflate the layout for this fragment // Inflate the layout for this fragment
binding = FragmentTestRightExpReferenceBinding.inflate(inflater, container, false) binding = FragmentTestRightExpReferenceBinding.inflate(inflater, container, false)
@@ -49,28 +47,17 @@ class TestRightExpReference : Fragment() {
// //
// DataHolder.sampleReadCounter <= Constants.MAXIMUM_TEST_ALLOWED_BEFORE_REFERENCE // DataHolder.sampleReadCounter <= Constants.MAXIMUM_TEST_ALLOWED_BEFORE_REFERENCE
Log.e("mariya", "onViewCreated 1") if (DataHolder.deviceConstant == null) {
if (DataHolder.deviceType.equals(Constants.DEVICE_TYPE_HOMOCUBE) ) { viewModel.progressBar.postValue(true)
Log.e("mariya", "onViewCreated if") Handler(Looper.getMainLooper()).postDelayed(
fetchHemoCubeResult() { sendCmdToFetchDeviceConstant() }, Constants.DELAY_BETWEEN_COMMANDS
Log.e("mariya", "onViewCreated 1") )
if (DataHolder.deviceType.equals(Constants.DEVICE_TYPE_HOMOCUBE) ) {
Log.e("mariya", "onViewCreated if")
// fetchHemoCubeResult()
} }
// if (DataHolder.deviceConstant == null) {
// viewModel.progressBar.postValue(true)
// Handler(Looper.getMainLooper()).postDelayed(
// { sendCmdToFetchDeviceConstant() },
// Constants.DELAY_BETWEEN_COMMANDS
// )
// }
} }
private fun setupListeners() { private fun setupListeners() {
binding.btnSetReference.setOnClickListener { binding.btnSetReference.setOnClickListener {
UIUtils.createAlertDialog( UIUtils.createAlertDialog(requireContext(),
requireContext(),
getString(R.string.have_you_placed), getString(R.string.have_you_placed),
getString(R.string.please_place), getString(R.string.please_place),
getString(R.string.no), getString(R.string.no),
@@ -79,17 +66,17 @@ class TestRightExpReference : Fragment() {
override fun onClickNegativeButton() { override fun onClickNegativeButton() {
} }
override fun onClickPositiveButton() { override fun onClickPositiveButton() {
// startTakingReference() startTakingReference()
fetchHemoCubeResult()
} }
}) })
} }
viewModel.errorTriggered.observe(viewLifecycleOwner) { viewModel.errorTriggered.observe(viewLifecycleOwner) {
if (it != null){ if (it != null) {
UIUtils.onShowErrorToast(requireContext(), it.message) UIUtils.onShowErrorToast(requireContext(), it.message)
if (it.code == Constants.ERROR_CRITICAL){ if (it.code == Constants.ERROR_CRITICAL) {
activity?.onBackPressed() activity?.onBackPressed()
} }
} }
@@ -118,51 +105,7 @@ class TestRightExpReference : Fragment() {
* 4. command print * 4. command print
*/ */
private fun startTakingReference() { private fun startTakingReference() {
// requireActivity().runOnUiThread {
sendCmdToSetLed() sendCmdToSetLed()
// }
}
// private fun sendCmdToFetchDeviceConstant(recursive: Boolean) {
private fun fetchHemoCubeResult() {
Log.d("mariya", "fetchHemoCubeResult() called")
viewModel.progressBar.postValue(true)
val fullReadOutput = StringBuilder()
(activity as TestRightActivity).mService.eventDrivenWrite2(
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {
Log.d("mariya", data.toString())
data?.let {
val stringData = String(it)
fullReadOutput.append(stringData)
Log.d("mariya", "fullReadOutput = $fullReadOutput")
if (stringData.contains("OK", true)) {
Log.d(
TAG,
"onUsbRead() called in sendCmdToFetchDeviceConstant() found OK"
)
viewModel.mapDeviceConstants(fullReadOutput.toString())
viewModel.progressBar.postValue(false)
} else if (stringData.contains("FINE", true)) {
Log.d(TAG, "results = FINE")
viewModel.progressBar.postValue(false)
viewModel.errorTriggered.postValue(ErrorMessage("Please Try Again!!", Constants.ERROR_CRITICAL))
}
}
}
override fun onUsbError(e: Exception?) {
Log.e(TAG, "onUsbIoError() called in sendCmdToFetchDeviceConstant() -> $e")
viewModel.errorTriggered.postValue(ErrorMessage("Please Try Again this step", Constants.ERROR_NORMAL))
viewModel.progressBar.postValue(false)
}
})
} }
@@ -173,7 +116,8 @@ class TestRightExpReference : Fragment() {
viewModel.progressBar.postValue(true) viewModel.progressBar.postValue(true)
val fullReadOutput = StringBuilder() val fullReadOutput = StringBuilder()
(activity as TestRightActivity).mService.eventDrivenWrite(TestRightCommands.read, (activity as TestRightActivity).mService.eventDrivenWrite(
TestRightCommands.read,
object : UsbServiceListener { object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) { override fun onUsbRead(data: ByteArray?) {
data?.let { data?.let {
@@ -183,8 +127,7 @@ class TestRightExpReference : Fragment() {
if (stringData.contains("OK", true)) { if (stringData.contains("OK", true)) {
Log.d( Log.d(
TAG, TAG, "onUsbRead() called in sendCmdToFetchDeviceConstant() found OK"
"onUsbRead() called in sendCmdToFetchDeviceConstant() found OK"
) )
viewModel.mapDeviceConstants(fullReadOutput.toString()) viewModel.mapDeviceConstants(fullReadOutput.toString())
viewModel.progressBar.postValue(false) viewModel.progressBar.postValue(false)
@@ -192,7 +135,11 @@ class TestRightExpReference : Fragment() {
Log.d(TAG, "results = FINE") Log.d(TAG, "results = FINE")
viewModel.progressBar.postValue(false) viewModel.progressBar.postValue(false)
viewModel.errorTriggered.postValue(ErrorMessage("Please Try Again!!", Constants.ERROR_CRITICAL)) viewModel.errorTriggered.postValue(
ErrorMessage(
"Please Try Again!!", Constants.ERROR_CRITICAL
)
)
} }
} }
@@ -200,7 +147,11 @@ class TestRightExpReference : Fragment() {
override fun onUsbError(e: Exception?) { override fun onUsbError(e: Exception?) {
Log.e(TAG, "onUsbIoError() called in sendCmdToFetchDeviceConstant() -> $e") Log.e(TAG, "onUsbIoError() called in sendCmdToFetchDeviceConstant() -> $e")
viewModel.errorTriggered.postValue(ErrorMessage("Please Try Again this step", Constants.ERROR_NORMAL)) viewModel.errorTriggered.postValue(
ErrorMessage(
"Please Try Again this step", Constants.ERROR_NORMAL
)
)
viewModel.progressBar.postValue(false) viewModel.progressBar.postValue(false)
} }
@@ -225,8 +176,7 @@ class TestRightExpReference : Fragment() {
Runnable { Runnable {
viewModel.progressBar.postValue(false) viewModel.progressBar.postValue(false)
sendCmdToAutoset() sendCmdToAutoset()
}, }, Constants.DELAY_BETWEEN_COMMANDS
Constants.DELAY_BETWEEN_COMMANDS
) )
} }
} }
@@ -257,8 +207,7 @@ class TestRightExpReference : Fragment() {
Runnable { Runnable {
viewModel.progressBar.postValue(false) viewModel.progressBar.postValue(false)
sendCmdToRun() sendCmdToRun()
}, }, Constants.DELAY_BETWEEN_COMMANDS
Constants.DELAY_BETWEEN_COMMANDS
) )
} }
@@ -291,8 +240,7 @@ class TestRightExpReference : Fragment() {
Runnable { Runnable {
viewModel.progressBar.postValue(false) viewModel.progressBar.postValue(false)
sendCmdToFetchLightIntensities() sendCmdToFetchLightIntensities()
}, }, Constants.DELAY_BETWEEN_COMMANDS
Constants.DELAY_BETWEEN_COMMANDS
) )
} }
} }
@@ -322,7 +270,12 @@ class TestRightExpReference : Fragment() {
// Log.d(TAG, stringData) // Log.d(TAG, stringData)
// if (stringData.contains("OK", true)) { // if (stringData.contains("OK", true)) {
// if (fullReadOutput.substring(Math.max(fullReadOutput.length - 15, 0)).contains("OK", true)) { // if (fullReadOutput.substring(Math.max(fullReadOutput.length - 15, 0)).contains("OK", true)) {
if (stringData.trim().isNotEmpty() && fullReadOutput.substring(Math.max(fullReadOutput.length - 15, 0)).contains("OK [0]", true)) { if (stringData.trim().isNotEmpty() && fullReadOutput.substring(
Math.max(
fullReadOutput.length - 15, 0
)
).contains("OK [0]", true)
) {
Log.d(TAG, "onUsbRead() called in sendCmdToFetchLightIntensities()") Log.d(TAG, "onUsbRead() called in sendCmdToFetchLightIntensities()")
// Log.d(TAG, fullReadOutput.toString()) // Log.d(TAG, fullReadOutput.toString())
@@ -344,7 +297,11 @@ class TestRightExpReference : Fragment() {
override fun onUsbError(e: Exception?) { override fun onUsbError(e: Exception?) {
Log.e(TAG, "onUsbIoError() called in sendCmdToFetchLightIntensities() -> $e") Log.e(TAG, "onUsbIoError() called in sendCmdToFetchLightIntensities() -> $e")
viewModel.errorTriggered.postValue(ErrorMessage("Please Try Again this step", Constants.ERROR_NORMAL)) viewModel.errorTriggered.postValue(
ErrorMessage(
"Please Try Again this step", Constants.ERROR_NORMAL
)
)
viewModel.progressBar.postValue(false) viewModel.progressBar.postValue(false)
} }

View File

@@ -111,21 +111,6 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_skip"
style="@style/title1_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="36dp"
android:text="@string/set_baseline_reference_again"
android:textColor="@color/blue_app_dark"
android:textStyle="italic"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btn_submit" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>