OhHiMark
OhHiMark

Reputation: 55

The Fragment is created endless

I made my school project and faced a problem.

There is an application in which there are two fragments. One with a RecyclerView, in which there is a list of elements and the second fragment opens the details of the selected element.

When I press the back button from the screen with details, the first fragment blinks for a moment and that’s it. I looked at Logcat, it turns out the second fragment is constantly being recreated. I tried to find the reason myself, but could not.

Classes are big, I don’t know what to show you, maybe every little thing affects. I will attach links to classes:

MainActivity.class

class MainActivity : MvpAppCompatActivity(), MainActivityView {
@InjectPresenter
lateinit var  presenter: MainActivityPresenter
lateinit var fm : FragmentManager

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.main_activity)
    fm = supportFragmentManager
    nav_bottom.setOnNavigationItemSelectedListener { item ->
        when(item.itemId){
            R.id.nav_list -> {
                fm.beginTransaction()
                    .replace(R.id.fragment_container, AllCharactersListFragment.newInstance())
                    .addToBackStack(null).commit()
                true
            }
            R.id.nav_favourites -> {
                fm.beginTransaction()
                    .replace(R.id.fragment_container, FavouriteListFragment.newInstance())
                    .addToBackStack(null).commit()
                true
            }
            R.id.nav_search -> {
                fm.beginTransaction()
                    .replace(R.id.fragment_container, SearchCharacterFragment.newInstance())
                    .addToBackStack(null).commit()
                true
            }
            else -> false
        }
    }
}

override fun setFirstFragment() {
    fm.beginTransaction()
        .replace(R.id.fragment_container, AllCharactersListFragment.newInstance())
        .commit()
}

AllCharactersListFragment.class

class AllCharactersListFragment : MvpAppCompatFragment(), AllCharactersFragmentView {
@Inject
lateinit var apiService : RetrofitService
@Inject
lateinit var repository: Repository
@InjectPresenter
lateinit var presenter: AllCharacterPresenter
@ProvidePresenter
fun provideAllPresenter(): AllCharacterPresenter{
    return AllCharacterPresenter(repository, apiService)
}
var isLastPage = false
var isLoading = false
private lateinit var  mAdapter : CharacterAdapter
private lateinit var progress : ProgressBar


companion object {
    fun newInstance(): AllCharactersListFragment = AllCharactersListFragment()
}

override fun onAttach(context: Context) {
    super.onAttach(context)
    val component = DaggerAppComponent.builder().netModule(NetModule()).appModule(AppModule(context)).roomModule(
        RoomModule()).build()
    component.inject(this)
}


override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
    val view = inflater.inflate(R.layout.all_characters, container, false)
    val myRecyclerView = view.findViewById(R.id.character_list) as RecyclerView
    progress = view.findViewById(R.id.progressBar) as ProgressBar
    val layoutManager = LinearLayoutManager(activity)
    myRecyclerView.layoutManager = layoutManager
    mAdapter = CharacterAdapter(presenter)
    presenter.loadFirstCharacters()
    myRecyclerView.addOnScrollListener(object :
        PaginationScrollListener(layoutManager) {
        override fun isLastPage(): Boolean {
            return isLastPage
        }

        override fun isLoading(): Boolean {
            return isLoading
        }

        override fun loadMoreItems() {
            isLoading = true
            presenter.paginate()
            Log.d("potok", "poshol")
        }
    })
    myRecyclerView.adapter = mAdapter
    return view
}

override fun onGetDataSuccess(list: List<Character>) {
    mAdapter.addItems(list)
}

override fun showDetails(character : Character){
    fragmentManager!!.beginTransaction()
        .replace(R.id.fragment_container, FavouriteListFragment.newInstance())
        .addToBackStack(null).commit()
    }

override fun hideProgress() {
    progress.visibility = View.INVISIBLE
    isLoading = false
}

override fun showProgress() {
    progress.visibility = View.VISIBLE
}


override fun onDestroy() {
    mAdapter.clear()
    super.onDestroy()

}

DetailFragment.class

class DetailFragment : MvpAppCompatFragment(), DetailFragmentView {
@Inject
lateinit var characterRepository : Repository
val TAG_CHARACTER = "DETAILS"
lateinit var character : Character
@InjectPresenter
lateinit var presenter : DetailPresenter
@ProvidePresenter
fun providePresenter(): DetailPresenter {
    return DetailPresenter(repository = characterRepository)
}

companion object {
    fun newInstance(character: Character) : DetailFragment {
        val fragment = DetailFragment()
        val args = Bundle()
        args.putSerializable("DETAILS", character)
        fragment.arguments = args
        return fragment
    }
}

override fun onAttach(context: Context) {
    super.onAttach(context)
    arguments?.getSerializable(TAG_CHARACTER)?.let { character = it as Character }
    val component = DaggerAppComponent.builder().appModule(AppModule(activity!!.applicationContext)).roomModule(RoomModule()).build()
    component.inject(this)
    Log.d("test", "$character")
}


override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
    val v = inflater.inflate(R.layout.detail_character, container, false)
    presenter.init()
    val favButton = v.findViewById(R.id.star_button) as ImageButton
    val backButton = v.findViewById(R.id.back_button) as ImageButton
    favButton.setOnClickListener{ if (!character.isFavourite) {
        presenter.addToFavourite(character)
    } else {
        presenter.removeFromFavourite(character)
        }
    }
    backButton.setOnClickListener {fragmentManager!!.popBackStackImmediate() }
    Log.d("loop", "Created again")
    return v
}

override fun initDetails() {
    name_text.text = character.name
    gender_text.text = character.gender
    when {
        character.gender == "female" -> gender_image.setImageResource(R.drawable.ic_female_gender)
        character.gender == "n/a" -> gender_image.setImageResource(R.drawable.ic_na_gender)
        character.gender == "hermaphrodite" -> gender_image.setImageResource(R.drawable.ic_hermophrod_gender)
        character.gender == "male" -> gender_image.setImageResource(R.drawable.ic_male_gender)
    }
    height_text.text = character.height
    mass_text.text = character.mass
    year_text.text = character.birth_year
    if (character.isFavourite) star_button.setImageResource(R.drawable.ic_fill_favourite)
}

override fun addFavourite() {
    star_button.setImageResource(R.drawable.ic_fill_favourite)
    character.isFavourite = true
    Toast.makeText(context,"Add to favorite",Toast.LENGTH_SHORT).show()
}

override fun removeFavourite() {
    star_button.setImageResource(R.drawable.ic_hollow_favourite)
    Toast.makeText(context, "Remove to favorite", Toast.LENGTH_SHORT).show()
}

Upvotes: 1

Views: 122

Answers (2)

Kishan Maurya
Kishan Maurya

Reputation: 3394

Please replace with below code

@StateStrategyType(AddToEndSingleStrategy::class)
interface AllCharactersFragmentView : MvpView {
    @StateStrategyType(OneExecutionStateStrategy::class)
    fun showDetails(character: Character)

    fun showProgress()
    fun hideProgress()
    fun onGetDataSuccess(list: List<Character>)
}

Basically, showdetail method was getting called agin and again. due to which, It keeps on adding DetailFragment every time

Upvotes: 1

user12013230
user12013230

Reputation:

The problem may be from the emulator.Sometimes it happens. Use the actual machine or if your computer's hardware is strong create a new emulator and try again.

Upvotes: 1

Related Questions