categories

This commit is contained in:
leca 2024-10-08 02:24:16 +03:00
parent a6c21f05f9
commit 5fb481a0d5
21 changed files with 297 additions and 90 deletions

View File

@ -45,6 +45,7 @@ dependencies {
implementation(libs.androidx.navigation.ui.ktx) implementation(libs.androidx.navigation.ui.ktx)
implementation(libs.firebase.crashlytics.buildtools) implementation(libs.firebase.crashlytics.buildtools)
implementation(libs.androidx.gridlayout) implementation(libs.androidx.gridlayout)
implementation(libs.androidx.activity)
testImplementation(libs.junit) testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit) androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core) androidTestImplementation(libs.androidx.espresso.core)

View File

@ -24,6 +24,9 @@
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/Theme.BarcodeScannerForEmployees" android:theme="@style/Theme.BarcodeScannerForEmployees"
tools:targetApi="31"> tools:targetApi="31">
<activity
android:name=".activities.AddCategoryActivity"
android:exported="false"/>
<activity <activity
android:name=".activities.AddProductActivity" android:name=".activities.AddProductActivity"
android:exported="false" android:exported="false"

View File

@ -5,7 +5,7 @@ class AbstractProduct(
public var name: String, public var name: String,
public var netWeight: Double, public var netWeight: Double,
public var imageHash: String, public var imageHash: String,
public var category: Int public var categoryName: String
) { ) {
} }

View File

@ -0,0 +1,8 @@
package org.foxarmy.barcodescannerforemployees
class Category(
public var id: Int,
public var name: String,
) {
}

View File

@ -13,6 +13,7 @@ object ProductContract {
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"
const val CATEGORY = "category"
} }
} }
@ -36,35 +37,38 @@ const val SQL_CREATE_PRODUCT_TABLE =
"${BaseColumns._ID} INTEGER PRIMARY KEY," + "${BaseColumns._ID} INTEGER PRIMARY KEY," +
"${ProductContract.ProductEntry.PRODUCT_NAME} TEXT," + "${ProductContract.ProductEntry.PRODUCT_NAME} TEXT," +
"${ProductContract.ProductEntry.PRODUCT_NET_WEIGHT} REAL," + "${ProductContract.ProductEntry.PRODUCT_NET_WEIGHT} REAL," +
"${ProductContract.ProductEntry.IMAGE_FILENAME} TEXT)" "${ProductContract.ProductEntry.IMAGE_FILENAME} TEXT," +
"${ProductContract.ProductEntry.CATEGORY} INTEGER)"
const val SQL_CREATE_SHELF_TABLE = const val SQL_CREATE_SHELF_TABLE =
"CREATE TABLE ${ShelfContract.ShelfEntry.TABLE_NAME} (" + "CREATE TABLE ${ShelfContract.ShelfEntry.TABLE_NAME} (" +
"${BaseColumns._ID} INTEGER PRIMARY KEY," +
"${ShelfContract.ShelfEntry.PRODUCT_ID} INTEGER," + "${ShelfContract.ShelfEntry.PRODUCT_ID} INTEGER," +
"${ShelfContract.ShelfEntry.EXPIRE_DATE} DATE)" "${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} (" +
"${BaseColumns._ID} INTEGER PRIMARY KEY," +
"${CategoriesContract.CategoryEntry.CATEGORY_NAME} TEXT)" "${CategoriesContract.CategoryEntry.CATEGORY_NAME} TEXT)"
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) {
Log.d("QWERTYUIOP", SQL_CREATE_PRODUCT_TABLE)
db.execSQL(SQL_CREATE_PRODUCT_TABLE) db.execSQL(SQL_CREATE_PRODUCT_TABLE)
db.execSQL(SQL_CREATE_SHELF_TABLE) db.execSQL(SQL_CREATE_SHELF_TABLE)
db.execSQL(SQL_CREATE_CATEGORIES_TABLE) db.execSQL(SQL_CREATE_CATEGORIES_TABLE)
} }
override fun onUpgrade(p0: SQLiteDatabase?, p1: Int, p2: Int) { override fun onUpgrade(db: SQLiteDatabase?, oldV: Int, newV: Int) {
TODO("Not yet implemented") TODO("Not yet implemented")
} }
public fun eraseAbstractProduct(db: SQLiteDatabase, id: Int, context: Context) { public fun eraseAbstractProduct(db: SQLiteDatabase, id: Int, context: Context) {
val projection = arrayOf(BaseColumns._ID, val projection = arrayOf(
ProductContract.ProductEntry.IMAGE_FILENAME ProductContract.ProductEntry.IMAGE_FILENAME
) )
// val cursor = db.query(ProductContract.ProductEntry.TABLE_NAME, projection, null, , null, null, null)
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(
@ -76,12 +80,10 @@ class DBStorageController(context: Context) : SQLiteOpenHelper(context, DATABASE
null, null,
null null
) )
// val cursor = db.rawQuery("SELECT image_filename FROM ${ProductContract.ProductEntry.TABLE_NAME} WHERE ${BaseColumns._ID}=$id", null)
var imageHash: String = "" var imageHash: String = ""
with (cursor) { with (cursor) {
while(moveToNext()) { while(moveToNext()) {
val productId = getInt(getColumnIndexOrThrow(BaseColumns._ID))
val productImageHash = getString(getColumnIndexOrThrow(ProductContract.ProductEntry.IMAGE_FILENAME)) val productImageHash = getString(getColumnIndexOrThrow(ProductContract.ProductEntry.IMAGE_FILENAME))
imageHash = productImageHash imageHash = productImageHash
} }

View File

@ -0,0 +1,46 @@
package org.foxarmy.barcodescannerforemployees.activities
import android.app.Activity
import android.content.ContentValues
import android.os.Bundle
import android.provider.BaseColumns
import android.widget.Button
import android.widget.EditText
import org.foxarmy.barcodescannerforemployees.CategoriesContract
import org.foxarmy.barcodescannerforemployees.DBStorageController
import org.foxarmy.barcodescannerforemployees.R
class AddCategoryActivity : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_add_category)
val extras = intent.extras
val categoryId = extras!!.get("categoryid") as Int?
val categoryName = extras.get("categoryname") as String?
val categoryNameTextEdit: EditText = findViewById(R.id.newCategoryName)
categoryNameTextEdit.setText(categoryName)
findViewById<Button>(R.id.saveButton).setOnClickListener {
val db = DBStorageController(this).writableDatabase
if (categoryId == 0) { // Inserting new category
val values = ContentValues().apply {
put(CategoriesContract.CategoryEntry.CATEGORY_NAME, categoryNameTextEdit.text.toString())
}
db.insert(CategoriesContract.CategoryEntry.TABLE_NAME, null, values)
} else { // Updating existing category
val values = ContentValues().apply {
put(CategoriesContract.CategoryEntry.CATEGORY_NAME, categoryNameTextEdit.text.toString())
}
db.update(CategoriesContract.CategoryEntry.TABLE_NAME, values, "${BaseColumns._ID} = ?", arrayOf(categoryId.toString()))
}
finish()
}
}
}

View File

@ -4,11 +4,9 @@ import android.Manifest
import android.content.ContentValues import android.content.ContentValues
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.provider.BaseColumns
import android.util.Log import android.util.Log
import android.widget.Button import android.widget.*
import android.widget.ImageView
import android.widget.TextView
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
@ -31,6 +29,8 @@ class AddProductActivity : AppCompatActivity() {
private lateinit var productNameText: TextView private lateinit var productNameText: TextView
private lateinit var netWeightText: TextView private lateinit var netWeightText: TextView
private lateinit var categorySpinner: Spinner
private lateinit var pictureFile: File private lateinit var pictureFile: File
private lateinit var picturesPath: File private lateinit var picturesPath: File
private lateinit var binding: ActivityAddProductBinding private lateinit var binding: ActivityAddProductBinding
@ -43,7 +43,6 @@ class AddProductActivity : AppCompatActivity() {
picturesPath = File(filesDir, "pictures") picturesPath = File(filesDir, "pictures")
picturesPath.mkdirs() picturesPath.mkdirs()
// imageView = binding.includeContent.addProductLayout
imageView = findViewById(R.id.imageView) imageView = findViewById(R.id.imageView)
saveButton = findViewById(R.id.saveButton) saveButton = findViewById(R.id.saveButton)
@ -53,6 +52,10 @@ class AddProductActivity : AppCompatActivity() {
productNameText = findViewById(R.id.productName) productNameText = findViewById(R.id.productName)
netWeightText = findViewById(R.id.netWeight) netWeightText = findViewById(R.id.netWeight)
categorySpinner = findViewById(R.id.categorySpinner)
fillupCategorySpinner()
saveButton.setOnClickListener { saveButton.setOnClickListener {
val productName = productNameText.text.toString() val productName = productNameText.text.toString()
val netWeight = netWeightText.text val netWeight = netWeightText.text
@ -70,13 +73,15 @@ class AddProductActivity : AppCompatActivity() {
} }
val db = DBStorageController(this).writableDatabase val db = DBStorageController(this).writableDatabase
Log.d("QWERTYUIOP", "Putting ${pictureFile.name}")
val values = ContentValues().apply { val values = ContentValues().apply {
put(ProductContract.ProductEntry.PRODUCT_NAME, productName) put(ProductContract.ProductEntry.PRODUCT_NAME, productName)
put(ProductContract.ProductEntry.PRODUCT_NET_WEIGHT, netWeight.toString()) put(ProductContract.ProductEntry.PRODUCT_NET_WEIGHT, netWeight.toString())
put(ProductContract.ProductEntry.IMAGE_FILENAME, pictureFile.nameWithoutExtension) put(ProductContract.ProductEntry.IMAGE_FILENAME, pictureFile.nameWithoutExtension)
put(ProductContract.ProductEntry.CATEGORY, categorySpinner.selectedItemPosition)
} }
Log.d("QWERTYUIOP", "SIP ${categorySpinner.selectedItemPosition}")
db.insert(ProductContract.ProductEntry.TABLE_NAME, null, values) db.insert(ProductContract.ProductEntry.TABLE_NAME, null, values)
finish() finish()
@ -112,6 +117,29 @@ class AddProductActivity : AppCompatActivity() {
// setContentView(binding.root) // 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) @RequiresApi(Build.VERSION_CODES.R)
val takePicture = registerForActivityResult(ActivityResultContracts.TakePicture()) { success: Boolean -> val takePicture = registerForActivityResult(ActivityResultContracts.TakePicture()) { success: Boolean ->
if (success) { if (success) {
@ -137,8 +165,10 @@ class AddProductActivity : AppCompatActivity() {
//Saving picture to a temp file for further hash calculation and moving to a proper directory //Saving picture to a temp file for further hash calculation and moving to a proper directory
val imageFile = File(this.filesDir, "image.png") val imageFile = File(this.filesDir, "image.png")
val imageUri = getImageUri(this, imageFile) val imageUri = getImageUri(this, imageFile)
if (imageUri != null) {
takePicture.launch(imageUri) takePicture.launch(imageUri)
} }
}
@RequiresApi(Build.VERSION_CODES.R) @RequiresApi(Build.VERSION_CODES.R)
val requestPermissionLauncher = val requestPermissionLauncher =

View File

@ -28,7 +28,7 @@ class FullscreenActivity : Activity() {
fullscreenImageView = findViewById(R.id.fullscreenImageView) fullscreenImageView = findViewById(R.id.fullscreenImageView)
val extras = intent.extras val extras = intent.extras
val imageHash = extras!!.get("imagehash") as String? //extras!!.getParcelable<Parcelable>("imagehash") as String? val imageHash = extras!!.get("imagehash") as String?
val picturesDir = File(filesDir, "pictures") val picturesDir = File(filesDir, "pictures")

View File

@ -33,11 +33,27 @@ class MainActivity : AppCompatActivity() {
// appBarConfiguration = AppBarConfiguration(navController.graph) // appBarConfiguration = AppBarConfiguration(navController.graph)
// setupActionBarWithNavController(navController, appBarConfiguration) // setupActionBarWithNavController(navController, appBarConfiguration)
binding.addProductFab.setOnClickListener { view -> binding.newElementFab.setOnClickListener { view ->
val currentPosition = binding.tabTablayout.selectedTabPosition
val fragment = adapter.getItem(currentPosition)
when (fragment::class.simpleName.toString()) {
"StorageFragment" -> {
val addProductIntent = Intent(this, AddProductActivity::class.java) val addProductIntent = Intent(this, AddProductActivity::class.java)
val extras = Bundle() val extras = Bundle()
ContextCompat.startActivity(this, addProductIntent, extras) ContextCompat.startActivity(this, addProductIntent, extras)
} }
"CategoriesFragment" -> {
val addCategoryIntent = Intent(this, AddCategoryActivity::class.java)
val extras = Bundle()
extras.putInt("categoryid", 0)
extras.putString("categoryname", "New category")
addCategoryIntent.putExtras(extras)
ContextCompat.startActivity(this, addCategoryIntent, extras)
}
}
}
} }
private fun setupViewPager(viewpager: ViewPager) { private fun setupViewPager(viewpager: ViewPager) {
@ -69,7 +85,6 @@ class MainActivity : AppCompatActivity() {
"StorageFragment" -> { "StorageFragment" -> {
val storageFragment = fragment as StorageFragment val storageFragment = fragment as StorageFragment
storageFragment.removeSelected() storageFragment.removeSelected()
} }
} }
true true

View File

@ -1,29 +1,20 @@
package org.foxarmy.barcodescannerforemployees.fragments package org.foxarmy.barcodescannerforemployees.fragments
import android.os.Bundle import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import org.foxarmy.barcodescannerforemployees.R import org.foxarmy.barcodescannerforemployees.R
import org.foxarmy.barcodescannerforemployees.databinding.FragmentAddProductBinding import org.foxarmy.barcodescannerforemployees.databinding.FragmentAddProductBinding
import java.io.File
class AddProductFragment : Fragment() { class AddProductFragment : Fragment() {
private lateinit var binding: FragmentAddProductBinding private lateinit var binding: FragmentAddProductBinding
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View { ): View {
Log.d("QWERTYUIOP", "хуета1")
binding = FragmentAddProductBinding.inflate(layoutInflater) binding = FragmentAddProductBinding.inflate(layoutInflater)
return inflater.inflate(R.layout.fragment_add_product, container, false) return inflater.inflate(R.layout.fragment_add_product, container, false)
} }

View File

@ -1,11 +1,17 @@
package org.foxarmy.barcodescannerforemployees.fragments package org.foxarmy.barcodescannerforemployees.fragments
import android.os.Bundle import android.os.Bundle
import android.provider.BaseColumns
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.LinearLayout
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import org.foxarmy.barcodescannerforemployees.CategoriesContract
import org.foxarmy.barcodescannerforemployees.Category
import org.foxarmy.barcodescannerforemployees.DBStorageController
import org.foxarmy.barcodescannerforemployees.R import org.foxarmy.barcodescannerforemployees.R
import org.foxarmy.barcodescannerforemployees.views.CategoryView
class CategoriesFragment : Fragment() { class CategoriesFragment : Fragment() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
@ -23,9 +29,34 @@ class CategoriesFragment : Fragment() {
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
// updateContent() updateContent()
} }
fun updateContent() {
val layout = view?.findViewById<LinearLayout>(R.id.categoriesLayout)
layout?.removeAllViews()
val db = DBStorageController(requireContext()).readableDatabase
val projection = arrayOf(
BaseColumns._ID,
CategoriesContract.CategoryEntry.CATEGORY_NAME
)
val cursor = db.query(CategoriesContract.CategoryEntry.TABLE_NAME, projection, null, null, null, null, null)
with (cursor) {
while(moveToNext()) {
val categoryId = getInt(getColumnIndexOrThrow(BaseColumns._ID))
val categoryName = getString(getColumnIndexOrThrow(CategoriesContract.CategoryEntry.CATEGORY_NAME))
val category = Category(categoryId, categoryName)
val categoryView = CategoryView(requireActivity(), requireContext(), category)
layout?.addView(categoryView)
}
}
}
// public fun updateContent() { // public fun updateContent() {
// //
// val grv = getView()?.findViewById<GridLayout>(R.id.contentGridLayout) // val grv = getView()?.findViewById<GridLayout>(R.id.contentGridLayout)
@ -65,6 +96,6 @@ class CategoriesFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
// updateContent() updateContent()
} }
} }

View File

@ -13,24 +13,12 @@ import androidx.gridlayout.widget.GridLayout
import org.foxarmy.barcodescannerforemployees.* import org.foxarmy.barcodescannerforemployees.*
import org.foxarmy.barcodescannerforemployees.views.AbstractProductView import org.foxarmy.barcodescannerforemployees.views.AbstractProductView
/**
* A simple [Fragment] subclass.
* Use the [StorageFragment.newInstance] factory method to
* create an instance of this fragment.
*/
class StorageFragment : Fragment() { class StorageFragment : Fragment() {
public var test_value = 1
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View? { ): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_storage, container, false) return inflater.inflate(R.layout.fragment_storage, container, false)
} }
@ -41,7 +29,7 @@ class StorageFragment : Fragment() {
} }
fun removeSelected() { fun removeSelected() {
val grv = getView()?.findViewById<GridLayout>(R.id.contentGridLayout) val grv = view?.findViewById<GridLayout>(R.id.contentGridLayout)
val db = DBStorageController(requireContext()) val db = DBStorageController(requireContext())
var deleted = false var deleted = false
@ -61,7 +49,7 @@ class StorageFragment : Fragment() {
fun updateContent() { fun updateContent() {
val grv = getView()?.findViewById<GridLayout>(R.id.contentGridLayout) val grv = view?.findViewById<GridLayout>(R.id.contentGridLayout)
grv?.removeAllViews() grv?.removeAllViews()
val db = DBStorageController(requireContext()).readableDatabase val db = DBStorageController(requireContext()).readableDatabase
@ -79,8 +67,20 @@ class StorageFragment : Fragment() {
val productName = getString(getColumnIndexOrThrow(ProductContract.ProductEntry.PRODUCT_NAME)) val productName = getString(getColumnIndexOrThrow(ProductContract.ProductEntry.PRODUCT_NAME))
val netWeight = getDouble(getColumnIndexOrThrow(ProductContract.ProductEntry.PRODUCT_NET_WEIGHT)) val netWeight = getDouble(getColumnIndexOrThrow(ProductContract.ProductEntry.PRODUCT_NET_WEIGHT))
val productImageHash = getString(getColumnIndexOrThrow(ProductContract.ProductEntry.IMAGE_FILENAME)) val productImageHash = getString(getColumnIndexOrThrow(ProductContract.ProductEntry.IMAGE_FILENAME))
val category = getInt(getColumnIndexOrThrow(ProductContract.ProductEntry.CATEGORY))
var categoryName = ""
val product = AbstractProduct(productId, productName, netWeight, productImageHash, 1) val projection2 = arrayOf(CategoriesContract.CategoryEntry.CATEGORY_NAME)
val cursor2 = db.query(CategoriesContract.CategoryEntry.TABLE_NAME, projection2, "${BaseColumns._ID} = ?",
arrayOf(category.toString()), null, null, BaseColumns._ID+" ASC")
with (cursor2) {
while (moveToNext()) {
categoryName = getString(getColumnIndexOrThrow(CategoriesContract.CategoryEntry.CATEGORY_NAME))
}
}
val product = AbstractProduct(productId, productName, netWeight, productImageHash, categoryName)
generateThumbnailForImage(context!!, productImageHash) generateThumbnailForImage(context!!, productImageHash)

View File

@ -61,8 +61,9 @@ class AbstractProductView: LinearLayout {
productNameField.text = product.name productNameField.text = product.name
netWeightField.text = product.netWeight.toString() netWeightField.text = product.netWeight.toString()
categoryField.text = product.categoryName
//TODO: category and units //TODO: units
productLayout.setOnLongClickListener { productLayout.setOnLongClickListener {
isProductSelected = !isProductSelected isProductSelected = !isProductSelected

View File

@ -0,0 +1,47 @@
package org.foxarmy.barcodescannerforemployees.views
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.widget.Button
import android.widget.LinearLayout
import android.widget.TextView
import androidx.core.content.ContextCompat
import org.foxarmy.barcodescannerforemployees.Category
import org.foxarmy.barcodescannerforemployees.R
import org.foxarmy.barcodescannerforemployees.activities.AddCategoryActivity
class CategoryView : LinearLayout {
var category: Category
val categoryName: TextView
val updateButton: Button
val deleteButton: Button
constructor(activity: Activity, context: Context, category: Category) : super(context) {
this.category = category
val inflater: LayoutInflater = activity.layoutInflater
inflater.inflate(R.layout.category_view, this)
categoryName = findViewById(R.id.categoryNameTextView)
updateButton = findViewById(R.id.updateButton)
deleteButton = findViewById(R.id.deleteButton)
categoryName.text = category.name
updateButton.setOnClickListener {
val addCategoryIntent = Intent(context, AddCategoryActivity::class.java)
val extras = Bundle()
extras.putInt("categoryid", category.id)
extras.putString("categoryname", category.name)
addCategoryIntent.putExtras(extras)
ContextCompat.startActivity(context, addCategoryIntent, extras)
}
deleteButton.setOnClickListener {
TODO("implement delete button")
}
}
}

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".activities.AddCategoryActivity">
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="text"
android:text="@string/sample_category"
android:ems="10"
android:id="@+id/newCategoryName" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="20dp"/>
<Button
android:text="@string/saveButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="@+id/saveButton"
app:layout_constraintTop_toBottomOf="@+id/newCategoryName" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" android:layout_marginTop="40dp"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -43,7 +43,7 @@
app:layout_behavior="@string/appbar_scrolling_view_behavior" /> app:layout_behavior="@string/appbar_scrolling_view_behavior" />
<com.google.android.material.floatingactionbutton.FloatingActionButton <com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/add_product_fab" android:id="@+id/new_element_fab"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="bottom|end" android:layout_gravity="bottom|end"

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:text="@string/sample_category"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="@+id/categoryNameTextView" android:layout_weight="1"/>
<Button
android:layout_width="0dp"
android:layout_height="wrap_content" android:id="@+id/updateButton" android:layout_weight="1"
android:text="@string/update" android:lines="1"/>
<Button
android:text="@string/delete"
android:layout_width="0dp"
android:layout_height="wrap_content" android:id="@+id/deleteButton" android:layout_weight="1"/>
</LinearLayout>

View File

@ -16,8 +16,8 @@
android:layout_height="50dp" android:layout_height="50dp"
android:text="@string/scan_label" android:text="@string/scan_label"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/netWeight" app:layout_constraintTop_toBottomOf="@+id/categoryTextView"
android:layout_marginTop="25dp"/> android:layout_marginTop="15dp"/>
<ImageView <ImageView
android:src="@android:drawable/ic_menu_camera" android:src="@android:drawable/ic_menu_camera"
android:layout_width="356dp" android:layout_width="356dp"
@ -51,18 +51,31 @@
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
android:visibility="visible" android:hint="@string/netWeight" android:textColorHint="#737373" android:visibility="visible" android:hint="@string/netWeight" android:textColorHint="#737373"
app:layout_constraintTop_toBottomOf="@+id/productName"/> 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 <Button
android:text="@string/saveButton" android:text="@string/saveButton"
android:layout_width="100dp" android:layout_width="100dp"
android:layout_height="50dp" android:id="@+id/saveButton" android:layout_height="50dp" android:id="@+id/saveButton"
app:layout_constraintTop_toBottomOf="@+id/netWeight" app:layout_constraintTop_toBottomOf="@+id/categoryTextView"
android:layout_marginTop="25dp" app:layout_constraintEnd_toEndOf="parent"/> android:layout_marginTop="15dp" app:layout_constraintEnd_toEndOf="parent"/>
<Button <Button
android:text="@string/takePicture" android:text="@string/takePicture"
android:layout_width="100dp" android:layout_width="100dp"
android:layout_height="55dp" android:id="@+id/takePictureButton" android:layout_height="55dp" android:id="@+id/takePictureButton"
app:layout_constraintTop_toBottomOf="@+id/netWeight" app:layout_constraintTop_toBottomOf="@+id/categoryTextView"
android:layout_marginTop="24dp" app:layout_constraintStart_toEndOf="@+id/scan_button" android:layout_marginTop="15dp" app:layout_constraintStart_toEndOf="@+id/scan_button"
android:layout_marginStart="33dp" app:layout_constraintEnd_toStartOf="@+id/saveButton" android:layout_marginStart="33dp" app:layout_constraintEnd_toStartOf="@+id/saveButton"
android:layout_marginEnd="6dp" app:layout_constraintHorizontal_bias="0.0"/> android:layout_marginEnd="6dp" app:layout_constraintHorizontal_bias="0.0"/>

View File

@ -5,9 +5,9 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:id="@+id/fragment_storage" android:id="@+id/fragment_storage"
tools:context=".fragments.CategoriesFragment"> tools:context=".fragments.CategoriesFragment">
<ScrollView <LinearLayout
android:orientation="vertical"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent" android:id="@+id/categoriesLayout">
android:id="@+id/categoriesLayout"> </LinearLayout>
</ScrollView>
</FrameLayout> </FrameLayout>

View File

@ -22,36 +22,8 @@
<string name="dummy_content">DUMMY\nCONTENT</string> <string name="dummy_content">DUMMY\nCONTENT</string>
<string name="fullscreen_image">Fullscreen image</string> <string name="fullscreen_image">Fullscreen image</string>
<string name="next">Next</string> <string name="next">Next</string>
<string name="delete_menu">Delete item(s)…</string>
<string name="lorem_ipsum"> <string name="update">update</string>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam in scelerisque sem. Mauris volutpat, dolor id <string name="delete">delete</string>
interdum ullamcorper, risus dolor egestas lectus, sit amet mattis purus dui nec risus. Maecenas non sodales <string name="category">Category</string>
nisi, vel dictum dolor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos
himenaeos. Suspendisse blandit eleifend diam, vel rutrum tellus vulputate quis. Aliquam eget libero aliquet,
imperdiet nisl a, ornare ex. Sed rhoncus est ut libero porta lobortis. Fusce in dictum tellus.\n\n
Suspendisse interdum ornare ante. Aliquam nec cursus lorem. Morbi id magna felis. Vivamus egestas, est a
condimentum egestas, turpis nisl iaculis ipsum, in dictum tellus dolor sed neque. Morbi tellus erat, dapibus ut
sem a, iaculis tincidunt dui. Interdum et malesuada fames ac ante ipsum primis in faucibus. Curabitur et eros
porttitor, ultricies urna vitae, molestie nibh. Phasellus at commodo eros, non aliquet metus. Sed maximus nisl
nec dolor bibendum, vel congue leo egestas.\n\n
Sed interdum tortor nibh, in sagittis risus mollis quis. Curabitur mi odio, condimentum sit amet auctor at,
mollis non turpis. Nullam pretium libero vestibulum, finibus orci vel, molestie quam. Fusce blandit tincidunt
nulla, quis sollicitudin libero facilisis et. Integer interdum nunc ligula, et fermentum metus hendrerit id.
Vestibulum lectus felis, dictum at lacinia sit amet, tristique id quam. Cras eu consequat dui. Suspendisse
sodales nunc ligula, in lobortis sem porta sed. Integer id ultrices magna, in luctus elit. Sed a pellentesque
est.\n\n
Aenean nunc velit, lacinia sed dolor sed, ultrices viverra nulla. Etiam a venenatis nibh. Morbi laoreet, tortor
sed facilisis varius, nibh orci rhoncus nulla, id elementum leo dui non lorem. Nam mollis ipsum quis auctor
varius. Quisque elementum eu libero sed commodo. In eros nisl, imperdiet vel imperdiet et, scelerisque a mauris.
Pellentesque varius ex nunc, quis imperdiet eros placerat ac. Duis finibus orci et est auctor tincidunt. Sed non
viverra ipsum. Nunc quis augue egestas, cursus lorem at, molestie sem. Morbi a consectetur ipsum, a placerat
diam. Etiam vulputate dignissim convallis. Integer faucibus mauris sit amet finibus convallis.\n\n
Phasellus in aliquet mi. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis
egestas. In volutpat arcu ut felis sagittis, in finibus massa gravida. Pellentesque id tellus orci. Integer
dictum, lorem sed efficitur ullamcorper, libero justo consectetur ipsum, in mollis nisl ex sed nisl. Donec
maximus ullamcorper sodales. Praesent bibendum rhoncus tellus nec feugiat. In a ornare nulla. Donec rhoncus
libero vel nunc consequat, quis tincidunt nisl eleifend. Cras bibendum enim a justo luctus vestibulum. Fusce
dictum libero quis erat maximus, vitae volutpat diam dignissim.
</string>
<string name="delete_menu">Delete item(s)...</string>
</resources> </resources>

View File

@ -14,6 +14,7 @@ navigationFragmentKtx = "2.8.0"
navigationUiKtx = "2.8.0" navigationUiKtx = "2.8.0"
firebaseCrashlyticsBuildtools = "3.0.2" firebaseCrashlyticsBuildtools = "3.0.2"
gridlayout = "1.0.0" gridlayout = "1.0.0"
activity = "1.9.2"
[libraries] [libraries]
androidx-camera-view = { module = "androidx.camera:camera-view", version.ref = "cameraView" } androidx-camera-view = { module = "androidx.camera:camera-view", version.ref = "cameraView" }
@ -29,6 +30,7 @@ androidx-navigation-fragment-ktx = { group = "androidx.navigation", name = "navi
androidx-navigation-ui-ktx = { group = "androidx.navigation", name = "navigation-ui-ktx", version.ref = "navigationUiKtx" } androidx-navigation-ui-ktx = { group = "androidx.navigation", name = "navigation-ui-ktx", version.ref = "navigationUiKtx" }
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" }
[plugins] [plugins]
android-application = { id = "com.android.application", version.ref = "agp" } android-application = { id = "com.android.application", version.ref = "agp" }