android - Fragment 是无限创造的

标签 android android-fragments kotlin

我在做我的学校项目时遇到了一个问题。

有一个应用程序,其中有两个 fragment 。一个带有 RecyclerView,其中有一个元素列表,第二个 fragment 打开所选元素的详细信息。

当我在显示详细信息的屏幕上按下后退按钮时,第一个 fragment 会闪烁片刻,仅此而已。我查看了 Logcat,发现第二个 fragment 正在不断被重新创建。我试图自己找到原因,但找不到。

类(class)很大,我不知道给你看什么,也许每一件小事都会影响。我将附上类(class)链接:

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()
}

最佳答案

请替换为以下代码

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

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

基本上,showdetail 方法被一次又一次地调用。 因此,它每次都会继续添加 DetailFragment

关于android - Fragment 是无限创造的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58146314/

相关文章:

android - 使用 match_parent 属性获取 View 宽度?

android - 如何从 RecyclerView.ViewHolder 调用 DialogFragment(带接口(interface)实现)

android - FragmentPagerAdapter 总是加载下一个 fragment 而不是当前 fragment

kotlin - kotlin 中的 init block 和构造函数有什么区别?

java - 如何在 JNI 中查找二维数组大小

android - 用于在android中打开/关闭相机手电筒的小部件

java - Kotlin:集合既没有泛型类型也没有 OneToMany.targetEntity()

android - 为什么 TextView 中的文本在回收器 View 中被截断?

c# - 动态标签 : Adding them using a dataset and checking if they exist

java - 嵌套viewpagers : letting the outer swipe but not the inner