UI changes
This commit is contained in:
parent
6de6ef8bf8
commit
7f24f1cae1
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="MarkdownSettings">
|
||||||
|
<option name="previewPanelProviderInfo">
|
||||||
|
<ProviderInfo name="Compose (experimental)" className="com.intellij.markdown.compose.preview.ComposePanelProvider" />
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
|
|
@ -45,6 +45,7 @@ dependencies {
|
||||||
val cameraxVersion = "1.5.1"
|
val cameraxVersion = "1.5.1"
|
||||||
implementation("androidx.appcompat:appcompat:1.7.0")
|
implementation("androidx.appcompat:appcompat:1.7.0")
|
||||||
implementation("androidx.cardview:cardview:1.0.0")
|
implementation("androidx.cardview:cardview:1.0.0")
|
||||||
|
implementation("com.google.android.material:material:1.12.0")
|
||||||
implementation("androidx.camera:camera-core:$cameraxVersion")
|
implementation("androidx.camera:camera-core:$cameraxVersion")
|
||||||
implementation("androidx.camera:camera-camera2:$cameraxVersion")
|
implementation("androidx.camera:camera-camera2:$cameraxVersion")
|
||||||
implementation("androidx.camera:camera-lifecycle:$cameraxVersion")
|
implementation("androidx.camera:camera-lifecycle:$cameraxVersion")
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,9 @@
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.CAMERA" />
|
<uses-permission android:name="android.permission.CAMERA" />
|
||||||
<uses-feature android:name="android.hardware.camera" />
|
<uses-feature android:name="android.hardware.camera" />
|
||||||
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||||
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||||
|
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" tools:ignore="ScopedStorage" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
|
|
@ -13,7 +16,8 @@
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/Theme.AnimalRating">
|
android:theme="@style/Theme.AnimalRating"
|
||||||
|
android:requestLegacyExternalStorage="true">
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".HomeActivity"
|
android:name=".HomeActivity"
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ import androidx.camera.view.PreviewView
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import com.example.animalrating.ml.CowAnalyzer
|
import com.example.animalrating.ml.CowAnalyzer
|
||||||
import com.example.animalrating.ui.SilhouetteOverlay
|
import com.example.animalrating.ui.SilhouetteOverlay
|
||||||
|
import com.google.android.material.button.MaterialButton
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.FileInputStream
|
import java.io.FileInputStream
|
||||||
import java.io.FileOutputStream
|
import java.io.FileOutputStream
|
||||||
|
|
@ -72,6 +73,10 @@ class CameraProcessor : AppCompatActivity(), CowAnalyzer.CowListener {
|
||||||
overlay = findViewById(R.id.silhouetteOverlay)
|
overlay = findViewById(R.id.silhouetteOverlay)
|
||||||
segmentationOverlay = findViewById(R.id.segmentationOverlay)
|
segmentationOverlay = findViewById(R.id.segmentationOverlay)
|
||||||
savedMaskOverlay = findViewById(R.id.savedMaskOverlay)
|
savedMaskOverlay = findViewById(R.id.savedMaskOverlay)
|
||||||
|
|
||||||
|
findViewById<MaterialButton>(R.id.btnExit).setOnClickListener {
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
|
||||||
frameProcessor = FrameProcessor()
|
frameProcessor = FrameProcessor()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,30 @@
|
||||||
package com.example.animalrating
|
package com.example.animalrating
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import android.content.pm.PackageManager
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.graphics.BitmapFactory
|
import android.graphics.BitmapFactory
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.view.View
|
||||||
|
import android.widget.ArrayAdapter
|
||||||
|
import android.widget.AutoCompleteTextView
|
||||||
import android.widget.Button
|
import android.widget.Button
|
||||||
|
import android.widget.GridLayout
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
import android.widget.LinearLayout
|
import android.widget.LinearLayout
|
||||||
|
import android.widget.RadioButton
|
||||||
|
import android.widget.RadioGroup
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.core.app.ActivityCompat
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
|
import com.google.android.material.textfield.TextInputEditText
|
||||||
|
import com.google.android.material.textfield.TextInputLayout
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.FileOutputStream
|
import java.io.FileOutputStream
|
||||||
|
import java.io.FileWriter
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
|
@ -21,12 +33,57 @@ class CowSelectionActivity : AppCompatActivity() {
|
||||||
|
|
||||||
private var currentCowName: String? = null
|
private var currentCowName: String? = null
|
||||||
private lateinit var imagesContainer: LinearLayout
|
private lateinit var imagesContainer: LinearLayout
|
||||||
|
private val storagePermissionCode = 101
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_cow_selection)
|
setContentView(R.layout.activity_cow_selection)
|
||||||
|
|
||||||
|
// Initialize StringProvider
|
||||||
|
StringProvider.initialize(this)
|
||||||
|
|
||||||
|
// Set UI text from StringProvider
|
||||||
|
findViewById<TextView>(R.id.tvToolbarTitle)?.text = StringProvider.getString("title_cow_selection")
|
||||||
|
findViewById<TextView>(R.id.tvAddCowDetails)?.text = StringProvider.getString("title_add_cow_details")
|
||||||
|
|
||||||
|
findViewById<TextInputLayout>(R.id.tilSpecies)?.hint = StringProvider.getString("hint_species")
|
||||||
|
findViewById<TextInputLayout>(R.id.tilBreed)?.hint = StringProvider.getString("hint_breed")
|
||||||
|
findViewById<TextInputLayout>(R.id.tilAge)?.hint = StringProvider.getString("hint_age")
|
||||||
|
findViewById<TextInputLayout>(R.id.tilMilk)?.hint = StringProvider.getString("hint_milk_yield")
|
||||||
|
findViewById<TextInputLayout>(R.id.tilCalving)?.hint = StringProvider.getString("hint_calving_number")
|
||||||
|
findViewById<TextInputLayout>(R.id.tilDescription)?.hint = StringProvider.getString("hint_description")
|
||||||
|
|
||||||
|
findViewById<TextView>(R.id.tvReproductiveStatus)?.text = StringProvider.getString("label_reproductive_status")
|
||||||
|
findViewById<RadioButton>(R.id.rbPregnant)?.text = StringProvider.getString("radio_pregnant")
|
||||||
|
findViewById<RadioButton>(R.id.rbCalved)?.text = StringProvider.getString("radio_calved")
|
||||||
|
findViewById<RadioButton>(R.id.rbNone)?.text = StringProvider.getString("radio_none")
|
||||||
|
|
||||||
|
findViewById<TextView>(R.id.tvUploadPhotos)?.text = StringProvider.getString("label_upload_photos")
|
||||||
|
findViewById<Button>(R.id.btnNewCow)?.text = StringProvider.getString("btn_save_profile")
|
||||||
|
findViewById<Button>(R.id.btnCancel)?.text = StringProvider.getString("btn_cancel")
|
||||||
|
|
||||||
|
findViewById<TextView>(R.id.tvFrontView)?.text = StringProvider.getString("text_front_view")
|
||||||
|
findViewById<TextView>(R.id.tvRearView)?.text = StringProvider.getString("text_rear_view")
|
||||||
|
findViewById<TextView>(R.id.tvLeftSide)?.text = StringProvider.getString("text_left_side")
|
||||||
|
findViewById<TextView>(R.id.tvRightSide)?.text = StringProvider.getString("text_right_side")
|
||||||
|
findViewById<TextView>(R.id.tvAngleView)?.text = StringProvider.getString("text_angle_view")
|
||||||
|
|
||||||
|
// Setup Toolbar Navigation Click (Exit instead of Back)
|
||||||
|
val toolbar = findViewById<androidx.appcompat.widget.Toolbar>(R.id.toolbar)
|
||||||
|
setSupportActionBar(toolbar)
|
||||||
|
supportActionBar?.setDisplayShowTitleEnabled(false)
|
||||||
|
|
||||||
|
// NOTE: The navigation icon is set in XML (@drawable/ic_back_arrow).
|
||||||
|
// We handle the click here.
|
||||||
|
toolbar.setNavigationOnClickListener {
|
||||||
|
// Exit behavior: Finish this activity.
|
||||||
|
// If "Exit" means close app, use finishAffinity() but user likely means exit this screen.
|
||||||
|
// Given "except home activity", finish() goes back to home or previous screen.
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
|
||||||
initializeDefaultMasks()
|
initializeDefaultMasks()
|
||||||
|
setupDropdowns()
|
||||||
|
|
||||||
imagesContainer = findViewById(R.id.currentCowImagesContainer)
|
imagesContainer = findViewById(R.id.currentCowImagesContainer)
|
||||||
|
|
||||||
|
|
@ -37,26 +94,38 @@ class CowSelectionActivity : AppCompatActivity() {
|
||||||
generateNewCowName()
|
generateNewCowName()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Try to load existing data if we are editing an existing cow
|
||||||
|
if (intent.hasExtra("COW_NAME")) {
|
||||||
|
loadCowDetails(currentCowName!!)
|
||||||
|
}
|
||||||
|
|
||||||
updateCowNameDisplay()
|
updateCowNameDisplay()
|
||||||
refreshCowImages()
|
refreshCowImages()
|
||||||
|
|
||||||
findViewById<Button>(R.id.btnNewCow).setOnClickListener {
|
findViewById<Button>(R.id.btnNewCow).setOnClickListener {
|
||||||
generateNewCowName()
|
if (checkStoragePermissions()) {
|
||||||
updateCowNameDisplay()
|
saveProfile()
|
||||||
refreshCowImages()
|
} else {
|
||||||
|
requestStoragePermissions()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
findViewById<Button>(R.id.btnCancel).setOnClickListener {
|
||||||
|
finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
val buttons = mapOf(
|
val buttons = mapOf(
|
||||||
R.id.btnLeft to Pair(R.drawable.left, "left"),
|
R.id.btnLeft to Pair(R.drawable.left, "left"),
|
||||||
R.id.btnRight to Pair(R.drawable.right, "right"),
|
R.id.btnRight to Pair(R.drawable.right, "right"),
|
||||||
R.id.btnTop to Pair(R.drawable.angle, "angle"), // Placeholder if no image yet
|
R.id.btnTop to Pair(R.drawable.angle, "angle"),
|
||||||
R.id.btnFront to Pair(R.drawable.front, "front"),
|
R.id.btnFront to Pair(R.drawable.front, "front"),
|
||||||
R.id.btnBack to Pair(R.drawable.back, "back")
|
R.id.btnBack to Pair(R.drawable.back, "back")
|
||||||
)
|
)
|
||||||
|
|
||||||
buttons.forEach { (btnId, pair) ->
|
buttons.forEach { (btnId, pair) ->
|
||||||
val (drawableId, orientation) = pair
|
val (drawableId, orientation) = pair
|
||||||
findViewById<Button>(btnId).setOnClickListener {
|
// Cast to View generic, as it is now a LinearLayout (clickable) in XML
|
||||||
|
findViewById<View>(btnId).setOnClickListener {
|
||||||
val intent = Intent(this, CameraProcessor::class.java)
|
val intent = Intent(this, CameraProcessor::class.java)
|
||||||
intent.putExtra("SILHOUETTE_ID", drawableId)
|
intent.putExtra("SILHOUETTE_ID", drawableId)
|
||||||
intent.putExtra("COW_NAME", currentCowName)
|
intent.putExtra("COW_NAME", currentCowName)
|
||||||
|
|
@ -66,6 +135,208 @@ class CowSelectionActivity : AppCompatActivity() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun checkStoragePermissions(): Boolean {
|
||||||
|
return if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
|
||||||
|
android.os.Environment.isExternalStorageManager()
|
||||||
|
} else {
|
||||||
|
val write = ContextCompat.checkSelfPermission(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||||
|
val read = ContextCompat.checkSelfPermission(this, android.Manifest.permission.READ_EXTERNAL_STORAGE)
|
||||||
|
write == PackageManager.PERMISSION_GRANTED && read == PackageManager.PERMISSION_GRANTED
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun requestStoragePermissions() {
|
||||||
|
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
|
||||||
|
try {
|
||||||
|
val intent = Intent(android.provider.Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION)
|
||||||
|
val uri = android.net.Uri.fromParts("package", packageName, null)
|
||||||
|
intent.data = uri
|
||||||
|
startActivity(intent)
|
||||||
|
} catch (_: Exception) {
|
||||||
|
val intent = Intent(android.provider.Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION)
|
||||||
|
startActivity(intent)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ActivityCompat.requestPermissions(
|
||||||
|
this,
|
||||||
|
arrayOf(android.Manifest.permission.WRITE_EXTERNAL_STORAGE, android.Manifest.permission.READ_EXTERNAL_STORAGE),
|
||||||
|
storagePermissionCode
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun saveProfile() {
|
||||||
|
// Get displayed values
|
||||||
|
val speciesDisplay = findViewById<AutoCompleteTextView>(R.id.spinnerSpecies).text.toString()
|
||||||
|
val breedDisplay = findViewById<AutoCompleteTextView>(R.id.spinnerBreed).text.toString()
|
||||||
|
|
||||||
|
// Convert to English for storage if needed (using reverse lookup or StringProvider helper)
|
||||||
|
// Assuming keys like "species_cow" map to "Cow" in English and something else in Hindi
|
||||||
|
// We try to find the key for the displayed value, then get the English value for that key.
|
||||||
|
// If not found (e.g. custom input), fallback to displayed value.
|
||||||
|
|
||||||
|
val speciesKey = StringProvider.getKeyForValue(speciesDisplay)
|
||||||
|
val species = if (speciesKey != null) StringProvider.getStringEnglish(speciesKey) else speciesDisplay
|
||||||
|
|
||||||
|
val breedKey = StringProvider.getKeyForValue(breedDisplay)
|
||||||
|
val breed = if (breedKey != null) StringProvider.getStringEnglish(breedKey) else breedDisplay
|
||||||
|
|
||||||
|
val ageInput = findViewById<TextInputEditText>(R.id.etAge).text.toString()
|
||||||
|
val milkInput = findViewById<TextInputLayout>(R.id.tilMilk).editText?.text.toString()
|
||||||
|
val calvingInput = findViewById<TextInputLayout>(R.id.tilCalving).editText?.text.toString()
|
||||||
|
val descriptionInput = findViewById<TextInputLayout>(R.id.tilDescription).editText?.text.toString()
|
||||||
|
|
||||||
|
val rgReproductive = findViewById<RadioGroup>(R.id.rgReproductiveStatus)
|
||||||
|
val reproductiveStatusKey = when(rgReproductive?.checkedRadioButtonId) {
|
||||||
|
R.id.rbPregnant -> "radio_pregnant"
|
||||||
|
R.id.rbCalved -> "radio_calved"
|
||||||
|
R.id.rbNone -> "radio_none"
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
val reproductiveStatus = if (reproductiveStatusKey != null) StringProvider.getStringEnglish(reproductiveStatusKey) else ""
|
||||||
|
|
||||||
|
val csvHeader = "CowID,Species,Breed,Age,MilkYield,CalvingNumber,ReproductiveStatus,Description\n"
|
||||||
|
val csvRow = "$currentCowName,$species,$breed,$ageInput,$milkInput,$calvingInput,$reproductiveStatus,$descriptionInput\n"
|
||||||
|
|
||||||
|
val csvFile = File(filesDir, "cow_profiles.csv")
|
||||||
|
|
||||||
|
try {
|
||||||
|
val fileExists = csvFile.exists()
|
||||||
|
val lines = if (fileExists) csvFile.readLines().toMutableList() else mutableListOf()
|
||||||
|
|
||||||
|
if (!fileExists) {
|
||||||
|
lines.add(csvHeader.trim())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if we are updating
|
||||||
|
val existingIndex = lines.indexOfFirst { it.startsWith("$currentCowName,") }
|
||||||
|
|
||||||
|
if (existingIndex != -1) {
|
||||||
|
lines[existingIndex] = csvRow.trim()
|
||||||
|
} else {
|
||||||
|
lines.add(csvRow.trim())
|
||||||
|
}
|
||||||
|
|
||||||
|
FileWriter(csvFile).use { writer ->
|
||||||
|
lines.forEach { line ->
|
||||||
|
writer.write(line + "\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Also export to public storage if needed
|
||||||
|
saveCsvToPublicStorage(lines)
|
||||||
|
|
||||||
|
Toast.makeText(this, StringProvider.getString("toast_profile_saved"), Toast.LENGTH_SHORT).show()
|
||||||
|
finish()
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
Toast.makeText(this, StringProvider.getString("toast_error_saving_profile") + " ${e.message}", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun saveCsvToPublicStorage(lines: List<String>) {
|
||||||
|
// Saving to public Documents folder
|
||||||
|
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) {
|
||||||
|
if (android.os.Environment.isExternalStorageManager()) {
|
||||||
|
val publicFile = File(android.os.Environment.getExternalStoragePublicDirectory(android.os.Environment.DIRECTORY_DOCUMENTS), "AnimalRating_Profiles.csv")
|
||||||
|
FileWriter(publicFile).use { writer ->
|
||||||
|
lines.forEach { line ->
|
||||||
|
writer.write(line + "\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
val publicFile = File(android.os.Environment.getExternalStoragePublicDirectory(android.os.Environment.DIRECTORY_DOCUMENTS), "AnimalRating_Profiles.csv")
|
||||||
|
FileWriter(publicFile).use { writer ->
|
||||||
|
lines.forEach { line ->
|
||||||
|
writer.write(line + "\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun loadCowDetails(cowId: String) {
|
||||||
|
val csvFile = File(filesDir, "cow_profiles.csv")
|
||||||
|
if (!csvFile.exists()) return
|
||||||
|
|
||||||
|
try {
|
||||||
|
val lines = csvFile.readLines()
|
||||||
|
// Removed unused header variable
|
||||||
|
val record = lines.find { it.startsWith("$cowId,") }?.split(",") ?: return
|
||||||
|
|
||||||
|
// Simple mapping based on known order
|
||||||
|
// CowID,Species,Breed,Age,MilkYield,CalvingNumber,ReproductiveStatus,Description
|
||||||
|
if (record.size >= 8) {
|
||||||
|
// Data is stored in English. Find key for English value, then get display string for that key.
|
||||||
|
val storedSpecies = record[1]
|
||||||
|
val speciesKey = StringProvider.getKeyForEnglishValue(storedSpecies)
|
||||||
|
val displaySpecies = if (speciesKey != null) StringProvider.getString(speciesKey) else storedSpecies
|
||||||
|
findViewById<AutoCompleteTextView>(R.id.spinnerSpecies).setText(displaySpecies, false)
|
||||||
|
|
||||||
|
val storedBreed = record[2]
|
||||||
|
val breedKey = StringProvider.getKeyForEnglishValue(storedBreed)
|
||||||
|
val displayBreed = if (breedKey != null) StringProvider.getString(breedKey) else storedBreed
|
||||||
|
findViewById<AutoCompleteTextView>(R.id.spinnerBreed).setText(displayBreed, false)
|
||||||
|
|
||||||
|
findViewById<TextInputEditText>(R.id.etAge).setText(record[3])
|
||||||
|
findViewById<TextInputLayout>(R.id.tilMilk).editText?.setText(record[4])
|
||||||
|
findViewById<TextInputLayout>(R.id.tilCalving).editText?.setText(record[5])
|
||||||
|
|
||||||
|
val storedStatus = record[6]
|
||||||
|
// Find which key matches this English value
|
||||||
|
val statusKey = StringProvider.getKeyForEnglishValue(storedStatus)
|
||||||
|
|
||||||
|
// We need to check radio buttons.
|
||||||
|
// Radio buttons text is set from StringProvider in onCreate.
|
||||||
|
// So we need to find which RadioButton corresponds to 'statusKey'.
|
||||||
|
|
||||||
|
// "radio_pregnant" -> R.id.rbPregnant
|
||||||
|
// "radio_calved" -> R.id.rbCalved
|
||||||
|
// "radio_none" -> R.id.rbNone
|
||||||
|
|
||||||
|
when(statusKey) {
|
||||||
|
"radio_pregnant" -> findViewById<RadioButton>(R.id.rbPregnant).isChecked = true
|
||||||
|
"radio_calved" -> findViewById<RadioButton>(R.id.rbCalved).isChecked = true
|
||||||
|
"radio_none" -> findViewById<RadioButton>(R.id.rbNone).isChecked = true
|
||||||
|
// Fallback if stored directly as text or unknown key
|
||||||
|
else -> {
|
||||||
|
// If stored directly as English "Pregnant" etc.
|
||||||
|
when (storedStatus) {
|
||||||
|
"Pregnant" -> findViewById<RadioButton>(R.id.rbPregnant).isChecked = true
|
||||||
|
"Calved" -> findViewById<RadioButton>(R.id.rbCalved).isChecked = true
|
||||||
|
"None" -> findViewById<RadioButton>(R.id.rbNone).isChecked = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
findViewById<TextInputLayout>(R.id.tilDescription).editText?.setText(record[7])
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupDropdowns() {
|
||||||
|
val species = listOf(
|
||||||
|
StringProvider.getString("species_cow"),
|
||||||
|
StringProvider.getString("species_buffalo")
|
||||||
|
)
|
||||||
|
val speciesAdapter = ArrayAdapter(this, android.R.layout.simple_dropdown_item_1line, species)
|
||||||
|
findViewById<AutoCompleteTextView>(R.id.spinnerSpecies).setAdapter(speciesAdapter)
|
||||||
|
|
||||||
|
val breeds = listOf(
|
||||||
|
StringProvider.getString("breed_holstein"),
|
||||||
|
StringProvider.getString("breed_jersey"),
|
||||||
|
StringProvider.getString("breed_sahiwal"),
|
||||||
|
StringProvider.getString("breed_gir"),
|
||||||
|
StringProvider.getString("breed_red_sindhi"),
|
||||||
|
StringProvider.getString("breed_murrah"),
|
||||||
|
StringProvider.getString("breed_surti")
|
||||||
|
)
|
||||||
|
val breedAdapter = ArrayAdapter(this, android.R.layout.simple_dropdown_item_1line, breeds)
|
||||||
|
findViewById<AutoCompleteTextView>(R.id.spinnerBreed).setAdapter(breedAdapter)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
refreshCowImages()
|
refreshCowImages()
|
||||||
|
|
@ -124,7 +395,8 @@ class CowSelectionActivity : AppCompatActivity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateCowNameDisplay() {
|
private fun updateCowNameDisplay() {
|
||||||
findViewById<TextView>(R.id.tvCowName).text = "Current Cow: $currentCowName"
|
// Cow Name is now in Toolbar title if needed, but we hide title.
|
||||||
|
// findViewById<TextView>(R.id.tvCowName).text = "Current Cow: $currentCowName"
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun refreshCowImages() {
|
private fun refreshCowImages() {
|
||||||
|
|
@ -148,67 +420,65 @@ class CowSelectionActivity : AppCompatActivity() {
|
||||||
private fun addOrientationSection(orientationStr: String, files: List<File>) {
|
private fun addOrientationSection(orientationStr: String, files: List<File>) {
|
||||||
// Orientation Header
|
// Orientation Header
|
||||||
val orientationHeader = TextView(this).apply {
|
val orientationHeader = TextView(this).apply {
|
||||||
text = orientationStr.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() }
|
val key = when(orientationStr.lowercase(Locale.getDefault())) {
|
||||||
|
"front" -> "text_front_view"
|
||||||
|
"back" -> "text_rear_view"
|
||||||
|
"left" -> "text_left_side"
|
||||||
|
"right" -> "text_right_side"
|
||||||
|
"angle" -> "text_angle_view"
|
||||||
|
else -> ""
|
||||||
|
}
|
||||||
|
val label = if (key.isNotEmpty()) StringProvider.getString(key) else orientationStr.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() }
|
||||||
|
text = label
|
||||||
|
|
||||||
textSize = 16f
|
textSize = 16f
|
||||||
setTypeface(null, android.graphics.Typeface.BOLD)
|
setTypeface(null, android.graphics.Typeface.BOLD)
|
||||||
setPadding(16, 8, 0, 8)
|
setPadding(16, 8, 0, 8)
|
||||||
}
|
}
|
||||||
imagesContainer.addView(orientationHeader)
|
imagesContainer.addView(orientationHeader)
|
||||||
|
|
||||||
|
// Grid for thumbnails
|
||||||
|
val gridLayout = GridLayout(this).apply {
|
||||||
|
columnCount = 3
|
||||||
|
layoutParams = LinearLayout.LayoutParams(
|
||||||
|
LinearLayout.LayoutParams.MATCH_PARENT,
|
||||||
|
LinearLayout.LayoutParams.WRAP_CONTENT
|
||||||
|
).apply {
|
||||||
|
setMargins(16, 0, 16, 16)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Images for this orientation
|
// Images for this orientation
|
||||||
files.forEach { file ->
|
files.forEach { file ->
|
||||||
val imageRow = LinearLayout(this).apply {
|
val thumbnailView = layoutInflater.inflate(R.layout.item_image_thumbnail, gridLayout, false)
|
||||||
orientation = LinearLayout.HORIZONTAL
|
|
||||||
layoutParams = LinearLayout.LayoutParams(
|
val imageView = thumbnailView.findViewById<ImageView>(R.id.ivThumbnail)
|
||||||
LinearLayout.LayoutParams.MATCH_PARENT,
|
val deleteButton = thumbnailView.findViewById<View>(R.id.btnDelete)
|
||||||
200 // Smaller height for images
|
|
||||||
).apply {
|
imageView.setImageBitmap(BitmapFactory.decodeFile(file.absolutePath))
|
||||||
setMargins(16, 0, 0, 16)
|
|
||||||
|
imageView.setOnClickListener {
|
||||||
|
val intent = Intent(this@CowSelectionActivity, FullScreenImageActivity::class.java)
|
||||||
|
intent.putExtra("IMAGE_PATH", file.absolutePath)
|
||||||
|
startActivity(intent)
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteButton.setOnClickListener {
|
||||||
|
if (file.delete()) {
|
||||||
|
Toast.makeText(this@CowSelectionActivity, StringProvider.getString("toast_image_deleted"), Toast.LENGTH_SHORT).show()
|
||||||
|
refreshCowImages()
|
||||||
|
} else {
|
||||||
|
Toast.makeText(this@CowSelectionActivity, StringProvider.getString("toast_error_deleting_image"), Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val imageView = ImageView(this).apply {
|
gridLayout.addView(thumbnailView)
|
||||||
layoutParams = LinearLayout.LayoutParams(
|
|
||||||
0,
|
|
||||||
LinearLayout.LayoutParams.MATCH_PARENT,
|
|
||||||
1f
|
|
||||||
)
|
|
||||||
scaleType = ImageView.ScaleType.CENTER_CROP
|
|
||||||
setImageBitmap(BitmapFactory.decodeFile(file.absolutePath))
|
|
||||||
setOnClickListener {
|
|
||||||
val intent = Intent(context, FullScreenImageActivity::class.java)
|
|
||||||
intent.putExtra("IMAGE_PATH", file.absolutePath)
|
|
||||||
startActivity(intent)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val deleteButton = Button(this).apply {
|
|
||||||
text = "Delete"
|
|
||||||
textSize = 12f
|
|
||||||
layoutParams = LinearLayout.LayoutParams(
|
|
||||||
LinearLayout.LayoutParams.WRAP_CONTENT,
|
|
||||||
LinearLayout.LayoutParams.WRAP_CONTENT
|
|
||||||
).apply {
|
|
||||||
setMargins(16,0,0,0)
|
|
||||||
}
|
|
||||||
setOnClickListener {
|
|
||||||
if (file.delete()) {
|
|
||||||
Toast.makeText(context, "Image deleted", Toast.LENGTH_SHORT).show()
|
|
||||||
refreshCowImages()
|
|
||||||
} else {
|
|
||||||
Toast.makeText(context, "Error deleting image", Toast.LENGTH_SHORT).show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
imageRow.addView(imageView)
|
|
||||||
imageRow.addView(deleteButton)
|
|
||||||
imagesContainer.addView(imageRow)
|
|
||||||
}
|
}
|
||||||
|
imagesContainer.addView(gridLayout)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSaveInstanceState(outState: Bundle) {
|
override fun onSaveInstanceState(outState: Bundle) {
|
||||||
super.onSaveInstanceState(outState)
|
super.onSaveInstanceState(outState)
|
||||||
outState.putString("COW_NAME", currentCowName)
|
outState.putString("COW_NAME", currentCowName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,16 @@
|
||||||
package com.example.animalrating
|
package com.example.animalrating
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import android.content.res.ColorStateList
|
||||||
import android.graphics.BitmapFactory
|
import android.graphics.BitmapFactory
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.widget.Button
|
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
import android.widget.LinearLayout
|
import android.widget.LinearLayout
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import com.google.android.material.button.MaterialButton
|
||||||
|
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
|
||||||
|
|
@ -19,8 +21,31 @@ class GalleryActivity : AppCompatActivity() {
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_gallery)
|
setContentView(R.layout.activity_gallery)
|
||||||
|
|
||||||
|
// Initialize StringProvider
|
||||||
|
StringProvider.initialize(this)
|
||||||
|
|
||||||
|
// Setup Back Button
|
||||||
|
val toolbar = findViewById<androidx.appcompat.widget.Toolbar>(R.id.toolbar)
|
||||||
|
setSupportActionBar(toolbar)
|
||||||
|
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||||
|
supportActionBar?.setDisplayShowHomeEnabled(true)
|
||||||
|
supportActionBar?.setDisplayShowTitleEnabled(false)
|
||||||
|
|
||||||
|
// Set Toolbar title
|
||||||
|
findViewById<TextView>(R.id.tvToolbarTitle)?.text = StringProvider.getString("title_gallery")
|
||||||
|
|
||||||
|
toolbar.setNavigationOnClickListener {
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
|
||||||
container = findViewById(R.id.galleryContainer)
|
container = findViewById(R.id.galleryContainer)
|
||||||
|
|
||||||
|
findViewById<FloatingActionButton>(R.id.fabAddCow).setOnClickListener {
|
||||||
|
val intent = Intent(this, CowSelectionActivity::class.java)
|
||||||
|
startActivity(intent)
|
||||||
|
}
|
||||||
|
|
||||||
refreshGallery()
|
refreshGallery()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -35,12 +60,23 @@ class GalleryActivity : AppCompatActivity() {
|
||||||
if (parts.size >= 2) "${parts[0]}_${parts[1]}" else "unknown"
|
if (parts.size >= 2) "${parts[0]}_${parts[1]}" else "unknown"
|
||||||
} ?: emptyMap()
|
} ?: emptyMap()
|
||||||
|
|
||||||
|
val csvFile = File(filesDir, "cow_profiles.csv")
|
||||||
|
val cowDetails = if (csvFile.exists()) {
|
||||||
|
csvFile.readLines().associate { line ->
|
||||||
|
val parts = line.split(",")
|
||||||
|
if (parts.isNotEmpty()) parts[0] to parts else "" to emptyList()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
emptyMap()
|
||||||
|
}
|
||||||
|
|
||||||
groupedFiles.forEach { (cowName, cowFiles) ->
|
groupedFiles.forEach { (cowName, cowFiles) ->
|
||||||
addCowSection(cowName, cowFiles)
|
val details = cowDetails[cowName] ?: emptyList()
|
||||||
|
addCowSection(cowName, cowFiles, details)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addCowSection(cowName: String, cowFiles: List<File>) {
|
private fun addCowSection(cowName: String, cowFiles: List<File>, details: List<String>) {
|
||||||
// Cow Name Header and Retake Button
|
// Cow Name Header and Retake Button
|
||||||
val headerLayout = LinearLayout(this).apply {
|
val headerLayout = LinearLayout(this).apply {
|
||||||
orientation = LinearLayout.HORIZONTAL
|
orientation = LinearLayout.HORIZONTAL
|
||||||
|
|
@ -53,8 +89,10 @@ class GalleryActivity : AppCompatActivity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
val nameView = TextView(this).apply {
|
val nameView = TextView(this).apply {
|
||||||
text = cowName
|
text = if (details.isNotEmpty()) "${StringProvider.getString("text_cow_id")} $cowName" else cowName
|
||||||
textSize = 20f
|
textSize = 20f
|
||||||
|
setTypeface(null, android.graphics.Typeface.BOLD)
|
||||||
|
setTextColor(android.graphics.Color.parseColor("#3E2723"))
|
||||||
layoutParams = LinearLayout.LayoutParams(
|
layoutParams = LinearLayout.LayoutParams(
|
||||||
0,
|
0,
|
||||||
LinearLayout.LayoutParams.WRAP_CONTENT,
|
LinearLayout.LayoutParams.WRAP_CONTENT,
|
||||||
|
|
@ -62,10 +100,21 @@ class GalleryActivity : AppCompatActivity() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val retakeButton = Button(this).apply {
|
val retakeButton = MaterialButton(this).apply {
|
||||||
text = "Retake"
|
text = StringProvider.getString("btn_edit")
|
||||||
|
textSize = 12f
|
||||||
|
setTypeface(null, android.graphics.Typeface.BOLD)
|
||||||
|
setTextColor(android.graphics.Color.parseColor("#5D4037"))
|
||||||
|
cornerRadius = (12 * resources.displayMetrics.density).toInt()
|
||||||
|
backgroundTintList = ColorStateList.valueOf(android.graphics.Color.parseColor("#EFEBE9"))
|
||||||
|
strokeWidth = (1 * resources.displayMetrics.density).toInt()
|
||||||
|
strokeColor = ColorStateList.valueOf(android.graphics.Color.parseColor("#5D4037"))
|
||||||
|
minHeight = 0
|
||||||
|
minimumHeight = 0
|
||||||
|
setPadding(24, 20, 24, 20)
|
||||||
|
|
||||||
setOnClickListener {
|
setOnClickListener {
|
||||||
val intent = Intent(context, CowSelectionActivity::class.java)
|
val intent = Intent(this@GalleryActivity, CowSelectionActivity::class.java)
|
||||||
intent.putExtra("COW_NAME", cowName)
|
intent.putExtra("COW_NAME", cowName)
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
}
|
}
|
||||||
|
|
@ -75,6 +124,48 @@ class GalleryActivity : AppCompatActivity() {
|
||||||
headerLayout.addView(retakeButton)
|
headerLayout.addView(retakeButton)
|
||||||
container.addView(headerLayout)
|
container.addView(headerLayout)
|
||||||
|
|
||||||
|
// Display details if available
|
||||||
|
// Header: CowID,Species,Breed,Age,MilkYield,CalvingNumber,ReproductiveStatus,Description
|
||||||
|
if (details.size >= 7) {
|
||||||
|
val detailsLayout = LinearLayout(this).apply {
|
||||||
|
orientation = LinearLayout.VERTICAL
|
||||||
|
layoutParams = LinearLayout.LayoutParams(
|
||||||
|
LinearLayout.LayoutParams.MATCH_PARENT,
|
||||||
|
LinearLayout.LayoutParams.WRAP_CONTENT
|
||||||
|
).apply {
|
||||||
|
setMargins(0, 0, 0, 16)
|
||||||
|
}
|
||||||
|
setPadding(24, 24, 24, 24)
|
||||||
|
background = android.graphics.drawable.GradientDrawable().apply {
|
||||||
|
setColor(android.graphics.Color.parseColor("#FAFAFA"))
|
||||||
|
cornerRadius = 16f
|
||||||
|
setStroke(2, android.graphics.Color.parseColor("#EEEEEE"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val infoText = StringBuilder()
|
||||||
|
// Note: Values like "Cow", "Holstein" stored in CSV are currently displayed as is.
|
||||||
|
// To translate stored values, we'd need a reverse lookup map or similar logic if the CSV stores English keys.
|
||||||
|
// For now, we translate the labels.
|
||||||
|
|
||||||
|
infoText.append("${StringProvider.getString("label_species")} ${details.getOrElse(1) { "-" }} ")
|
||||||
|
infoText.append("${StringProvider.getString("label_breed")} ${details.getOrElse(2) { "-" }}\n")
|
||||||
|
infoText.append("${StringProvider.getString("label_age")} ${details.getOrElse(3) { "-" }} ${StringProvider.getString("unit_years")} ")
|
||||||
|
infoText.append("${StringProvider.getString("label_milk_yield")} ${details.getOrElse(4) { "-" }} ${StringProvider.getString("unit_liters")}\n")
|
||||||
|
infoText.append("${StringProvider.getString("label_calving_no")} ${details.getOrElse(5) { "-" }} ")
|
||||||
|
infoText.append("${StringProvider.getString("label_status")} ${details.getOrElse(6) { "-" }}")
|
||||||
|
|
||||||
|
val detailsView = TextView(this).apply {
|
||||||
|
text = infoText.toString()
|
||||||
|
textSize = 14f
|
||||||
|
setTextColor(android.graphics.Color.parseColor("#5D4037"))
|
||||||
|
setLineSpacing(10f, 1f)
|
||||||
|
}
|
||||||
|
|
||||||
|
detailsLayout.addView(detailsView)
|
||||||
|
container.addView(detailsLayout)
|
||||||
|
}
|
||||||
|
|
||||||
// Group files by orientation (e.g., left, right, etc.)
|
// Group files by orientation (e.g., left, right, etc.)
|
||||||
val filesByOrientation = cowFiles.groupBy { file ->
|
val filesByOrientation = cowFiles.groupBy { file ->
|
||||||
val parts = file.name.split("_")
|
val parts = file.name.split("_")
|
||||||
|
|
@ -101,63 +192,60 @@ class GalleryActivity : AppCompatActivity() {
|
||||||
private fun addOrientationSection(orientationStr: String, files: List<File>) {
|
private fun addOrientationSection(orientationStr: String, files: List<File>) {
|
||||||
// Orientation Header
|
// Orientation Header
|
||||||
val orientationHeader = TextView(this).apply {
|
val orientationHeader = TextView(this).apply {
|
||||||
text = orientationStr.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() }
|
val key = when(orientationStr.lowercase(Locale.getDefault())) {
|
||||||
|
"front" -> "text_front_view"
|
||||||
|
"back" -> "text_rear_view"
|
||||||
|
"left" -> "text_left_side"
|
||||||
|
"right" -> "text_right_side"
|
||||||
|
"angle" -> "text_angle_view"
|
||||||
|
else -> ""
|
||||||
|
}
|
||||||
|
val label = if (key.isNotEmpty()) StringProvider.getString(key) else orientationStr.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() }
|
||||||
|
text = label
|
||||||
textSize = 16f
|
textSize = 16f
|
||||||
setTypeface(null, android.graphics.Typeface.BOLD)
|
setTypeface(null, android.graphics.Typeface.BOLD)
|
||||||
setPadding(16, 8, 0, 8)
|
setPadding(16, 8, 0, 8)
|
||||||
}
|
}
|
||||||
container.addView(orientationHeader)
|
container.addView(orientationHeader)
|
||||||
|
|
||||||
|
// Grid for thumbnails
|
||||||
|
val gridLayout = android.widget.GridLayout(this).apply {
|
||||||
|
columnCount = 3
|
||||||
|
layoutParams = LinearLayout.LayoutParams(
|
||||||
|
LinearLayout.LayoutParams.MATCH_PARENT,
|
||||||
|
LinearLayout.LayoutParams.WRAP_CONTENT
|
||||||
|
).apply {
|
||||||
|
setMargins(16, 0, 16, 16)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Images for this orientation
|
// Images for this orientation
|
||||||
files.forEach { file ->
|
files.forEach { file ->
|
||||||
val imageRow = LinearLayout(this).apply {
|
val thumbnailView = layoutInflater.inflate(R.layout.item_image_thumbnail, gridLayout, false)
|
||||||
orientation = LinearLayout.HORIZONTAL
|
|
||||||
layoutParams = LinearLayout.LayoutParams(
|
val imageView = thumbnailView.findViewById<ImageView>(R.id.ivThumbnail)
|
||||||
LinearLayout.LayoutParams.MATCH_PARENT,
|
val deleteButton = thumbnailView.findViewById<android.view.View>(R.id.btnDelete)
|
||||||
200
|
|
||||||
).apply {
|
imageView.setImageBitmap(BitmapFactory.decodeFile(file.absolutePath))
|
||||||
setMargins(32, 0, 0, 16)
|
|
||||||
|
imageView.setOnClickListener {
|
||||||
|
val intent = Intent(this@GalleryActivity, FullScreenImageActivity::class.java)
|
||||||
|
intent.putExtra("IMAGE_PATH", file.absolutePath)
|
||||||
|
startActivity(intent)
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteButton.setOnClickListener {
|
||||||
|
if (file.delete()) {
|
||||||
|
Toast.makeText(this@GalleryActivity, StringProvider.getString("toast_image_deleted"), Toast.LENGTH_SHORT).show()
|
||||||
|
refreshGallery()
|
||||||
|
} else {
|
||||||
|
Toast.makeText(this@GalleryActivity, StringProvider.getString("toast_error_deleting_image"), Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val imageView = ImageView(this).apply {
|
gridLayout.addView(thumbnailView)
|
||||||
layoutParams = LinearLayout.LayoutParams(
|
|
||||||
0,
|
|
||||||
LinearLayout.LayoutParams.MATCH_PARENT,
|
|
||||||
1f
|
|
||||||
)
|
|
||||||
scaleType = ImageView.ScaleType.CENTER_CROP
|
|
||||||
setImageBitmap(BitmapFactory.decodeFile(file.absolutePath))
|
|
||||||
setOnClickListener {
|
|
||||||
val intent = Intent(context, FullScreenImageActivity::class.java)
|
|
||||||
intent.putExtra("IMAGE_PATH", file.absolutePath)
|
|
||||||
startActivity(intent)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val deleteButton = Button(this).apply {
|
|
||||||
text = "Delete"
|
|
||||||
textSize = 12f
|
|
||||||
layoutParams = LinearLayout.LayoutParams(
|
|
||||||
LinearLayout.LayoutParams.WRAP_CONTENT,
|
|
||||||
LinearLayout.LayoutParams.WRAP_CONTENT
|
|
||||||
).apply {
|
|
||||||
setMargins(16,0,0,0)
|
|
||||||
}
|
|
||||||
setOnClickListener {
|
|
||||||
if (file.delete()) {
|
|
||||||
Toast.makeText(context, "Image deleted", Toast.LENGTH_SHORT).show()
|
|
||||||
refreshGallery()
|
|
||||||
} else {
|
|
||||||
Toast.makeText(context, "Error deleting image", Toast.LENGTH_SHORT).show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
imageRow.addView(imageView)
|
|
||||||
imageRow.addView(deleteButton)
|
|
||||||
container.addView(imageRow)
|
|
||||||
}
|
}
|
||||||
|
container.addView(gridLayout)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,21 @@
|
||||||
package com.example.animalrating
|
package com.example.animalrating
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import android.content.pm.PackageManager
|
||||||
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.view.View
|
||||||
|
import android.widget.AdapterView
|
||||||
import android.widget.ArrayAdapter
|
import android.widget.ArrayAdapter
|
||||||
import android.widget.Button
|
import android.widget.ImageView
|
||||||
|
import android.widget.PopupMenu
|
||||||
import android.widget.SeekBar
|
import android.widget.SeekBar
|
||||||
import android.widget.Spinner
|
import android.widget.Spinner
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.core.app.ActivityCompat
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
|
import com.google.android.material.button.MaterialButton
|
||||||
|
|
||||||
class HomeActivity : AppCompatActivity() {
|
class HomeActivity : AppCompatActivity() {
|
||||||
|
|
||||||
|
|
@ -15,22 +23,103 @@ class HomeActivity : AppCompatActivity() {
|
||||||
const val ALGORITHM_HAMMING = "Hamming Distance"
|
const val ALGORITHM_HAMMING = "Hamming Distance"
|
||||||
const val ALGORITHM_EUCLIDEAN = "Euclidean Distance"
|
const val ALGORITHM_EUCLIDEAN = "Euclidean Distance"
|
||||||
const val ALGORITHM_JACCARD = "Jaccard Similarity"
|
const val ALGORITHM_JACCARD = "Jaccard Similarity"
|
||||||
|
private const val PERMISSION_REQUEST_CODE = 101
|
||||||
|
private const val PREF_COW_ILLUSTRATION_INDEX = "COW_ILLUSTRATION_INDEX"
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_home)
|
setContentView(R.layout.activity_home)
|
||||||
|
|
||||||
|
StringProvider.initialize(this)
|
||||||
|
|
||||||
setupUI()
|
setupUI()
|
||||||
|
checkAndRequestPermissions()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun checkAndRequestPermissions() {
|
||||||
|
val permissions = mutableListOf<String>()
|
||||||
|
|
||||||
|
if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
|
||||||
|
permissions.add(android.Manifest.permission.CAMERA)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
|
||||||
|
if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
|
||||||
|
permissions.add(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||||
|
}
|
||||||
|
if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
|
||||||
|
permissions.add(android.Manifest.permission.READ_EXTERNAL_STORAGE)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
|
if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.READ_MEDIA_IMAGES) != PackageManager.PERMISSION_GRANTED) {
|
||||||
|
permissions.add(android.Manifest.permission.READ_MEDIA_IMAGES)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
|
||||||
|
permissions.add(android.Manifest.permission.READ_EXTERNAL_STORAGE)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (permissions.isNotEmpty()) {
|
||||||
|
ActivityCompat.requestPermissions(this, permissions.toTypedArray(), PERMISSION_REQUEST_CODE)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupUI() {
|
private fun setupUI() {
|
||||||
|
// Language Spinner
|
||||||
|
val languageSpinner = findViewById<Spinner>(R.id.spinnerLanguage)
|
||||||
|
val languages = StringProvider.getLanguages()
|
||||||
|
val languageAdapter = ArrayAdapter(this, android.R.layout.simple_spinner_item, languages)
|
||||||
|
languageAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
|
||||||
|
languageSpinner.adapter = languageAdapter
|
||||||
|
|
||||||
|
val prefs = getSharedPreferences("AnimalRatingPrefs", MODE_PRIVATE)
|
||||||
|
val savedLang = prefs.getString("LANGUAGE", "English")
|
||||||
|
languageSpinner.setSelection(languages.indexOf(savedLang))
|
||||||
|
|
||||||
|
languageSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
|
||||||
|
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
|
||||||
|
val selectedLanguage = languages[position]
|
||||||
|
val currentLang = prefs.getString("LANGUAGE", "English")
|
||||||
|
|
||||||
|
// Only update and recreate if language actually changed
|
||||||
|
if (selectedLanguage != currentLang) {
|
||||||
|
saveSettings() // Save UI state so it's not lost
|
||||||
|
StringProvider.setLanguage(selectedLanguage, this@HomeActivity)
|
||||||
|
// Post recreate to avoid WindowLeaked (allows spinner popup to close)
|
||||||
|
android.os.Handler(android.os.Looper.getMainLooper()).post {
|
||||||
|
recreate()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
override fun onNothingSelected(parent: AdapterView<*>?) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set text from StringProvider
|
||||||
|
findViewById<TextView>(R.id.tvTitle).text = StringProvider.getString("title_home")
|
||||||
|
findViewById<MaterialButton>(R.id.btnViewGallery).text = StringProvider.getString("btn_view_gallery")
|
||||||
|
findViewById<MaterialButton>(R.id.btnSelectCow).text = StringProvider.getString("btn_select_cow")
|
||||||
|
findViewById<TextView>(R.id.tvAlgorithmLabel).text = StringProvider.getString("label_algorithm")
|
||||||
|
findViewById<TextView>(R.id.tvThresholdLabel).text = StringProvider.getString("label_match_threshold")
|
||||||
|
|
||||||
|
// Cow Illustration and Logic
|
||||||
|
val ivCowIllustration = findViewById<ImageView>(R.id.ivCowIllustration)
|
||||||
|
val savedIndex = prefs.getInt(PREF_COW_ILLUSTRATION_INDEX, 0)
|
||||||
|
setCowIllustration(ivCowIllustration, savedIndex)
|
||||||
|
|
||||||
|
ivCowIllustration.setOnClickListener { view ->
|
||||||
|
showIllustrationPopup(view, ivCowIllustration)
|
||||||
|
}
|
||||||
|
|
||||||
// Navigation buttons
|
// Navigation buttons
|
||||||
findViewById<Button>(R.id.btnViewGallery).setOnClickListener {
|
findViewById<MaterialButton>(R.id.btnViewGallery).setOnClickListener {
|
||||||
startActivity(Intent(this, GalleryActivity::class.java))
|
startActivity(Intent(this, GalleryActivity::class.java))
|
||||||
}
|
}
|
||||||
|
|
||||||
findViewById<Button>(R.id.btnSelectCow).setOnClickListener {
|
findViewById<MaterialButton>(R.id.btnSelectCow).setOnClickListener {
|
||||||
saveSettingsAndStart()
|
saveSettingsAndStart()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -42,7 +131,6 @@ class HomeActivity : AppCompatActivity() {
|
||||||
spinner.adapter = adapter
|
spinner.adapter = adapter
|
||||||
|
|
||||||
// Set default selection from preferences or intent
|
// Set default selection from preferences or intent
|
||||||
val prefs = getSharedPreferences("AnimalRatingPrefs", MODE_PRIVATE)
|
|
||||||
val savedAlg = prefs.getString("ALGORITHM", ALGORITHM_HAMMING)
|
val savedAlg = prefs.getString("ALGORITHM", ALGORITHM_HAMMING)
|
||||||
spinner.setSelection(algorithms.indexOf(savedAlg))
|
spinner.setSelection(algorithms.indexOf(savedAlg))
|
||||||
|
|
||||||
|
|
@ -63,21 +151,68 @@ class HomeActivity : AppCompatActivity() {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun saveSettingsAndStart() {
|
private fun showIllustrationPopup(anchor: View, imageView: ImageView) {
|
||||||
|
val popup = PopupMenu(this, anchor)
|
||||||
|
for (i in 0..4) {
|
||||||
|
popup.menu.add(0, i, i, "Illustration $i")
|
||||||
|
}
|
||||||
|
|
||||||
|
popup.setOnMenuItemClickListener { item ->
|
||||||
|
val index = item.itemId
|
||||||
|
setCowIllustration(imageView, index)
|
||||||
|
|
||||||
|
// Save preference
|
||||||
|
getSharedPreferences("AnimalRatingPrefs", MODE_PRIVATE).edit()
|
||||||
|
.putInt(PREF_COW_ILLUSTRATION_INDEX, index)
|
||||||
|
.apply()
|
||||||
|
true
|
||||||
|
}
|
||||||
|
popup.show()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setCowIllustration(imageView: ImageView, index: Int) {
|
||||||
|
// Map index to drawable resource
|
||||||
|
// We assume resources are named cow_illustration (for index 0 or default) or similar logic if strictly named
|
||||||
|
// But user said "cow_illustration_{n}, where n=0,1,2,3,4"
|
||||||
|
// However, currently we likely only have 'cow_illustration' in drawable from previous step, or user implies they exist.
|
||||||
|
// We will try to find resources dynamically.
|
||||||
|
|
||||||
|
val resName = "cow_illustration_$index"
|
||||||
|
val resId = resources.getIdentifier(resName, "drawable", packageName)
|
||||||
|
|
||||||
|
if (resId != 0) {
|
||||||
|
imageView.setImageResource(resId)
|
||||||
|
} else {
|
||||||
|
// Fallback to default if specific one not found
|
||||||
|
if (index == 0) {
|
||||||
|
// Maybe it's just "cow_illustration" without suffix if n=0 is base?
|
||||||
|
// Or user provided 5 distinct files. We try 'cow_illustration' as fallback.
|
||||||
|
val defaultId = resources.getIdentifier("cow_illustration", "drawable", packageName)
|
||||||
|
if (defaultId != 0) imageView.setImageResource(defaultId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun saveSettings() {
|
||||||
val spinner = findViewById<Spinner>(R.id.spinnerAlgorithm)
|
val spinner = findViewById<Spinner>(R.id.spinnerAlgorithm)
|
||||||
val seekBar = findViewById<SeekBar>(R.id.seekBarThreshold)
|
val seekBar = findViewById<SeekBar>(R.id.seekBarThreshold)
|
||||||
|
|
||||||
val selectedAlgorithm = spinner.selectedItem.toString()
|
if (spinner != null && seekBar != null) {
|
||||||
val threshold = seekBar.progress
|
val selectedAlgorithm = spinner.selectedItem?.toString() ?: ALGORITHM_HAMMING
|
||||||
|
val threshold = seekBar.progress
|
||||||
// Save to preferences
|
|
||||||
val prefs = getSharedPreferences("AnimalRatingPrefs", MODE_PRIVATE)
|
// Save to preferences
|
||||||
prefs.edit().apply {
|
val prefs = getSharedPreferences("AnimalRatingPrefs", MODE_PRIVATE)
|
||||||
putString("ALGORITHM", selectedAlgorithm)
|
prefs.edit().apply {
|
||||||
putInt("THRESHOLD", threshold)
|
putString("ALGORITHM", selectedAlgorithm)
|
||||||
apply()
|
putInt("THRESHOLD", threshold)
|
||||||
|
apply()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun saveSettingsAndStart() {
|
||||||
|
saveSettings()
|
||||||
startActivity(Intent(this, CowSelectionActivity::class.java))
|
startActivity(Intent(this, CowSelectionActivity::class.java))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,101 @@
|
||||||
|
package com.example.animalrating
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import org.json.JSONObject
|
||||||
|
import java.io.InputStream
|
||||||
|
|
||||||
|
object StringProvider {
|
||||||
|
|
||||||
|
private var stringData: JSONObject? = null
|
||||||
|
private var currentLanguage = "English"
|
||||||
|
private const val DEFAULT_LANGUAGE = "English"
|
||||||
|
|
||||||
|
fun initialize(context: Context) {
|
||||||
|
if (stringData == null) {
|
||||||
|
try {
|
||||||
|
val inputStream: InputStream = context.resources.openRawResource(R.raw.strings)
|
||||||
|
val jsonString = inputStream.bufferedReader().use { it.readText() }
|
||||||
|
stringData = JSONObject(jsonString)
|
||||||
|
|
||||||
|
// Load saved language
|
||||||
|
val prefs = context.getSharedPreferences("AnimalRatingPrefs", Context.MODE_PRIVATE)
|
||||||
|
currentLanguage = prefs.getString("LANGUAGE", DEFAULT_LANGUAGE) ?: DEFAULT_LANGUAGE
|
||||||
|
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
// Handle error, maybe load default strings or log
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setLanguage(language: String, context: Context) {
|
||||||
|
currentLanguage = language
|
||||||
|
// Save selected language
|
||||||
|
val prefs = context.getSharedPreferences("AnimalRatingPrefs", Context.MODE_PRIVATE)
|
||||||
|
prefs.edit().putString("LANGUAGE", language).apply()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getLanguages(): List<String> {
|
||||||
|
return stringData?.keys()?.asSequence()?.toList() ?: listOf(DEFAULT_LANGUAGE)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getString(key: String): String {
|
||||||
|
return getStringForLanguage(key, currentLanguage)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getStringEnglish(key: String): String {
|
||||||
|
return getStringForLanguage(key, DEFAULT_LANGUAGE)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getStringForLanguage(key: String, language: String): String {
|
||||||
|
return try {
|
||||||
|
stringData?.getJSONObject(language)?.getString(key) ?: ""
|
||||||
|
} catch (e: Exception) {
|
||||||
|
// Fallback to English if key not found in current language
|
||||||
|
try {
|
||||||
|
if (language != DEFAULT_LANGUAGE) {
|
||||||
|
stringData?.getJSONObject(DEFAULT_LANGUAGE)?.getString(key) ?: ""
|
||||||
|
} else {
|
||||||
|
""
|
||||||
|
}
|
||||||
|
} catch (e2: Exception) {
|
||||||
|
"" // Return empty if not found anywhere
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getKeyForValue(value: String): String? {
|
||||||
|
// Helper to find the key for a given localized value in current language
|
||||||
|
// This is expensive, but useful if we need to reverse lookup
|
||||||
|
val langData = stringData?.optJSONObject(currentLanguage) ?: return null
|
||||||
|
val keys = langData.keys()
|
||||||
|
while (keys.hasNext()) {
|
||||||
|
val key = keys.next()
|
||||||
|
if (langData.getString(key) == value) {
|
||||||
|
return key
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Also check English just in case it was stored as English
|
||||||
|
val englishData = stringData?.optJSONObject(DEFAULT_LANGUAGE) ?: return null
|
||||||
|
val engKeys = englishData.keys()
|
||||||
|
while (engKeys.hasNext()) {
|
||||||
|
val key = engKeys.next()
|
||||||
|
if (englishData.getString(key) == value) {
|
||||||
|
return key
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getKeyForEnglishValue(value: String): String? {
|
||||||
|
val englishData = stringData?.optJSONObject(DEFAULT_LANGUAGE) ?: return null
|
||||||
|
val engKeys = englishData.keys()
|
||||||
|
while (engKeys.hasNext()) {
|
||||||
|
val key = engKeys.next()
|
||||||
|
if (englishData.getString(key) == value) {
|
||||||
|
return key
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<solid android:color="#EFEBE9" />
|
||||||
|
<corners android:radius="16dp" />
|
||||||
|
</shape>
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 337 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 616 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 168 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 183 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 157 KiB |
|
|
@ -0,0 +1,10 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24"
|
||||||
|
android:tint="#FFFFFF">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFFFFF"
|
||||||
|
android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8l8,8l1.41,-1.41L7.83,13H20v-2z"/>
|
||||||
|
</vector>
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="40dp"
|
||||||
|
android:height="40dp"
|
||||||
|
android:viewportWidth="40"
|
||||||
|
android:viewportHeight="40">
|
||||||
|
|
||||||
|
<!-- Circle Background -->
|
||||||
|
<path
|
||||||
|
android:fillColor="#EFEBE9"
|
||||||
|
android:pathData="M20,20m-20,0a20,20 0,1 1,40 0a20,20 0,1 1,-40 0"/>
|
||||||
|
|
||||||
|
<!-- Arrow Icon (Centered and Scaled) -->
|
||||||
|
<group
|
||||||
|
android:scaleX="1.0"
|
||||||
|
android:scaleY="1.0"
|
||||||
|
android:translateX="8.0"
|
||||||
|
android:translateY="8.0">
|
||||||
|
<path
|
||||||
|
android:fillColor="#5D4037"
|
||||||
|
android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8l8,8l1.41,-1.41L7.83,13H20v-2z"/>
|
||||||
|
</group>
|
||||||
|
</vector>
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<solid android:color="#EFEBE9" />
|
||||||
|
<corners android:radius="16dp" />
|
||||||
|
</shape>
|
||||||
|
|
@ -1,133 +1,451 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:background="#F5F5F5">
|
android:orientation="vertical"
|
||||||
|
android:background="#FFFFFF">
|
||||||
|
|
||||||
<LinearLayout
|
<androidx.appcompat.widget.Toolbar
|
||||||
|
android:id="@+id/toolbar"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="?attr/actionBarSize"
|
||||||
android:orientation="vertical"
|
android:background="#FFFFFF"
|
||||||
android:gravity="center"
|
app:navigationIcon="@drawable/ic_round_back_button">
|
||||||
android:padding="16dp">
|
|
||||||
|
|
||||||
<androidx.cardview.widget.CardView
|
<TextView
|
||||||
|
android:id="@+id/tvToolbarTitle"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Cow Selection"
|
||||||
|
android:textSize="20sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="#3E2723"/>
|
||||||
|
|
||||||
|
</androidx.appcompat.widget.Toolbar>
|
||||||
|
|
||||||
|
<ScrollView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:fillViewport="true">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginBottom="24dp"
|
android:orientation="vertical"
|
||||||
app:cardCornerRadius="12dp"
|
android:padding="24dp">
|
||||||
app:cardElevation="4dp"
|
|
||||||
app:contentPadding="16dp">
|
<TextView
|
||||||
|
android:id="@+id/tvAddCowDetails"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Add Cow Details"
|
||||||
|
android:textSize="24sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="#3E2723"
|
||||||
|
android:layout_marginBottom="24dp"/>
|
||||||
|
|
||||||
|
<!-- Form Fields -->
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:id="@+id/tilSpecies"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="16dp"
|
||||||
|
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
|
||||||
|
app:boxCornerRadiusTopStart="12dp"
|
||||||
|
app:boxCornerRadiusTopEnd="12dp"
|
||||||
|
app:boxCornerRadiusBottomStart="12dp"
|
||||||
|
app:boxCornerRadiusBottomEnd="12dp"
|
||||||
|
app:boxStrokeColor="#6D4C41"
|
||||||
|
android:hint="Species">
|
||||||
|
|
||||||
|
<AutoCompleteTextView
|
||||||
|
android:id="@+id/spinnerSpecies"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:inputType="none"/>
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:id="@+id/tilBreed"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="16dp"
|
||||||
|
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
|
||||||
|
app:boxCornerRadiusTopStart="12dp"
|
||||||
|
app:boxCornerRadiusTopEnd="12dp"
|
||||||
|
app:boxCornerRadiusBottomStart="12dp"
|
||||||
|
app:boxCornerRadiusBottomEnd="12dp"
|
||||||
|
app:boxStrokeColor="#6D4C41"
|
||||||
|
android:hint="Breed">
|
||||||
|
|
||||||
|
<AutoCompleteTextView
|
||||||
|
android:id="@+id/spinnerBreed"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:inputType="none"/>
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:orientation="horizontal"
|
||||||
android:gravity="center">
|
android:baselineAligned="false"
|
||||||
|
android:layout_marginBottom="16dp">
|
||||||
|
|
||||||
<TextView
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
android:id="@+id/tvCowName"
|
android:id="@+id/tilAge"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:textSize="20sp"
|
android:layout_weight="1"
|
||||||
android:textStyle="bold"
|
android:layout_marginEnd="8dp"
|
||||||
android:textColor="#333333"
|
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
||||||
android:layout_marginBottom="16dp"/>
|
app:boxCornerRadiusTopStart="12dp"
|
||||||
|
app:boxCornerRadiusTopEnd="12dp"
|
||||||
|
app:boxCornerRadiusBottomStart="12dp"
|
||||||
|
app:boxCornerRadiusBottomEnd="12dp"
|
||||||
|
app:boxStrokeColor="#6D4C41"
|
||||||
|
android:hint="Age (Years)">
|
||||||
|
|
||||||
<Button
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
android:id="@+id/btnNewCow"
|
android:id="@+id/etAge"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:inputType="number"/>
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:id="@+id/tilMilk"
|
||||||
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="Capture New Cow"
|
android:layout_weight="1"
|
||||||
android:backgroundTint="#2196F3"
|
android:layout_marginStart="8dp"
|
||||||
android:textColor="#FFFFFF"/>
|
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
||||||
|
app:boxCornerRadiusTopStart="12dp"
|
||||||
|
app:boxCornerRadiusTopEnd="12dp"
|
||||||
|
app:boxCornerRadiusBottomStart="12dp"
|
||||||
|
app:boxCornerRadiusBottomEnd="12dp"
|
||||||
|
app:boxStrokeColor="#6D4C41"
|
||||||
|
android:hint="Milk Yield (L)">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:inputType="numberDecimal"/>
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</androidx.cardview.widget.CardView>
|
|
||||||
|
|
||||||
<TextView
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
android:layout_width="wrap_content"
|
android:id="@+id/tilCalving"
|
||||||
android:layout_height="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:text="Select Orientation"
|
|
||||||
android:textSize="20sp"
|
|
||||||
android:textStyle="bold"
|
|
||||||
android:layout_marginBottom="16dp"/>
|
|
||||||
|
|
||||||
<GridLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:columnCount="2"
|
|
||||||
android:rowCount="3"
|
|
||||||
android:alignmentMode="alignMargins"
|
|
||||||
android:columnOrderPreserved="false"
|
|
||||||
android:layout_marginBottom="32dp">
|
|
||||||
|
|
||||||
<!-- Left -->
|
|
||||||
<Button
|
|
||||||
android:id="@+id/btnLeft"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_columnWeight="1"
|
android:layout_marginBottom="16dp"
|
||||||
android:text="Left"
|
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
||||||
android:layout_margin="8dp"
|
app:boxCornerRadiusTopStart="12dp"
|
||||||
android:backgroundTint="#FF5722"
|
app:boxCornerRadiusTopEnd="12dp"
|
||||||
android:textColor="#FFFFFF"/>
|
app:boxCornerRadiusBottomStart="12dp"
|
||||||
|
app:boxCornerRadiusBottomEnd="12dp"
|
||||||
|
app:boxStrokeColor="#6D4C41"
|
||||||
|
android:hint="Calving Number">
|
||||||
|
|
||||||
<!-- Right -->
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
<Button
|
android:layout_width="match_parent"
|
||||||
android:id="@+id/btnRight"
|
android:layout_height="wrap_content"
|
||||||
android:layout_width="0dp"
|
android:inputType="number"/>
|
||||||
android:layout_height="wrap_content"
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
android:layout_columnWeight="1"
|
|
||||||
android:text="Right"
|
|
||||||
android:layout_margin="8dp"
|
|
||||||
android:backgroundTint="#FF5722"
|
|
||||||
android:textColor="#FFFFFF"/>
|
|
||||||
|
|
||||||
<!-- Front -->
|
<TextView
|
||||||
<Button
|
android:id="@+id/tvReproductiveStatus"
|
||||||
android:id="@+id/btnFront"
|
android:layout_width="wrap_content"
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_columnWeight="1"
|
android:text="Reproductive Status"
|
||||||
android:text="Front"
|
android:textColor="#5D4037"
|
||||||
android:layout_margin="8dp"
|
android:layout_marginBottom="8dp"/>
|
||||||
android:backgroundTint="#FF5722"
|
|
||||||
android:textColor="#FFFFFF"/>
|
|
||||||
|
|
||||||
<!-- Back -->
|
<RadioGroup
|
||||||
<Button
|
android:id="@+id/rgReproductiveStatus"
|
||||||
android:id="@+id/btnBack"
|
android:layout_width="match_parent"
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_columnWeight="1"
|
android:orientation="horizontal"
|
||||||
android:text="Back"
|
android:layout_marginBottom="16dp">
|
||||||
android:layout_margin="8dp"
|
|
||||||
android:backgroundTint="#FF5722"
|
<RadioButton
|
||||||
android:textColor="#FFFFFF"/>
|
android:id="@+id/rbPregnant"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Pregnant"
|
||||||
|
android:layout_marginEnd="16dp"/>
|
||||||
|
|
||||||
|
<RadioButton
|
||||||
|
android:id="@+id/rbCalved"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Calved"
|
||||||
|
android:layout_marginEnd="16dp"/>
|
||||||
|
|
||||||
|
<RadioButton
|
||||||
|
android:id="@+id/rbNone"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="None"/>
|
||||||
|
</RadioGroup>
|
||||||
|
|
||||||
<!-- Top (Centered in last row) -->
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
<Button
|
android:id="@+id/tilDescription"
|
||||||
android:id="@+id/btnTop"
|
android:layout_width="match_parent"
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_columnWeight="1"
|
android:layout_marginBottom="24dp"
|
||||||
android:layout_gravity="fill_horizontal"
|
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
||||||
android:layout_columnSpan="2"
|
app:boxCornerRadiusTopStart="12dp"
|
||||||
android:text="Angle"
|
app:boxCornerRadiusTopEnd="12dp"
|
||||||
android:layout_margin="8dp"
|
app:boxCornerRadiusBottomStart="12dp"
|
||||||
android:backgroundTint="#FF5722"
|
app:boxCornerRadiusBottomEnd="12dp"
|
||||||
android:textColor="#FFFFFF"/>
|
app:boxStrokeColor="#6D4C41"
|
||||||
|
android:hint="Description">
|
||||||
|
|
||||||
</GridLayout>
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:inputType="textMultiLine"
|
||||||
|
android:minLines="3"/>
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
<!-- Container for displaying current cow's images -->
|
<!-- Upload Photos -->
|
||||||
<LinearLayout
|
<TextView
|
||||||
android:id="@+id/currentCowImagesContainer"
|
android:id="@+id/tvUploadPhotos"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:text="Upload Photos"
|
||||||
android:padding="8dp"/>
|
android:textSize="18sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="#3E2723"
|
||||||
|
android:layout_marginBottom="16dp"/>
|
||||||
|
|
||||||
</LinearLayout>
|
<GridLayout
|
||||||
</ScrollView>
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:columnCount="2"
|
||||||
|
android:rowCount="3"
|
||||||
|
android:alignmentMode="alignMargins"
|
||||||
|
android:columnOrderPreserved="false"
|
||||||
|
android:layout_marginBottom="24dp">
|
||||||
|
|
||||||
|
<!-- Front View -->
|
||||||
|
<androidx.cardview.widget.CardView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="100dp"
|
||||||
|
android:layout_columnWeight="1"
|
||||||
|
android:layout_margin="8dp"
|
||||||
|
app:cardCornerRadius="8dp"
|
||||||
|
app:cardElevation="2dp">
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/btnFront"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:gravity="center"
|
||||||
|
android:background="#F5F5F5"
|
||||||
|
android:clickable="true"
|
||||||
|
android:focusable="true">
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:src="@android:drawable/ic_menu_camera"
|
||||||
|
app:tint="#5D4037"/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvFrontView"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Front View"
|
||||||
|
android:textSize="12sp"
|
||||||
|
android:textColor="#5D4037"
|
||||||
|
android:layout_marginTop="4dp"/>
|
||||||
|
</LinearLayout>
|
||||||
|
</androidx.cardview.widget.CardView>
|
||||||
|
|
||||||
|
<!-- Rear View (Back) -->
|
||||||
|
<androidx.cardview.widget.CardView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="100dp"
|
||||||
|
android:layout_columnWeight="1"
|
||||||
|
android:layout_margin="8dp"
|
||||||
|
app:cardCornerRadius="8dp"
|
||||||
|
app:cardElevation="2dp">
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/btnBack"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:gravity="center"
|
||||||
|
android:background="#F5F5F5"
|
||||||
|
android:clickable="true"
|
||||||
|
android:focusable="true">
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:src="@android:drawable/ic_menu_camera"
|
||||||
|
app:tint="#5D4037"/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvRearView"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Rear View"
|
||||||
|
android:textSize="12sp"
|
||||||
|
android:textColor="#5D4037"
|
||||||
|
android:layout_marginTop="4dp"/>
|
||||||
|
</LinearLayout>
|
||||||
|
</androidx.cardview.widget.CardView>
|
||||||
|
|
||||||
|
<!-- Left Side -->
|
||||||
|
<androidx.cardview.widget.CardView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="100dp"
|
||||||
|
android:layout_columnWeight="1"
|
||||||
|
android:layout_margin="8dp"
|
||||||
|
app:cardCornerRadius="8dp"
|
||||||
|
app:cardElevation="2dp">
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/btnLeft"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:gravity="center"
|
||||||
|
android:background="#F5F5F5"
|
||||||
|
android:clickable="true"
|
||||||
|
android:focusable="true">
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:src="@android:drawable/ic_menu_camera"
|
||||||
|
app:tint="#5D4037"/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvLeftSide"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Left Side"
|
||||||
|
android:textSize="12sp"
|
||||||
|
android:textColor="#5D4037"
|
||||||
|
android:layout_marginTop="4dp"/>
|
||||||
|
</LinearLayout>
|
||||||
|
</androidx.cardview.widget.CardView>
|
||||||
|
|
||||||
|
<!-- Right Side -->
|
||||||
|
<androidx.cardview.widget.CardView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="100dp"
|
||||||
|
android:layout_columnWeight="1"
|
||||||
|
android:layout_margin="8dp"
|
||||||
|
app:cardCornerRadius="8dp"
|
||||||
|
app:cardElevation="2dp">
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/btnRight"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:gravity="center"
|
||||||
|
android:background="#F5F5F5"
|
||||||
|
android:clickable="true"
|
||||||
|
android:focusable="true">
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:src="@android:drawable/ic_menu_camera"
|
||||||
|
app:tint="#5D4037"/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvRightSide"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Right Side"
|
||||||
|
android:textSize="12sp"
|
||||||
|
android:textColor="#5D4037"
|
||||||
|
android:layout_marginTop="4dp"/>
|
||||||
|
</LinearLayout>
|
||||||
|
</androidx.cardview.widget.CardView>
|
||||||
|
|
||||||
|
<!-- Angle View -->
|
||||||
|
<androidx.cardview.widget.CardView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="100dp"
|
||||||
|
android:layout_columnWeight="1"
|
||||||
|
android:layout_columnSpan="2"
|
||||||
|
android:layout_margin="8dp"
|
||||||
|
app:cardCornerRadius="8dp"
|
||||||
|
app:cardElevation="2dp">
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/btnTop"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:gravity="center"
|
||||||
|
android:background="#F5F5F5"
|
||||||
|
android:clickable="true"
|
||||||
|
android:focusable="true">
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:src="@android:drawable/ic_menu_camera"
|
||||||
|
app:tint="#5D4037"/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvAngleView"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Angle View"
|
||||||
|
android:textSize="12sp"
|
||||||
|
android:textColor="#5D4037"
|
||||||
|
android:layout_marginTop="4dp"/>
|
||||||
|
</LinearLayout>
|
||||||
|
</androidx.cardview.widget.CardView>
|
||||||
|
</GridLayout>
|
||||||
|
|
||||||
|
<!-- Container for showing captured thumbnails -->
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/currentCowImagesContainer"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_marginBottom="24dp"/>
|
||||||
|
|
||||||
|
<!-- Bottom Buttons -->
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/btnNewCow"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="56dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="Save Profile"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
app:cornerRadius="12dp"
|
||||||
|
app:backgroundTint="#6D4C41"
|
||||||
|
android:layout_marginEnd="8dp"/>
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/btnCancel"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="56dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="Cancel"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="#5D4037"
|
||||||
|
app:cornerRadius="12dp"
|
||||||
|
app:backgroundTint="#EFEBE9"
|
||||||
|
app:strokeColor="#5D4037"
|
||||||
|
app:strokeWidth="1dp"
|
||||||
|
android:layout_marginStart="8dp"/>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<!-- Hidden TextView for Cow Name logic compatibility -->
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvCowName"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:visibility="gone"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
</ScrollView>
|
||||||
|
</LinearLayout>
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<RelativeLayout 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_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:background="#000000">
|
android:background="#000000">
|
||||||
|
|
@ -12,13 +13,16 @@
|
||||||
android:scaleType="fitCenter"
|
android:scaleType="fitCenter"
|
||||||
android:contentDescription="Full Screen Image" />
|
android:contentDescription="Full Screen Image" />
|
||||||
|
|
||||||
<Button
|
<ImageButton
|
||||||
android:id="@+id/btnBack"
|
android:id="@+id/btnBack"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="48dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="48dp"
|
||||||
android:layout_alignParentBottom="true"
|
android:layout_alignParentStart="true"
|
||||||
android:layout_centerHorizontal="true"
|
android:layout_alignParentTop="true"
|
||||||
android:layout_marginBottom="32dp"
|
android:layout_margin="16dp"
|
||||||
android:text="Back" />
|
android:src="@drawable/ic_round_back_button"
|
||||||
|
android:background="@android:color/transparent"
|
||||||
|
android:scaleType="centerInside"
|
||||||
|
android:contentDescription="Back" />
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
@ -1,26 +1,101 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.coordinatorlayout.widget.CoordinatorLayout 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_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:background="#F5F5F5">
|
android:background="#F5F5F5">
|
||||||
|
|
||||||
<LinearLayout
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
android:id="@+id/galleryContainer"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:background="#FFFFFF"
|
||||||
android:padding="16dp">
|
app:elevation="0dp">
|
||||||
|
|
||||||
<TextView
|
<androidx.appcompat.widget.Toolbar
|
||||||
android:layout_width="wrap_content"
|
android:id="@+id/toolbar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="?attr/actionBarSize"
|
||||||
|
android:background="#FFFFFF"
|
||||||
|
app:navigationIcon="@drawable/ic_round_back_button">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Saved Cow Profiles"
|
||||||
|
android:textSize="20sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="#3E2723"/>
|
||||||
|
|
||||||
|
</androidx.appcompat.widget.Toolbar>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="Captured Images"
|
android:orientation="horizontal"
|
||||||
android:textSize="28sp"
|
android:paddingStart="16dp"
|
||||||
android:textStyle="bold"
|
android:paddingEnd="16dp"
|
||||||
android:textColor="#333333"
|
android:paddingBottom="16dp">
|
||||||
android:layout_gravity="center_horizontal"
|
|
||||||
android:layout_marginBottom="24dp"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
app:boxBackgroundColor="#F5F5F5"
|
||||||
|
app:boxCornerRadiusTopStart="24dp"
|
||||||
|
app:boxCornerRadiusTopEnd="24dp"
|
||||||
|
app:boxCornerRadiusBottomStart="24dp"
|
||||||
|
app:boxCornerRadiusBottomEnd="24dp"
|
||||||
|
app:boxStrokeWidth="0dp"
|
||||||
|
app:startIconDrawable="@android:drawable/ic_menu_search"
|
||||||
|
app:startIconTint="#8D6E63"
|
||||||
|
android:hint="Search profiles...">
|
||||||
|
|
||||||
</ScrollView>
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingTop="12dp"
|
||||||
|
android:paddingBottom="12dp"/>
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:layout_width="52dp"
|
||||||
|
android:layout_height="52dp"
|
||||||
|
android:layout_marginStart="12dp"
|
||||||
|
app:icon="@android:drawable/ic_menu_sort_by_size"
|
||||||
|
app:iconTint="#5D4037"
|
||||||
|
app:backgroundTint="#EFEBE9"
|
||||||
|
app:cornerRadius="12dp"
|
||||||
|
app:iconGravity="textStart"
|
||||||
|
app:iconPadding="0dp"
|
||||||
|
android:insetTop="0dp"
|
||||||
|
android:insetBottom="0dp"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
|
<androidx.core.widget.NestedScrollView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/galleryContainer"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="16dp"/>
|
||||||
|
|
||||||
|
</androidx.core.widget.NestedScrollView>
|
||||||
|
|
||||||
|
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||||
|
android:id="@+id/fabAddCow"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="bottom|end"
|
||||||
|
android:layout_margin="24dp"
|
||||||
|
app:srcCompat="@android:drawable/ic_input_add"
|
||||||
|
app:tint="#FFFFFF"
|
||||||
|
app:backgroundTint="#6D4C41"/>
|
||||||
|
|
||||||
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||||
|
|
@ -1,122 +1,198 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical"
|
android:background="#F7F7F7"
|
||||||
android:gravity="center"
|
android:fillViewport="true">
|
||||||
android:padding="16dp"
|
|
||||||
android:background="#F5F5F5">
|
|
||||||
|
|
||||||
<TextView
|
<LinearLayout
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Animal Rating"
|
|
||||||
android:textSize="32sp"
|
|
||||||
android:textStyle="bold"
|
|
||||||
android:textColor="#333333"
|
|
||||||
android:layout_marginBottom="32dp"/>
|
|
||||||
|
|
||||||
<androidx.cardview.widget.CardView
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginBottom="24dp"
|
android:orientation="vertical"
|
||||||
app:cardCornerRadius="12dp"
|
android:padding="24dp"
|
||||||
app:cardElevation="4dp"
|
android:gravity="center_horizontal">
|
||||||
app:contentPadding="16dp">
|
|
||||||
|
|
||||||
|
<!-- Language Selection (Top Right) -->
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="end"
|
||||||
|
android:layout_marginBottom="16dp">
|
||||||
|
|
||||||
|
<Spinner
|
||||||
|
android:id="@+id/spinnerLanguage"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:padding="8dp"
|
||||||
|
android:background="@drawable/bg_spinner_rounded"/>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<!-- Cow Illustration - Circular Logo -->
|
||||||
|
<androidx.cardview.widget.CardView
|
||||||
|
android:layout_width="180dp"
|
||||||
|
android:layout_height="180dp"
|
||||||
|
app:cardCornerRadius="90dp"
|
||||||
|
app:cardElevation="8dp"
|
||||||
|
app:cardBackgroundColor="#FFFFFF"
|
||||||
|
android:layout_marginBottom="24dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/ivCowIllustration"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:src="@drawable/cow_illustration_0"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
|
android:contentDescription="Cow Illustration"/>
|
||||||
|
</androidx.cardview.widget.CardView>
|
||||||
|
|
||||||
|
<!-- Title -->
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvTitle"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Cow Data Collector"
|
||||||
|
android:textSize="28sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="#3E2723"
|
||||||
|
android:textAlignment="center"
|
||||||
|
android:layout_marginBottom="8dp"/>
|
||||||
|
|
||||||
|
<!-- Subtitle -->
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvSubtitle"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Record and manage cow information easily."
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:textColor="#6D4C41"
|
||||||
|
android:textAlignment="center"
|
||||||
|
android:layout_marginBottom="40dp"/>
|
||||||
|
|
||||||
|
<!-- Main Buttons Container -->
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:gravity="center">
|
android:layout_marginBottom="32dp">
|
||||||
|
|
||||||
<TextView
|
<!-- Add New Cow Profile Button -->
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/btnSelectCow"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="72dp"
|
||||||
android:text="Settings"
|
android:text="Add New Cow Profile"
|
||||||
|
android:textSize="18sp"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
android:layout_marginBottom="8dp"/>
|
app:cornerRadius="16dp"
|
||||||
|
app:backgroundTint="#6D4C41"
|
||||||
<LinearLayout
|
app:icon="@android:drawable/ic_input_add"
|
||||||
|
app:iconGravity="textStart"
|
||||||
|
app:iconPadding="12dp"
|
||||||
|
android:layout_marginBottom="16dp"
|
||||||
|
android:elevation="4dp"/>
|
||||||
|
|
||||||
|
<!-- View Saved Profiles Button -->
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/btnViewGallery"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="72dp"
|
||||||
android:orientation="horizontal"
|
android:text="View Saved Profiles"
|
||||||
android:layout_marginBottom="8dp">
|
android:textSize="18sp"
|
||||||
|
android:textStyle="bold"
|
||||||
<TextView
|
android:textColor="#5D4037"
|
||||||
android:layout_width="wrap_content"
|
app:cornerRadius="16dp"
|
||||||
android:layout_height="wrap_content"
|
app:backgroundTint="#EFEBE9"
|
||||||
android:text="Algorithm:"
|
app:strokeColor="#5D4037"
|
||||||
android:layout_marginEnd="8dp"/>
|
app:strokeWidth="1dp"
|
||||||
|
app:icon="@android:drawable/ic_menu_gallery"
|
||||||
<Spinner
|
app:iconTint="#5D4037"
|
||||||
android:id="@+id/spinnerAlgorithm"
|
app:iconGravity="textStart"
|
||||||
android:layout_width="0dp"
|
app:iconPadding="12dp"
|
||||||
android:layout_height="wrap_content"
|
android:elevation="4dp"/>
|
||||||
android:layout_weight="1"/>
|
</LinearLayout>
|
||||||
</LinearLayout>
|
|
||||||
|
<!-- Settings Card -->
|
||||||
|
<androidx.cardview.widget.CardView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:cardCornerRadius="16dp"
|
||||||
|
app:cardElevation="2dp"
|
||||||
|
app:cardBackgroundColor="#FFFFFF"
|
||||||
|
android:layout_marginBottom="24dp">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:layout_marginBottom="16dp">
|
android:padding="20dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Settings"
|
||||||
|
android:textSize="18sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="#3E2723"
|
||||||
|
android:layout_marginBottom="16dp"/>
|
||||||
|
|
||||||
|
<!-- Algorithm Selection -->
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvAlgorithmLabel"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Algorithm"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:textColor="#5D4037"
|
||||||
|
android:layout_marginBottom="8dp"/>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@drawable/bg_spinner_rounded"
|
||||||
|
android:padding="4dp"
|
||||||
|
android:layout_marginBottom="20dp">
|
||||||
|
<Spinner
|
||||||
|
android:id="@+id/spinnerAlgorithm"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="48dp"/>
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
<!-- Threshold Slider -->
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:gravity="center_vertical">
|
android:gravity="center_vertical"
|
||||||
|
android:layout_marginBottom="8dp">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:id="@+id/tvThresholdLabel"
|
||||||
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="Threshold: "/>
|
android:layout_weight="1"
|
||||||
|
android:text="Match Threshold"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:textColor="#5D4037"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/tvThresholdValue"
|
android:id="@+id/tvThresholdValue"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="75%"/>
|
android:text="75%"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="#3E2723"/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<SeekBar
|
<SeekBar
|
||||||
android:id="@+id/seekBarThreshold"
|
android:id="@+id/seekBarThreshold"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:max="100"
|
android:max="100"
|
||||||
android:progress="75"/>
|
android:progressTint="#6D4C41"
|
||||||
|
android:thumbTint="#6D4C41"/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
</androidx.cardview.widget.CardView>
|
||||||
|
|
||||||
<TextView
|
</LinearLayout>
|
||||||
android:layout_width="wrap_content"
|
</ScrollView>
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Start New Rating"
|
|
||||||
android:textSize="18sp"
|
|
||||||
android:textColor="#666666"
|
|
||||||
android:layout_marginBottom="16dp"/>
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/btnSelectCow"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Select Cow"
|
|
||||||
android:textSize="16sp"
|
|
||||||
android:padding="12dp"
|
|
||||||
android:backgroundTint="#FF5722"
|
|
||||||
android:textColor="#FFFFFF"/>
|
|
||||||
</LinearLayout>
|
|
||||||
</androidx.cardview.widget.CardView>
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/btnViewGallery"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="View Collected Images"
|
|
||||||
android:textSize="16sp"
|
|
||||||
android:padding="12dp"
|
|
||||||
android:backgroundTint="#2196F3"
|
|
||||||
android:textColor="#FFFFFF"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<FrameLayout 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_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
|
@ -28,5 +29,26 @@
|
||||||
android:scaleType="centerCrop"
|
android:scaleType="centerCrop"
|
||||||
android:alpha="0.9"
|
android:alpha="0.9"
|
||||||
android:elevation="10dp"/>
|
android:elevation="10dp"/>
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/btnExit"
|
||||||
|
android:layout_width="48dp"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:layout_gravity="top|start"
|
||||||
|
android:layout_margin="16dp"
|
||||||
|
style="@style/Widget.MaterialComponents.Button.Icon"
|
||||||
|
app:icon="@drawable/ic_back_arrow"
|
||||||
|
app:iconSize="24dp"
|
||||||
|
app:iconTint="#FFFFFF"
|
||||||
|
app:backgroundTint="#80000000"
|
||||||
|
app:cornerRadius="24dp"
|
||||||
|
android:padding="0dp"
|
||||||
|
android:insetLeft="0dp"
|
||||||
|
android:insetTop="0dp"
|
||||||
|
android:insetRight="0dp"
|
||||||
|
android:insetBottom="0dp"
|
||||||
|
app:iconGravity="textStart"
|
||||||
|
app:iconPadding="0dp"
|
||||||
|
android:gravity="center"/>
|
||||||
|
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="4dp">
|
||||||
|
|
||||||
|
<androidx.cardview.widget.CardView
|
||||||
|
android:layout_width="100dp"
|
||||||
|
android:layout_height="100dp"
|
||||||
|
app:cardCornerRadius="8dp"
|
||||||
|
app:cardElevation="2dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/ivThumbnail"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
|
android:background="#E0E0E0"/>
|
||||||
|
|
||||||
|
</androidx.cardview.widget.CardView>
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/btnDelete"
|
||||||
|
style="@style/Widget.MaterialComponents.Button.Icon"
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:layout_gravity="top|end"
|
||||||
|
android:layout_margin="4dp"
|
||||||
|
app:icon="@android:drawable/ic_delete"
|
||||||
|
app:iconSize="14dp"
|
||||||
|
app:iconTint="#FFFFFF"
|
||||||
|
android:backgroundTint="#C62828"
|
||||||
|
app:cornerRadius="12dp"
|
||||||
|
android:padding="0dp"
|
||||||
|
android:insetLeft="0dp"
|
||||||
|
android:insetTop="0dp"
|
||||||
|
android:insetRight="0dp"
|
||||||
|
android:insetBottom="0dp"
|
||||||
|
app:iconGravity="textStart"
|
||||||
|
app:iconPadding="0dp"
|
||||||
|
android:gravity="center"/>
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
|
@ -0,0 +1,118 @@
|
||||||
|
{
|
||||||
|
"English": {
|
||||||
|
"app_name": "Animal Rating",
|
||||||
|
"title_home": "Animal Rating",
|
||||||
|
"title_gallery": "Saved Cow Profiles",
|
||||||
|
"title_add_cow_details": "Add Cow Details",
|
||||||
|
"title_cow_selection": "Cow Selection",
|
||||||
|
"btn_view_gallery": "View Saved Cow Profiles",
|
||||||
|
"btn_select_cow": "Select a Cow",
|
||||||
|
"label_algorithm": "Algorithm",
|
||||||
|
"label_match_threshold": "Match Threshold",
|
||||||
|
"btn_edit": "Edit",
|
||||||
|
"hint_search_profiles": "Search profiles...",
|
||||||
|
"toast_image_deleted": "Image deleted",
|
||||||
|
"toast_error_deleting_image": "Error deleting image",
|
||||||
|
"text_cow_id": "Cow ID:",
|
||||||
|
"label_species": "Species:",
|
||||||
|
"label_breed": "Breed:",
|
||||||
|
"label_age": "Age:",
|
||||||
|
"unit_years": "years",
|
||||||
|
"label_milk_yield": "Milk Yield:",
|
||||||
|
"unit_liters": "L",
|
||||||
|
"label_calving_no": "Calving #:",
|
||||||
|
"label_status": "Status:",
|
||||||
|
"hint_species": "Species",
|
||||||
|
"hint_breed": "Breed",
|
||||||
|
"hint_age": "Age (Years)",
|
||||||
|
"hint_milk_yield": "Milk Yield (L)",
|
||||||
|
"hint_calving_number": "Calving Number",
|
||||||
|
"label_reproductive_status": "Reproductive Status",
|
||||||
|
"radio_pregnant": "Pregnant",
|
||||||
|
"radio_calved": "Calved",
|
||||||
|
"radio_none": "None",
|
||||||
|
"hint_description": "Description",
|
||||||
|
"label_upload_photos": "Upload Photos",
|
||||||
|
"text_front_view": "Front View",
|
||||||
|
"text_rear_view": "Rear View",
|
||||||
|
"text_left_side": "Left Side",
|
||||||
|
"text_right_side": "Right Side",
|
||||||
|
"text_angle_view": "Angle View",
|
||||||
|
"btn_save_profile": "Save Profile",
|
||||||
|
"btn_cancel": "Cancel",
|
||||||
|
"toast_profile_saved": "Profile Saved!",
|
||||||
|
"toast_error_saving_profile": "Error saving profile:",
|
||||||
|
"toast_capture_failed": "Photo capture failed",
|
||||||
|
"toast_saved_as": "Saved as",
|
||||||
|
"toast_error_saving_image": "Error saving image",
|
||||||
|
"content_desc_back": "Back",
|
||||||
|
"content_desc_full_screen_image": "Full Screen Image",
|
||||||
|
"species_cow": "Cow",
|
||||||
|
"species_buffalo": "Buffalo",
|
||||||
|
"breed_holstein": "Holstein Friesian",
|
||||||
|
"breed_jersey": "Jersey",
|
||||||
|
"breed_sahiwal": "Sahiwal",
|
||||||
|
"breed_gir": "Gir",
|
||||||
|
"breed_red_sindhi": "Red Sindhi",
|
||||||
|
"breed_murrah": "Murrah",
|
||||||
|
"breed_surti": "Surti"
|
||||||
|
},
|
||||||
|
"Hindi": {
|
||||||
|
"app_name": "पशु रेटिंग",
|
||||||
|
"title_home": "पशु रेटिंग",
|
||||||
|
"title_gallery": "सहेजे गए गाय प्रोफाइल",
|
||||||
|
"title_add_cow_details": "गाय का विवरण जोड़ें",
|
||||||
|
"title_cow_selection": "गाय का चयन",
|
||||||
|
"btn_view_gallery": "सहेजे गए प्रोफाइल देखें",
|
||||||
|
"btn_select_cow": "एक गाय का चयन करें",
|
||||||
|
"label_algorithm": "एल्गोरिदम",
|
||||||
|
"label_match_threshold": "मैच थ्रेसहोल्ड",
|
||||||
|
"btn_edit": "संपादित करें",
|
||||||
|
"hint_search_profiles": "प्रोफ़ाइल खोजें...",
|
||||||
|
"toast_image_deleted": "छवि हटा दी गई",
|
||||||
|
"toast_error_deleting_image": "छवि हटाने में त्रुटि",
|
||||||
|
"text_cow_id": "गाय आईडी:",
|
||||||
|
"label_species": "प्रजाति:",
|
||||||
|
"label_breed": "नस्ल:",
|
||||||
|
"label_age": "आयु:",
|
||||||
|
"unit_years": "वर्ष",
|
||||||
|
"label_milk_yield": "दूध की उपज:",
|
||||||
|
"unit_liters": "L",
|
||||||
|
"label_calving_no": "बछड़ों की संख्या:",
|
||||||
|
"label_status": "स्थिति:",
|
||||||
|
"hint_species": "प्रजाति",
|
||||||
|
"hint_breed": "नस्ल",
|
||||||
|
"hint_age": "आयु (वर्ष)",
|
||||||
|
"hint_milk_yield": "दूध की उपज (L)",
|
||||||
|
"hint_calving_number": "बछड़ों की संख्या",
|
||||||
|
"label_reproductive_status": "प्रजनन स्थिति",
|
||||||
|
"radio_pregnant": "गर्भवती",
|
||||||
|
"radio_calved": "बछड़ा हुआ",
|
||||||
|
"radio_none": "कोई नहीं",
|
||||||
|
"hint_description": "विवरण",
|
||||||
|
"label_upload_photos": "तस्वीरें अपलोड करें",
|
||||||
|
"text_front_view": "सामने का दृश्य",
|
||||||
|
"text_rear_view": "पीछे का दृश्य",
|
||||||
|
"text_left_side": "बाईं ओर",
|
||||||
|
"text_right_side": "दाईं ओर",
|
||||||
|
"text_angle_view": "कोणीय दृश्य",
|
||||||
|
"btn_save_profile": "प्रोफ़ाइल सहेजें",
|
||||||
|
"btn_cancel": "रद्द करें",
|
||||||
|
"toast_profile_saved": "प्रोफ़ाइल सहेजा गया!",
|
||||||
|
"toast_error_saving_profile": "प्रोफ़ाइल सहेजने में त्रुटि:",
|
||||||
|
"toast_capture_failed": "फोटो कैप्चर विफल",
|
||||||
|
"toast_saved_as": "के रूप में सहेजा गया",
|
||||||
|
"toast_error_saving_image": "छवि सहेजने में त्रुटि",
|
||||||
|
"content_desc_back": "वापस",
|
||||||
|
"content_desc_full_screen_image": "पूर्ण स्क्रीन छवि",
|
||||||
|
"species_cow": "गाय",
|
||||||
|
"species_buffalo": "भैंस",
|
||||||
|
"breed_holstein": "होल्सटीन फ्राइज़ियन",
|
||||||
|
"breed_jersey": "जर्सी",
|
||||||
|
"breed_sahiwal": "साहिवाल",
|
||||||
|
"breed_gir": "गिर",
|
||||||
|
"breed_red_sindhi": "लाल सिंधी",
|
||||||
|
"breed_murrah": "मुर्रा",
|
||||||
|
"breed_surti": "सुरती"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,17 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
|
|
||||||
<style name="Theme.AnimalRating" parent="Theme.AppCompat.Light.NoActionBar" />
|
<style name="Theme.AnimalRating" parent="Theme.MaterialComponents.DayNight.NoActionBar">
|
||||||
|
<!-- Primary brand color. -->
|
||||||
|
<item name="colorPrimary">#6D4C41</item>
|
||||||
|
<item name="colorPrimaryVariant">#5D4037</item>
|
||||||
|
<item name="colorOnPrimary">#FFFFFF</item>
|
||||||
|
<!-- Secondary brand color. -->
|
||||||
|
<item name="colorSecondary">#FF5722</item>
|
||||||
|
<item name="colorSecondaryVariant">#E64A19</item>
|
||||||
|
<item name="colorOnSecondary">#FFFFFF</item>
|
||||||
|
<!-- Status bar color. -->
|
||||||
|
<item name="android:statusBarColor">?attr/colorPrimaryVariant</item>
|
||||||
|
<!-- Customize your theme here. -->
|
||||||
|
</style>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
Adobe Stock - https://stock.adobe.com/
|
||||||
Loading…
Reference in New Issue