片段的初始化会导致动画滞后

时间:2018-08-29 18:51:17

标签: android performance android-fragments kotlin bottomnavigationview

在编写Android应用程序时,我遇到了口吃动画的问题。我将AHBottomNavigation用于导航,FragNav用于交换片段,而FlexibleAdapter用于RecyclerView。 该应用程序是由一个活动和五个片段组成的。当我尝试切换到应用程序中的第一个片段时,BottomNavigation动画会冻结一会儿。看起来非常难看。第二次选择相同的片段时,一切都会顺利进行。在我看来,初始化片段中的视图是错误的,但是我不知道如何以不同的方式进行操作。

AHBottomNavigation https://github.com/aurelhubert/ahbottomnavigation
FragNav https://github.com/ncapdevi/FragNav
FlexibleAdapter https://github.com/davideas/FlexibleAdapter

片段

class GradeFragment : BaseFragment(), GradeView {

@Inject
lateinit var presenter: GradePresenter

private val gradeAdapter = FlexibleAdapter<AbstractFlexibleItem<*>>(null, null, true)

companion object {
    fun newInstance() = GradeFragment()
}

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

override fun onActivityCreated(savedInstanceState: Bundle?) {
    super.onActivityCreated(savedInstanceState)
    presenter.run {
        attachView(this@GradeFragment)
        loadData()
    }
}

override fun initView() {
    gradeAdapter.run {
        isAutoCollapseOnExpand = true
        isAutoScrollOnExpand = true
        setOnUpdateListener { presenter.onUpdateDataList(it) }
        setOnItemClickListener { position ->
            getItem(position).let {
                if (it is GradeItem) {
                    GradeDialog.newInstance(it.grade).show(fragmentManager, it.toString())
                }
            }
        }
    }
    gradeRecycler.run {
        layoutManager = SmoothScrollLinearLayoutManager(context)
        adapter = gradeAdapter
    }
    gradeSwipe.setOnRefreshListener { presenter.loadData(forceRefresh = true) }
}

override fun updateData(data: List<GradeHeader>) {
    gradeAdapter.updateDataSet(data, true)
}

override fun isViewEmpty(): Boolean = gradeAdapter.isEmpty

override fun showEmptyView(show: Boolean) {
    gradeEmpty.visibility = if (show) VISIBLE else GONE
}

override fun showProgress(show: Boolean) {
    gradeProgress.visibility = if (show) VISIBLE else GONE
}

override fun setRefresh(show: Boolean) {
    gradeSwipe.isRefreshing = show
}

演示者

class GradePresenter @Inject constructor(
    private val errorHandler: ErrorHandler,
    private val schedulers: SchedulersManager,
    private val gradeRepository: GradeRepository,
    private val sessionRepository: SessionRepository) : BasePresenter<GradeView>(errorHandler) {

override fun attachView(view: GradeView) {
    super.attachView(view)
    view.initView()
}

fun loadData(forceRefresh: Boolean = false) {
    disposable.add(sessionRepository.getSemesters()
            .map { it.single { semester -> semester.current } }
            .flatMap { gradeRepository.getGrades(it, forceRefresh) }
            .map { it.groupBy { grade -> grade.subject } }
            .map { createGradeItems(it) }
            .subscribeOn(schedulers.backgroundThread())
            .observeOn(schedulers.mainThread())
            .doFinally { view?.setRefresh(false) }
            .doOnSuccess { if (it.isEmpty()) view?.showEmptyView(true) }
            .doOnError { view?.run { if (isViewEmpty()) showEmptyView(true) } }
            .subscribe({ view?.updateData(it) }) { errorHandler.proceed(it) })
}

private fun createGradeItems(items: Map<String, List<Grade>>): List<GradeHeader> {
    return items.map {
        val gradesAverage = calcAverage(it.value)
        GradeHeader().apply {
            subject = it.key
            average = view?.run {
                if (gradesAverage == 0f) emptyAverageString()
                else averageString().format(gradesAverage)
            }.orEmpty()
            number = view?.gradeNumberString(it.value.size).orEmpty()
            subItems = (it.value.map { item ->
                GradeItem().apply {
                    grade = item
                    weightString = view?.weightString().orEmpty()
                    valueColor = getValueColor(item.value)
                }
            })
        }
    }
}

fun onUpdateDataList(size: Int) {
    if (size != 0) view?.showProgress(false)
}

1 个答案:

答案 0 :(得分:0)

几天后,我设法通过将SDK更新到版本28来解决了该问题。充气时RecyclerView不再导致动画卡纸