commit ce65b1b7e4e46cef29f6a7c405ff56804842196e Author: Ninjdai Date: Wed Dec 18 16:15:02 2024 +0100 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..aa724b7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +*.iml +.gradle +/local.properties +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml +.DS_Store +/build +/captures +.externalNativeBuild +.cxx +local.properties diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/.name b/.idea/.name new file mode 100644 index 0000000..f5d8cdf --- /dev/null +++ b/.idea/.name @@ -0,0 +1 @@ +BAL Scanner \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..b86273d --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml new file mode 100644 index 0000000..b268ef3 --- /dev/null +++ b/.idea/deploymentTargetSelector.xml @@ -0,0 +1,10 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..7b3006b --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml new file mode 100644 index 0000000..75d68e4 --- /dev/null +++ b/.idea/jarRepositories.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml new file mode 100644 index 0000000..bb44937 --- /dev/null +++ b/.idea/kotlinc.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/migrations.xml b/.idea/migrations.xml new file mode 100644 index 0000000..f8051a6 --- /dev/null +++ b/.idea/migrations.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..74dd639 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,10 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..16660f1 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,17 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..b90a710 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,58 @@ +plugins { + alias(libs.plugins.android.application) + alias(libs.plugins.kotlin.android) +} + +android { + namespace 'dev.ninjdai.balscanner' + compileSdk 35 + + defaultConfig { + applicationId "dev.ninjdai.balscanner" + minSdk 24 + targetSdk 34 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 + } + buildFeatures { + viewBinding true + } + + kotlinOptions { + jvmTarget = '11' + } +} + +dependencies { + + implementation libs.appcompat + implementation libs.material + implementation libs.constraintlayout + implementation libs.vectordrawable + implementation libs.lifecycle.livedata.ktx + implementation libs.lifecycle.viewmodel.ktx + implementation libs.navigation.fragment + implementation libs.navigation.ui + implementation libs.core.ktx + testImplementation libs.junit + androidTestImplementation libs.ext.junit + androidTestImplementation libs.espresso.core + + implementation libs.zxing.android.embedded + implementation ("com.squareup.retrofit2:retrofit:2.9.0") + implementation ("com.squareup.retrofit2:converter-gson:2.9.0") + implementation ("com.google.code.gson:gson:2.9.0") +} \ No newline at end of file diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/app/src/androidTest/java/dev/ninjdai/balscanner/ExampleInstrumentedTest.java b/app/src/androidTest/java/dev/ninjdai/balscanner/ExampleInstrumentedTest.java new file mode 100644 index 0000000..85536c4 --- /dev/null +++ b/app/src/androidTest/java/dev/ninjdai/balscanner/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package dev.ninjdai.balscanner; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + assertEquals("dev.ninjdai.balscanner", appContext.getPackageName()); + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..3039629 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/dev/ninjdai/balscanner/MainActivity.java b/app/src/main/java/dev/ninjdai/balscanner/MainActivity.java new file mode 100644 index 0000000..d3a785c --- /dev/null +++ b/app/src/main/java/dev/ninjdai/balscanner/MainActivity.java @@ -0,0 +1,48 @@ +package dev.ninjdai.balscanner; + +import android.os.Bundle; + +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import androidx.appcompat.app.AppCompatActivity; +import androidx.navigation.NavController; +import androidx.navigation.Navigation; +import androidx.navigation.ui.AppBarConfiguration; +import androidx.navigation.ui.NavigationUI; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import dev.ninjdai.balscanner.books.Book; +import dev.ninjdai.balscanner.books.Owner; +import dev.ninjdai.balscanner.databinding.ActivityMainBinding; + +public class MainActivity extends AppCompatActivity { + + private ActivityMainBinding binding; + + public static ConcurrentHashMap> books = new ConcurrentHashMap<>(); + public static Owner avril = new Owner("Avril", "Papillon"); + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + binding = ActivityMainBinding.inflate(getLayoutInflater()); + setContentView(binding.getRoot()); + + BottomNavigationView navView = findViewById(R.id.nav_view); + AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder( + R.id.navigation_home, R.id.navigation_scanner) + .build(); + NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_activity_main); + NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration); + NavigationUI.setupWithNavController(binding.navView, navController); + + books.put(avril, new ArrayList<>()); + books.get(avril).add(new Book("Test book", "Albert", "69420", avril, 0)); + } +} \ No newline at end of file diff --git a/app/src/main/java/dev/ninjdai/balscanner/books/Book.kt b/app/src/main/java/dev/ninjdai/balscanner/books/Book.kt new file mode 100644 index 0000000..7dac6e7 --- /dev/null +++ b/app/src/main/java/dev/ninjdai/balscanner/books/Book.kt @@ -0,0 +1,7 @@ +package dev.ninjdai.balscanner.books + +data class Book(val title: String, val author: String, val EAN: String, val owner: Owner, var price: Int) + +data class Owner(val firstName: String, val lastName: String) { + val id: String = firstName[0].toString() + lastName[0].toString() +} \ No newline at end of file diff --git a/app/src/main/java/dev/ninjdai/balscanner/ui/home/HomeFragment.java b/app/src/main/java/dev/ninjdai/balscanner/ui/home/HomeFragment.java new file mode 100644 index 0000000..2fff92e --- /dev/null +++ b/app/src/main/java/dev/ninjdai/balscanner/ui/home/HomeFragment.java @@ -0,0 +1,37 @@ +package dev.ninjdai.balscanner.ui.home; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.lifecycle.ViewModelProvider; + +import dev.ninjdai.balscanner.databinding.FragmentHomeBinding; + +public class HomeFragment extends Fragment { + + private FragmentHomeBinding binding; + + public View onCreateView(@NonNull LayoutInflater inflater, + ViewGroup container, Bundle savedInstanceState) { + HomeViewModel homeViewModel = + new ViewModelProvider(this).get(HomeViewModel.class); + + binding = FragmentHomeBinding.inflate(inflater, container, false); + View root = binding.getRoot(); + + final TextView textView = binding.textHome; + homeViewModel.getText().observe(getViewLifecycleOwner(), textView::setText); + return root; + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + binding = null; + } +} \ No newline at end of file diff --git a/app/src/main/java/dev/ninjdai/balscanner/ui/home/HomeViewModel.java b/app/src/main/java/dev/ninjdai/balscanner/ui/home/HomeViewModel.java new file mode 100644 index 0000000..6b77abf --- /dev/null +++ b/app/src/main/java/dev/ninjdai/balscanner/ui/home/HomeViewModel.java @@ -0,0 +1,19 @@ +package dev.ninjdai.balscanner.ui.home; + +import androidx.lifecycle.LiveData; +import androidx.lifecycle.MutableLiveData; +import androidx.lifecycle.ViewModel; + +public class HomeViewModel extends ViewModel { + + private final MutableLiveData mText; + + public HomeViewModel() { + mText = new MutableLiveData<>(); + mText.setValue("This is home fragment"); + } + + public LiveData getText() { + return mText; + } +} \ No newline at end of file diff --git a/app/src/main/java/dev/ninjdai/balscanner/ui/scanner/ScanViewModel.java b/app/src/main/java/dev/ninjdai/balscanner/ui/scanner/ScanViewModel.java new file mode 100644 index 0000000..a69345e --- /dev/null +++ b/app/src/main/java/dev/ninjdai/balscanner/ui/scanner/ScanViewModel.java @@ -0,0 +1,19 @@ +package dev.ninjdai.balscanner.ui.scanner; + +import androidx.lifecycle.LiveData; +import androidx.lifecycle.MutableLiveData; +import androidx.lifecycle.ViewModel; + +public class ScanViewModel extends ViewModel { + + private final MutableLiveData mText; + + public ScanViewModel() { + mText = new MutableLiveData<>(); + mText.setValue("Start scanning"); + } + + public LiveData getText() { + return mText; + } +} \ No newline at end of file diff --git a/app/src/main/java/dev/ninjdai/balscanner/ui/scanner/ScannerFragment.java b/app/src/main/java/dev/ninjdai/balscanner/ui/scanner/ScannerFragment.java new file mode 100644 index 0000000..0ad537b --- /dev/null +++ b/app/src/main/java/dev/ninjdai/balscanner/ui/scanner/ScannerFragment.java @@ -0,0 +1,208 @@ +package dev.ninjdai.balscanner.ui.scanner; + +import android.app.ProgressDialog; +import android.content.DialogInterface; +import android.os.AsyncTask; +import android.os.Bundle; +import android.text.InputType; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.EditText; +import android.widget.Toast; + +import androidx.activity.result.ActivityResultLauncher; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AlertDialog; +import androidx.fragment.app.Fragment; +import androidx.lifecycle.ViewModelProvider; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.journeyapps.barcodescanner.ScanContract; +import com.journeyapps.barcodescanner.ScanOptions; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.URL; +import java.net.URLConnection; +import java.util.ArrayList; + +import dev.ninjdai.balscanner.MainActivity; +import dev.ninjdai.balscanner.R; +import dev.ninjdai.balscanner.books.Book; +import dev.ninjdai.balscanner.databinding.FragmentScannerBinding; + +public class ScannerFragment extends Fragment { + + private FragmentScannerBinding binding; + private ScannerItemsAdapter adapter; + + private ProgressDialog pd; + + public View onCreateView(@NonNull LayoutInflater inflater, + ViewGroup container, Bundle savedInstanceState) { + ScanViewModel scanViewModel = + new ViewModelProvider(this).get(ScanViewModel.class); + + binding = FragmentScannerBinding.inflate(inflater, container, false); + View root = binding.getRoot(); + + return root; + } + + public void updateItems() { + adapter.notifyItemChanged(MainActivity.books.get(MainActivity.avril).size()-1); + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + + RecyclerView recyclerView = view.findViewById(R.id.scanner_items); + recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); + adapter = new ScannerItemsAdapter(getContext(), MainActivity.books.get(MainActivity.avril)); + + adapter.setClickListener((v, position) -> { + Toast.makeText(getActivity(), "Book: " + adapter.getItem(position), Toast.LENGTH_LONG).show(); + }); + adapter.setLongClickListener((v, position) -> { + Toast.makeText(getActivity(), "Removed " + adapter.getItem(position), Toast.LENGTH_LONG).show(); + adapter.removeItem(position); + adapter.notifyItemRemoved(position); + return true; + }); + recyclerView.setAdapter(adapter); + + ActivityResultLauncher barcodeLauncher = registerForActivityResult(new ScanContract(), + result -> { + if(result.getContents() == null) { + Toast.makeText(getActivity(), "Cancelled", Toast.LENGTH_LONG).show(); + } else { + String ean = result.getContents(); + Toast.makeText(getActivity(), "Scanned: " + ean, Toast.LENGTH_LONG).show(); + Thread thread = new Thread(() -> { + try { + String bookURL="https://openlibrary.org/isbn/"+ean+".json"; + URLConnection urlConn = null; + BufferedReader bufferedReader = null; + try + { + URL url = new URL(bookURL); + urlConn = url.openConnection(); + bufferedReader = new BufferedReader(new InputStreamReader(urlConn.getInputStream())); + + StringBuffer stringBuffer = new StringBuffer(); + String line; + while ((line = bufferedReader.readLine()) != null) + { + stringBuffer.append(line); + } + + JSONObject res = new JSONObject(stringBuffer.toString()); + try { + String title = res.getString("title"); + Book book = new Book(title, "", ean, MainActivity.avril, 0); + getActivity().runOnUiThread(() -> { + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + builder.setTitle("Prix"); + + final EditText input = new EditText(getActivity()); + input.setInputType(InputType.TYPE_CLASS_NUMBER); + builder.setView(input); + + builder.setPositiveButton("Valider", (dialog, which) -> { + book.setPrice(Integer.parseInt(input.getText().toString())); + MainActivity.books.computeIfPresent(MainActivity.avril, ((owner, ownerBooks) -> { + ownerBooks.add(book); + return ownerBooks; + })); + updateItems(); + }); + builder.setNegativeButton("Annuler", (dialog, which) -> dialog.cancel()); + builder.show(); + }); + } catch (JSONException ex) { + Log.e("App", "Failure", ex); + } + } + catch(Exception ex) + { + Log.e("App", "OpenLibraryFetchTask", ex); + } + finally + { + if(bufferedReader != null) + { + try { + bufferedReader.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + //Your code goes here + } catch (Exception e) { + Log.e("App", e.getMessage()); + } + }); + thread.start(); + } + }); + + Button scannerButton = view.findViewById(R.id.scanner_button); + scannerButton.setOnClickListener(v -> { + ScanOptions options = new ScanOptions(); + options.setOrientationLocked(false); + options.setPrompt("Scan a barcode"); + barcodeLauncher.launch(options); + }); + } + + JSONObject getJSONFromUrl(String fetchURL) { + URLConnection urlConn = null; + BufferedReader bufferedReader = null; + JSONObject object = null; + try { + URL url = new URL(fetchURL); + urlConn = url.openConnection(); + bufferedReader = new BufferedReader(new InputStreamReader(urlConn.getInputStream())); + + StringBuilder stringBuffer = new StringBuilder(); + String line; + while ((line = bufferedReader.readLine()) != null) { + stringBuffer.append(line); + } + + object = new JSONObject(stringBuffer.toString()); + } + catch (Exception e) { + Log.e("App", e.getMessage()); + } + finally + { + if(bufferedReader != null) + { + try { + bufferedReader.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return object; + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + binding = null; + } +} \ No newline at end of file diff --git a/app/src/main/java/dev/ninjdai/balscanner/ui/scanner/ScannerItemsAdapter.java b/app/src/main/java/dev/ninjdai/balscanner/ui/scanner/ScannerItemsAdapter.java new file mode 100644 index 0000000..6abec39 --- /dev/null +++ b/app/src/main/java/dev/ninjdai/balscanner/ui/scanner/ScannerItemsAdapter.java @@ -0,0 +1,99 @@ +package dev.ninjdai.balscanner.ui.scanner; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import java.util.List; + +import dev.ninjdai.balscanner.R; +import dev.ninjdai.balscanner.books.Book; + +public class ScannerItemsAdapter extends RecyclerView.Adapter { + + private final List mData; + private final LayoutInflater mInflater; + private ItemClickListener mClickListener; + private ItemLongClickListener mLongClickListener; + + // data is passed into the constructor + ScannerItemsAdapter(Context context, List data) { + this.mInflater = LayoutInflater.from(context); + this.mData = data; + } + + // inflates the row layout from xml when needed + @NonNull + @Override + public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = mInflater.inflate(R.layout.text_row_item, parent, false); + return new ViewHolder(view); + } + + // binds the data to the TextView in each row + @Override + public void onBindViewHolder(ViewHolder holder, int position) { + Book book = mData.get(position); + holder.myTextView.setText(String.format("%s (%s) - %s", book.getTitle(), book.getPrice()!=0 ? book.getPrice()+"€" : "PL", book.getEAN())); + } + + // total number of rows + @Override + public int getItemCount() { + return mData.size(); + } + + + // stores and recycles views as they are scrolled off screen + public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener { + TextView myTextView; + + ViewHolder(View itemView) { + super(itemView); + myTextView = itemView.findViewById(R.id.bookText); + itemView.setOnClickListener(this); + itemView.setOnLongClickListener(this); + } + + @Override + public void onClick(View view) { + if (mClickListener != null) mClickListener.onItemClick(view, getAdapterPosition()); + } + + @Override + public boolean onLongClick(View view) { + if (mClickListener != null) return mLongClickListener.onItemLongClick(view, getAdapterPosition()); + return false; + } + } + + // convenience method for getting data at click position + Book getItem(int id) { + return mData.get(id); + } + + Book removeItem(int id) { + return mData.remove(id); + } + + // allows clicks events to be caught + void setClickListener(ItemClickListener itemClickListener) { + this.mClickListener = itemClickListener; + } + void setLongClickListener(ItemLongClickListener itemLongClickListener) { + this.mLongClickListener = itemLongClickListener; + } + + // parent activity will implement this method to respond to click events + public interface ItemClickListener { + void onItemClick(View view, int position); + } + public interface ItemLongClickListener { + boolean onItemLongClick(View view, int position); + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000..2b068d1 --- /dev/null +++ b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_home_black_24dp.xml b/app/src/main/res/drawable/ic_home_black_24dp.xml new file mode 100644 index 0000000..f8bb0b5 --- /dev/null +++ b/app/src/main/res/drawable/ic_home_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..07d5da9 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_scanner_black_24dp.xml b/app/src/main/res/drawable/ic_scanner_black_24dp.xml new file mode 100644 index 0000000..46fc8de --- /dev/null +++ b/app/src/main/res/drawable/ic_scanner_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..a040d97 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,32 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml new file mode 100644 index 0000000..f3d9b08 --- /dev/null +++ b/app/src/main/res/layout/fragment_home.xml @@ -0,0 +1,22 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_scanner.xml b/app/src/main/res/layout/fragment_scanner.xml new file mode 100644 index 0000000..7d79acb --- /dev/null +++ b/app/src/main/res/layout/fragment_scanner.xml @@ -0,0 +1,24 @@ + + + +