Commit c81ee0c6 authored by Wahyu Wibowo's avatar Wahyu Wibowo

fixing crud product

parent 7c5ad26a
......@@ -2,6 +2,13 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.yourcashiertest">
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-feature
android:name="android.hardware.camera"
android:required="true" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
......@@ -24,6 +31,17 @@
android:theme="@style/AppTheme2" />
<activity android:name=".activities.MainActivity" android:theme="@style/AppTheme2"/>
<activity android:name=".activities.ProductActivity" android:theme="@style/AppTheme2"/>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.example.android.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_path"/>
</provider>
<meta-data
android:name="preloaded_fonts"
android:resource="@array/preloaded_fonts" />
......
package com.example.yourcashiertest.activities;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;
import androidx.lifecycle.ViewModelProvider;
import android.Manifest;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.PopupMenu;
import com.example.yourcashiertest.R;
import com.example.yourcashiertest.adapters.ProductAdapter;
import com.example.yourcashiertest.databinding.ActivityMainBinding;
import com.example.yourcashiertest.databinding.ItemListBinding;
import com.example.yourcashiertest.entities.Product;
import com.example.yourcashiertest.viewmodels.ProductViewModel;
public class MainActivity extends AppCompatActivity {
ActivityMainBinding binding;
ItemListBinding bindingItem;
public static final String DATA_PRODUCT = "DATA_PRODUCT";
private static final int REQUEST_PERMISSIONS = 111;
private String[] permissions = new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
requestPermissions(permissions, REQUEST_PERMISSIONS);
ImageView iv_settings, ivCart;
ProductAdapter adapter = new ProductAdapter();
binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
ivCart = findViewById(R.id.ivCart);
iv_settings = findViewById(R.id.iv_settings);
ivCart.setOnClickListener(view -> startActivity(new Intent(MainActivity.this, CartActivity.class)));
iv_settings.setOnClickListener(view -> {
PopupMenu popupMenu = new PopupMenu(getApplicationContext(), iv_settings);
// settings menu
binding.ivCart.setOnClickListener(view -> startActivity(new Intent(MainActivity.this, CartActivity.class)));
binding.ivSettings.setOnClickListener(view -> {
PopupMenu popupMenu = new PopupMenu(getApplicationContext(), binding.ivSettings);
popupMenu.setOnMenuItemClickListener(item -> {
switch (item.getItemId()) {
case R.id.item_one:
......@@ -33,14 +54,63 @@ public class MainActivity extends AppCompatActivity {
startActivity(new Intent(MainActivity.this, ProductActivity.class));
break;
case R.id.item_two:
// item two clicked
adapter.setVisibility(true);
return true;
}
return false;
});
popupMenu.inflate(R.menu.settings_menu);
popupMenu.show();
});
binding.rvProducts.setAdapter(adapter);
ProductViewModel viewModel = new ViewModelProvider(this).get(ProductViewModel.class);
viewModel.getProducts().observe(this, adapter::setProducts);
adapter.setListener(new ProductAdapter.ProductListener() {
@Override
public void onUpdate(Product product) {
startActivity(new Intent(MainActivity.this, ProductActivity.class)
.putExtra(DATA_PRODUCT, product));
}
@Override
public void onDelete(Product product) {
viewModel.deleteProduct(product);
}
});
binding.etSearch.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
viewModel.filter(s.toString().toLowerCase());
}
@Override
public void afterTextChanged(Editable s) {
}
});
binding.setViewModel(viewModel);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_PERMISSIONS && grantResults.length != permissions.length) {
requestPermissions(permissions, REQUEST_PERMISSIONS);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
binding = null;
}
}
\ No newline at end of file
package com.example.yourcashiertest.activities;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.FileProvider;
import androidx.databinding.DataBindingUtil;
import androidx.lifecycle.ViewModelProvider;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Spinner;
import android.widget.Toast;
import com.example.yourcashiertest.R;
import com.example.yourcashiertest.databinding.ActivityProductBinding;
import com.example.yourcashiertest.entities.Product;
import com.example.yourcashiertest.utils.ViewUtil;
import com.example.yourcashiertest.viewmodels.ProductViewModel;
public class ProductActivity extends AppCompatActivity implements AdapterView.OnItemSelectedListener{
AutoCompleteTextView spCategory;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
public class ProductActivity extends AppCompatActivity{
ActivityProductBinding binding;
private boolean isUpdate = false;
private static final int REQUEST_IMAGE_CAPTURE = 1;
private File file;
private ProductViewModel viewModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_product);
spCategory = findViewById(R.id.spCategory);
spCategory.setOnItemSelectedListener(this);
ArrayAdapter<CharSequence> arrayAdapter = ArrayAdapter.createFromResource(this, R.array.category,
android.R.layout.simple_spinner_item);
viewModel = new ViewModelProvider(this).get(ProductViewModel.class);
binding = DataBindingUtil.setContentView(this, R.layout.activity_product);
Product product = getIntent().getParcelableExtra(MainActivity.DATA_PRODUCT);
if (getSupportActionBar() != null) {
getSupportActionBar().setHomeButtonEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
if (product != null){
isUpdate = true;
viewModel.setProduct(product);
binding.btnSubmit.setText(R.string.btn_edit);
binding.tvHeadProduct.setText("UPDATE PRODUCT");
}else {
product = new Product("", "", 0, 0, "", "");
}
binding.cvProduct.setOnClickListener(v -> takePhoto());
Product fixProduct = product;
binding.btnSubmit.setOnClickListener(v -> {
try {
if (TextUtils.isEmpty(binding.etProduct.getText().toString())
|| TextUtils.isEmpty(binding.etPrice.getText().toString())
|| TextUtils.isEmpty(binding.etDescription.getText().toString())
|| TextUtils.isEmpty(binding.etQuantity.getText().toString())
|| TextUtils.isEmpty(binding.etCategory.getText().toString())){
ViewUtil.showMessage(binding.getRoot(), getString(R.string.form_error_message));
return;
}
if (file != null){
fixProduct.setPhoto(file.getAbsolutePath());
}else {
fixProduct.setPhoto("");
}
fixProduct.setName(binding.etProduct.getText().toString());
fixProduct.setCategory(binding.etCategory.getText().toString());
fixProduct.setDescription(binding.etDescription.getText().toString());
fixProduct.setPrice(Long.parseLong(binding.etPrice.getText().toString()));
fixProduct.setQuantity(Long.parseLong(binding.etQuantity.getText().toString()));
if (isUpdate){
viewModel.updateProduct(fixProduct);
}else {
viewModel.insertProduct(fixProduct);
}
arrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spCategory.setAdapter(arrayAdapter);
finish();
}catch (Exception e){
e.printStackTrace();
}
});
binding.setViewModel(viewModel);
}
private void takePhoto() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
File photoFile = createImageFile();
if (photoFile != null) {
Uri photoURI = FileProvider.getUriForFile(this,
"com.example.android.fileprovider",
photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
}
private File createImageFile() {
try {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File image = File.createTempFile(
"IMG_" + timeStamp + "_",
".jpg",
getExternalFilesDir(Environment.DIRECTORY_PICTURES)
);
file = image;
return image;
} catch (Exception ex) {
ex.printStackTrace();
return null;
}
}
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
//
// if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
// binding.setPhoto(file.getAbsolutePath());
// }
}
@Override
public boolean onSupportNavigateUp() {
onBackPressed();
return super.onSupportNavigateUp();
}
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
protected void onDestroy() {
super.onDestroy();
binding = null;
}
}
\ No newline at end of file
......@@ -19,6 +19,7 @@ import java.util.List;
public class ProductAdapter extends RecyclerView.Adapter<ProductAdapter.ViewHolder> {
private List<Product> products = new ArrayList<>();
private Boolean visibility;
public interface ProductListener {
void onUpdate(Product product);
......@@ -44,7 +45,7 @@ public class ProductAdapter extends RecyclerView.Adapter<ProductAdapter.ViewHold
return new ViewHolder(
DataBindingUtil.inflate(
LayoutInflater.from(parent.getContext()),
R.layout.item_product,
R.layout.item_list,
parent,
false
)
......@@ -54,6 +55,7 @@ public class ProductAdapter extends RecyclerView.Adapter<ProductAdapter.ViewHold
@Override
public void onBindViewHolder(@NonNull ProductAdapter.ViewHolder holder, int position) {
holder.bindData(products.get(position), listener);
holder.binding.setVisibility(visibility);
}
@Override
......@@ -63,7 +65,7 @@ public class ProductAdapter extends RecyclerView.Adapter<ProductAdapter.ViewHold
public static class ViewHolder extends RecyclerView.ViewHolder {
private ItemListBinding binding;
private Boolean visibility;
public ViewHolder(@NonNull ItemListBinding binding) {
super(binding.getRoot());
......@@ -88,4 +90,9 @@ public class ProductAdapter extends RecyclerView.Adapter<ProductAdapter.ViewHold
binding.ivDelete.setOnClickListener(view -> listener.onDelete(product));
}
}
public void setVisibility(Boolean visibility){
this.visibility = visibility;
}
}
\ No newline at end of file
......@@ -32,7 +32,7 @@ public abstract class LocalDatabase extends RoomDatabase {
synchronized (LocalDatabase.class) {
if (INSTANCE == null) {
INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
LocalDatabase.class, "pasarindo_database")
LocalDatabase.class, "yourcashier_database")
.build();
}
}
......
......@@ -2,10 +2,18 @@ package com.example.yourcashiertest.entities;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
import android.widget.ImageView;
import androidx.databinding.BindingAdapter;
import androidx.room.Entity;
import androidx.room.PrimaryKey;
import com.bumptech.glide.Glide;
import com.example.yourcashiertest.R;
import java.io.File;
@Entity(tableName = "products")
public class Product implements Parcelable {
......@@ -15,7 +23,7 @@ public class Product implements Parcelable {
private long price, quantity;
private String photo = "", name = "", description = "", category = "";
public Product(long price, long quantity, String photo, String name, String description, String category) {
public Product(String photo, String name, long price, long quantity, String description, String category) {
this.price = price;
this.quantity = quantity;
this.photo = photo;
......@@ -46,7 +54,6 @@ public class Product implements Parcelable {
return new Product[size];
}
};
public long getId() {
return id;
}
......@@ -118,4 +125,15 @@ public class Product implements Parcelable {
parcel.writeString(description);
parcel.writeString(category);
}
@BindingAdapter("file")
public static void setImage(ImageView view, String path) {
if (TextUtils.isEmpty(path)) view.setImageResource(R.drawable.unnamed);
else {
File file = new File(path);
if (file.exists()) Glide.with(view).load(file).into(view);
else view.setImageResource(R.drawable.unnamed);
}
}
}
package com.example.yourcashiertest.utils;
import android.view.View;
import com.google.android.material.snackbar.Snackbar;
public class ViewUtil {
public static void showMessage(View view, String message) {
Snackbar.make(view, message, Snackbar.LENGTH_LONG).show();
}
}
<?xml version="1.0" encoding="utf-8"?>
<font-family xmlns:app="http://schemas.android.com/apk/res-auto"
app:fontProviderAuthority="com.google.android.gms.fonts"
app:fontProviderPackage="com.google.android.gms"
app:fontProviderQuery="Allerta"
app:fontProviderCerts="@array/com_google_android_gms_fonts_certs">
</font-family>
<?xml version="1.0" encoding="utf-8"?>
<font-family xmlns:app="http://schemas.android.com/apk/res-auto"
app:fontProviderAuthority="com.google.android.gms.fonts"
app:fontProviderPackage="com.google.android.gms"
app:fontProviderQuery="Carter One"
app:fontProviderCerts="@array/com_google_android_gms_fonts_certs">
</font-family>
This diff is collapsed.
......@@ -4,9 +4,6 @@
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="photo"
type="String" />
<variable
name="viewModel"
......@@ -18,20 +15,22 @@
android:orientation="vertical"
android:background="@color/white"
android:layout_height="wrap_content">
<com.google.android.material.textview.MaterialTextView
android:id="@+id/tvHeadProduct"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="24dp"
android:layout_margin="@dimen/space_default"
android:text="ADD PRODUCT"/>
android:fontFamily="@font/carter_one"
android:text="ADD PRODUCT"
android:textSize="24dp" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_height="wrap_content"
tools:context=".activities.ProductActivity">
<com.google.android.material.card.MaterialCardView
......@@ -47,7 +46,8 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="@drawable/unnamed"/>
android:src="@drawable/unnamed"
app:file="@{viewModel.product.photo}"/>
</com.google.android.material.card.MaterialCardView>
......@@ -66,6 +66,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Nama produk"
android:text="@{viewModel.product.name}"
android:inputType="textCapWords"
android:textSize="@dimen/text_default" />
......@@ -86,6 +87,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Harga"
android:text="@{viewModel.product.price + ``}"
android:inputType="number"
android:textSize="@dimen/text_default" />
......@@ -107,22 +109,24 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Jumlah"
android:text="@{viewModel.product.quantity + ``}"
android:inputType="number"
android:textSize="@dimen/text_default" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/tilCategory"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.Dense.ExposedDropdownMenu"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.Dense"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/tilPrice"
android:layout_marginStart="@dimen/space_default"
android:layout_marginBottom="@dimen/space_default"
android:layout_marginEnd="@dimen/space_default">
<AutoCompleteTextView
android:id="@+id/spCategory"
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/etCategory"
android:hint="Categori"
android:text="@{viewModel.product.category}"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</com.google.android.material.textfield.TextInputLayout>
......@@ -145,7 +149,7 @@
android:inputType="textMultiLine"
android:lines="3"
android:maxLines="3"
android:text=""
android:text="@{viewModel.product.description}"
android:textSize="@dimen/text_default" />
</com.google.android.material.textfield.TextInputLayout>
......@@ -159,7 +163,7 @@
android:layout_margin="@dimen/space_default"
android:backgroundTint="@color/colorPrimary"
android:padding="16dp"
android:text="Tambah Produk"
android:text="@string/add_product"
android:textColor="@color/white"
app:cornerRadius="@dimen/space_default"
android:elevation="5dp" />
......
......@@ -4,6 +4,7 @@
xmlns:tools="http://schemas.android.com/tools">
<data>
<import type="android.view.View"/>
<variable
name="product"
type="com.example.yourcashiertest.entities.Product" />
......@@ -12,10 +13,15 @@
name="price"
type="String" />
<variable
name="visibility"
type="Boolean" />
</data>
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
app:cardElevation="2dp"
android:layout_height="wrap_content">
<androidx.constraintlayout.widget.ConstraintLayout
......@@ -27,20 +33,22 @@
android:id="@+id/iv_product"
android:adjustViewBounds="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_height="130dp"
android:scaleType="fitXY"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.526"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.075"
android:src="@drawable/burger"/>
app:file="@{product.photo}"/>
<ImageView
android:id="@+id/ivUpdate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="@dimen/space_small"
android:visibility="visible"
android:src="@drawable/ic_update"
app:layout_constraintBottom_toBottomOf="@+id/iv_product"
app:layout_constraintStart_toStartOf="@+id/iv_product"
......@@ -53,6 +61,7 @@
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:padding="@dimen/space_small"
android:visibility="visible"
android:src="@drawable/ic_delete"
app:layout_constraintBottom_toBottomOf="@+id/iv_product"
app:layout_constraintEnd_toEndOf="@+id/iv_product"
......@@ -63,22 +72,21 @@
android:id="@+id/tv_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/name"
android:layout_margin="10dp"
android:text="@{product.name}"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.45"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/iv_product"
app:layout_constraintVertical_bias="0.089" />
app:layout_constraintVertical_bias="0.0" />
<TextView
android:id="@+id/tv_desc"
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="@string/deskripsi"
android:text="@{product.description}"
android:layout_marginTop="10dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/tv_name"
app:layout_constraintHorizontal_bias="0.0"
......@@ -88,39 +96,30 @@
<TextView
android:id="@+id/tv_price"
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:text="@string/price"
android:text="@{price}"
android:textStyle="bold"
android:layout_marginTop="7dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="@+id/tv_desc"
app:layout_constraintTop_toBottomOf="@+id/tv_desc"
app:layout_constraintVertical_bias="0.37" />
<View
android:id="@+id/v_add"
android:layout_width="70dp"
android:layout_height="30dp"
android:background="@drawable/btn_shape"
app:layout_constraintBottom_toBottomOf="@+id/tv_price"
app:layout_constraintEnd_toEndOf="@+id/tv_name"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toEndOf="@+id/tv_price"
app:layout_constraintTop_toTopOf="@+id/tv_price"
app:layout_constraintVertical_bias="0.0" />
<ImageView
android:id="@+id/iv_add"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="@+id/v_add"
app:layout_constraintEnd_toEndOf="@+id/v_add"
app:layout_constraintStart_toStartOf="@+id/v_add"
app:layout_constraintTop_toTopOf="@+id/v_add"
app:srcCompat="@drawable/ic_baseline_add_shopping_cart_24" />
<com.google.android.material.button.MaterialButton
android:id="@+id/v_add"
style="@style/Widget.MaterialComponents.Button.Icon"
android:layout_width="match_parent"
android:layout_height="50dp"
android:padding="5dp"
android:layout_marginTop="7dp"
app:cornerRadius="5dp"
app:icon="@drawable/ic_baseline_add_shopping_cart_24"
app:iconGravity="textStart"
android:text="Add to cart"
app:layout_constraintTop_toBottomOf="@+id/tv_price" />
</androidx.constraintlayout.widget.ConstraintLayout>
......
<?xml version="1.0" encoding="utf-8"?>
<resources>
<array name="preloaded_fonts" translatable="false">
<item>@font/allerta</item>
<item>@font/carter_one</item>
<item>@font/roboto_bold</item>
</array>
</resources>
......@@ -20,4 +20,7 @@
<string name="deskripsi">Burger medium with tomato and meet.</string>
<string name="name">Burger Medium</string>
<string name="price">$600.00</string>
<string name="btn_edit">Update Product</string>
<string name="form_error_message">Nama produk, harga, deskripsi, quantity tidak boleh kosong</string>
<string name="add_product">Tambah Produk</string>
</resources>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-files-path
name="photos"
path="/" />
</paths>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment