Home > Net >  Kotlin Android - adding values to data class error, Why would it cause my app to crash
Kotlin Android - adding values to data class error, Why would it cause my app to crash

Time:07-17

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"))
  • Related