Compare commits
2 Commits
dev-server
...
dev-server
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
964f2c4178 | ||
|
|
e64fb09144 |
@@ -2,12 +2,16 @@
|
|||||||
## current version : 2.1.132
|
## current version : 2.1.132
|
||||||
|
|
||||||
### Release key
|
### Release key
|
||||||
|
|
||||||
key0: prime24
|
key0: prime24
|
||||||
|
|
||||||
### Version 133.3
|
### Version 133.3
|
||||||
|
|
||||||
Printer not added yet
|
Printer not added yet
|
||||||
|
|
||||||
//update it when it is completed
|
|
||||||
|
|
||||||
|
## added secure server
|
||||||
|
## aded molbio server
|
||||||
|
## advanced with ping network check
|
||||||
|
|
||||||
@@ -22,7 +22,7 @@ android {
|
|||||||
minSdk 30
|
minSdk 30
|
||||||
targetSdk 34
|
targetSdk 34
|
||||||
versionCode 138
|
versionCode 138
|
||||||
versionName "2.1.133.3"
|
versionName "2.1.132"
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
externalNativeBuild {
|
externalNativeBuild {
|
||||||
cmake {
|
cmake {
|
||||||
@@ -183,4 +183,7 @@ dependencies {
|
|||||||
implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.17'
|
implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.17'
|
||||||
implementation 'androidx.security:security-crypto:1.1.0-alpha03'
|
implementation 'androidx.security:security-crypto:1.1.0-alpha03'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -43,7 +43,7 @@
|
|||||||
android:theme="@style/Theme.HPOSTesting"
|
android:theme="@style/Theme.HPOSTesting"
|
||||||
tools:targetApi="31">
|
tools:targetApi="31">
|
||||||
<activity
|
<activity
|
||||||
android:name="com.example.hpostesting.data.model.reportgen.ReportActivity"
|
android:name="com.example.hpostesting.presentation.reportgen.ReportActivity"
|
||||||
android:exported="false" />
|
android:exported="false" />
|
||||||
<activity
|
<activity
|
||||||
android:name="com.example.hpostesting.presentation.main_base.UpdateValuesActivity"
|
android:name="com.example.hpostesting.presentation.main_base.UpdateValuesActivity"
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ std::vector<std::pair<int, std::pair<std::string, std::unordered_map<std::string
|
|||||||
{1, {"qc-qa", {{"apiKey", "AIzaSyC4d4GhWHr_NMJAeBvnztQ_yQ3Qe9MAnLs"}, {"appId", "1:1004619739289:android:3dbcefb10ea99654e5c808"}, {"projectId", "hpos-qa"}, {"storageBucket", "hpos-qa.appspot.com"}}}},
|
{1, {"qc-qa", {{"apiKey", "AIzaSyC4d4GhWHr_NMJAeBvnztQ_yQ3Qe9MAnLs"}, {"appId", "1:1004619739289:android:3dbcefb10ea99654e5c808"}, {"projectId", "hpos-qa"}, {"storageBucket", "hpos-qa.appspot.com"}}}},
|
||||||
{2, {"prod", {{"apiKey", "AIzaSyA_O0oZGzy3Kiw9fiLQ3OFPME-xQJP88vs"}, {"appId", "1:1012719870714:android:d8d7c962d96f4097de5f43"}, {"projectId", "hpos-prod"}, {"storageBucket", "hpos-prod.appspot.com"}}}},
|
{2, {"prod", {{"apiKey", "AIzaSyA_O0oZGzy3Kiw9fiLQ3OFPME-xQJP88vs"}, {"appId", "1:1012719870714:android:d8d7c962d96f4097de5f43"}, {"projectId", "hpos-prod"}, {"storageBucket", "hpos-prod.appspot.com"}}}},
|
||||||
{3, {"pre prod", {{"apiKey", "AIzaSyDYySi27LioZGNisP1NfnNU5inJX_0FT38"}, {"appId", "1:121176529204:android:e6841fdac57bdc95bbed61"}, {"projectId", "hpos-preprod"}, {"storageBucket", "hpos-preprod.appspot.com"}}}},
|
{3, {"pre prod", {{"apiKey", "AIzaSyDYySi27LioZGNisP1NfnNU5inJX_0FT38"}, {"appId", "1:121176529204:android:e6841fdac57bdc95bbed61"}, {"projectId", "hpos-preprod"}, {"storageBucket", "hpos-preprod.appspot.com"}}}},
|
||||||
{4, {"SMI R&D", {{"apiKey", "AIzaSyAVxpilbB804iRCCpMBDjjmdZhQguctGHM"}, {"appId", "1:327771387914:android:a3b4ed2e42ea6e38dc87f3"}, {"projectId", "hposrandd"}, {"storageBucket", "hposrandd.firebasestorage.app"}}}},
|
// {4, {"SMI R&D", {{"apiKey", "AIzaSyAVxpilbB804iRCCpMBDjjmdZhQguctGHM"}, {"appId", "1:327771387914:android:a3b4ed2e42ea6e38dc87f3"}, {"projectId", "hposrandd"}, {"storageBucket", "hposrandd.firebasestorage.app"}}}},
|
||||||
{5, {"molbio", {{"apiKey", "molbio"}, {"appId", "molbio"}, {"projectId", "molbio"}, {"storageBucket", "molbio"}}}}
|
{5, {"molbio", {{"apiKey", "molbio"}, {"appId", "molbio"}, {"projectId", "molbio"}, {"storageBucket", "molbio"}}}}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
package com.example.hpostesting.data.model.reportgen.ui.report
|
|
||||||
|
|
||||||
import androidx.lifecycle.LiveData
|
|
||||||
import androidx.lifecycle.ViewModel
|
|
||||||
import com.example.hpostesting.data.dao.HemoCubeBufferDao
|
|
||||||
import com.example.hpostesting.data.dao.HemoCubeDao
|
|
||||||
import com.example.hpostesting.data.model.patient.BufferCheckData
|
|
||||||
import com.example.hpostesting.data.model.patient.HemoCubeTestData
|
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
|
||||||
import javax.inject.Inject
|
|
||||||
|
|
||||||
|
|
||||||
@HiltViewModel
|
|
||||||
class ReportViewModel @Inject constructor(
|
|
||||||
private val hemoCubeDao: HemoCubeDao,
|
|
||||||
) : ViewModel() {
|
|
||||||
|
|
||||||
val allKitTestData: LiveData<List<HemoCubeTestData>> = hemoCubeDao.getAll()
|
|
||||||
}
|
|
||||||
@@ -25,7 +25,7 @@ import android.view.ViewGroup
|
|||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.activityViewModels
|
import androidx.fragment.app.activityViewModels
|
||||||
import com.example.hpostesting.data.constant.Constants
|
import com.example.hpostesting.data.constant.Constants
|
||||||
import com.example.hpostesting.data.model.reportgen.ReportActivity
|
import com.example.hpostesting.presentation.reportgen.ReportActivity
|
||||||
import com.example.hpostesting.presentation.autodac.AutoDacActivity
|
import com.example.hpostesting.presentation.autodac.AutoDacActivity
|
||||||
import com.example.hpostesting.presentation.buffercheck.HemocubeBufferCheckActivity
|
import com.example.hpostesting.presentation.buffercheck.HemocubeBufferCheckActivity
|
||||||
import com.example.hpostesting.presentation.calibration.CalibrationActivity
|
import com.example.hpostesting.presentation.calibration.CalibrationActivity
|
||||||
@@ -90,7 +90,7 @@ class PanelFragment : Fragment() {
|
|||||||
binding.btnDeviceInfo.visibility = View.VISIBLE
|
binding.btnDeviceInfo.visibility = View.VISIBLE
|
||||||
binding.btnResetPassword.visibility = View.VISIBLE
|
binding.btnResetPassword.visibility = View.VISIBLE
|
||||||
binding.btnUpdateValues.visibility = View.VISIBLE
|
binding.btnUpdateValues.visibility = View.VISIBLE
|
||||||
binding.btnPrintReport.visibility = View.VISIBLE
|
binding.btnPrintReport.visibility = View.GONE
|
||||||
}else{
|
}else{
|
||||||
binding.btnResetPassword.visibility = View.GONE
|
binding.btnResetPassword.visibility = View.GONE
|
||||||
binding.btnDeviceProvision.visibility = View.GONE
|
binding.btnDeviceProvision.visibility = View.GONE
|
||||||
@@ -104,7 +104,7 @@ class PanelFragment : Fragment() {
|
|||||||
binding.btnSubmit.visibility = View.GONE
|
binding.btnSubmit.visibility = View.GONE
|
||||||
binding.btnDeviceInfo.visibility = View.VISIBLE
|
binding.btnDeviceInfo.visibility = View.VISIBLE
|
||||||
binding.btnUpdateValues.visibility = View.GONE
|
binding.btnUpdateValues.visibility = View.GONE
|
||||||
binding.btnPrintReport.visibility = View.VISIBLE
|
binding.btnPrintReport.visibility = View.GONE
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.btnResetPassword.setOnClickListener{
|
binding.btnResetPassword.setOnClickListener{
|
||||||
@@ -140,7 +140,7 @@ class PanelFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
binding.btnPrintReport.setOnClickListener{
|
binding.btnPrintReport.setOnClickListener{
|
||||||
startActivity(Intent(requireContext(),ReportActivity::class.java))
|
startActivity(Intent(requireContext(), ReportActivity::class.java))
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.btnFirefox.setOnClickListener {
|
binding.btnFirefox.setOnClickListener {
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
package com.example.hpostesting.data.model.reportgen
|
package com.example.hpostesting.presentation.reportgen
|
||||||
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import com.example.hpostesting.data.model.reportgen.ui.report.ReportFragment
|
import com.example.hpostesting.presentation.reportgen.ui.report.ReportFragment
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import `in`.sminnovations.hpostesting.R
|
import `in`.sminnovations.hpostesting.R
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.hpostesting.data.model.reportgen.ui.report
|
package com.example.hpostesting.presentation.reportgen.ui.report
|
||||||
|
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
@@ -0,0 +1,329 @@
|
|||||||
|
package com.example.hpostesting.presentation.reportgen.ui.report
|
||||||
|
|
||||||
|
import android.content.ActivityNotFoundException
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.graphics.Canvas
|
||||||
|
import android.graphics.Color
|
||||||
|
import android.graphics.Paint
|
||||||
|
import android.graphics.Typeface
|
||||||
|
import android.graphics.pdf.PdfDocument
|
||||||
|
import android.util.Log
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
|
import androidx.core.content.FileProvider
|
||||||
|
import com.example.hpostesting.data.model.patient.HemoCubeTestData
|
||||||
|
import `in`.sminnovations.hpostesting.R
|
||||||
|
import java.io.File
|
||||||
|
import java.io.FileOutputStream
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
|
import java.util.Date
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
|
|
||||||
|
object ReportGen {
|
||||||
|
|
||||||
|
private const val PAGE_WIDTH = 595 // A4 width in points
|
||||||
|
private const val PAGE_HEIGHT = 842 // A4 height in points
|
||||||
|
private const val MARGIN_LEFT = 50f
|
||||||
|
private const val MARGIN_RIGHT = 50f
|
||||||
|
private const val MARGIN_TOP = 80f
|
||||||
|
private const val MARGIN_BOTTOM = 80f
|
||||||
|
|
||||||
|
fun generate(context: Context, dataList: List<HemoCubeTestData>) {
|
||||||
|
if (dataList.isEmpty()) {
|
||||||
|
Toast.makeText(context, "No items selected for report generation", Toast.LENGTH_SHORT).show()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.d("ReportGen", "Generating report for ${dataList.size} items")
|
||||||
|
|
||||||
|
val message = if (dataList.size == 1) {
|
||||||
|
"Report for kit ${dataList.first()._id} started."
|
||||||
|
} else {
|
||||||
|
"Report for ${dataList.size} kits started."
|
||||||
|
}
|
||||||
|
Toast.makeText(context, message, Toast.LENGTH_SHORT).show()
|
||||||
|
|
||||||
|
val pdfFile = createProfessionalPdfReport(context, dataList)
|
||||||
|
previewPdf(context, pdfFile)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createProfessionalPdfReport(context: Context, dataList: List<HemoCubeTestData>): File {
|
||||||
|
val timestamp = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(Date())
|
||||||
|
val file = File(context.getExternalFilesDir(null), "HemoCube_Report_$timestamp.pdf")
|
||||||
|
|
||||||
|
val pdfDocument = PdfDocument()
|
||||||
|
|
||||||
|
// Paint styles
|
||||||
|
val headerPaint = Paint().apply {
|
||||||
|
typeface = Typeface.create(Typeface.DEFAULT_BOLD, Typeface.BOLD)
|
||||||
|
textSize = 20f
|
||||||
|
color = Color.rgb(0, 102, 153) // Professional blue
|
||||||
|
}
|
||||||
|
|
||||||
|
val titlePaint = Paint().apply {
|
||||||
|
typeface = Typeface.create(Typeface.DEFAULT_BOLD, Typeface.BOLD)
|
||||||
|
textSize = 18f
|
||||||
|
color = Color.BLACK
|
||||||
|
}
|
||||||
|
|
||||||
|
val sectionHeaderPaint = Paint().apply {
|
||||||
|
typeface = Typeface.create(Typeface.DEFAULT_BOLD, Typeface.BOLD)
|
||||||
|
textSize = 14f
|
||||||
|
color = Color.rgb(0, 102, 153)
|
||||||
|
}
|
||||||
|
|
||||||
|
val contentPaint = Paint().apply {
|
||||||
|
textSize = 11f
|
||||||
|
color = Color.DKGRAY
|
||||||
|
}
|
||||||
|
|
||||||
|
val boldContentPaint = Paint().apply {
|
||||||
|
typeface = Typeface.create(Typeface.DEFAULT_BOLD, Typeface.BOLD)
|
||||||
|
textSize = 11f
|
||||||
|
color = Color.BLACK
|
||||||
|
}
|
||||||
|
|
||||||
|
val disclaimerPaint = Paint().apply {
|
||||||
|
textSize = 9f
|
||||||
|
color = Color.GRAY
|
||||||
|
typeface = Typeface.create(Typeface.DEFAULT, Typeface.ITALIC)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create one page per test data
|
||||||
|
dataList.forEachIndexed { index, testData ->
|
||||||
|
val pageInfo = PdfDocument.PageInfo.Builder(PAGE_WIDTH, PAGE_HEIGHT, index + 1).create()
|
||||||
|
val page = pdfDocument.startPage(pageInfo)
|
||||||
|
val canvas = page.canvas
|
||||||
|
|
||||||
|
drawPage(canvas, testData, index + 1, dataList.size,
|
||||||
|
headerPaint, titlePaint, sectionHeaderPaint,
|
||||||
|
contentPaint, boldContentPaint, disclaimerPaint,context)
|
||||||
|
|
||||||
|
pdfDocument.finishPage(page)
|
||||||
|
}
|
||||||
|
|
||||||
|
pdfDocument.writeTo(FileOutputStream(file))
|
||||||
|
pdfDocument.close()
|
||||||
|
return file
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun drawPage(
|
||||||
|
canvas: Canvas,
|
||||||
|
testData: HemoCubeTestData,
|
||||||
|
pageNumber: Int,
|
||||||
|
totalPages: Int,
|
||||||
|
headerPaint: Paint,
|
||||||
|
titlePaint: Paint,
|
||||||
|
sectionHeaderPaint: Paint,
|
||||||
|
contentPaint: Paint,
|
||||||
|
boldContentPaint: Paint,
|
||||||
|
disclaimerPaint: Paint,
|
||||||
|
context: Context
|
||||||
|
) {
|
||||||
|
var currentY = MARGIN_TOP
|
||||||
|
|
||||||
|
// Header with logo placeholder and title
|
||||||
|
drawHeader(canvas, headerPaint, titlePaint, currentY, context)
|
||||||
|
currentY += 100f
|
||||||
|
|
||||||
|
// Sample Information Section
|
||||||
|
currentY = drawSection(canvas, "SAMPLE INFORMATION", sectionHeaderPaint, currentY)
|
||||||
|
currentY = drawKeyValuePair(canvas, "Sample ID:", testData.sampleid.toString(), boldContentPaint, contentPaint, currentY)
|
||||||
|
currentY = drawKeyValuePair(canvas, "Blood Group:", testData.bloodGroup, boldContentPaint, contentPaint, currentY)
|
||||||
|
currentY += 15f
|
||||||
|
|
||||||
|
// Test Information Section
|
||||||
|
currentY = drawSection(canvas, "TEST INFORMATION", sectionHeaderPaint, currentY)
|
||||||
|
currentY = drawKeyValuePair(canvas, "Test ID:", testData._id, boldContentPaint, contentPaint, currentY)
|
||||||
|
currentY = drawKeyValuePair(canvas, "Test Type:", testData.testType ?: "TrueHeme", boldContentPaint, contentPaint, currentY)
|
||||||
|
currentY = drawKeyValuePair(canvas, "Test Time:", testData.testTime ?: "N/A", boldContentPaint, contentPaint, currentY)
|
||||||
|
currentY = drawKeyValuePair(canvas, "Incubation Time:", testData.incubationTime, boldContentPaint, contentPaint, currentY)
|
||||||
|
currentY = drawKeyValuePair(canvas, "Kit Serial:", testData.kitSerial, boldContentPaint, contentPaint, currentY)
|
||||||
|
currentY = drawKeyValuePair(canvas, "Device Serial:", testData.deviceSerialNumber, boldContentPaint, contentPaint, currentY)
|
||||||
|
currentY += 15f
|
||||||
|
|
||||||
|
// Test Results Section
|
||||||
|
currentY = drawSection(canvas, "TEST RESULTS", sectionHeaderPaint, currentY)
|
||||||
|
currentY = drawKeyValuePair(canvas, "Classification Result:", testData.classificationResult, boldContentPaint, contentPaint, currentY)
|
||||||
|
currentY = drawKeyValuePair(canvas, "Device Ratio:", testData.deviceRatio?.toString() ?: "N/A", boldContentPaint, contentPaint, currentY)
|
||||||
|
currentY = drawKeyValuePair(canvas, "Calculated Ratio:", testData.calculatedRatio?.toString() ?: "N/A", boldContentPaint, contentPaint, currentY)
|
||||||
|
currentY = drawKeyValuePair(canvas, "Slope Ratio:", testData.slopeRatio?.toString() ?: "N/A", boldContentPaint, contentPaint, currentY)
|
||||||
|
currentY += 15f
|
||||||
|
|
||||||
|
// LED Measurements Section
|
||||||
|
currentY = drawSection(canvas, "LED MEASUREMENTS", sectionHeaderPaint, currentY)
|
||||||
|
currentY = drawLEDData(canvas, testData, boldContentPaint, contentPaint, currentY)
|
||||||
|
currentY += 15f
|
||||||
|
|
||||||
|
// Laboratory Information Section
|
||||||
|
currentY = drawSection(canvas, "LABORATORY INFORMATION", sectionHeaderPaint, currentY)
|
||||||
|
currentY = drawKeyValuePair(canvas, "Lab Name:", testData.labName ?: "N/A", boldContentPaint, contentPaint, currentY)
|
||||||
|
currentY = drawKeyValuePair(canvas, "Center Name:", testData.centerName ?: "N/A", boldContentPaint, contentPaint, currentY)
|
||||||
|
currentY = drawKeyValuePair(canvas, "District:", testData.district ?: "N/A", boldContentPaint, contentPaint, currentY)
|
||||||
|
currentY += 15f
|
||||||
|
|
||||||
|
// Footer with page number and disclaimer
|
||||||
|
drawFooter(canvas, pageNumber, totalPages, contentPaint, disclaimerPaint)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun drawHeader(canvas: Canvas, headerPaint: Paint, titlePaint: Paint, startY: Float, context: Context) {
|
||||||
|
// Load and draw actual logo
|
||||||
|
try {
|
||||||
|
// Method 1: Load from drawable resources
|
||||||
|
val logoDrawable = ContextCompat.getDrawable(context, R.mipmap.hpos_icon) // Replace with your logo resource
|
||||||
|
logoDrawable?.let { drawable ->
|
||||||
|
val logoWidth = 70
|
||||||
|
val logoHeight = 60
|
||||||
|
drawable.setBounds(
|
||||||
|
MARGIN_LEFT.toInt(),
|
||||||
|
(startY - 20f).toInt(),
|
||||||
|
(MARGIN_LEFT + logoWidth).toInt(),
|
||||||
|
(startY + logoHeight - 20f).toInt()
|
||||||
|
)
|
||||||
|
drawable.draw(canvas)
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
// Fallback to placeholder if logo loading fails
|
||||||
|
val logoPaint = Paint().apply {
|
||||||
|
color = Color.rgb(0, 102, 153)
|
||||||
|
style = Paint.Style.FILL
|
||||||
|
}
|
||||||
|
canvas.drawRect(MARGIN_LEFT, startY - 20f, MARGIN_LEFT + 60f, startY + 20f, logoPaint)
|
||||||
|
|
||||||
|
// Draw "LOGO" text as placeholder
|
||||||
|
val placeholderPaint = Paint().apply {
|
||||||
|
color = Color.WHITE
|
||||||
|
textSize = 12f
|
||||||
|
typeface = Typeface.create(Typeface.DEFAULT_BOLD, Typeface.BOLD)
|
||||||
|
textAlign = Paint.Align.CENTER
|
||||||
|
}
|
||||||
|
canvas.drawText("LOGO", MARGIN_LEFT + 30f, startY, placeholderPaint)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Company name and title
|
||||||
|
canvas.drawText("HemoCube", MARGIN_LEFT + 80f, startY + 10f, headerPaint)
|
||||||
|
canvas.drawText("Medical Test Report", MARGIN_LEFT, startY + 40f, titlePaint)
|
||||||
|
|
||||||
|
// Report generation date
|
||||||
|
val currentDate = SimpleDateFormat("dd MMM yyyy, HH:mm", Locale.getDefault()).format(Date())
|
||||||
|
canvas.drawText("Generated: $currentDate", PAGE_WIDTH - MARGIN_RIGHT - 150f, startY + 10f, Paint().apply {
|
||||||
|
textSize = 10f
|
||||||
|
color = Color.GRAY
|
||||||
|
})
|
||||||
|
|
||||||
|
// Line under header
|
||||||
|
val linePaint = Paint().apply {
|
||||||
|
color = Color.rgb(0, 102, 153)
|
||||||
|
strokeWidth = 2f
|
||||||
|
}
|
||||||
|
canvas.drawLine(MARGIN_LEFT, startY + 60f, PAGE_WIDTH - MARGIN_RIGHT, startY + 60f, linePaint)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun drawSection(canvas: Canvas, title: String, paint: Paint, y: Float): Float {
|
||||||
|
canvas.drawText(title, MARGIN_LEFT, y, paint)
|
||||||
|
|
||||||
|
// Underline for section
|
||||||
|
val linePaint = Paint().apply {
|
||||||
|
color = Color.rgb(0, 102, 153)
|
||||||
|
strokeWidth = 1f
|
||||||
|
}
|
||||||
|
canvas.drawLine(MARGIN_LEFT, y + 5f, MARGIN_LEFT + paint.measureText(title), y + 5f, linePaint)
|
||||||
|
|
||||||
|
return y + 25f
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun drawKeyValuePair(canvas: Canvas, key: String, value: String, keyPaint: Paint, valuePaint: Paint, y: Float): Float {
|
||||||
|
canvas.drawText(key, MARGIN_LEFT + 10f, y, keyPaint)
|
||||||
|
canvas.drawText(value, MARGIN_LEFT + 150f, y, valuePaint)
|
||||||
|
return y + 18f
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun drawLEDData(canvas: Canvas, testData: HemoCubeTestData, keyPaint: Paint, valuePaint: Paint, startY: Float): Float {
|
||||||
|
var currentY = startY
|
||||||
|
|
||||||
|
currentY = drawKeyValuePair(canvas, "LED1 Sample:", testData.led1Sample?.toString() ?: "N/A", keyPaint, valuePaint, currentY)
|
||||||
|
currentY = drawKeyValuePair(canvas, "LED2 Sample:", testData.led2Sample?.toString() ?: "N/A", keyPaint, valuePaint, currentY)
|
||||||
|
currentY = drawKeyValuePair(canvas, "LED3 Sample:", testData.led3Sample?.toString() ?: "N/A", keyPaint, valuePaint, currentY)
|
||||||
|
currentY = drawKeyValuePair(canvas, "LED4 Sample:", testData.led4Sample?.toString() ?: "N/A", keyPaint, valuePaint, currentY)
|
||||||
|
|
||||||
|
currentY = drawKeyValuePair(canvas, "ABS1:", testData.abs1?.toString() ?: "N/A", keyPaint, valuePaint, currentY)
|
||||||
|
currentY = drawKeyValuePair(canvas, "ABS2:", testData.abs2?.toString() ?: "N/A", keyPaint, valuePaint, currentY)
|
||||||
|
currentY = drawKeyValuePair(canvas, "ABS3:", testData.abs3?.toString() ?: "N/A", keyPaint, valuePaint, currentY)
|
||||||
|
currentY = drawKeyValuePair(canvas, "ABS4:", testData.abs4?.toString() ?: "N/A", keyPaint, valuePaint, currentY)
|
||||||
|
|
||||||
|
return currentY
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun drawFooter(canvas: Canvas, pageNumber: Int, totalPages: Int, contentPaint: Paint, disclaimerPaint: Paint) {
|
||||||
|
val footerY = PAGE_HEIGHT - MARGIN_BOTTOM + 20f
|
||||||
|
|
||||||
|
// Page number
|
||||||
|
canvas.drawText("Page $pageNumber of $totalPages", PAGE_WIDTH - MARGIN_RIGHT - 80f, footerY, contentPaint)
|
||||||
|
|
||||||
|
// Disclaimer
|
||||||
|
val disclaimerText = "DISCLAIMER: This report is generated by HemoCube automated system. " +
|
||||||
|
"Results should be interpreted by qualified medical professionals. " +
|
||||||
|
"This report is for diagnostic purposes only and should not be used as the sole basis for medical decisions. " +
|
||||||
|
"Please consult with your healthcare provider for proper interpretation and treatment recommendations."
|
||||||
|
|
||||||
|
val disclaimerLines = wrapText(disclaimerText, disclaimerPaint, PAGE_WIDTH - MARGIN_LEFT - MARGIN_RIGHT)
|
||||||
|
var disclaimerY = footerY + 20f
|
||||||
|
|
||||||
|
disclaimerLines.forEach { line ->
|
||||||
|
canvas.drawText(line, MARGIN_LEFT, disclaimerY, disclaimerPaint)
|
||||||
|
disclaimerY += 12f
|
||||||
|
}
|
||||||
|
|
||||||
|
// Footer line
|
||||||
|
val linePaint = Paint().apply {
|
||||||
|
color = Color.rgb(0, 102, 153)
|
||||||
|
strokeWidth = 1f
|
||||||
|
}
|
||||||
|
canvas.drawLine(MARGIN_LEFT, footerY - 10f, PAGE_WIDTH - MARGIN_RIGHT, footerY - 10f, linePaint)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun wrapText(text: String, paint: Paint, maxWidth: Float): List<String> {
|
||||||
|
val words = text.split(" ")
|
||||||
|
val lines = mutableListOf<String>()
|
||||||
|
var currentLine = ""
|
||||||
|
|
||||||
|
for (word in words) {
|
||||||
|
val testLine = if (currentLine.isEmpty()) word else "$currentLine $word"
|
||||||
|
if (paint.measureText(testLine) <= maxWidth) {
|
||||||
|
currentLine = testLine
|
||||||
|
} else {
|
||||||
|
if (currentLine.isNotEmpty()) {
|
||||||
|
lines.add(currentLine)
|
||||||
|
}
|
||||||
|
currentLine = word
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentLine.isNotEmpty()) {
|
||||||
|
lines.add(currentLine)
|
||||||
|
}
|
||||||
|
|
||||||
|
return lines
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun previewPdf(context: Context, file: File) {
|
||||||
|
val uri = FileProvider.getUriForFile(
|
||||||
|
context,
|
||||||
|
"${context.packageName}.fileprovider",
|
||||||
|
file
|
||||||
|
)
|
||||||
|
|
||||||
|
val intent = Intent(Intent.ACTION_VIEW).apply {
|
||||||
|
setDataAndType(uri, "application/pdf")
|
||||||
|
flags = Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_ACTIVITY_NO_HISTORY
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
context.startActivity(intent)
|
||||||
|
} catch (e: ActivityNotFoundException) {
|
||||||
|
Toast.makeText(context, "No PDF viewer found", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,14 @@
|
|||||||
package com.example.hpostesting.data.model.reportgen.ui.report
|
package com.example.hpostesting.presentation.reportgen.ui.report
|
||||||
|
|
||||||
import android.app.DatePickerDialog
|
import android.app.DatePickerDialog
|
||||||
|
import android.content.ActivityNotFoundException
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.graphics.Canvas
|
||||||
|
import android.graphics.Color
|
||||||
|
import android.graphics.Paint
|
||||||
|
import android.graphics.Typeface
|
||||||
|
import android.graphics.pdf.PdfDocument
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
@@ -14,27 +21,31 @@ import android.widget.EditText
|
|||||||
import android.widget.Spinner
|
import android.widget.Spinner
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
|
import androidx.core.content.FileProvider
|
||||||
import androidx.core.widget.addTextChangedListener
|
import androidx.core.widget.addTextChangedListener
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.viewModels
|
import androidx.fragment.app.viewModels
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.example.hpostesting.data.model.patient.HemoCubeTestData
|
import com.example.hpostesting.data.model.patient.HemoCubeTestData
|
||||||
|
import com.example.hpostesting.presentation.reportgen.viewModel.ReportViewModel
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import `in`.sminnovations.hpostesting.R
|
import `in`.sminnovations.hpostesting.R
|
||||||
|
import java.io.File
|
||||||
|
import java.io.FileOutputStream
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.Calendar
|
import java.util.Calendar
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class ReportFragment : Fragment() {
|
class ReportFragment : Fragment() {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun newInstance() = ReportFragment()
|
fun newInstance() = ReportFragment()
|
||||||
}
|
}
|
||||||
|
|
||||||
private val viewModel: ReportViewModel by viewModels()
|
private val viewModel: ReportViewModel by viewModels()
|
||||||
|
|
||||||
private lateinit var recyclerView: RecyclerView
|
private lateinit var recyclerView: RecyclerView
|
||||||
private lateinit var searchBar: EditText
|
private lateinit var searchBar: EditText
|
||||||
private lateinit var filterSpinner: Spinner
|
private lateinit var filterSpinner: Spinner
|
||||||
@@ -59,7 +70,7 @@ class ReportFragment : Fragment() {
|
|||||||
setupObservers()
|
setupObservers()
|
||||||
setupListeners()
|
setupListeners()
|
||||||
|
|
||||||
// Set default filter to Today
|
// default filter to Today
|
||||||
setDefaultFilter()
|
setDefaultFilter()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,7 +159,7 @@ class ReportFragment : Fragment() {
|
|||||||
val sdf = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
|
val sdf = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
|
||||||
val selectedCalendar = Calendar.getInstance()
|
val selectedCalendar = Calendar.getInstance()
|
||||||
selectedCalendar.set(selectedYear, selectedMonth, selectedDay)
|
selectedCalendar.set(selectedYear, selectedMonth, selectedDay)
|
||||||
customDate = sdf.format(selectedCalendar.time)
|
customDate = sdf.format(selectedCalendar.time)
|
||||||
|
|
||||||
// Update calendar button text
|
// Update calendar button text
|
||||||
val displayFormat = SimpleDateFormat("MMM dd, yyyy", Locale.getDefault())
|
val displayFormat = SimpleDateFormat("MMM dd, yyyy", Locale.getDefault())
|
||||||
@@ -205,30 +216,3 @@ class ReportFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
object ReportGen {
|
|
||||||
fun generate(context: Context, dataList: List<HemoCubeTestData>) {
|
|
||||||
if (dataList.isEmpty()) {
|
|
||||||
Toast.makeText(context, "No items selected for report generation", Toast.LENGTH_SHORT).show()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
Log.d("ReportGen", "Generating report for ${dataList.size} items")
|
|
||||||
|
|
||||||
val kitNumbers = dataList.map { it._id }
|
|
||||||
val message = if (dataList.size == 1) {
|
|
||||||
"Report for kit ${kitNumbers.first()} started."
|
|
||||||
} else {
|
|
||||||
"Report for ${dataList.size} kits started."
|
|
||||||
}
|
|
||||||
|
|
||||||
Toast.makeText(context, message, Toast.LENGTH_SHORT).show()
|
|
||||||
|
|
||||||
// TODO: Add PDF generation, email, or preview logic here
|
|
||||||
// You can iterate through dataList to include all selected items in the report
|
|
||||||
dataList.forEach { item->
|
|
||||||
Log.d("ReportGen", "Processing kit: ${item._id}, Result: ${item.classificationResult}, Time: ${item.testTime}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,188 @@
|
|||||||
|
package com.example.hpostesting.presentation.reportgen.viewModel
|
||||||
|
|
||||||
|
import androidx.lifecycle.MutableLiveData
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import com.example.hpostesting.data.dao.HemoCubeDao
|
||||||
|
import com.example.hpostesting.data.model.patient.HemoCubeTestData
|
||||||
|
import com.example.hpostesting.data.model.patient.UserData
|
||||||
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
|
||||||
|
@HiltViewModel
|
||||||
|
class ReportViewModel @Inject constructor(
|
||||||
|
private val hemoCubeDao: HemoCubeDao,
|
||||||
|
) : ViewModel() {
|
||||||
|
// val allKitTestData: LiveData<List<HemoCubeTestData>> = hemoCubeDao.getAll()
|
||||||
|
val allKitTestData = MutableLiveData<List<HemoCubeTestData>>()
|
||||||
|
init {
|
||||||
|
loadTestData()
|
||||||
|
}
|
||||||
|
private fun loadTestData() {
|
||||||
|
viewModelScope.launch {
|
||||||
|
val data = hemoCubeDao.getAll()
|
||||||
|
if (data.value.isNullOrEmpty()) {
|
||||||
|
allKitTestData.value = dummyDataList
|
||||||
|
} else {
|
||||||
|
allKitTestData.value = data.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
val dummyDataList = listOf(
|
||||||
|
HemoCubeTestData(
|
||||||
|
sampleid = 1,
|
||||||
|
_id = "ID001",
|
||||||
|
name = "John Doe",
|
||||||
|
incubationTime = "15 mins",
|
||||||
|
bloodGroup = "A+",
|
||||||
|
age = "30",
|
||||||
|
state = "Karnataka",
|
||||||
|
abhaId = "ABHA123456",
|
||||||
|
userImageURL = "https://example.com/image1.jpg",
|
||||||
|
location = UserData.Location(latitude = 12.9716, longitude = 77.5946),
|
||||||
|
reportUploadTime = "2025-07-20T10:30:00",
|
||||||
|
testTime = "2025-07-20T10:00:00",
|
||||||
|
gender = "Male",
|
||||||
|
classificationResult = "Normal",
|
||||||
|
prdClassification = "Class A",
|
||||||
|
deviceSerialNumber = "SN123456",
|
||||||
|
deviceId = "DEVICE001",
|
||||||
|
appVersion = "1.2.3",
|
||||||
|
kitSerial = "KIT001",
|
||||||
|
resultData = "{\"hb\":13.5}",
|
||||||
|
led1Buffer = 0.95,
|
||||||
|
led2Buffer = 1.01,
|
||||||
|
led3Buffer = 0.98,
|
||||||
|
led4Buffer = 1.02,
|
||||||
|
led1Sample = 0.75,
|
||||||
|
led2Sample = 0.80,
|
||||||
|
led3Sample = 0.78,
|
||||||
|
led4Sample = 0.81,
|
||||||
|
led1Average = 0.85,
|
||||||
|
led2Average = 0.86,
|
||||||
|
led3Average = 0.87,
|
||||||
|
led4Average = 0.88,
|
||||||
|
abs1 = 0.10,
|
||||||
|
abs2 = 0.12,
|
||||||
|
abs3 = 0.11,
|
||||||
|
abs4 = 0.13,
|
||||||
|
hb3 = 13.2,
|
||||||
|
hb4 = 13.6,
|
||||||
|
led1Gain1 = 1.1,
|
||||||
|
led2Gain1 = 1.1,
|
||||||
|
led3Gain1 = 1.1,
|
||||||
|
led4Gain1 = 1.1,
|
||||||
|
led1Air1 = 0.5,
|
||||||
|
led2Air1 = 0.5,
|
||||||
|
led3Air1 = 0.5,
|
||||||
|
led4Air1 = 0.5,
|
||||||
|
deviceRatio = 1.23,
|
||||||
|
calculatedRatio = 1.21,
|
||||||
|
predictedDenovixRatio = 1.22,
|
||||||
|
slopeRatio = 0.98,
|
||||||
|
coefficients = "{\"a\":0.1,\"b\":0.2}",
|
||||||
|
deviceRatioClass = "Optimal",
|
||||||
|
slopeRatioClass = "Stable",
|
||||||
|
borderlineMethod2Class = "Negative",
|
||||||
|
errorMessages = "",
|
||||||
|
batteryLevel = "85%",
|
||||||
|
batteryCapacity = "4000mAh",
|
||||||
|
batteryMaxCapacity = "5000mAh",
|
||||||
|
batteryTemperature = "36C",
|
||||||
|
batteryVoltage = "3.7V",
|
||||||
|
molbioFlag = true,
|
||||||
|
quickCapture = true,
|
||||||
|
solution = "NaCl",
|
||||||
|
concentration = "5%",
|
||||||
|
filter = "HE",
|
||||||
|
volume = "0.5ml",
|
||||||
|
isCSVCreated = true,
|
||||||
|
labName = "LabCorp",
|
||||||
|
cuvetteSize = "Standard",
|
||||||
|
district = "Bangalore Urban",
|
||||||
|
centerName = "Health Center 1",
|
||||||
|
ipAddress = "192.168.0.100",
|
||||||
|
configUpdatedRecent = "2025-07-19T08:45:00"
|
||||||
|
),
|
||||||
|
|
||||||
|
HemoCubeTestData(
|
||||||
|
sampleid = 2,
|
||||||
|
_id = "ID002",
|
||||||
|
name = "Jane Smith",
|
||||||
|
incubationTime = "10 mins",
|
||||||
|
bloodGroup = "B-",
|
||||||
|
age = "28",
|
||||||
|
state = "Maharashtra",
|
||||||
|
abhaId = "ABHA654321",
|
||||||
|
userImageURL = "https://example.com/image2.jpg",
|
||||||
|
location = UserData.Location(latitude = 18.5204, longitude = 73.8567),
|
||||||
|
reportUploadTime = "2025-07-21T09:15:00",
|
||||||
|
testTime = "2025-07-21T08:45:00",
|
||||||
|
gender = "Female",
|
||||||
|
classificationResult = "Anemia",
|
||||||
|
prdClassification = "Class B",
|
||||||
|
deviceSerialNumber = "SN654321",
|
||||||
|
deviceId = "DEVICE002",
|
||||||
|
appVersion = "1.2.3",
|
||||||
|
kitSerial = "KIT002",
|
||||||
|
resultData = "{\"hb\":9.0}",
|
||||||
|
led1Buffer = 1.05,
|
||||||
|
led2Buffer = 1.00,
|
||||||
|
led3Buffer = 1.02,
|
||||||
|
led4Buffer = 0.99,
|
||||||
|
led1Sample = 0.60,
|
||||||
|
led2Sample = 0.65,
|
||||||
|
led3Sample = 0.63,
|
||||||
|
led4Sample = 0.62,
|
||||||
|
led1Average = 0.70,
|
||||||
|
led2Average = 0.71,
|
||||||
|
led3Average = 0.72,
|
||||||
|
led4Average = 0.69,
|
||||||
|
abs1 = 0.15,
|
||||||
|
abs2 = 0.16,
|
||||||
|
abs3 = 0.17,
|
||||||
|
abs4 = 0.14,
|
||||||
|
hb3 = 9.2,
|
||||||
|
hb4 = 8.8,
|
||||||
|
led1Gain1 = 1.2,
|
||||||
|
led2Gain1 = 1.2,
|
||||||
|
led3Gain1 = 1.2,
|
||||||
|
led4Gain1 = 1.2,
|
||||||
|
led1Air1 = 0.6,
|
||||||
|
led2Air1 = 0.6,
|
||||||
|
led3Air1 = 0.6,
|
||||||
|
led4Air1 = 0.6,
|
||||||
|
deviceRatio = 0.95,
|
||||||
|
calculatedRatio = 0.93,
|
||||||
|
predictedDenovixRatio = 0.94,
|
||||||
|
slopeRatio = 1.02,
|
||||||
|
coefficients = "{\"a\":0.15,\"b\":0.25}",
|
||||||
|
deviceRatioClass = "Low",
|
||||||
|
slopeRatioClass = "Fluctuating",
|
||||||
|
borderlineMethod2Class = "Positive",
|
||||||
|
errorMessages = "Low Hb detected",
|
||||||
|
batteryLevel = "78%",
|
||||||
|
batteryCapacity = "3800mAh",
|
||||||
|
batteryMaxCapacity = "5000mAh",
|
||||||
|
batteryTemperature = "37C",
|
||||||
|
batteryVoltage = "3.6V",
|
||||||
|
molbioFlag = false,
|
||||||
|
quickCapture = false,
|
||||||
|
solution = "PBS",
|
||||||
|
concentration = "3%",
|
||||||
|
filter = "LE",
|
||||||
|
volume = "0.4ml",
|
||||||
|
isCSVCreated = false,
|
||||||
|
labName = "MedLab",
|
||||||
|
cuvetteSize = "Small",
|
||||||
|
district = "Pune",
|
||||||
|
centerName = "Health Center 2",
|
||||||
|
ipAddress = "192.168.0.101",
|
||||||
|
configUpdatedRecent = "2025-07-20T11:00:00"
|
||||||
|
)
|
||||||
|
)
|
||||||
@@ -56,6 +56,8 @@ import kotlin.random.Random
|
|||||||
//This is TrueHemeTestFragment, where actual tests are done first buffer check and then sample check
|
//This is TrueHemeTestFragment, where actual tests are done first buffer check and then sample check
|
||||||
//and finally on submit test data to database if online or store in offline database
|
//and finally on submit test data to database if online or store in offline database
|
||||||
@Suppress("MemberVisibilityCanBePrivate")
|
@Suppress("MemberVisibilityCanBePrivate")
|
||||||
|
|
||||||
|
val autoSumbt = false
|
||||||
class TrueHemeTestFragment : Fragment() {
|
class TrueHemeTestFragment : Fragment() {
|
||||||
private var positiveBoderLine10mm1=Constants.positiveBoderLineMetricCheck10mmMin
|
private var positiveBoderLine10mm1=Constants.positiveBoderLineMetricCheck10mmMin
|
||||||
private var positiveBoderLine10mm2=Constants.positiveBoderLineMetricCheck10mmMax
|
private var positiveBoderLine10mm2=Constants.positiveBoderLineMetricCheck10mmMax
|
||||||
@@ -1011,11 +1013,14 @@ class TrueHemeTestFragment : Fragment() {
|
|||||||
activity?.runOnUiThread {
|
activity?.runOnUiThread {
|
||||||
|
|
||||||
//changing to invisible
|
//changing to invisible
|
||||||
binding.btnSubmit.visibility = View.GONE
|
binding.btnSubmit.visibility = View.VISIBLE
|
||||||
// binding.btnSubmit.isEnabled = true
|
// binding.btnSubmit.isEnabled = true
|
||||||
// binding.btnSubmit.isClickable = true
|
// binding.btnSubmit.isClickable = true
|
||||||
// binding.clParent.setBackgroundColor(Color.parseColor("#edfffd"))
|
// binding.clParent.setBackgroundColor(Color.parseColor("#edfffd"))
|
||||||
autoSmbt(true)
|
if (autoSumbt){
|
||||||
|
binding.btnSubmit.visibility = View.GONE
|
||||||
|
autoSmbt(autoSumbt)
|
||||||
|
}
|
||||||
binding.ivCheck.visibility = View.VISIBLE
|
binding.ivCheck.visibility = View.VISIBLE
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
android:id="@+id/searchBar"
|
android:id="@+id/searchBar"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:hint="Search by kitno or result"
|
android:hint="Search by smaple ID or result"
|
||||||
android:imeOptions="actionSearch"
|
android:imeOptions="actionSearch"
|
||||||
android:inputType="text" />
|
android:inputType="text" />
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user