-2

I am new to android development. I have only been doing it for about a month now so I apologize if this is a simple question. I am keep getting the following error when trying to run my app

     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void androidx.swiperefreshlayout.widget.SwipeRefreshLayout.setOnRefreshListener(androidx.swiperefreshlayout.widget.SwipeRefreshLayout$OnRefreshListener)' on a null object reference
        at edu.cogswell.tn.prism.MainActivity.onCreate(MainActivity.kt:54)
        at android.app.Activity.performCreate(Activity.java:7136)
        at android.app.Activity.performCreate(Activity.java:7127)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2893)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048) 
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78) 
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808) 
        at android.os.Handler.dispatchMessage(Handler.java:106) 
        at android.os.Looper.loop(Looper.java:193) 
        at android.app.ActivityThread.main(ActivityThread.java:6669) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858) 

Here is my code

package (package name)
import android.app.AlertDialog
import android.os.Bundle
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.navigation.findNavController
import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.setupActionBarWithNavController
import androidx.navigation.ui.setupWithNavController
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.google.android.material.bottomnavigation.BottomNavigationView
import com.google.gson.Gson
import edu.cogswell.tn.prism.`interface`.NewsService
import edu.cogswell.tn.prism.adapter.viewHolder.ListSourceAdapter
import edu.cogswell.tn.prism.common.Common
import edu.cogswell.tn.prism.modle.WebSite
import io.paperdb.Paper
import kotlinx.android.synthetic.main.fragment_central.*
import retrofit2.Call
import retrofit2.Response
import javax.security.auth.callback.Callback

class MainActivity : AppCompatActivity() {

    lateinit var layoutManager: LinearLayoutManager
    lateinit var myService: NewsService
    lateinit var adapter: ListSourceAdapter
    lateinit var dialog: AlertDialog
    var mSwipeRefreshLayout: SwipeRefreshLayout? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val bottomNavigationView = findViewById<BottomNavigationView>(R.id.bottomNaigationView)
        val navController = findNavController(R.id.fragment)

        val appBarConfiguration = AppBarConfiguration(
            setOf(
                R.id.central,
                R.id.leftWing,
                R.id.rightWing
            )
        )
        setupActionBarWithNavController(navController, appBarConfiguration)
        bottomNavigationView.setupWithNavController(navController)

        Paper.init(this)

        myService = Common.newsService

        swipe_to_refresh_centreal.setOnRefreshListener {
            loadWebSiteSource(true)
        }

        recycler_view_source_news_central.setHasFixedSize(true)
        layoutManager = LinearLayoutManager(this)
        recycler_view_source_news_central.layoutManager = layoutManager

        //dialog = SpotsDialog.Builder().setContext(this).build()

        loadWebSiteSource(false)

    }

    private fun loadWebSiteSource(isRefresh: Boolean) {
        if(!isRefresh){
            val cache = Paper.book().read<String>("cache")
            if(cache != null && !cache.isBlank() && cache != "null"){
                val website = Gson().fromJson<WebSite>(cache, WebSite::class.java)
                adapter = ListSourceAdapter(baseContext, website)
                adapter.notifyDataSetChanged()
                recycler_view_source_news_central.adapter = adapter
            }
            else{
                dialog.show()
                myService.sources.enqueue(object:retrofit2.Callback<WebSite>{
                    override fun onResponse(call: Call<WebSite>, response: Response<WebSite>) {
                        adapter = ListSourceAdapter(baseContext,response!!.body()!!)
                        adapter.notifyDataSetChanged()
                        recycler_view_source_news_central.adapter = adapter

                        Paper.book().write("cache", Gson().toJson(response!!.body()!!))
                        dialog.dismiss()
                    }

                    override fun onFailure(call: Call<WebSite>, t: Throwable) {
                        Toast.makeText(baseContext,"Failed",Toast.LENGTH_SHORT).show()
                    }
                })
            }
        }
        else{
            swipe_to_refresh_centreal.isRefreshing = true

            myService.sources.enqueue(object:retrofit2.Callback<WebSite>{
                override fun onResponse(call: Call<WebSite>, response: Response<WebSite>) {
                    adapter = ListSourceAdapter(baseContext,response!!.body()!!)
                    adapter.notifyDataSetChanged()
                    recycler_view_source_news_central.adapter = adapter

                    Paper.book().write("cache", Gson().toJson(response!!.body()!!))
                    swipe_to_refresh_centreal.isRefreshing=false
                }

                override fun onFailure(call: Call<WebSite>, t: Throwable) {
                    Toast.makeText(baseContext,"Failed",Toast.LENGTH_SHORT).show()
                }
            })
        }
    }
}

Here is the xml code

<?xml version="1.0" encoding="utf-8"?>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
    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/swipe_to_refresh_centreal"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".Central">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recycler_view_source_news_central"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="10dp" />

    </RelativeLayout>

</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

Not too sure why I keep getting this error. I am using this tutorial https://www.youtube.com/watch?v=mvVcqzJYAbY For reference.

Thank you in advance.

AllUser
  • 13
  • 1
  • 3
  • Hammered this as a dupe because loading views that exist in different layouts is equivalent to loading one that isn't present in the current one. That returns null. The dupe on fragments is barely applicable, but added it because it explains what synthetic does, which is call findViewById, which returns null if the view isn't present in the current view. – Zoe Dec 13 '20 at 10:38

2 Answers2

-1

I see that you use kotlin synthetic properties here. It's deprecated. So I recommend using any other instrument instead. Even findViewById is better in my opinion. So what's wrong here. It's an often issue related to kotlin synthetic properties - wrong imports. Look, you do all actions in an activity, but imported

import kotlinx.android.synthetic.main.fragment_central.*

So this line import view from layout named fragment_central. But you inflated activity_main instead. So this view simply does not exist here.

KoirN
  • 338
  • 1
  • 4
  • 14
  • What would you change in order to fix this? What is Kotlin Synthetic properties? Sorry if this is a dumb question I just really do not understand all the terminology yet. – AllUser Dec 13 '20 at 09:13
  • First of all remove import kotlinx.android.synthetic.main.fragment_central.*. Than change it to something like that val swipeToRefreshCentreal = findViewById(R.id.swipe_to_refresh_centreal) in onCreate method and use this variable – KoirN Dec 14 '20 at 15:07
-1

You are importing wrong layout. Can you try this. Pass your main activity layout in import section and remove the swiperefresh layout from import as well as from variable declaratiion. import kotlinx.android.synthetic.main.your_layout.*

Rajshekhar
  • 571
  • 5
  • 9