android cra sh ошибка: java .lang.IllegalStateException - PullRequest
0 голосов
/ 09 марта 2020

У меня есть домашняя да sh доска объявлений, содержащая навигационное представление. когда приложение запускается, оно ведет себя нормально. но когда я пытаюсь нажать на меню навигации и открыть заметки, мое приложение вылетает, показывая это сообщение об ошибке.

java.lang.IllegalStateException: Fragment NoteFragment not attached to a context

Ниже приведен мой код по этому поводу. исключение возникает при попытке добавить LinearLayoutManager в представление рециркулятора в noteFragment

  /**
 * Fundoo Notes
 * @description HomeDashBoardActivity displays all user actions.
 * @file HomeDashBoardActivity.kt
 * @author ksoundarya4
 * @version 1.0
 * @since 07/02/2020
 */
package com.bridgelabz.fundoonotes.note_module.dashboard_page.view

import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import androidx.appcompat.app.ActionBarDrawerToggle
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar
import androidx.drawerlayout.widget.DrawerLayout
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import com.bridgelabz.fundoonotes.R
import com.bridgelabz.fundoonotes.label_module.view.LabelFragment
import com.bridgelabz.fundoonotes.note_module.dashboard_page.model.Note
import com.bridgelabz.fundoonotes.note_module.dashboard_page.viewmodel.DashBoardViewModel
import com.bridgelabz.fundoonotes.note_module.dashboard_page.viewmodel.DashBoardViewModelFactory
import com.bridgelabz.fundoonotes.note_module.note_page.view.AddNoteFragment
import com.bridgelabz.fundoonotes.repository.local_service.DatabaseHelper
import com.bridgelabz.fundoonotes.user_module.login.view.LoginActivity
import com.bridgelabz.fundoonotes.user_module.login.view.toast
import com.bridgelabz.fundoonotes.user_module.registration.model.User
import com.google.android.material.floatingactionbutton.FloatingActionButton
import com.google.android.material.navigation.NavigationView

class HomeDashBoardActivity : AppCompatActivity() {

    private val dashBoadViewModelFactory: DashBoardViewModelFactory by lazy {
        DashBoardViewModelFactory(DatabaseHelper(this))
    }
    private val dashBoardViewModel: DashBoardViewModel by lazy {
        ViewModelProvider(this, dashBoadViewModelFactory).get(DashBoardViewModel::class.java)
    }
    private val toolbar: Toolbar by lazy {
        findViewById<Toolbar>(R.id.toolbar)
    }

    private val drawerLayout: DrawerLayout by lazy {
        findViewById<DrawerLayout>(R.id.drawer_layout)
    }

    private val navigationView: NavigationView by lazy {
        findViewById<NavigationView>(R.id.nav_view)
    }

    private val floatingActionButton: FloatingActionButton by lazy {
        findViewById<FloatingActionButton>(R.id.fab)
    }

    private val preferences: SharedPreferences by lazy {
        this.getSharedPreferences(
            "LaunchScreen",
            Context.MODE_PRIVATE
        )
    }
    private lateinit var authenticatedEmail: String
    private var authenticatedUser: User? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_home_dash_board)
        setSupportActionBar(toolbar)

        initHomeDashBoardActivity()
        authenticateUser()
        setClickOnFloatingActionButton()
        setNavigationItemClicked()
    }

    private fun authenticateUser() {

        dashBoardViewModel.authenticatedUser(authenticatedEmail)
        dashBoardViewModel.getUser().observe(this, Observer {
            observeUser(it)
        })
    }

    private fun observeUser(user: User?) {
        if (user != null)
            authenticatedUser = user
    }

    private fun initHomeDashBoardActivity() {

        getUserSharedPreferences()
        setActionBarToggle()
        setNoteFragment()
    }

    private fun setNoteFragment() {
        navigationView.setCheckedItem(R.id.nav_home)
        val fragment = NoteFragment()
        replaceFragment(fragment)
    }

    private fun getUserSharedPreferences() {
        val editor = preferences.edit()
        val email = preferences.getString("email", "")
        authenticatedEmail = email!!
        editor.apply()
    }

    override fun onCreateOptionsMenu(menu: Menu): Boolean {
        menuInflater.inflate(R.menu.home_dash_board, menu)
        return true
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        return when (item.itemId) {
            R.id.app_bar_user_info -> {
                startUserProfileFragment()
                toast(getString(R.string.tast_when_user_profile_clicked))
                true
            }
            else -> super.onOptionsItemSelected(item)
        }
    }

    override fun onBackPressed() {
        callFragmentsOnBackPressed()
        super.onBackPressed()
    }

    /**Function to set Floating Action Bar when it is clicked*/
    private fun setClickOnFloatingActionButton() {
        floatingActionButton.setOnClickListener {
            val bundle = setNoteArguments()
            replaceAddNoteFragment(bundle)
        }
    }

    private fun setNoteArguments(): Bundle? {
        val bundle = Bundle()
        val note = Note()
        if (authenticatedUser != null)
            note.userId = authenticatedUser!!.id
        bundle.putSerializable(getString(R.string.note), note)
        return bundle
    }

    /**Function to set Navigation Items when they are clicked*/
    private fun setNavigationItemClicked(): Boolean {

        navigationView.setNavigationItemSelectedListener { item ->
            when (item.itemId) {
                R.id.nav_home -> {
                    replaceFragment(NoteFragment())
                    return@setNavigationItemSelectedListener true
                }
                R.id.nav_sing_out -> {
                    onSignOutMenuClick()
                    return@setNavigationItemSelectedListener true
                }
                R.id.nav_archive -> {
                    replaceFragment(ArchiveFragment())
                    return@setNavigationItemSelectedListener true
                }
                R.id.nav_delete -> {
                    replaceFragment(TrashFragment())
                    return@setNavigationItemSelectedListener true
                }
                R.id.nav_label -> {
                    replaceFragment(LabelFragment())
                    return@setNavigationItemSelectedListener true
                }
                R.id.nav_reminder -> {
                    replaceFragment(ReminderFragment())
                    return@setNavigationItemSelectedListener true
                }
                else -> return@setNavigationItemSelectedListener false
            }
        }
        return true
    }

    private fun replaceFragment(fragment: Fragment?) {
        drawerLayout.closeDrawer(navigationView)
        val transaction = supportFragmentManager.beginTransaction()
        transaction.replace(R.id.fragment_container, fragment!!)
        transaction.commit()
    }


    /**Function to set Action Bar Toggle of Drawer Layout*/
    private fun setActionBarToggle() {
        val actionBarDrawerToggle = ActionBarDrawerToggle(
            this,
            drawerLayout,
            toolbar,
            R.string.navigation_drawer_open,
            R.string.navigation_drawer_close
        )
        drawerLayout.addDrawerListener(actionBarDrawerToggle)
        actionBarDrawerToggle.syncState()
    }

    /**Function to set alert dialog when SignOut
     * Menu item is clicked */
    private fun onSignOutMenuClick() {
        removePreference()
        signOutAlertDialog()
    }

    private fun removePreference() {
        if (preferences.contains("email")) {
            val editor = preferences.edit()
            editor.clear().apply()
        }
    }

    /**Function that performs sign out alert operation*/
    private fun signOutAlertDialog() {
        val alertDialogBuilder = AlertDialog.Builder(this)

        alertDialogBuilder.setMessage(getString(R.string.sign_out_alert_message))
        alertDialogBuilder.setTitle(getString(R.string.sign_out_alert_title))
        alertDialogBuilder.setCancelable(false)

        alertDialogBuilder
            .setPositiveButton(
                getString(R.string.sign_out_alert_positive_button)
            ) { _, _ ->
                navigateToLoginScreen()
                toast(
                    getString(R.string.toast_when_sign_out_alert_positive_button_clicked)
                )
            }
        alertDialogBuilder.setNegativeButton(getString(R.string.sign_out_alerst_negative_button))
        { dialog, _ ->
            drawerLayout.closeDrawer(navigationView)
            dialog.cancel()
        }

        val alertDialog = alertDialogBuilder.create()
        alertDialog.show()
    }

    /**Function to tell fragment that back navigation is Pressed*/
    private fun callFragmentsOnBackPressed() {
        val fragments: List<Fragment> = supportFragmentManager.fragments
        for (fragment in fragments) {
            if (fragment is OnBackPressed) {
                fragment.onBackPressed()
                setNoteFragment()
            }
        }
    }

    /**Function to replace home dash board with AddNoteFragment*/
    private fun replaceAddNoteFragment(bundle: Bundle?) {
        val fragment = AddNoteFragment()
        fragment.arguments = bundle
        val transaction = supportFragmentManager.beginTransaction()
        transaction.replace(R.id.fragment_container, fragment)
            .addToBackStack(null)
            .commit()
    }

    /**Function to navigate to LoginActivity*/
    private fun navigateToLoginScreen() {
        val intent = Intent(this, LoginActivity::class.java)
        finish()
        startActivity(intent)
    }

    private fun startUserProfileFragment(): Boolean {
        val fragmentManager = supportFragmentManager
        val reminderDialog = UserProfileDialogFragment()
        reminderDialog.arguments = Bundle().apply {
            putSerializable(getString(R.string.authenticated_user), authenticatedUser)
        }
        reminderDialog.show(fragmentManager, getString(R.string.dialog_reminder_title))
        return true
    }
}

Это мой фрагмент заметки

package com.bridgelabz.fundoonotes.note_module.dashboard_page.view

import android.os.Bundle
import android.util.Log
import android.view.*
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.SearchView
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.RecyclerView
import com.bridgelabz.fundoonotes.R
import com.bridgelabz.fundoonotes.note_module.dashboard_page.model.Note
import com.bridgelabz.fundoonotes.note_module.dashboard_page.view.recycler_view_strategy.RecyclerViewType
import com.bridgelabz.fundoonotes.note_module.dashboard_page.view.recycler_view_strategy.LinearRecyclerViewManager
import com.bridgelabz.fundoonotes.note_module.dashboard_page.view.recycler_view_strategy.RecyclerViewLayoutManager
import com.bridgelabz.fundoonotes.note_module.dashboard_page.view.recycler_view_strategy.StaggeredRecyclerViewtManager
import com.bridgelabz.fundoonotes.note_module.dashboard_page.viewmodel.NoteTableManagerFactory
import com.bridgelabz.fundoonotes.note_module.dashboard_page.viewmodel.SharedViewModel
import com.bridgelabz.fundoonotes.note_module.note_page.view.AddNoteFragment
import com.bridgelabz.fundoonotes.repository.local_service.DatabaseHelper
import com.bridgelabz.fundoonotes.repository.local_service.note_module.NoteTableManagerImpl

class NoteFragment : Fragment(), OnNoteClickListener {

    private val noteFactory by lazy {
        NoteTableManagerFactory(NoteTableManagerImpl(DatabaseHelper(requireContext())))
    }
    private val sharedViewModel: SharedViewModel by lazy {
        requireActivity().run {
            ViewModelProvider(
                this,
                noteFactory
            ).get(SharedViewModel::class.java)
        }
    }
    private val recyclerView: RecyclerView by lazy {
        requireView().findViewById<RecyclerView>(R.id.notes_recycler_view)
    }

    private lateinit var noteAdapter: NoteViewAdapter

    private lateinit var notes: ArrayList<Note>

    private var recyclerViewType = RecyclerViewType.ListView

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        setHasOptionsMenu(true)
        return inflater.inflate(R.layout.fragment_note, container, false)
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)

        sharedViewModel.getRecyclerViewType()
            .observe(requireActivity(), Observer { recyclerViewType = it })
        sharedViewModel.getSimpleNoteLiveData()
            .observe(requireActivity(), Observer { observeNotes(it) })

    }

    private fun initRecyclerView() {
        recyclerView.setHasFixedSize(true)
        recyclerView.layoutManager = setRecyclerViewType(recyclerViewType)
        recyclerView.adapter = noteAdapter
    }

    private fun observeNotes(noteList: ArrayList<Note>) {
        Log.d("noteList", noteList.toString())
        notes = noteList
        noteAdapter = NoteViewAdapter(notes, this)
        noteAdapter.notifyDataSetChanged()
        initRecyclerView()
    }

    override fun onClick(adapterPosition: Int) {
        val note = notes[adapterPosition]
        val bundle = Bundle()
        bundle.putSerializable(getString(R.string.note), note)
        replaceWithAddNoteFragment(bundle)
    }

    override fun onLongClick(adapterPosition: Int) {
        val note = notes[adapterPosition]
        Toast.makeText(requireActivity(), "$note", Toast.LENGTH_SHORT).show()
    }

    private fun replaceWithAddNoteFragment(bundle: Bundle) {
        val addNoteFragment = AddNoteFragment()
        addNoteFragment.arguments = bundle
        requireActivity().supportFragmentManager.beginTransaction()
            .replace(R.id.fragment_container, addNoteFragment).addToBackStack(null).commit()

    }

    override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
        (requireActivity() as AppCompatActivity).supportActionBar!!.title =
            getString(R.string.menu_notes)
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        return when (item.itemId) {
            R.id.app_bar_recycler_view -> {
                switchRecyclerViewType()
                switchIcon(item)
                true
            }
            R.id.app_bar_search_note -> {
                val searchView = item.actionView as SearchView
                searchView.setOnQueryTextListener(searchQueryListener)
                true
            }
            else -> false
        }
    }

    private val searchQueryListener = object : SearchView.OnQueryTextListener {
        override fun onQueryTextSubmit(query: String?): Boolean {
            return false
        }

        override fun onQueryTextChange(newText: String?): Boolean {
            noteAdapter.filter.filter(newText)
            return false
        }

    }

    private fun switchIcon(item: MenuItem) {

        if (recyclerViewType == RecyclerViewType.ListView)
            item.setIcon(R.drawable.ic_grid_view_white)
        else {
            item.setIcon(R.drawable.ic_list_view_white)
        }
    }

    private fun switchRecyclerViewType() {

        when (recyclerViewType) {
            RecyclerViewType.GridView -> {
                sharedViewModel.setRecyclerViewType(RecyclerViewType.ListView)
                recyclerView.layoutManager = setRecyclerViewType(recyclerViewType)
            }
            RecyclerViewType.ListView -> {
                sharedViewModel.setRecyclerViewType(RecyclerViewType.GridView)
                recyclerView.layoutManager = setRecyclerViewType(recyclerViewType)
            }
        }
    }

    private fun setRecyclerViewType(viewType: RecyclerViewType): RecyclerView.LayoutManager {
        val layoutManager = RecyclerViewLayoutManager()
        layoutManager.addRecyclerView(recyclerView)

        return when (viewType) {
            RecyclerViewType.ListView -> {
                layoutManager.setRecyclerView(LinearRecyclerViewManager(requireContext()))
            }
            RecyclerViewType.GridView -> {
                layoutManager.setRecyclerView(
                    StaggeredRecyclerViewtManager(
                        numberOfRows = 2,
                        orientation = 1
                    )
                )
            }
        }
    }
}

1 Ответ

0 голосов
/ 03 апреля 2020

Скорее всего, вы дважды нажимаете кнопку или как-то дважды вызывается навигационный вызов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...