I am creating a food orderin app. When I switch to dark mode, the app is crashing

I have posted the entire code in MainFragment.kt.Please look into it.

         lateinit var recl_view:RecyclerView
    lateinit var progress_bar:RelativeLayout
     var list =ArrayList<DataList>()
    lateinit var no_net:ImageView
    lateinit var refresh:SwipeRefreshLayout
    lateinit var search_bar:EditText
    lateinit var appbar:AppBarLayout
    lateinit var nav_view:NavigationView
    var asc = true
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val view = inflater.inflate(R.layout.fragment_main, container, false)
        setHasOptionsMenu(true)
        search_bar = view.findViewById(R.id.main_search_bar)
        refresh = view.findViewById(R.id.main_frg_swipe_refresh)
        search_bar.setHint("Search Restaurants")
        no_net = view.findViewById(R.id.main_frg_no_net)
        appbar = view.findViewById(R.id.main_frg_appbar)
        progress_bar = view.findViewById(R.id.frg_main_prgs)
        nav_view = requireActivity().findViewById(R.id.main_navigation_view) as NavigationView
        nav_view.setCheckedItem(R.id.home_select)
        if(Connection().checkConnectivity(activity as Context)) {
            no_net.visibility = View.GONE
            appbar.visibility = View.VISIBLE
            val q = Volley.newRequestQueue(activity as Context)
            val url = "http://13.235.250.119/v2/restaurants/fetch_result/"
            try{
                progress_bar.visibility = View.VISIBLE
                val jsonreq = object : JsonObjectRequest(
                    Request.Method.GET,url,null,
                    Response.Listener {
                        if(it.getJSONObject("data").getBoolean("success")){
                            list = arrayListOf<DataList>()
                            val data = it.getJSONObject("data").getJSONArray("data")
                            for(i in 0 until data.length()){
                                list.add(
                                    DataList(
                                        data.getJSONObject(i).getString("id"),
                                        data.getJSONObject(i).getString("name"),
                                        data.getJSONObject(i).getString("rating"),
                                        data.getJSONObject(i).getString("cost_for_one"),
                                        data.getJSONObject(i).getString("image_url")
                                    )
                                )
                            }
                            recl_view = view.findViewById(R.id.frg_main_rec_view)
                            recl_view.layoutManager = LinearLayoutManager(activity)
                            recl_view.adapter = MainAdapter(activity as Context,list)
                            progress_bar.visibility = View.GONE
                        }
                    },
                    Response.ErrorListener {
                        appbar.visibility = View.GONE
                        progress_bar.visibility = View.GONE
                        Toast.makeText(activity as Context,"Please Try Again Later.", Toast.LENGTH_SHORT).show()
                    }){
                    override fun getHeaders(): MutableMap<String, String> {
                        val headers = HashMap<String, String>()
                        headers["Content-type"] = "application/json"
                        headers["token"] = "c3acf1e14c21f9"
                        return headers
                    }
                }
                q.add(jsonreq)
            }catch (e: Exception){
                appbar.visibility = View.GONE
                progress_bar.visibility = View.GONE
                Toast.makeText(activity as Context,"Please Try Again Later.", Toast.LENGTH_SHORT).show()
            }
        }
        else{
            appbar.visibility = View.GONE
            Toast.makeText(activity as Context,"Please Check your Internet Connection", Toast.LENGTH_SHORT).show()
            no_net.visibility = View.VISIBLE
        }
        search_bar.addTextChangedListener(object :TextWatcher{
            override fun afterTextChanged(p0: Editable?) {
            }
            override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
            }
            override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {

                val listData = arrayListOf<DataList>()
                for (i in 0 until list.size) {
                    if (list[i].name.toLowerCase()
                            .contains(search_bar.text.toString().toLowerCase()) ||
                        list[i].cost_for_one.contains(search_bar.text.toString()) ||
                        list[i].rating.contains(search_bar.text.toString())
                    ) {
                        listData.add(list[i])
                    }
                }
                recl_view.adapter = MainAdapter(activity as Context, listData)
                (recl_view.adapter as MainAdapter).notifyDataSetChanged()
            }


        }
        )
        refresh.setOnRefreshListener {
            getFragmentManager()?.beginTransaction()?.detach(this)?.attach(this)?.commit()

        }
        return view

    }
         
    override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
        if(Connection().checkConnectivity(activity as Context)) {
            MenuInflater(activity as Context).inflate(R.menu.app_bar_menu, menu)
            return super.onCreateOptionsMenu(menu, inflater)
        }

The error is shown here

Process: com.example.foodly, PID: 9860 kotlin.UninitializedPropertyAccessException: lateinit property recl_view has not been initialized at com.example.foodly.fragments.MainFragment.getRecl_view(MainFragment.kt:32) at com.example.foodly.fragments.MainFragment$onCreateView$1.onTextChanged(MainFragment.kt:126) at android.widget.TextView.sendOnTextChanged(TextView.java:11785) at android.widget.TextView.setText(TextView.java:6965) at android.widget.TextView.setText(TextView.java:6761) at android.widget.EditText.setText(EditText.java:145) at android.widget.TextView.setText(TextView.java:6713) at android.widget.TextView.onRestoreInstanceState(TextView.java:6580) at android.view.View.dispatchRestoreInstanceState(View.java:22288) at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:4805) at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:4805) at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:4805) at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:4805) at android.view.View.restoreHierarchyState(View.java:22266) at androidx.fragment.app.Fragment.restoreViewState(Fragment.java:639) at androidx.fragment.app.Fragment.restoreViewState(Fragment.java:3010) at androidx.fragment.app.Fragment.performActivityCreated(Fragment.java:3001)

This error is shown only when we switch from dark mode to light mode or vice versa.

1 answer

  • answered 2021-06-23 12:57 user2042632

    You need to move the assignment of the recl_view variable outside your network request callback and into the main body of onCreateView, e.g.:

    ...
    nav_view = requireActivity().findViewById(R.id.main_navigation_view) as NavigationView
    nav_view.setCheckedItem(R.id.home_select)
    
    recl_view = view.findViewById(R.id.frg_main_rec_view)
    
    if(Connection().checkConnectivity(activity as Context)) {
        no_net.visibility = View.GONE
        ...
    

    This is because when the view is recreated (e.g. when rotated, or switch dark/light mode) the onTextChanged method of the TextWatcher attached to search_bar is called and this method accesses recl_view, but this will only have been initialised once your network request has finished.