I tried creating a simple database in which i can add a product. delete products, and search. I followed a tutorial on a book as i am a beginner in kotlin and android studio.
Here is the Manifest :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.RoomDemo"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data
android:name="android.app.lib_name"
android:value="" />
</activity>
</application>
</manifest>
Here is my main activity :
package com.ebookfrenzy.roomdemo
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.fragment.app.FragmentActivity
import com.ebookfrenzy.roomdemo.ui.main.MainFragment
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
if (savedInstanceState == null) {
supportFragmentManager.beginTransaction()
.replace(R.id.container, MainFragment.newInstance())
.commitNow()
}
}
}
here is the fragmentmain.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".ui.main.MainFragment">
<TableLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp">
<TextView
android:id="@+id/productID"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/product_id"
android:textSize="18sp" />
<TextView
android:id="@+id/text_not_assigned"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/not_assigned"
android:textSize="18sp" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp">
<TextView
android:id="@+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/product_name"
android:textSize="18sp" />
<EditText
android:id="@+id/productName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="none"
android:text=""
android:textSize="18sp"
tools:ignore="SpeakableTextPresentCheck,TouchTargetSizeCheck" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp">
<TextView
android:id="@+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/product_quantity"
android:textSize="18sp" />
<EditText
android:id="@+id/productQuantity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="number"
android:textSize="18sp"
tools:ignore="TouchTargetSizeCheck,SpeakableTextPresentCheck" />
</TableRow>
</TableLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:gravity="center_horizontal"
android:orientation="horizontal">
<Button
android:id="@+id/addButton"
style="@style/Widget.AppCompat.Button.Borderless"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/add"
android:textColor="@color/black" />
<Button
android:id="@+id/findButton"
style="@style/Widget.AppCompat.Button.Borderless"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Find"
android:textColor="@color/black" />
<Button
android:id="@+id/deleteButton"
style="@style/Widget.AppCompat.Button.Borderless"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/delete"
android:textColor="@color/black" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:baselineAligned="false" />
</LinearLayout>
</LinearLayout>
Finally, here is the logcat (only errors) :
2023-01-18 20:14:36.108 1950-1950/com.ebookfrenzy.roomdemo E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.ebookfrenzy.roomdemo, PID: 1950
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.ebookfrenzy.roomdemo/com.ebookfrenzy.roomdemo.MainActivity}: java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3676)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3813)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:101)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2308)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.app.ActivityThread.main(ActivityThread.java:7898)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
Caused by: java.lang.NullPointerException
at com.ebookfrenzy.roomdemo.ui.main.MainFragment.getBinding(MainFragment.kt:32)
at com.ebookfrenzy.roomdemo.ui.main.MainFragment.listenerSetup(MainFragment.kt:65)
at com.ebookfrenzy.roomdemo.ui.main.MainFragment.onCreate(MainFragment.kt:44)
at androidx.fragment.app.Fragment.performCreate(Fragment.java:2981)
at androidx.fragment.app.FragmentStateManager.create(FragmentStateManager.java:474)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:257)
at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1840)
at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1758)
at androidx.fragment.app.FragmentManager.execSingleAction(FragmentManager.java:1670)
at androidx.fragment.app.BackStackRecord.commitNow(BackStackRecord.java:317)
at com.ebookfrenzy.roomdemo.MainActivity.onCreate(MainActivity.kt:16)
at android.app.Activity.performCreate(Activity.java:8290)
at android.app.Activity.performCreate(Activity.java:8269)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1384)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3657)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3813)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:101)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2308)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.app.ActivityThread.main(ActivityThread.java:7898)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
as requested, here is the mainFragment file:
import androidx.lifecycle.ViewModelProvider
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import com.ebookfrenzy.roomdemo.ProductRepository
import com.ebookfrenzy.roomdemo.MainActivity
import com.ebookfrenzy.roomdemo.ProductDao
import com.ebookfrenzy.roomdemo.ui.main.ProductListAdapter
import android.view.ViewGroup
import com.ebookfrenzy.roomdemo.R
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.LinearLayoutManager
import com.ebookfrenzy.roomdemo.Product
import androidx.fragment.app.viewModels
import java.util.*
import com.ebookfrenzy.roomdemo.databinding.FragmentMainBinding
//preparation du main fragment
class MainFragment : Fragment() {
private var adapter: ProductListAdapter? = null
companion object {
fun newInstance() = MainFragment()
}
val viewModel: MainViewModel by viewModels()
private var _binding: FragmentMainBinding? = null
private val binding get() = _binding!!
// si ya une erreur c'est ici
private fun recyclerSetup(){
adapter = ProductListAdapter(R.layout.product_list_item)
binding.recyclerView.layoutManager = LinearLayoutManager(context)
binding.recyclerView.adapter = adapter
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
listenerSetup()
observerSetup()
recyclerSetup()
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentMainBinding.inflate(inflater, container, false)
return binding.root
}
private fun clearFields() {
binding.productID.text = ""
binding.productName.setText("")
binding.productQuantity.setText("")
}
//ajout de bouton listeners
private fun listenerSetup() {
binding.addButton.setOnClickListener {
val name = binding.productName.text.toString()
val quantity = binding.productQuantity.text.toString()
if (name != "" && quantity != "") {
val product = Product(name, Integer.parseInt(quantity))
viewModel.insertProduct(product)
clearFields()
} else {
binding.productID.text = " Infos Incompletes "
}
}
binding.findButton.setOnClickListener {
viewModel.findProduct(binding.productName.text.toString())
}
binding.deleteButton.setOnClickListener {
viewModel.deleteProduct(
binding.productName.text.toString()
)
clearFields()
}
}
private fun observerSetup() {
viewModel.getAllProducts()
?.observe(this, Observer { products -> products?.let { adapter?.setProductList(it) } })
viewModel.getSearchResults().observe(this, Observer { products ->
products?.let {
if(it.isNotEmpty()){
binding.productID.text = String .format(Locale.US, "%d", it[0].id)
binding.productName.setText(it[0].productName)
binding.productQuantity.setText(String.format(Locale.US,"%d",it[0].quantity))
}
else {
binding.productID.text = "No Match"
}
}
})
}
}
Thanks a lot for taking the time to help me !
i just tried to run the app on the android studio emulator and it displayed an error message saying : "RoomDemo keeps stoping" right after i launched the app. RoomDemo is the name of my app