I am trying to have a grid layout in a recyclerview to show and image text and a double variable. The goal is to add a search bar that will display the results to the recycleView. I am new to kotlin so forgive me if the problem is obvious. I am not sure exactly what is causing my app to crash, but I narrowed it down to 1 line of code in my
MainActivity.kt
dataList.add(mealData("mealTitle.toString()",
Restaurant.toString(),R.drawable.food1,"mealCat.toString()",
"mealDescription.toString()"))
I suspected it was my mealCost variable so I took it out but it is still crashing, here is my code
MainActivity.kt
package com.example.foodme2
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.recyclerview.widget.GridLayoutManager
import com.smarteist.autoimageslider.SliderView
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.food_search_list.*
class MainActivity : AppCompatActivity() {
private lateinit var showImage: ArrayList<Int>
lateinit var sliderView: SliderView
lateinit var sliderAdapter: SliderAdapter
private lateinit var photoAdapter: PhotoAdapter
private var dataList = mutableListOf<mealData>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
sliderView = findViewById(R.id.slider)
showImage = ArrayList()
showImage.add(R.drawable.food1)
showImage.add(R.drawable.food3)
showImage.add(R.drawable.food4)
sliderAdapter =SliderAdapter(showImage)
sliderView.autoCycleDirection = SliderView.LAYOUT_DIRECTION_LTR
sliderView.setSliderAdapter(sliderAdapter)
sliderView.scrollTimeInSec = 3
sliderView.isAutoCycle = true
sliderView.startAutoCycle()
recyclerView.layoutManager = GridLayoutManager(applicationContext,2)
photoAdapter = PhotoAdapter()
recyclerView.adapter = photoAdapter
dataList.add(mealData("mealTitle.toString()",
Restaurant.toString(),R.drawable.food1,"mealCat.toString()",
"mealDescription.toString()"))
photoAdapter.setDataList(dataList)
}
}
activityMain.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/Background"
android:layout_margin="2dp"
android:outlineAmbientShadowColor="@color/BorderColor"
tools:context=".MainActivity">
<com.smarteist.autoimageslider.SliderView
android:id="@ id/slider"
android:layout_width="match_parent"
android:layout_height="150dp"
android:layout_centerInParent="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:sliderAnimationDuration="600"
app:sliderAutoCycleDirection="back_and_forth"
app:sliderIndicatorAnimationDuration="600"
app:sliderIndicatorEnabled="true"
app:sliderIndicatorGravity="center_horizontal|bottom"
app:sliderIndicatorMargin="15dp"
app:sliderIndicatorOrientation="horizontal"
app:sliderIndicatorPadding="3dp"
app:sliderIndicatorRadius="2dp"
app:sliderIndicatorSelectedColor="#5A5A5A"
app:sliderIndicatorUnselectedColor="#FFF"
app:sliderScrollTimeInSec="1" />
<SearchView
android:id="@ id/searchView"
android:layout_width="match_parent"
android:layout_height="50dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@ id/slider" />
<androidx.recyclerview.widget.RecyclerView
android:id="@ id/recyclerView"
android:layout_width="406dp"
android:layout_height="400dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@ id/searchView" />
</androidx.constraintlayout.widget.ConstraintLayout>
The layout for the recyclerView food_search_list.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:background="@color/cadetGrey"
android:layout_margin="2dp"
android:layout_height="match_parent">
<ImageView
android:id="@ id/MealImage"
android:contentDescription="@string/Description"
android:layout_width="match_parent"
android:layout_height="130dp"
android:layout_marginTop="75dp"
android:background="@color/white"
android:padding="2dp" />
<TextView
android:id="@ id/Restaurant"
android:layout_width="156dp"
android:layout_height="29dp"
android:layout_marginStart="115dp"
android:textAlignment="center"
android:layout_marginTop="8dp"
android:padding="2dp"
android:background="@color/white"
/>
<TextView
android:id="@ id/mealTite"
android:layout_width="100dp"
android:layout_height="20dp"
android:layout_marginStart="140dp"
android:layout_marginTop="44dp"
android:background="@color/white"
android:padding="2dp" />
<TextView
android:id="@ id/mealDescription"
android:layout_width="168dp"
android:layout_height="95dp"
android:layout_marginStart="110dp"
android:layout_marginTop="210dp"
android:background="@color/white"
android:padding="2dp"
android:scaleX="45" />
<TextView
android:id="@ id/mealCost"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginStart="24dp"
android:layout_marginTop="10dp"
android:padding="2dp"
android:background="@color/white"
/>
<TextView
android:id="@ id/mealCat"
android:layout_width="50dp"
android:layout_height="20dp"
android:layout_marginStart="24dp"
android:layout_marginTop="10dp"/>
</androidx.cardview.widget.CardView>
data class mealData.kt
package com.example.foodme2
import android.widget.TextView
data class mealData(
// var mealId:Int = 0;
var mealName: String,
var restaurant: String,
var mealImage: Int,
var mealCat: String,
var mealDescription: String,
//var mealCost: Double,
)
The adapter for recyclerView mRecycleViewAdapter.kt
package com.example.foodme2
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
//import kotlinx.android.synthetic.main.food_search_list.view.*
class PhotoAdapter :RecyclerView.Adapter<PhotoAdapter.ViewHolder>() {
private var dataList = emptyList<mealData>()
internal fun setDataList(dataList: List<mealData>) {
this.dataList = dataList
}
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var mealImage: ImageView = itemView.findViewById(R.id.MealImage)
var mealName: TextView = itemView.findViewById(R.id.mealTite)
var mealCat: TextView = itemView.findViewById(R.id.mealCat)
var restaurant: TextView = itemView.findViewById(R.id.Restaurant)
var mealDescription: TextView = itemView.findViewById(R.id.mealDescription)
//var mealCost: TextView = itemView.findViewById(R.id.mealCost)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.food_search_list, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val data = dataList[position]
holder.mealImage.setImageResource(data.mealImage)
holder.mealName.text = data.mealName
holder.mealDescription.text = data.mealDescription
holder.mealCat.text = data.mealCat
holder.restaurant.text = data.restaurant
//holder.mealCost.text = data.mealCost.toString()
}
override fun getItemCount() = dataList.size
}
And The Android Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.foodme2">
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.FoodMe2">
<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>
</activity>
</application>
</manifest>
and the s from the debugger. I am trying to understand what was going on here all I got is the the Issue was in my MainActivity.kt and it was the line of code i first started.
--------- beginning of crash
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.foodme2, PID: 1784
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.foodme2/com.example.foodme2.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.widget.TextView.toString()' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3449)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
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:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.widget.TextView.toString()' on a null object reference
at com.example.foodme2.MainActivity.onCreate(MainActivity.kt:43)
at android.app.Activity.performCreate(Activity.java:7994)
at android.app.Activity.performCreate(Activity.java:7978)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3422)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
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:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
I/Process: Sending signal. PID: 1784 SIG: 9
Disconnected from the target VM, address: 'localhost:62990', transport: 'socket'
CodePudding user response:
Start by deleting:
import kotlinx.android.synthetic.main.food_search_list.*
(and consider moving away from Kotlin synthetic accessors, as they are deprecated)
That is not the activity's layout; do not attempt to reference widgets using those accessors.
Then, modify:
dataList.add(mealData("mealTitle.toString()",
Restaurant.toString(),R.drawable.food1,"mealCat.toString()",
"mealDescription.toString()"))
to get rid of references to widgets that are not in this activity and to populate your dataList
from actual data. For example, you could start with:
dataList.add(mealData("Sample Title",
Restaurant.toString(),R.drawable.food1,"Sample Category",
"Sample Description"))