some refactor, renaming, started working with product on shelf
This commit is contained in:
parent
926403f9ea
commit
3bfad0f6ad
|
@ -46,6 +46,8 @@ dependencies {
|
||||||
implementation(libs.firebase.crashlytics.buildtools)
|
implementation(libs.firebase.crashlytics.buildtools)
|
||||||
implementation(libs.androidx.gridlayout)
|
implementation(libs.androidx.gridlayout)
|
||||||
implementation(libs.androidx.activity)
|
implementation(libs.androidx.activity)
|
||||||
|
implementation(libs.androidx.legacy.support.v4)
|
||||||
|
implementation(libs.androidx.fragment)
|
||||||
testImplementation(libs.junit)
|
testImplementation(libs.junit)
|
||||||
androidTestImplementation(libs.androidx.junit)
|
androidTestImplementation(libs.androidx.junit)
|
||||||
androidTestImplementation(libs.androidx.espresso.core)
|
androidTestImplementation(libs.androidx.espresso.core)
|
||||||
|
|
|
@ -31,6 +31,10 @@
|
||||||
android:name=".activities.AddProductActivity"
|
android:name=".activities.AddProductActivity"
|
||||||
android:exported="false"
|
android:exported="false"
|
||||||
android:theme="@style/Theme.BarcodeScannerForEmployees"/>
|
android:theme="@style/Theme.BarcodeScannerForEmployees"/>
|
||||||
|
<activity
|
||||||
|
android:name=".activities.AddAbstractProductActivity"
|
||||||
|
android:exported="false"
|
||||||
|
android:theme="@style/Theme.BarcodeScannerForEmployees"/>
|
||||||
<activity
|
<activity
|
||||||
android:name=".activities.FullscreenActivity"
|
android:name=".activities.FullscreenActivity"
|
||||||
android:configChanges="orientation|keyboardHidden|screenSize"
|
android:configChanges="orientation|keyboardHidden|screenSize"
|
||||||
|
@ -40,7 +44,7 @@
|
||||||
|
|
||||||
<provider
|
<provider
|
||||||
android:name="androidx.core.content.FileProvider"
|
android:name="androidx.core.content.FileProvider"
|
||||||
android:authorities="com.google.firebase.components.activities.MainActivity.provider;com.google.firebase.components.activities.FullscreenActivity.provider;com.google.firebase.components.activities.AddProductActivity.provider"
|
android:authorities="com.google.firebase.components.activities.MainActivity.provider;com.google.firebase.components.activities.FullscreenActivity.provider;com.google.firebase.components.activities.AddAbstractProductActivity.provider"
|
||||||
android:exported="false"
|
android:exported="false"
|
||||||
android:grantUriPermissions="true">
|
android:grantUriPermissions="true">
|
||||||
<meta-data
|
<meta-data
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
package org.foxarmy.barcodescannerforemployees
|
|
||||||
|
|
||||||
class Category(
|
|
||||||
public var id: Int,
|
|
||||||
public var name: String,
|
|
||||||
) {
|
|
||||||
|
|
||||||
}
|
|
|
@ -5,11 +5,12 @@ import android.database.DatabaseUtils
|
||||||
import android.database.sqlite.SQLiteDatabase
|
import android.database.sqlite.SQLiteDatabase
|
||||||
import android.database.sqlite.SQLiteOpenHelper
|
import android.database.sqlite.SQLiteOpenHelper
|
||||||
import android.provider.BaseColumns
|
import android.provider.BaseColumns
|
||||||
|
import org.foxarmy.barcodescannerforemployees.dataclasses.AbstractProduct
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
object ProductContract {
|
object AbstractProductContract {
|
||||||
object ProductEntry : BaseColumns {
|
object AbstractProductEntry : BaseColumns {
|
||||||
const val TABLE_NAME = "products"
|
const val TABLE_NAME = "abstract_products"
|
||||||
const val PRODUCT_NAME = "name"
|
const val PRODUCT_NAME = "name"
|
||||||
const val PRODUCT_NET_WEIGHT = "net_weight"
|
const val PRODUCT_NET_WEIGHT = "net_weight"
|
||||||
const val IMAGE_FILENAME = "image_filename"
|
const val IMAGE_FILENAME = "image_filename"
|
||||||
|
@ -17,14 +18,6 @@ object ProductContract {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object ShelfContract {
|
|
||||||
object ShelfEntry : BaseColumns {
|
|
||||||
const val TABLE_NAME = "shelf"
|
|
||||||
const val PRODUCT_ID = "product_id"
|
|
||||||
const val EXPIRE_DATE = "expire_date"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
object CategoriesContract {
|
object CategoriesContract {
|
||||||
object CategoryEntry : BaseColumns {
|
object CategoryEntry : BaseColumns {
|
||||||
const val TABLE_NAME = "categories"
|
const val TABLE_NAME = "categories"
|
||||||
|
@ -32,19 +25,31 @@ object CategoriesContract {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const val SQL_CREATE_PRODUCT_TABLE =
|
object ProductContract {
|
||||||
|
object ProductEntry : BaseColumns {
|
||||||
|
const val TABLE_NAME = "products"
|
||||||
|
const val ABSTRACT_PRODUCT_ID = "abstract_product_id"
|
||||||
|
const val AMOUNT = "amount"
|
||||||
|
const val DATE_OF_PRODUCTION = "date_of_production"
|
||||||
|
const val EXPIRY_DATE = "expiry_date"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const val SQL_CREATE_ABSTRACT_PRODUCTS_TABLE =
|
||||||
|
"CREATE TABLE ${AbstractProductContract.AbstractProductEntry.TABLE_NAME} (" +
|
||||||
|
"${BaseColumns._ID} INTEGER PRIMARY KEY," +
|
||||||
|
"${AbstractProductContract.AbstractProductEntry.PRODUCT_NAME} TEXT," +
|
||||||
|
"${AbstractProductContract.AbstractProductEntry.PRODUCT_NET_WEIGHT} REAL," +
|
||||||
|
"${AbstractProductContract.AbstractProductEntry.IMAGE_FILENAME} TEXT," +
|
||||||
|
"${AbstractProductContract.AbstractProductEntry.CATEGORY} INTEGER)"
|
||||||
|
|
||||||
|
const val SQL_CREATE_PRODUCTS_TABLE =
|
||||||
"CREATE TABLE ${ProductContract.ProductEntry.TABLE_NAME} (" +
|
"CREATE TABLE ${ProductContract.ProductEntry.TABLE_NAME} (" +
|
||||||
"${BaseColumns._ID} INTEGER PRIMARY KEY," +
|
"${BaseColumns._ID} INTEGER PRIMARY KEY," +
|
||||||
"${ProductContract.ProductEntry.PRODUCT_NAME} TEXT," +
|
"${ProductContract.ProductEntry.ABSTRACT_PRODUCT_ID} INTEGER," +
|
||||||
"${ProductContract.ProductEntry.PRODUCT_NET_WEIGHT} REAL," +
|
"${ProductContract.ProductEntry.AMOUNT} INTEGER," +
|
||||||
"${ProductContract.ProductEntry.IMAGE_FILENAME} TEXT," +
|
"${ProductContract.ProductEntry.DATE_OF_PRODUCTION} DATE," +
|
||||||
"${ProductContract.ProductEntry.CATEGORY} INTEGER)"
|
"${ProductContract.ProductEntry.EXPIRY_DATE} DATE)"
|
||||||
|
|
||||||
const val SQL_CREATE_SHELF_TABLE =
|
|
||||||
"CREATE TABLE ${ShelfContract.ShelfEntry.TABLE_NAME} (" +
|
|
||||||
"${BaseColumns._ID} INTEGER PRIMARY KEY," +
|
|
||||||
"${ShelfContract.ShelfEntry.PRODUCT_ID} INTEGER," +
|
|
||||||
"${ShelfContract.ShelfEntry.EXPIRE_DATE} DATE)"
|
|
||||||
|
|
||||||
const val SQL_CREATE_CATEGORIES_TABLE =
|
const val SQL_CREATE_CATEGORIES_TABLE =
|
||||||
"CREATE TABLE ${CategoriesContract.CategoryEntry.TABLE_NAME} (" +
|
"CREATE TABLE ${CategoriesContract.CategoryEntry.TABLE_NAME} (" +
|
||||||
|
@ -54,8 +59,8 @@ const val SQL_CREATE_CATEGORIES_TABLE =
|
||||||
class DBStorageController(context: Context) : SQLiteOpenHelper(context, DATABASE_NAME, null, DATABASE_VERSION) {
|
class DBStorageController(context: Context) : SQLiteOpenHelper(context, DATABASE_NAME, null, DATABASE_VERSION) {
|
||||||
|
|
||||||
override fun onCreate(db: SQLiteDatabase) {
|
override fun onCreate(db: SQLiteDatabase) {
|
||||||
db.execSQL(SQL_CREATE_PRODUCT_TABLE)
|
db.execSQL(SQL_CREATE_ABSTRACT_PRODUCTS_TABLE)
|
||||||
db.execSQL(SQL_CREATE_SHELF_TABLE)
|
db.execSQL(SQL_CREATE_PRODUCTS_TABLE)
|
||||||
db.execSQL(SQL_CREATE_CATEGORIES_TABLE)
|
db.execSQL(SQL_CREATE_CATEGORIES_TABLE)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,22 +101,22 @@ class DBStorageController(context: Context) : SQLiteOpenHelper(context, DATABASE
|
||||||
var result = mutableListOf<AbstractProduct>()
|
var result = mutableListOf<AbstractProduct>()
|
||||||
val projection = arrayOf(
|
val projection = arrayOf(
|
||||||
BaseColumns._ID,
|
BaseColumns._ID,
|
||||||
ProductContract.ProductEntry.PRODUCT_NAME,
|
AbstractProductContract.AbstractProductEntry.PRODUCT_NAME,
|
||||||
ProductContract.ProductEntry.IMAGE_FILENAME,
|
AbstractProductContract.AbstractProductEntry.IMAGE_FILENAME,
|
||||||
ProductContract.ProductEntry.PRODUCT_NET_WEIGHT,
|
AbstractProductContract.AbstractProductEntry.PRODUCT_NET_WEIGHT,
|
||||||
)
|
)
|
||||||
|
|
||||||
val selection = "${ProductContract.ProductEntry.CATEGORY} = ?"
|
val selection = "${AbstractProductContract.AbstractProductEntry.CATEGORY} = ?"
|
||||||
val selectionArgs = arrayOf(id.toString())
|
val selectionArgs = arrayOf(id.toString())
|
||||||
|
|
||||||
val cursor = db.query(ProductContract.ProductEntry.TABLE_NAME, projection, selection, selectionArgs, null, null, null)
|
val cursor = db.query(AbstractProductContract.AbstractProductEntry.TABLE_NAME, projection, selection, selectionArgs, null, null, null)
|
||||||
|
|
||||||
with(cursor) {
|
with(cursor) {
|
||||||
while (moveToNext()) {
|
while (moveToNext()) {
|
||||||
val abstractProductId = getInt(getColumnIndexOrThrow(BaseColumns._ID))
|
val abstractProductId = getInt(getColumnIndexOrThrow(BaseColumns._ID))
|
||||||
val abstractProductName = getString(getColumnIndexOrThrow(ProductContract.ProductEntry.PRODUCT_NAME))
|
val abstractProductName = getString(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.PRODUCT_NAME))
|
||||||
val abstractProductNetWeight = getDouble(getColumnIndexOrThrow(ProductContract.ProductEntry.PRODUCT_NET_WEIGHT))
|
val abstractProductNetWeight = getDouble(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.PRODUCT_NET_WEIGHT))
|
||||||
val abstractProductImageHash = getString(getColumnIndexOrThrow(ProductContract.ProductEntry.IMAGE_FILENAME))
|
val abstractProductImageHash = getString(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.IMAGE_FILENAME))
|
||||||
|
|
||||||
val abstractProduct = AbstractProduct(abstractProductId, abstractProductName, abstractProductNetWeight, abstractProductImageHash, category = id)
|
val abstractProduct = AbstractProduct(abstractProductId, abstractProductName, abstractProductNetWeight, abstractProductImageHash, category = id)
|
||||||
|
|
||||||
|
@ -123,17 +128,17 @@ class DBStorageController(context: Context) : SQLiteOpenHelper(context, DATABASE
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getAmountOfAbstractProductsInCategory(db:SQLiteDatabase, id: Int) : Int {
|
fun getAmountOfAbstractProductsInCategory(db:SQLiteDatabase, id: Int) : Int {
|
||||||
return DatabaseUtils.longForQuery(db, "SELECT COUNT(*) FROM ${ProductContract.ProductEntry.TABLE_NAME} WHERE ${ProductContract.ProductEntry.CATEGORY} = ?", arrayOf(id.toString())).toInt()
|
return DatabaseUtils.longForQuery(db, "SELECT COUNT(*) FROM ${AbstractProductContract.AbstractProductEntry.TABLE_NAME} WHERE ${AbstractProductContract.AbstractProductEntry.CATEGORY} = ?", arrayOf(id.toString())).toInt()
|
||||||
}
|
}
|
||||||
fun eraseAbstractProduct(db: SQLiteDatabase, id: Int, context: Context) {
|
fun eraseAbstractProduct(db: SQLiteDatabase, id: Int, context: Context) {
|
||||||
val projection = arrayOf(
|
val projection = arrayOf(
|
||||||
ProductContract.ProductEntry.IMAGE_FILENAME
|
AbstractProductContract.AbstractProductEntry.IMAGE_FILENAME
|
||||||
)
|
)
|
||||||
|
|
||||||
val selection = "${BaseColumns._ID} = ?"
|
val selection = "${BaseColumns._ID} = ?"
|
||||||
val selectionArgs = arrayOf(id.toString())
|
val selectionArgs = arrayOf(id.toString())
|
||||||
val cursor = db.query(
|
val cursor = db.query(
|
||||||
ProductContract.ProductEntry.TABLE_NAME,
|
AbstractProductContract.AbstractProductEntry.TABLE_NAME,
|
||||||
projection,
|
projection,
|
||||||
selection,
|
selection,
|
||||||
selectionArgs,
|
selectionArgs,
|
||||||
|
@ -145,7 +150,7 @@ class DBStorageController(context: Context) : SQLiteOpenHelper(context, DATABASE
|
||||||
|
|
||||||
with (cursor) {
|
with (cursor) {
|
||||||
while(moveToNext()) {
|
while(moveToNext()) {
|
||||||
val productImageHash = getString(getColumnIndexOrThrow(ProductContract.ProductEntry.IMAGE_FILENAME))
|
val productImageHash = getString(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.IMAGE_FILENAME))
|
||||||
imageHash = productImageHash
|
imageHash = productImageHash
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -154,7 +159,7 @@ class DBStorageController(context: Context) : SQLiteOpenHelper(context, DATABASE
|
||||||
|
|
||||||
File(picturesDir, "$imageHash.png").delete()
|
File(picturesDir, "$imageHash.png").delete()
|
||||||
File(thumbnailsDir, "$imageHash.webp").delete()
|
File(thumbnailsDir, "$imageHash.webp").delete()
|
||||||
db.delete(ProductContract.ProductEntry.TABLE_NAME, BaseColumns._ID + "=" + id, null)
|
db.delete(AbstractProductContract.AbstractProductEntry.TABLE_NAME, BaseColumns._ID + "=" + id, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package org.foxarmy.barcodescannerforemployees
|
package org.foxarmy.barcodescannerforemployees
|
||||||
|
|
||||||
|
import org.foxarmy.barcodescannerforemployees.dataclasses.AbstractProduct
|
||||||
|
|
||||||
class Parser constructor(payloadStartRegex: String, payloadEndRegex: String, payloadRegex: String){
|
class Parser constructor(payloadStartRegex: String, payloadEndRegex: String, payloadRegex: String){
|
||||||
val payloadStartRegex: String = payloadStartRegex
|
val payloadStartRegex: String = payloadStartRegex
|
||||||
val payloadEndRegex: String = payloadEndRegex
|
val payloadEndRegex: String = payloadEndRegex
|
||||||
|
|
|
@ -0,0 +1,194 @@
|
||||||
|
package org.foxarmy.barcodescannerforemployees.activities
|
||||||
|
|
||||||
|
import android.Manifest
|
||||||
|
import android.content.ContentValues
|
||||||
|
import android.os.Build
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.provider.BaseColumns
|
||||||
|
import android.util.Log
|
||||||
|
import android.widget.*
|
||||||
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
|
import androidx.annotation.RequiresApi
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import com.google.mlkit.vision.barcode.common.Barcode
|
||||||
|
import com.google.mlkit.vision.codescanner.GmsBarcodeScannerOptions
|
||||||
|
import com.google.mlkit.vision.codescanner.GmsBarcodeScanning
|
||||||
|
import org.foxarmy.barcodescannerforemployees.*
|
||||||
|
import org.foxarmy.barcodescannerforemployees.dataclasses.AbstractProduct
|
||||||
|
import java.io.File
|
||||||
|
import java.nio.file.Files
|
||||||
|
import java.nio.file.StandardCopyOption
|
||||||
|
|
||||||
|
class AddAbstractProductActivity : AppCompatActivity() {
|
||||||
|
private lateinit var imageView: ImageView
|
||||||
|
|
||||||
|
private lateinit var saveButton: Button
|
||||||
|
private lateinit var takePictureButton: Button
|
||||||
|
private lateinit var scanButton: Button
|
||||||
|
|
||||||
|
private lateinit var productNameText: TextView
|
||||||
|
private lateinit var netWeightText: TextView
|
||||||
|
|
||||||
|
private lateinit var categorySpinner: Spinner
|
||||||
|
|
||||||
|
private var abstractProduct: AbstractProduct? = null
|
||||||
|
private lateinit var pictureFile: File
|
||||||
|
private lateinit var picturesPath: File
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
|
setContentView(R.layout.fragment_add_abstract_product)
|
||||||
|
|
||||||
|
val extras = intent.extras
|
||||||
|
abstractProduct = extras!!.get("abstractProduct") as AbstractProduct?
|
||||||
|
|
||||||
|
picturesPath = File(filesDir, "pictures")
|
||||||
|
val thumbnailsDir = File(cacheDir, "thumbnails")
|
||||||
|
thumbnailsDir.mkdirs()
|
||||||
|
picturesPath.mkdirs()
|
||||||
|
imageView = findViewById(R.id.imageView)
|
||||||
|
|
||||||
|
saveButton = findViewById(R.id.saveButton)
|
||||||
|
takePictureButton = findViewById(R.id.takePictureButton)
|
||||||
|
scanButton = findViewById(R.id.scan_button)
|
||||||
|
|
||||||
|
productNameText = findViewById(R.id.productName)
|
||||||
|
netWeightText = findViewById(R.id.netWeight)
|
||||||
|
|
||||||
|
categorySpinner = findViewById(R.id.categorySpinner)
|
||||||
|
|
||||||
|
fillupCategorySpinner()
|
||||||
|
|
||||||
|
if (abstractProduct != null) {
|
||||||
|
val imageThumbnailUri = getImageUri(this, File(thumbnailsDir, "${abstractProduct!!.imageHash}.webp"))
|
||||||
|
pictureFile = File(picturesPath, "${abstractProduct!!.imageHash}.png]")
|
||||||
|
imageView.setImageURI(imageThumbnailUri)
|
||||||
|
imageView.rotation = 90f
|
||||||
|
productNameText.text = abstractProduct!!.name
|
||||||
|
netWeightText.text = abstractProduct!!.netWeight.toString()
|
||||||
|
categorySpinner.setSelection(abstractProduct!!.category)
|
||||||
|
}
|
||||||
|
|
||||||
|
saveButton.setOnClickListener {
|
||||||
|
val productName = productNameText.text.toString()
|
||||||
|
val netWeight = netWeightText.text
|
||||||
|
if (!this::pictureFile.isInitialized && !pictureFile.exists()) {
|
||||||
|
|
||||||
|
Toast.makeText(this, "Please, make a picture of a product!", Toast.LENGTH_SHORT).show()
|
||||||
|
return@setOnClickListener
|
||||||
|
}
|
||||||
|
|
||||||
|
if (productName == "") {
|
||||||
|
Toast.makeText(this, "Please, write a name of a product!", Toast.LENGTH_SHORT).show()
|
||||||
|
return@setOnClickListener
|
||||||
|
}
|
||||||
|
if (netWeight.toString() == "" || netWeight.toString().toDoubleOrNull() == null) {
|
||||||
|
Toast.makeText(this, "Please, write a valid net weight of a product!", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
|
||||||
|
val db = DBStorageController(this).writableDatabase
|
||||||
|
val values = ContentValues().apply {
|
||||||
|
put(AbstractProductContract.AbstractProductEntry.PRODUCT_NAME, productName)
|
||||||
|
put(AbstractProductContract.AbstractProductEntry.PRODUCT_NET_WEIGHT, netWeight.toString())
|
||||||
|
put(AbstractProductContract.AbstractProductEntry.IMAGE_FILENAME, pictureFile.nameWithoutExtension)
|
||||||
|
put(AbstractProductContract.AbstractProductEntry.CATEGORY, categorySpinner.selectedItemPosition)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (abstractProduct == null) {
|
||||||
|
db.insert(AbstractProductContract.AbstractProductEntry.TABLE_NAME, null, values)
|
||||||
|
} else {
|
||||||
|
db.update(AbstractProductContract.AbstractProductEntry.TABLE_NAME, values, "${BaseColumns._ID} = ?", arrayOf(abstractProduct!!.id.toString()))
|
||||||
|
}
|
||||||
|
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
takePictureButton.setOnClickListener {
|
||||||
|
requestPermissionLauncher.launch(Manifest.permission.CAMERA)
|
||||||
|
}
|
||||||
|
|
||||||
|
scanButton.setOnClickListener {
|
||||||
|
val options = GmsBarcodeScannerOptions.Builder()
|
||||||
|
.setBarcodeFormats(
|
||||||
|
Barcode.FORMAT_EAN_13
|
||||||
|
)
|
||||||
|
.build()
|
||||||
|
val scanner = GmsBarcodeScanning.getClient(this)
|
||||||
|
scanner.startScan()
|
||||||
|
.addOnSuccessListener { barcode ->
|
||||||
|
productNameText.setText(barcode.rawValue)
|
||||||
|
}
|
||||||
|
.addOnFailureListener { e ->
|
||||||
|
Toast.makeText(
|
||||||
|
this,
|
||||||
|
"Failed to scan barcode. Please, try again or enter data manually",
|
||||||
|
Toast.LENGTH_LONG
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun fillupCategorySpinner() {
|
||||||
|
val db = DBStorageController(this).readableDatabase
|
||||||
|
|
||||||
|
val categories = mutableListOf("")
|
||||||
|
|
||||||
|
val projection = arrayOf(
|
||||||
|
CategoriesContract.CategoryEntry.CATEGORY_NAME
|
||||||
|
)
|
||||||
|
|
||||||
|
val cursor = db.query(CategoriesContract.CategoryEntry.TABLE_NAME, projection, null, null, null, null, BaseColumns._ID+" ASC")
|
||||||
|
|
||||||
|
with (cursor) {
|
||||||
|
while (moveToNext()) {
|
||||||
|
categories.add(getString(getColumnIndexOrThrow(CategoriesContract.CategoryEntry.CATEGORY_NAME)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val arrayAdapter = ArrayAdapter<String>(this, androidx.appcompat.R.layout.support_simple_spinner_dropdown_item, categories)
|
||||||
|
arrayAdapter.setDropDownViewResource(androidx.appcompat.R.layout.support_simple_spinner_dropdown_item)
|
||||||
|
categorySpinner.adapter = arrayAdapter
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.R)
|
||||||
|
val takePicture = registerForActivityResult(ActivityResultContracts.TakePicture()) { success: Boolean ->
|
||||||
|
if (success) {
|
||||||
|
//Move picture to a proper directory according to its calculated hash
|
||||||
|
val tempfile = File(filesDir, "image.png")
|
||||||
|
val imageContent = tempfile.inputStream().readBytes()
|
||||||
|
val imageHash = imageContent.toString(Charsets.UTF_8).md5()
|
||||||
|
|
||||||
|
pictureFile = File(picturesPath, "$imageHash.png")
|
||||||
|
Files.move(tempfile.toPath(), pictureFile.toPath(), StandardCopyOption.REPLACE_EXISTING)
|
||||||
|
tempfile.delete()
|
||||||
|
generateThumbnailForImage(this, imageHash)
|
||||||
|
|
||||||
|
imageView.setImageURI(getImageUri(this, pictureFile))
|
||||||
|
} else {
|
||||||
|
Log.e("QWERTYUIOP", "Cannot save a picture")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.R)
|
||||||
|
fun getPicture () {
|
||||||
|
//Saving picture to a temp file for further hash calculation and moving to a proper directory
|
||||||
|
val imageFile = File(this.filesDir, "image.png")
|
||||||
|
val imageUri = getImageUri(this, imageFile)
|
||||||
|
if (imageUri != null) {
|
||||||
|
takePicture.launch(imageUri)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.R)
|
||||||
|
val requestPermissionLauncher =
|
||||||
|
registerForActivityResult(
|
||||||
|
ActivityResultContracts.RequestPermission()
|
||||||
|
) { isGranted: Boolean ->
|
||||||
|
if (isGranted) {
|
||||||
|
getPicture()
|
||||||
|
} else {
|
||||||
|
Toast.makeText(this, "I need permission in order to take a picture", Toast.LENGTH_LONG).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,6 +7,7 @@ import android.provider.BaseColumns
|
||||||
import android.widget.Button
|
import android.widget.Button
|
||||||
import android.widget.EditText
|
import android.widget.EditText
|
||||||
import org.foxarmy.barcodescannerforemployees.CategoriesContract
|
import org.foxarmy.barcodescannerforemployees.CategoriesContract
|
||||||
|
import org.foxarmy.barcodescannerforemployees.dataclasses.Category
|
||||||
import org.foxarmy.barcodescannerforemployees.DBStorageController
|
import org.foxarmy.barcodescannerforemployees.DBStorageController
|
||||||
import org.foxarmy.barcodescannerforemployees.R
|
import org.foxarmy.barcodescannerforemployees.R
|
||||||
|
|
||||||
|
@ -17,17 +18,16 @@ class AddCategoryActivity : Activity() {
|
||||||
setContentView(R.layout.activity_add_category)
|
setContentView(R.layout.activity_add_category)
|
||||||
|
|
||||||
val extras = intent.extras
|
val extras = intent.extras
|
||||||
val categoryId = extras!!.get("categoryid") as Int?
|
val category = extras!!.get("category") as Category?
|
||||||
val categoryName = extras.get("categoryname") as String?
|
|
||||||
|
|
||||||
val categoryNameTextEdit: EditText = findViewById(R.id.newCategoryName)
|
val categoryNameTextEdit: EditText = findViewById(R.id.newCategoryName)
|
||||||
|
|
||||||
categoryNameTextEdit.setText(categoryName)
|
categoryNameTextEdit.setText(category!!.name)
|
||||||
|
|
||||||
findViewById<Button>(R.id.saveButton).setOnClickListener {
|
findViewById<Button>(R.id.saveButton).setOnClickListener {
|
||||||
val db = DBStorageController(this).writableDatabase
|
val db = DBStorageController(this).writableDatabase
|
||||||
|
|
||||||
if (categoryId == 0) { // Inserting new category
|
if (category.id == 0) { // Inserting new category
|
||||||
val values = ContentValues().apply {
|
val values = ContentValues().apply {
|
||||||
put(CategoriesContract.CategoryEntry.CATEGORY_NAME, categoryNameTextEdit.text.toString())
|
put(CategoriesContract.CategoryEntry.CATEGORY_NAME, categoryNameTextEdit.text.toString())
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ class AddCategoryActivity : Activity() {
|
||||||
val values = ContentValues().apply {
|
val values = ContentValues().apply {
|
||||||
put(CategoriesContract.CategoryEntry.CATEGORY_NAME, categoryNameTextEdit.text.toString())
|
put(CategoriesContract.CategoryEntry.CATEGORY_NAME, categoryNameTextEdit.text.toString())
|
||||||
}
|
}
|
||||||
db.update(CategoriesContract.CategoryEntry.TABLE_NAME, values, "${BaseColumns._ID} = ?", arrayOf(categoryId.toString()))
|
db.update(CategoriesContract.CategoryEntry.TABLE_NAME, values, "${BaseColumns._ID} = ?", arrayOf(category.id.toString()))
|
||||||
}
|
}
|
||||||
|
|
||||||
finish()
|
finish()
|
||||||
|
|
|
@ -1,200 +1,18 @@
|
||||||
package org.foxarmy.barcodescannerforemployees.activities
|
package org.foxarmy.barcodescannerforemployees.activities
|
||||||
|
|
||||||
import android.Manifest
|
|
||||||
import android.content.ContentValues
|
|
||||||
import android.os.Build
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.provider.BaseColumns
|
|
||||||
import android.util.Log
|
|
||||||
import android.widget.*
|
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
|
||||||
import androidx.annotation.RequiresApi
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import com.google.mlkit.vision.barcode.common.Barcode
|
import org.foxarmy.barcodescannerforemployees.R
|
||||||
import com.google.mlkit.vision.codescanner.GmsBarcodeScannerOptions
|
import org.foxarmy.barcodescannerforemployees.dataclasses.Product
|
||||||
import com.google.mlkit.vision.codescanner.GmsBarcodeScanning
|
|
||||||
import org.foxarmy.barcodescannerforemployees.*
|
|
||||||
import org.foxarmy.barcodescannerforemployees.databinding.ActivityAddProductBinding
|
|
||||||
import java.io.File
|
|
||||||
import java.nio.file.Files
|
|
||||||
import java.nio.file.StandardCopyOption
|
|
||||||
|
|
||||||
class AddProductActivity : AppCompatActivity() {
|
class AddProductActivity : AppCompatActivity() {
|
||||||
private lateinit var imageView: ImageView
|
|
||||||
|
|
||||||
private lateinit var saveButton: Button
|
|
||||||
private lateinit var takePictureButton: Button
|
|
||||||
private lateinit var scanButton: Button
|
|
||||||
|
|
||||||
private lateinit var productNameText: TextView
|
|
||||||
private lateinit var netWeightText: TextView
|
|
||||||
|
|
||||||
private lateinit var categorySpinner: Spinner
|
|
||||||
|
|
||||||
private var product: AbstractProduct? = null
|
|
||||||
private lateinit var pictureFile: File
|
|
||||||
private lateinit var picturesPath: File
|
|
||||||
private lateinit var binding: ActivityAddProductBinding
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
setContentView(R.layout.fragment_add_product)
|
setContentView(R.layout.activity_add_product)
|
||||||
|
|
||||||
val extras = intent.extras
|
val extras = intent.extras
|
||||||
product = extras!!.get("updatingObject") as AbstractProduct?
|
val product = extras!!.get("product") as Product?
|
||||||
|
|
||||||
picturesPath = File(filesDir, "pictures")
|
|
||||||
val thumbnailsDir = File(cacheDir, "thumbnails")
|
|
||||||
thumbnailsDir.mkdirs()
|
|
||||||
picturesPath.mkdirs()
|
|
||||||
imageView = findViewById(R.id.imageView)
|
|
||||||
|
|
||||||
saveButton = findViewById(R.id.saveButton)
|
|
||||||
takePictureButton = findViewById(R.id.takePictureButton)
|
|
||||||
scanButton = findViewById(R.id.scan_button)
|
|
||||||
|
|
||||||
productNameText = findViewById(R.id.productName)
|
|
||||||
netWeightText = findViewById(R.id.netWeight)
|
|
||||||
|
|
||||||
categorySpinner = findViewById(R.id.categorySpinner)
|
|
||||||
|
|
||||||
fillupCategorySpinner()
|
|
||||||
|
|
||||||
if (product != null) {
|
|
||||||
val imageThumbnailUri = getImageUri(this, File(thumbnailsDir, "${product!!.imageHash}.webp"))
|
|
||||||
pictureFile = File(picturesPath, "${product!!.imageHash}.png]")
|
|
||||||
imageView.setImageURI(imageThumbnailUri)
|
|
||||||
imageView.rotation = 90f
|
|
||||||
productNameText.text = product!!.name
|
|
||||||
netWeightText.text = product!!.netWeight.toString()
|
|
||||||
categorySpinner.setSelection(product!!.category)
|
|
||||||
}
|
|
||||||
|
|
||||||
saveButton.setOnClickListener {
|
|
||||||
val productName = productNameText.text.toString()
|
|
||||||
val netWeight = netWeightText.text
|
|
||||||
if (!this::pictureFile.isInitialized && !pictureFile.exists()) {
|
|
||||||
|
|
||||||
Toast.makeText(this, "Please, make a picture of a product!", Toast.LENGTH_SHORT).show()
|
|
||||||
return@setOnClickListener
|
|
||||||
}
|
|
||||||
|
|
||||||
if (productName == "") {
|
|
||||||
Toast.makeText(this, "Please, write a name of a product!", Toast.LENGTH_SHORT).show()
|
|
||||||
return@setOnClickListener
|
|
||||||
}
|
|
||||||
if (netWeight.toString() == "" || netWeight.toString().toDoubleOrNull() == null) {
|
|
||||||
Toast.makeText(this, "Please, write a valid net weight of a product!", Toast.LENGTH_SHORT).show()
|
|
||||||
}
|
|
||||||
|
|
||||||
val db = DBStorageController(this).writableDatabase
|
|
||||||
val values = ContentValues().apply {
|
|
||||||
put(ProductContract.ProductEntry.PRODUCT_NAME, productName)
|
|
||||||
put(ProductContract.ProductEntry.PRODUCT_NET_WEIGHT, netWeight.toString())
|
|
||||||
put(ProductContract.ProductEntry.IMAGE_FILENAME, pictureFile.nameWithoutExtension)
|
|
||||||
put(ProductContract.ProductEntry.CATEGORY, categorySpinner.selectedItemPosition)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (product == null) {
|
|
||||||
db.insert(ProductContract.ProductEntry.TABLE_NAME, null, values)
|
|
||||||
} else {
|
|
||||||
db.update(ProductContract.ProductEntry.TABLE_NAME, values, "${BaseColumns._ID} = ?", arrayOf(product!!.id.toString()))
|
|
||||||
}
|
|
||||||
|
|
||||||
finish()
|
|
||||||
}
|
|
||||||
|
|
||||||
takePictureButton.setOnClickListener {
|
|
||||||
requestPermissionLauncher.launch(Manifest.permission.CAMERA)
|
|
||||||
}
|
|
||||||
|
|
||||||
scanButton.setOnClickListener {
|
|
||||||
val options = GmsBarcodeScannerOptions.Builder()
|
|
||||||
.setBarcodeFormats(
|
|
||||||
Barcode.FORMAT_EAN_13
|
|
||||||
)
|
|
||||||
.build()
|
|
||||||
val scanner = GmsBarcodeScanning.getClient(this)
|
|
||||||
scanner.startScan()
|
|
||||||
.addOnSuccessListener { barcode ->
|
|
||||||
productNameText.setText(barcode.rawValue)
|
|
||||||
}
|
|
||||||
.addOnFailureListener { e ->
|
|
||||||
Toast.makeText(
|
|
||||||
this,
|
|
||||||
"Failed to scan barcode. Please, try again or enter data manually",
|
|
||||||
Toast.LENGTH_LONG
|
|
||||||
).show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// binding = ActivityAddProductBinding.inflate(layoutInflater)
|
|
||||||
|
|
||||||
// setContentView(binding.root)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
fun fillupCategorySpinner() {
|
|
||||||
val db = DBStorageController(this).readableDatabase
|
|
||||||
|
|
||||||
val categories = mutableListOf("")
|
|
||||||
|
|
||||||
val projection = arrayOf(
|
|
||||||
CategoriesContract.CategoryEntry.CATEGORY_NAME
|
|
||||||
)
|
|
||||||
|
|
||||||
val cursor = db.query(CategoriesContract.CategoryEntry.TABLE_NAME, projection, null, null, null, null, BaseColumns._ID+" ASC")
|
|
||||||
|
|
||||||
with (cursor) {
|
|
||||||
while (moveToNext()) {
|
|
||||||
categories.add(getString(getColumnIndexOrThrow(CategoriesContract.CategoryEntry.CATEGORY_NAME)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val arrayAdapter = ArrayAdapter<String>(this, androidx.appcompat.R.layout.support_simple_spinner_dropdown_item, categories)
|
|
||||||
arrayAdapter.setDropDownViewResource(androidx.appcompat.R.layout.support_simple_spinner_dropdown_item)
|
|
||||||
categorySpinner.adapter = arrayAdapter
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.R)
|
|
||||||
val takePicture = registerForActivityResult(ActivityResultContracts.TakePicture()) { success: Boolean ->
|
|
||||||
if (success) {
|
|
||||||
//Move picture to a proper directory according to its calculated hash
|
|
||||||
val tempfile = File(filesDir, "image.png")
|
|
||||||
val imageContent = tempfile.inputStream().readBytes()
|
|
||||||
val imageHash = imageContent.toString(Charsets.UTF_8).md5()
|
|
||||||
|
|
||||||
pictureFile = File(picturesPath, "$imageHash.png")
|
|
||||||
Files.move(tempfile.toPath(), pictureFile.toPath(), StandardCopyOption.REPLACE_EXISTING)
|
|
||||||
tempfile.delete()
|
|
||||||
generateThumbnailForImage(this, imageHash)
|
|
||||||
|
|
||||||
imageView.setImageURI(getImageUri(this, pictureFile))
|
|
||||||
} else {
|
|
||||||
Log.e("QWERTYUIOP", "Cannot save a picture")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.R)
|
|
||||||
fun getPicture () {
|
|
||||||
//Saving picture to a temp file for further hash calculation and moving to a proper directory
|
|
||||||
val imageFile = File(this.filesDir, "image.png")
|
|
||||||
val imageUri = getImageUri(this, imageFile)
|
|
||||||
if (imageUri != null) {
|
|
||||||
takePicture.launch(imageUri)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.R)
|
|
||||||
val requestPermissionLauncher =
|
|
||||||
registerForActivityResult(
|
|
||||||
ActivityResultContracts.RequestPermission()
|
|
||||||
) { isGranted: Boolean ->
|
|
||||||
if (isGranted) {
|
|
||||||
getPicture()
|
|
||||||
} else {
|
|
||||||
Toast.makeText(this, "I need permission in order to take a picture", Toast.LENGTH_LONG).show()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -12,7 +12,9 @@ import androidx.viewpager.widget.ViewPager
|
||||||
import org.foxarmy.barcodescannerforemployees.R
|
import org.foxarmy.barcodescannerforemployees.R
|
||||||
import org.foxarmy.barcodescannerforemployees.ViewPagerAdapter
|
import org.foxarmy.barcodescannerforemployees.ViewPagerAdapter
|
||||||
import org.foxarmy.barcodescannerforemployees.databinding.ActivityMainBinding
|
import org.foxarmy.barcodescannerforemployees.databinding.ActivityMainBinding
|
||||||
|
import org.foxarmy.barcodescannerforemployees.dataclasses.Category
|
||||||
import org.foxarmy.barcodescannerforemployees.fragments.CategoriesFragment
|
import org.foxarmy.barcodescannerforemployees.fragments.CategoriesFragment
|
||||||
|
import org.foxarmy.barcodescannerforemployees.fragments.ShelfFragment
|
||||||
import org.foxarmy.barcodescannerforemployees.fragments.StorageFragment
|
import org.foxarmy.barcodescannerforemployees.fragments.StorageFragment
|
||||||
|
|
||||||
class MainActivity : AppCompatActivity() {
|
class MainActivity : AppCompatActivity() {
|
||||||
|
@ -36,25 +38,34 @@ class MainActivity : AppCompatActivity() {
|
||||||
|
|
||||||
when (fragment::class.simpleName.toString()) {
|
when (fragment::class.simpleName.toString()) {
|
||||||
"StorageFragment" -> {
|
"StorageFragment" -> {
|
||||||
val addProductIntent = Intent(this, AddProductActivity::class.java)
|
val addAbstractProductIntent = Intent(this, AddAbstractProductActivity::class.java)
|
||||||
val extras = Bundle()
|
val extras = Bundle()
|
||||||
// I reuse the same stuff for editing and adding new product.
|
// I reuse the same stuff for editing and adding new product.
|
||||||
// if updatingObject == null, it means that we need to create new object
|
// if abstractProduct == null, it means that we need to create new object
|
||||||
extras.putParcelable("updatingObject", null)
|
extras.putParcelable("abstractProduct", null)
|
||||||
addProductIntent.putExtras(extras)
|
addAbstractProductIntent.putExtras(extras)
|
||||||
ContextCompat.startActivity(this, addProductIntent, extras)
|
ContextCompat.startActivity(this, addAbstractProductIntent, extras)
|
||||||
}
|
}
|
||||||
|
|
||||||
"CategoriesFragment" -> {
|
"CategoriesFragment" -> {
|
||||||
val addCategoryIntent = Intent(this, AddCategoryActivity::class.java)
|
val addCategoryIntent = Intent(this, AddCategoryActivity::class.java)
|
||||||
val extras = Bundle()
|
val extras = Bundle()
|
||||||
extras.putInt("categoryid", 0)
|
//TODO: Implement parcellable for Category class to simplify this
|
||||||
extras.putString("categoryname", "New category")
|
// extras.putInt("categoryid", 0)
|
||||||
|
// extras.putString("categoryname", "New category")
|
||||||
|
extras.putParcelable("category", Category(0, "New category"))
|
||||||
addCategoryIntent.putExtras(extras)
|
addCategoryIntent.putExtras(extras)
|
||||||
ContextCompat.startActivity(this, addCategoryIntent, extras)
|
ContextCompat.startActivity(this, addCategoryIntent, extras)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
"ShelfFragment" -> {
|
||||||
|
val addProductIntent = Intent(this, AddProductActivity::class.java)
|
||||||
|
val extras = Bundle()
|
||||||
|
extras.putParcelable("product", null)
|
||||||
|
addProductIntent.putExtras(extras)
|
||||||
|
ContextCompat.startActivity(this, addProductIntent, extras)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,7 +74,8 @@ class MainActivity : AppCompatActivity() {
|
||||||
|
|
||||||
adapter.addFragment(CategoriesFragment(), "Categories")
|
adapter.addFragment(CategoriesFragment(), "Categories")
|
||||||
adapter.addFragment(StorageFragment(), "Storage")
|
adapter.addFragment(StorageFragment(), "Storage")
|
||||||
//TODO: shelf and settings fragments
|
adapter.addFragment(ShelfFragment(), "Shelf")
|
||||||
|
//TODO: settings fragments
|
||||||
|
|
||||||
// setting adapter to view pager.
|
// setting adapter to view pager.
|
||||||
viewpager.setAdapter(adapter)
|
viewpager.setAdapter(adapter)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package org.foxarmy.barcodescannerforemployees
|
package org.foxarmy.barcodescannerforemployees.dataclasses
|
||||||
|
|
||||||
import android.os.Parcel
|
import android.os.Parcel
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
|
@ -0,0 +1,39 @@
|
||||||
|
package org.foxarmy.barcodescannerforemployees.dataclasses
|
||||||
|
|
||||||
|
import android.os.Parcel
|
||||||
|
import android.os.Parcelable
|
||||||
|
|
||||||
|
class Category() : Parcelable {
|
||||||
|
var id = 0
|
||||||
|
var name = ""
|
||||||
|
|
||||||
|
|
||||||
|
constructor(id: Int, name: String) : this() {
|
||||||
|
this.id = id
|
||||||
|
this.name = name
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(parcel: Parcel) : this() {
|
||||||
|
id = parcel.readInt()
|
||||||
|
name = parcel.readString()!!
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun writeToParcel(parcel: Parcel, flags: Int) {
|
||||||
|
parcel.writeInt(id)
|
||||||
|
parcel.writeString(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun describeContents(): Int {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object CREATOR : Parcelable.Creator<Category> {
|
||||||
|
override fun createFromParcel(parcel: Parcel): Category {
|
||||||
|
return Category(parcel)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun newArray(size: Int): Array<Category?> {
|
||||||
|
return arrayOfNulls(size)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
package org.foxarmy.barcodescannerforemployees.dataclasses
|
||||||
|
|
||||||
|
import android.os.Parcel
|
||||||
|
import android.os.Parcelable
|
||||||
|
|
||||||
|
class Product() : Parcelable {
|
||||||
|
var abstractProductId = 0
|
||||||
|
var amount = 0
|
||||||
|
|
||||||
|
|
||||||
|
constructor(abstractProductId: Int, amount: Int) : this() {
|
||||||
|
this.abstractProductId = abstractProductId
|
||||||
|
this.amount = amount
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(parcel: Parcel) : this() {
|
||||||
|
abstractProductId = parcel.readInt()
|
||||||
|
amount = parcel.readInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun writeToParcel(parcel: Parcel, flags: Int) {
|
||||||
|
parcel.writeInt(abstractProductId)
|
||||||
|
parcel.writeInt(amount)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun describeContents(): Int {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object CREATOR : Parcelable.Creator<Product> {
|
||||||
|
override fun createFromParcel(parcel: Parcel): Product {
|
||||||
|
return Product(parcel)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun newArray(size: Int): Array<Product?> {
|
||||||
|
return arrayOfNulls(size)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
package org.foxarmy.barcodescannerforemployees.fragments
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import org.foxarmy.barcodescannerforemployees.R
|
||||||
|
import org.foxarmy.barcodescannerforemployees.databinding.FragmentAddAbstractProductBinding
|
||||||
|
|
||||||
|
class AddAbstractProductFragment : Fragment() {
|
||||||
|
private lateinit var binding: FragmentAddAbstractProductBinding
|
||||||
|
|
||||||
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater, container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?
|
||||||
|
): View {
|
||||||
|
binding = FragmentAddAbstractProductBinding.inflate(layoutInflater)
|
||||||
|
return inflater.inflate(R.layout.fragment_add_abstract_product, container, false)
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,7 +12,7 @@ import androidx.core.content.ContextCompat
|
||||||
import androidx.core.view.children
|
import androidx.core.view.children
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import org.foxarmy.barcodescannerforemployees.CategoriesContract
|
import org.foxarmy.barcodescannerforemployees.CategoriesContract
|
||||||
import org.foxarmy.barcodescannerforemployees.Category
|
import org.foxarmy.barcodescannerforemployees.dataclasses.Category
|
||||||
import org.foxarmy.barcodescannerforemployees.DBStorageController
|
import org.foxarmy.barcodescannerforemployees.DBStorageController
|
||||||
import org.foxarmy.barcodescannerforemployees.R
|
import org.foxarmy.barcodescannerforemployees.R
|
||||||
import org.foxarmy.barcodescannerforemployees.activities.AddCategoryActivity
|
import org.foxarmy.barcodescannerforemployees.activities.AddCategoryActivity
|
||||||
|
@ -56,8 +56,7 @@ class CategoriesFragment : Fragment() {
|
||||||
if (view.isCategorySelected) {
|
if (view.isCategorySelected) {
|
||||||
val addCategoryIntent = Intent(context, AddCategoryActivity::class.java)
|
val addCategoryIntent = Intent(context, AddCategoryActivity::class.java)
|
||||||
val extras = Bundle()
|
val extras = Bundle()
|
||||||
extras.putInt("categoryid", view.category.id)
|
extras.putParcelable("category", view.category)
|
||||||
extras.putString("categoryname", view.category.name)
|
|
||||||
addCategoryIntent.putExtras(extras)
|
addCategoryIntent.putExtras(extras)
|
||||||
ContextCompat.startActivity(context!!, addCategoryIntent, extras)
|
ContextCompat.startActivity(context!!, addCategoryIntent, extras)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
package org.foxarmy.barcodescannerforemployees.fragments
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import org.foxarmy.barcodescannerforemployees.R
|
||||||
|
|
||||||
|
class ShelfFragment : Fragment() {
|
||||||
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater, container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?
|
||||||
|
): View? {
|
||||||
|
return inflater.inflate(R.layout.fragment_shelf, container, false)
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,8 +12,12 @@ import androidx.core.content.ContextCompat
|
||||||
import androidx.core.view.children
|
import androidx.core.view.children
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.gridlayout.widget.GridLayout
|
import androidx.gridlayout.widget.GridLayout
|
||||||
import org.foxarmy.barcodescannerforemployees.*
|
import org.foxarmy.barcodescannerforemployees.AbstractProductContract
|
||||||
import org.foxarmy.barcodescannerforemployees.activities.AddProductActivity
|
import org.foxarmy.barcodescannerforemployees.DBStorageController
|
||||||
|
import org.foxarmy.barcodescannerforemployees.R
|
||||||
|
import org.foxarmy.barcodescannerforemployees.activities.AddAbstractProductActivity
|
||||||
|
import org.foxarmy.barcodescannerforemployees.dataclasses.AbstractProduct
|
||||||
|
import org.foxarmy.barcodescannerforemployees.generateThumbnailForImage
|
||||||
import org.foxarmy.barcodescannerforemployees.views.AbstractProductView
|
import org.foxarmy.barcodescannerforemployees.views.AbstractProductView
|
||||||
|
|
||||||
class StorageFragment : Fragment() {
|
class StorageFragment : Fragment() {
|
||||||
|
@ -39,7 +43,7 @@ class StorageFragment : Fragment() {
|
||||||
for (view: AbstractProductView in grv?.children!!.iterator() as Iterator<AbstractProductView>) {
|
for (view: AbstractProductView in grv?.children!!.iterator() as Iterator<AbstractProductView>) {
|
||||||
view.findViewById<ImageView>(R.id.productPicture).setImageURI(null)
|
view.findViewById<ImageView>(R.id.productPicture).setImageURI(null)
|
||||||
if (view.isProductSelected) {
|
if (view.isProductSelected) {
|
||||||
db.eraseAbstractProduct(db.writableDatabase, view.product.id, requireContext())
|
db.eraseAbstractProduct(db.writableDatabase, view.abstractProduct.id, requireContext())
|
||||||
deleted = true
|
deleted = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -55,9 +59,9 @@ class StorageFragment : Fragment() {
|
||||||
|
|
||||||
for (view: AbstractProductView in grv?.children!!.iterator() as Iterator<AbstractProductView>) {
|
for (view: AbstractProductView in grv?.children!!.iterator() as Iterator<AbstractProductView>) {
|
||||||
if (view.isProductSelected) {
|
if (view.isProductSelected) {
|
||||||
val addProductIntent = Intent(requireContext(), AddProductActivity::class.java)
|
val addProductIntent = Intent(requireContext(), AddAbstractProductActivity::class.java)
|
||||||
val extras = Bundle()
|
val extras = Bundle()
|
||||||
extras.putParcelable("updatingObject", view.product)
|
extras.putParcelable("abstractProduct", view.abstractProduct)
|
||||||
addProductIntent.putExtras(extras)
|
addProductIntent.putExtras(extras)
|
||||||
ContextCompat.startActivity(requireContext(), addProductIntent, extras)
|
ContextCompat.startActivity(requireContext(), addProductIntent, extras)
|
||||||
}
|
}
|
||||||
|
@ -72,21 +76,21 @@ class StorageFragment : Fragment() {
|
||||||
|
|
||||||
val db = DBStorageController(requireContext()).readableDatabase
|
val db = DBStorageController(requireContext()).readableDatabase
|
||||||
val projection = arrayOf(BaseColumns._ID,
|
val projection = arrayOf(BaseColumns._ID,
|
||||||
ProductContract.ProductEntry.PRODUCT_NAME,
|
AbstractProductContract.AbstractProductEntry.PRODUCT_NAME,
|
||||||
ProductContract.ProductEntry.PRODUCT_NET_WEIGHT,
|
AbstractProductContract.AbstractProductEntry.PRODUCT_NET_WEIGHT,
|
||||||
ProductContract.ProductEntry.IMAGE_FILENAME,
|
AbstractProductContract.AbstractProductEntry.IMAGE_FILENAME,
|
||||||
ProductContract.ProductEntry.CATEGORY
|
AbstractProductContract.AbstractProductEntry.CATEGORY
|
||||||
)
|
)
|
||||||
|
|
||||||
val cursor = db.query(ProductContract.ProductEntry.TABLE_NAME, projection, null, null, null, null, null)
|
val cursor = db.query(AbstractProductContract.AbstractProductEntry.TABLE_NAME, projection, null, null, null, null, null)
|
||||||
|
|
||||||
with (cursor) {
|
with (cursor) {
|
||||||
while(moveToNext()) {
|
while(moveToNext()) {
|
||||||
val productId = getInt(getColumnIndexOrThrow(BaseColumns._ID))
|
val productId = getInt(getColumnIndexOrThrow(BaseColumns._ID))
|
||||||
val productName = getString(getColumnIndexOrThrow(ProductContract.ProductEntry.PRODUCT_NAME))
|
val productName = getString(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.PRODUCT_NAME))
|
||||||
val netWeight = getDouble(getColumnIndexOrThrow(ProductContract.ProductEntry.PRODUCT_NET_WEIGHT))
|
val netWeight = getDouble(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.PRODUCT_NET_WEIGHT))
|
||||||
val productImageHash = getString(getColumnIndexOrThrow(ProductContract.ProductEntry.IMAGE_FILENAME))
|
val productImageHash = getString(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.IMAGE_FILENAME))
|
||||||
val category = getInt(getColumnIndexOrThrow(ProductContract.ProductEntry.CATEGORY))
|
val category = getInt(getColumnIndexOrThrow(AbstractProductContract.AbstractProductEntry.CATEGORY))
|
||||||
|
|
||||||
val product = AbstractProduct(productId, productName, netWeight, productImageHash, category)
|
val product = AbstractProduct(productId, productName, netWeight, productImageHash, category)
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ import android.widget.TextView
|
||||||
import androidx.constraintlayout.widget.ConstraintLayout
|
import androidx.constraintlayout.widget.ConstraintLayout
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.content.ContextCompat.startActivity
|
import androidx.core.content.ContextCompat.startActivity
|
||||||
import org.foxarmy.barcodescannerforemployees.AbstractProduct
|
import org.foxarmy.barcodescannerforemployees.dataclasses.AbstractProduct
|
||||||
import org.foxarmy.barcodescannerforemployees.DBStorageController
|
import org.foxarmy.barcodescannerforemployees.DBStorageController
|
||||||
import org.foxarmy.barcodescannerforemployees.R
|
import org.foxarmy.barcodescannerforemployees.R
|
||||||
import org.foxarmy.barcodescannerforemployees.activities.FullscreenActivity
|
import org.foxarmy.barcodescannerforemployees.activities.FullscreenActivity
|
||||||
|
@ -25,12 +25,12 @@ class AbstractProductView: LinearLayout {
|
||||||
private var netWeightField: TextView
|
private var netWeightField: TextView
|
||||||
private var categoryField: TextView
|
private var categoryField: TextView
|
||||||
private var unitField: TextView
|
private var unitField: TextView
|
||||||
var product: AbstractProduct
|
var abstractProduct: AbstractProduct
|
||||||
var isProductSelected = false
|
var isProductSelected = false
|
||||||
|
|
||||||
constructor(activity: Activity, context: Context, product: AbstractProduct) : super(context) {
|
constructor(activity: Activity, context: Context, abstractProduct: AbstractProduct) : super(context) {
|
||||||
|
|
||||||
this.product = product
|
this.abstractProduct = abstractProduct
|
||||||
|
|
||||||
val inflater:LayoutInflater = activity.layoutInflater
|
val inflater:LayoutInflater = activity.layoutInflater
|
||||||
inflater.inflate(R.layout.abstract_product_view, this)
|
inflater.inflate(R.layout.abstract_product_view, this)
|
||||||
|
@ -44,13 +44,13 @@ class AbstractProductView: LinearLayout {
|
||||||
|
|
||||||
val thumbnailsDir = File(context.cacheDir, "thumbnails")
|
val thumbnailsDir = File(context.cacheDir, "thumbnails")
|
||||||
thumbnailsDir.mkdirs()
|
thumbnailsDir.mkdirs()
|
||||||
val imageUri = getImageUri(activity, File(thumbnailsDir, "${product.imageHash}.webp"))
|
val imageUri = getImageUri(activity, File(thumbnailsDir, "${abstractProduct.imageHash}.webp"))
|
||||||
productPicture.setImageURI(imageUri)
|
productPicture.setImageURI(imageUri)
|
||||||
productPicture.rotation = 90f
|
productPicture.rotation = 90f
|
||||||
productPicture.setOnClickListener {
|
productPicture.setOnClickListener {
|
||||||
val fullscreenIntent = Intent(activity, FullscreenActivity::class.java)
|
val fullscreenIntent = Intent(activity, FullscreenActivity::class.java)
|
||||||
val extras = Bundle()
|
val extras = Bundle()
|
||||||
extras.putString("imagehash", product.imageHash)
|
extras.putString("imagehash", abstractProduct.imageHash)
|
||||||
fullscreenIntent.putExtras(extras)
|
fullscreenIntent.putExtras(extras)
|
||||||
startActivity(context, fullscreenIntent, extras)
|
startActivity(context, fullscreenIntent, extras)
|
||||||
}
|
}
|
||||||
|
@ -61,9 +61,9 @@ class AbstractProductView: LinearLayout {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
productNameField.text = product.name
|
productNameField.text = abstractProduct.name
|
||||||
netWeightField.text = product.netWeight.toString()
|
netWeightField.text = abstractProduct.netWeight.toString()
|
||||||
categoryField.text = DBStorageController(context).getCategoryNameById(DBStorageController(context).readableDatabase, product.category)
|
categoryField.text = DBStorageController(context).getCategoryNameById(DBStorageController(context).readableDatabase, abstractProduct.category)
|
||||||
|
|
||||||
//TODO: units
|
//TODO: units
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ import android.view.LayoutInflater
|
||||||
import android.widget.LinearLayout
|
import android.widget.LinearLayout
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import org.foxarmy.barcodescannerforemployees.Category
|
import org.foxarmy.barcodescannerforemployees.dataclasses.Category
|
||||||
import org.foxarmy.barcodescannerforemployees.DBStorageController
|
import org.foxarmy.barcodescannerforemployees.DBStorageController
|
||||||
import org.foxarmy.barcodescannerforemployees.R
|
import org.foxarmy.barcodescannerforemployees.R
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.core.widget.NestedScrollView
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:context=".fragments.AddAbstractProductFragment">
|
||||||
|
<include layout="@layout/content_add_abstract_product" android:id="@+id/include_content"/>
|
||||||
|
</androidx.core.widget.NestedScrollView>
|
|
@ -0,0 +1,14 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
app:layout_behavior="@string/appbar_scrolling_view_behavior" android:id="@+id/addAbstractProductLayout">
|
||||||
|
|
||||||
|
<androidx.fragment.app.FragmentContainerView
|
||||||
|
android:name="androidx.navigation.fragment.NavHostFragment"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent" app:navGraph="@navigation/nav_graph_add_abstract_product"
|
||||||
|
app:defaultNavHost="true" android:id="@+id/fragmentContainerView"/>
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -0,0 +1,83 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.core.widget.NestedScrollView
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:context=".fragments.AddAbstractProductFragment">
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:padding="16dp">
|
||||||
|
<Button
|
||||||
|
android:id="@+id/scan_button"
|
||||||
|
android:layout_width="100dp"
|
||||||
|
android:layout_height="50dp"
|
||||||
|
android:text="@string/scan_label"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/categoryTextView"
|
||||||
|
android:layout_marginTop="15dp"/>
|
||||||
|
<ImageView
|
||||||
|
android:src="@android:drawable/ic_menu_camera"
|
||||||
|
android:layout_width="356dp"
|
||||||
|
android:layout_height="303dp" android:id="@+id/imageView"
|
||||||
|
android:layout_marginBottom="25dp"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/productName" app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent"
|
||||||
|
android:layout_marginTop="15dp"/>
|
||||||
|
<EditText
|
||||||
|
android:layout_width="350dp"
|
||||||
|
android:layout_height="50dp"
|
||||||
|
android:inputType="text"
|
||||||
|
android:ems="10"
|
||||||
|
android:id="@+id/productName"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
android:layout_marginStart="8dp" android:layout_marginEnd="8dp"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/netWeight"
|
||||||
|
app:layout_constraintHorizontal_bias="0.5"
|
||||||
|
android:visibility="visible" android:hint="@string/product_name_label" android:textColorHint="#737373"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/imageView"/>
|
||||||
|
<EditText
|
||||||
|
android:layout_width="350dp"
|
||||||
|
android:layout_height="50dp"
|
||||||
|
android:inputType="text"
|
||||||
|
android:ems="10"
|
||||||
|
android:id="@+id/netWeight"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
android:visibility="visible" android:hint="@string/netWeight" android:textColorHint="#737373"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/productName"/>
|
||||||
|
<TextView
|
||||||
|
android:text="@string/category"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content" android:id="@+id/categoryTextView"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/netWeight"
|
||||||
|
android:layout_marginTop="20dp" app:layout_constraintStart_toStartOf="parent"
|
||||||
|
android:layout_marginStart="8dp"/>
|
||||||
|
<Spinner
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content" android:id="@+id/categorySpinner"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/categoryTextView"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/netWeight" android:layout_marginStart="8dp"
|
||||||
|
android:layout_marginTop="20dp"/>
|
||||||
|
<Button
|
||||||
|
android:text="@string/saveButton"
|
||||||
|
android:layout_width="100dp"
|
||||||
|
android:layout_height="50dp" android:id="@+id/saveButton"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/categoryTextView"
|
||||||
|
android:layout_marginTop="15dp" app:layout_constraintEnd_toEndOf="parent"/>
|
||||||
|
<Button
|
||||||
|
android:text="@string/takePicture"
|
||||||
|
android:layout_width="100dp"
|
||||||
|
android:layout_height="55dp" android:id="@+id/takePictureButton"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/categoryTextView"
|
||||||
|
android:layout_marginTop="15dp" app:layout_constraintStart_toEndOf="@+id/scan_button"
|
||||||
|
android:layout_marginStart="33dp" app:layout_constraintEnd_toStartOf="@+id/saveButton"
|
||||||
|
android:layout_marginEnd="6dp" app:layout_constraintHorizontal_bias="0.0"/>
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
</androidx.core.widget.NestedScrollView>
|
|
@ -10,74 +10,11 @@
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:padding="16dp">
|
android:padding="16dp">
|
||||||
<Button
|
|
||||||
android:id="@+id/scan_button"
|
|
||||||
android:layout_width="100dp"
|
|
||||||
android:layout_height="50dp"
|
|
||||||
android:text="@string/scan_label"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/categoryTextView"
|
|
||||||
android:layout_marginTop="15dp"/>
|
|
||||||
<ImageView
|
|
||||||
android:src="@android:drawable/ic_menu_camera"
|
|
||||||
android:layout_width="356dp"
|
|
||||||
android:layout_height="303dp" android:id="@+id/imageView"
|
|
||||||
android:layout_marginBottom="25dp"
|
|
||||||
app:layout_constraintBottom_toTopOf="@+id/productName" app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent"
|
|
||||||
android:layout_marginTop="15dp"/>
|
|
||||||
<EditText
|
|
||||||
android:layout_width="350dp"
|
|
||||||
android:layout_height="50dp"
|
|
||||||
android:inputType="text"
|
|
||||||
android:ems="10"
|
|
||||||
android:id="@+id/productName"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
android:layout_marginStart="8dp" android:layout_marginEnd="8dp"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintBottom_toTopOf="@+id/netWeight"
|
|
||||||
app:layout_constraintHorizontal_bias="0.5"
|
|
||||||
android:visibility="visible" android:hint="@string/product_name_label" android:textColorHint="#737373"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/imageView"/>
|
|
||||||
<EditText
|
|
||||||
android:layout_width="350dp"
|
|
||||||
android:layout_height="50dp"
|
|
||||||
android:inputType="text"
|
|
||||||
android:ems="10"
|
|
||||||
android:id="@+id/netWeight"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
android:layout_marginStart="8dp"
|
|
||||||
android:layout_marginEnd="8dp"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
android:visibility="visible" android:hint="@string/netWeight" android:textColorHint="#737373"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/productName"/>
|
|
||||||
<TextView
|
|
||||||
android:text="@string/category"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content" android:id="@+id/categoryTextView"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/netWeight"
|
|
||||||
android:layout_marginTop="20dp" app:layout_constraintStart_toStartOf="parent"
|
|
||||||
android:layout_marginStart="8dp"/>
|
|
||||||
<Spinner
|
<Spinner
|
||||||
android:layout_width="match_parent"
|
android:layout_width="400dp"
|
||||||
android:layout_height="wrap_content" android:id="@+id/categorySpinner"
|
android:layout_height="50dp" android:id="@+id/abstractProductSelect"
|
||||||
app:layout_constraintStart_toEndOf="@+id/categoryTextView"
|
app:layout_constraintTop_toTopOf="parent" android:layout_marginTop="12dp"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/netWeight" android:layout_marginStart="8dp"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
android:layout_marginTop="20dp"/>
|
app:layout_constraintEnd_toEndOf="parent"/>
|
||||||
<Button
|
|
||||||
android:text="@string/saveButton"
|
|
||||||
android:layout_width="100dp"
|
|
||||||
android:layout_height="50dp" android:id="@+id/saveButton"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/categoryTextView"
|
|
||||||
android:layout_marginTop="15dp" app:layout_constraintEnd_toEndOf="parent"/>
|
|
||||||
<Button
|
|
||||||
android:text="@string/takePicture"
|
|
||||||
android:layout_width="100dp"
|
|
||||||
android:layout_height="55dp" android:id="@+id/takePictureButton"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/categoryTextView"
|
|
||||||
android:layout_marginTop="15dp" app:layout_constraintStart_toEndOf="@+id/scan_button"
|
|
||||||
android:layout_marginStart="33dp" app:layout_constraintEnd_toStartOf="@+id/saveButton"
|
|
||||||
android:layout_marginEnd="6dp" app:layout_constraintHorizontal_bias="0.0"/>
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
</androidx.core.widget.NestedScrollView>
|
</androidx.core.widget.NestedScrollView>
|
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
</FrameLayout>
|
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
</LinearLayout>
|
|
@ -0,0 +1,11 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/nav_graph_add_abstract_product"
|
||||||
|
app:startDestination="@id/addAbstractProductFragment">
|
||||||
|
|
||||||
|
<fragment android:id="@+id/addAbstractProductFragment"
|
||||||
|
android:name="org.foxarmy.barcodescannerforemployees.fragments.AddAbstractProductFragment"
|
||||||
|
android:label="activity_add_abstract_product" tools:layout="@layout/fragment_add_abstract_product"/>
|
||||||
|
</navigation>
|
|
@ -5,6 +5,7 @@
|
||||||
android:id="@+id/nav_graph_add_product"
|
android:id="@+id/nav_graph_add_product"
|
||||||
app:startDestination="@id/addProductFragment">
|
app:startDestination="@id/addProductFragment">
|
||||||
|
|
||||||
<fragment android:id="@+id/addProductFragment" android:name="org.foxarmy.barcodescannerforemployees.fragments.AddProductFragment"
|
<fragment android:id="@+id/addProductFragment"
|
||||||
android:label="add_product_fragment" tools:layout="@layout/fragment_add_product"/>
|
android:name="org.foxarmy.barcodescannerforemployees.fragments.AddProductFragment"
|
||||||
|
android:label="activity_add_product" tools:layout="@layout/fragment_add_product"/>
|
||||||
</navigation>
|
</navigation>
|
|
@ -15,6 +15,8 @@ navigationUiKtx = "2.8.0"
|
||||||
firebaseCrashlyticsBuildtools = "3.0.2"
|
firebaseCrashlyticsBuildtools = "3.0.2"
|
||||||
gridlayout = "1.0.0"
|
gridlayout = "1.0.0"
|
||||||
activity = "1.9.2"
|
activity = "1.9.2"
|
||||||
|
legacySupportV4 = "1.0.0"
|
||||||
|
fragment = "1.8.4"
|
||||||
|
|
||||||
[libraries]
|
[libraries]
|
||||||
androidx-camera-view = { module = "androidx.camera:camera-view", version.ref = "cameraView" }
|
androidx-camera-view = { module = "androidx.camera:camera-view", version.ref = "cameraView" }
|
||||||
|
@ -31,6 +33,8 @@ androidx-navigation-ui-ktx = { group = "androidx.navigation", name = "navigation
|
||||||
firebase-crashlytics-buildtools = { group = "com.google.firebase", name = "firebase-crashlytics-buildtools", version.ref = "firebaseCrashlyticsBuildtools" }
|
firebase-crashlytics-buildtools = { group = "com.google.firebase", name = "firebase-crashlytics-buildtools", version.ref = "firebaseCrashlyticsBuildtools" }
|
||||||
androidx-gridlayout = { group = "androidx.gridlayout", name = "gridlayout", version.ref = "gridlayout" }
|
androidx-gridlayout = { group = "androidx.gridlayout", name = "gridlayout", version.ref = "gridlayout" }
|
||||||
androidx-activity = { group = "androidx.activity", name = "activity", version.ref = "activity" }
|
androidx-activity = { group = "androidx.activity", name = "activity", version.ref = "activity" }
|
||||||
|
androidx-legacy-support-v4 = { group = "androidx.legacy", name = "legacy-support-v4", version.ref = "legacySupportV4" }
|
||||||
|
androidx-fragment = { group = "androidx.fragment", name = "fragment", version.ref = "fragment" }
|
||||||
|
|
||||||
[plugins]
|
[plugins]
|
||||||
android-application = { id = "com.android.application", version.ref = "agp" }
|
android-application = { id = "com.android.application", version.ref = "agp" }
|
||||||
|
|
Loading…
Reference in New Issue