| import com.suliang.common.base.adapter.BaseAdapterViewHolder | import com.suliang.common.base.adapter.BaseAdapterViewHolder | ||||
| import com.suliang.common.base.adapter.BaseRVAdapter | import com.suliang.common.base.adapter.BaseRVAdapter | ||||
| import com.suliang.common.extension.click | import com.suliang.common.extension.click | ||||
| import com.suliang.common.util.LogUtil | |||||
| import com.suliang.common.util.StringUtil | import com.suliang.common.util.StringUtil | ||||
| import com.xkl.cdl.R | import com.xkl.cdl.R | ||||
| import com.xkl.cdl.data.AppConstants | import com.xkl.cdl.data.AppConstants | ||||
| override fun onBindVH(holder : BaseAdapterViewHolder, position : Int) { | override fun onBindVH(holder : BaseAdapterViewHolder, position : Int) { | ||||
| when (courseType) { | when (courseType) { | ||||
| AppConstants.COURSE_TYPE_ENGLISH_VOICE, | AppConstants.COURSE_TYPE_ENGLISH_VOICE, | ||||
| AppConstants.COURSE_TYPE_ENGLISH_SPELL -> bindSpellOrVoice(holder, position) | |||||
| AppConstants.COURSE_TYPE_ENGLISH_SPELL -> bindSpellOrVoice(holder, holder.adapterPosition) | |||||
| else -> bindDiscern(holder, position) | else -> bindDiscern(holder, position) | ||||
| } | } | ||||
| } | } | ||||
| previousIsShowLine = previousSelectPosition == itemCount-1 && !lastIsLearnOver | previousIsShowLine = previousSelectPosition == itemCount-1 && !lastIsLearnOver | ||||
| currentSelectPosition = position | currentSelectPosition = position | ||||
| currentIsShowLine = true | currentIsShowLine = true | ||||
| LogUtil.e(" root click previousSelectPosition = $previousSelectPosition currentSelectPosition = $currentSelectPosition") | |||||
| notifyItemChanged(previousSelectPosition) | notifyItemChanged(previousSelectPosition) | ||||
| notifyItemChanged(currentSelectPosition) | notifyItemChanged(currentSelectPosition) | ||||
| //事件 | //事件 | ||||
| /** 拼写完成,点击下一条时,按需要调用移除当前item项 */ | /** 拼写完成,点击下一条时,按需要调用移除当前item项 */ | ||||
| fun spellNeedRemoveCurrent(){ | fun spellNeedRemoveCurrent(){ | ||||
| val tempPosition = currentSelectPosition | |||||
| currentIsShowLine = false | |||||
| currentSelectPosition = -1 | |||||
| removeData(tempPosition) | |||||
| LogUtil.e(" remove item before -> previousSelectPosition = $previousSelectPosition currentSelectPosition = $currentSelectPosition itemCount = $itemCount") | |||||
| // val tempPosition = currentSelectPosition | |||||
| // currentIsShowLine = false | |||||
| // currentSelectPosition = -1 | |||||
| // 如果上一个位置大于现在的选择位置,则移除当前位置后,坐标改变,上一个选中位置需要减一,否则位置不一致 | |||||
| if (previousSelectPosition > currentSelectPosition){ | |||||
| previousSelectPosition-- | |||||
| } | |||||
| removeData(currentSelectPosition) | |||||
| LogUtil.e(" remove item after-> previousSelectPosition = $previousSelectPosition currentSelectPosition = $currentSelectPosition itemCount = $itemCount") | |||||
| } | } | ||||
| private fun initLessonAfterTestOver(){ | private fun initLessonAfterTestOver(){ | ||||
| initNumber() | initNumber() | ||||
| initScore() | initScore() | ||||
| binding.run { | binding.run { | ||||
| tvScore.visibility = View.VISIBLE | tvScore.visibility = View.VISIBLE | ||||
| tvTip.visibility = View.VISIBLE | tvTip.visibility = View.VISIBLE | ||||
| tvTitle.visibility = View.VISIBLE | tvTitle.visibility = View.VISIBLE | ||||
| tvTip1.visibility = View.VISIBLE | |||||
| incStatisticsNumber.root.visibility = View.VISIBLE | incStatisticsNumber.root.visibility = View.VISIBLE | ||||
| tvTop.visibility = View.VISIBLE | tvTop.visibility = View.VISIBLE | ||||
| tvLeft.visibility = View.VISIBLE | tvLeft.visibility = View.VISIBLE | ||||
| vSplit.visibility = View.VISIBLE | vSplit.visibility = View.VISIBLE | ||||
| tvTitle.text = "恭喜你,完成了课时学后测试" | tvTitle.text = "恭喜你,完成了课时学后测试" |
| /** 获取下一题数据 */ | /** 获取下一题数据 */ | ||||
| fun loadNext() { | fun loadNext() { | ||||
| LogUtil.e("获取下一题") | |||||
| // LogUtil.e("获取下一题") | |||||
| isGetNextIng = true | isGetNextIng = true | ||||
| mHandler.postDelayed(toNextRunable, toNextTime) | mHandler.postDelayed(toNextRunable, toNextTime) | ||||
| } | } |
| import com.suliang.common.extension.click | import com.suliang.common.extension.click | ||||
| import com.suliang.common.util.DateUtil | import com.suliang.common.util.DateUtil | ||||
| import com.suliang.common.util.DrawableUti | import com.suliang.common.util.DrawableUti | ||||
| import com.suliang.common.util.LogUtil | |||||
| import com.suliang.common.util.image.ImageLoader | import com.suliang.common.util.image.ImageLoader | ||||
| import com.suliang.common.util.media.EMediaState | import com.suliang.common.util.media.EMediaState | ||||
| import com.suliang.common.util.media.IMPListener | import com.suliang.common.util.media.IMPListener | ||||
| /** 历史轨迹初始 */ | /** 历史轨迹初始 */ | ||||
| private fun initHistoricalRoute() { | private fun initHistoricalRoute() { | ||||
| adapterHistorical = AdapterHistoricalRoute(vm.learnData.lesson.courseType).apply { | |||||
| val initCourseType = when{ | |||||
| //自动播放时,将历史轨迹的课时类型修改为单词类型,避免辨音课程自动播放时显示横线 | |||||
| vm.learnData.isAutoPlay -> AppConstants.COURSE_TYPE_ENGLISH_DISCERN | |||||
| else -> vm.learnData.lesson.courseType | |||||
| } | |||||
| adapterHistorical = AdapterHistoricalRoute(initCourseType).apply { | |||||
| onItemClick = { v : View, position : Int, item : LearnWord -> | onItemClick = { v : View, position : Int, item : LearnWord -> | ||||
| if (!vm.learnData.isAutoPlay) { //自动播放历史轨迹点击无效 | if (!vm.learnData.isAutoPlay) { //自动播放历史轨迹点击无效 | ||||
| vm.clickHistoricalItem(item) | vm.clickHistoricalItem(item) | ||||
| bindingSpell.spellRecyclerView.run { | bindingSpell.spellRecyclerView.run { | ||||
| layoutManager = GridLayoutManager(this@LearnWordActivity, 2, GridLayoutManager.HORIZONTAL, false) | layoutManager = GridLayoutManager(this@LearnWordActivity, 2, GridLayoutManager.HORIZONTAL, false) | ||||
| addItemDecoration(SpellItemDecoration()) | addItemDecoration(SpellItemDecoration()) | ||||
| setHasFixedSize(true) | |||||
| // setHasFixedSize(true) | |||||
| (itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false | (itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false | ||||
| spellAdapter = AdapterSpell().apply { | spellAdapter = AdapterSpell().apply { | ||||
| onItemSpellingClickListener = itemSpellingClick | onItemSpellingClickListener = itemSpellingClick | ||||
| return@observe | return@observe | ||||
| } | } | ||||
| it?.run { | it?.run { | ||||
| if (vm.learnData.lesson.courseType == AppConstants.COURSE_TYPE_ENGLISH_VOICE && bindingWord.ivVoice.visibility == View.VISIBLE) MPManager.play( | |||||
| it, listener = impListener) | |||||
| if (vm.learnData.lesson.courseType == AppConstants.COURSE_TYPE_ENGLISH_VOICE && bindingWord.ivVoice.visibility == View.VISIBLE) | |||||
| MPManager.play(it, listener = impListener) | |||||
| else MPManager.play(it) | else MPManager.play(it) | ||||
| } ?: showToast("未找到发音文件") | } ?: showToast("未找到发音文件") | ||||
| } | } | ||||
| } | } | ||||
| //界面初始 | //界面初始 | ||||
| when (vm.learnData.lesson.courseType) { | when (vm.learnData.lesson.courseType) { | ||||
| AppConstants.COURSE_TYPE_ENGLISH_VOICE -> initVoice(it) | |||||
| AppConstants.COURSE_TYPE_ENGLISH_VOICE -> { | |||||
| initVoice(it) | |||||
| readFirst() | |||||
| } | |||||
| AppConstants.COURSE_TYPE_ENGLISH_SPELL -> initSpell(it) | AppConstants.COURSE_TYPE_ENGLISH_SPELL -> initSpell(it) | ||||
| else -> initWord(it) | |||||
| else -> { | |||||
| initWord(it) | |||||
| readFirst() //发音 | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| /**新数据到来,进行初始化*/ | /**新数据到来,进行初始化*/ | ||||
| @SuppressLint("SetTextI18n") | @SuppressLint("SetTextI18n") | ||||
| private fun initWord(learnWord : LearnWord) { | private fun initWord(learnWord : LearnWord) { | ||||
| //发音 | |||||
| readFirst() | |||||
| //图片 | //图片 | ||||
| if (vm.isNeedLoadPhoto) { | if (vm.isNeedLoadPhoto) { | ||||
| bindingWord.imgWord.visibility = View.INVISIBLE | bindingWord.imgWord.visibility = View.INVISIBLE | ||||
| /** 滑动到最后一项进行点击 */ | /** 滑动到最后一项进行点击 */ | ||||
| private fun skipToHistoricalLastItem() { | private fun skipToHistoricalLastItem() { | ||||
| val lastPosition = historicalLayoutManager.findLastCompletelyVisibleItemPosition() | |||||
| val itemCount = historicalLayoutManager.itemCount | |||||
| LogUtil.e("recyclerView smooth before -> completeVisibleItemPositon = $lastPosition , itemCount = $itemCount") | |||||
| if (lastPosition == itemCount - 1) { | |||||
| historicalLayoutManager.findViewByPosition(lastPosition)?.performClick() | |||||
| } else { | |||||
| binding.rvHistoricalRoute.addOnScrollListener(historicalScrollListener) | |||||
| binding.rvHistoricalRoute.smoothScrollToPosition(adapterHistorical.itemCount - 1) | |||||
| binding.rvHistoricalRoute.post{ | |||||
| val position = adapterHistorical.itemCount - 1 //最后item的位置 | |||||
| val last = historicalLayoutManager.findLastCompletelyVisibleItemPosition() //最后完全可见 | |||||
| if (position > last ){ //需要操作的位置大于当前最后显示的位置,则进行滚动 | |||||
| binding.rvHistoricalRoute.addOnScrollListener(historicalScrollListener) | |||||
| binding.rvHistoricalRoute.smoothScrollToPosition(position) | |||||
| }else { //position view 可见 | |||||
| historicalLayoutManager.findViewByPosition(position)?.performClick() | |||||
| } | |||||
| } | } | ||||
| //other way | |||||
| // historicalLayoutManager.scrollToPositionWithOffset(adapterHistorical.itemCount - 1,0) | |||||
| // historicalLayoutManager.findViewByPosition(historicalLayoutManager.findLastCompletelyVisibleItemPosition())?.performClick() | |||||
| } | } | ||||
| private val historicalScrollListener = object : OnScrollListener() { | private val historicalScrollListener = object : OnScrollListener() { | ||||
| override fun onScrollStateChanged(recyclerView : RecyclerView, newState : Int) { | override fun onScrollStateChanged(recyclerView : RecyclerView, newState : Int) { | ||||
| super.onScrollStateChanged(recyclerView, newState) | super.onScrollStateChanged(recyclerView, newState) |
| //数据上传完成监听: true 学习完成的上传 false可能是半途的返回事件,直接退出 | //数据上传完成监听: true 学习完成的上传 false可能是半途的返回事件,直接退出 | ||||
| val saveDataLiveData = MutableLiveData<Boolean>() | val saveDataLiveData = MutableLiveData<Boolean>() | ||||
| //是否显示返回弹窗 | //是否显示返回弹窗 | ||||
| private var isShowBackDialog = false | private var isShowBackDialog = false | ||||
| //自动播放模式:是否在自动播放中,默认是 | //自动播放模式:是否在自动播放中,默认是 | ||||
| var isAutoPlaying = true | var isAutoPlaying = true | ||||
| //当前单词的自动播放次数 | //当前单词的自动播放次数 | ||||
| var currentPlayTime = 0 | var currentPlayTime = 0 | ||||
| */ | */ | ||||
| override fun initRunValidTime() { | override fun initRunValidTime() { | ||||
| //自动播放单独定义有效时间规则,播放时时间和总时间一直,停止时播放时,通过触摸判断 | //自动播放单独定义有效时间规则,播放时时间和总时间一直,停止时播放时,通过触摸判断 | ||||
| if (learnData.isAutoPlay){ | |||||
| if (isRunValidTime){ | |||||
| if (learnData.isAutoPlay) { | |||||
| if (isRunValidTime) { | |||||
| validTime.postValue(validTime.value!!.plus(200)) | validTime.postValue(validTime.value!!.plus(200)) | ||||
| if (!isAutoPlaying){ //停止播放了 | |||||
| if (!isAutoPlaying) { //停止播放了 | |||||
| currentValidSurplusTime -= 200 | currentValidSurplusTime -= 200 | ||||
| isRunValidTime = currentValidSurplusTime > 0 | isRunValidTime = currentValidSurplusTime > 0 | ||||
| } | } | ||||
| } | } | ||||
| }else { | |||||
| } else { | |||||
| super.initRunValidTime() | super.initRunValidTime() | ||||
| } | } | ||||
| } | } | ||||
| /** 获取数据 */ | /** 获取数据 */ | ||||
| fun loadNext() { | fun loadNext() { | ||||
| //修改标记 | //修改标记 | ||||
| currentIsHistoricalItemClick = false | currentIsHistoricalItemClick = false | ||||
| //新数据自动播放次数归0 | //新数据自动播放次数归0 | ||||
| if (learnData.isAutoPlay){ | |||||
| if (learnData.isAutoPlay) { | |||||
| currentPlayTime = 0 | currentPlayTime = 0 | ||||
| } | } | ||||
| private fun sendEventBus() { | private fun sendEventBus() { | ||||
| //自动播放不发送信息通知 | //自动播放不发送信息通知 | ||||
| if (learnData.isAutoPlay) return | if (learnData.isAutoPlay) return | ||||
| LiveEventBus.get<LearnEventData>(AppConstants.EVENT_LESSON_DATA).post(LearnEventData(learnData.lesson.subjectId, | |||||
| learnData.lesson.courseId, | |||||
| AppConstants.DATA_LESSON_LEARN_OVER).apply { | |||||
| LiveEventBus.get<LearnEventData>(AppConstants.EVENT_LESSON_DATA) | |||||
| .post(LearnEventData(learnData.lesson.subjectId, learnData.lesson.courseId, | |||||
| AppConstants.DATA_LESSON_LEARN_OVER).apply { | |||||
| this.leesonPositionIndex = learnData.lesson.lessonPositionInList | this.leesonPositionIndex = learnData.lesson.lessonPositionInList | ||||
| this.newErrorMap = learnData.examErrorMap | this.newErrorMap = learnData.examErrorMap | ||||
| }) | }) | ||||
| override fun onResume(owner : LifecycleOwner) { | override fun onResume(owner : LifecycleOwner) { | ||||
| super.onResume(owner) | super.onResume(owner) | ||||
| if (!isAllOver) startTotalCounting() | |||||
| if (!isAllOver) { | |||||
| if (!isShowBackDialog || (learnData.isAutoPlay && isAutoPlaying)) { | |||||
| executeLearnValidTime() | |||||
| } | |||||
| startTotalCounting() | |||||
| } | |||||
| } | } | ||||
| override fun onPause(owner : LifecycleOwner) { | override fun onPause(owner : LifecycleOwner) { |
| //子课程对应的Fragment | //子课程对应的Fragment | ||||
| private var childFragments = mutableListOf<Fragment>() | private var childFragments = mutableListOf<Fragment>() | ||||
| //更多按钮的弹窗显示 | |||||
| private var moreDialog : BottomSheetDialog? = null | |||||
| // //更多按钮的弹窗显示 | |||||
| // private var moreDialog : BottomSheetDialog? = null | |||||
| //自动播放次数的弹窗选择 | //自动播放次数的弹窗选择 | ||||
| private var autoPlaySeletDialog : BottomSheetDialog? = null | private var autoPlaySeletDialog : BottomSheetDialog? = null | ||||
| /** 点击显示更多的弹窗 */ | /** 点击显示更多的弹窗 */ | ||||
| private fun showMoreDialog() { | private fun showMoreDialog() { | ||||
| if (moreDialog == null) { | |||||
| moreDialog = BottomSheetDialog(this, R.style.dialog_style).apply { | |||||
| val moreDialog = BottomSheetDialog(this, R.style.dialog_style).apply { | |||||
| val moreBinding = DataBindingUtil.inflate<DialogBottomCourseMoreBinding>(layoutInflater, | val moreBinding = DataBindingUtil.inflate<DialogBottomCourseMoreBinding>(layoutInflater, | ||||
| R.layout.dialog_bottom_course_more, null, | R.layout.dialog_bottom_course_more, null, | ||||
| false) | false) | ||||
| dismiss() | dismiss() | ||||
| showCourseRelearnDialog() | showCourseRelearnDialog() | ||||
| } | } | ||||
| } | |||||
| } | |||||
| moreDialog?.show() | |||||
| }.show() | |||||
| } | } | ||||
| /** 课程重学弹窗提示 */ | /** 课程重学弹窗提示 */ |
| } | } | ||||
| (requireParentFragment().parentFragment as CourseMainFragment).startExam(examData) | (requireParentFragment().parentFragment as CourseMainFragment).startExam(examData) | ||||
| } | } | ||||
| //完成,切换到学后总测试fragment | |||||
| AppConstants.DIALOG_OVER -> (requireParentFragment().parentFragment as CourseMainFragment).changeFragment(2) | |||||
| } | } | ||||
| } | } | ||||
| }.show(childFragmentManager, "course_learn_after_test_before") | }.show(childFragmentManager, "course_learn_after_test_before") |
| companion object { | companion object { | ||||
| @JvmStatic | @JvmStatic | ||||
| fun newInstance(courseIndex : Int) = CourseMainFragment().apply { | |||||
| arguments = Bundle().apply { | |||||
| putInt(AppConfig.INTENT_1, courseIndex) | |||||
| fun newInstance(courseIndex : Int):CourseMainFragment { | |||||
| return CourseMainFragment().apply { | |||||
| arguments = Bundle().apply { | |||||
| putInt(AppConfig.INTENT_1, courseIndex) | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| } | } |
| import com.suliang.common.extension.diskIo2DiskIo | import com.suliang.common.extension.diskIo2DiskIo | ||||
| import com.suliang.common.extension.diskIo2Main | import com.suliang.common.extension.diskIo2Main | ||||
| import com.suliang.common.util.DateUtil | import com.suliang.common.util.DateUtil | ||||
| import com.suliang.common.util.LogUtil | |||||
| import com.suliang.common.util.file.FileUtil | import com.suliang.common.util.file.FileUtil | ||||
| import com.suliang.common.util.thread.AppExecutors | import com.suliang.common.util.thread.AppExecutors | ||||
| import com.xkl.cdl.data.AppConstants | import com.xkl.cdl.data.AppConstants | ||||
| // TODO: 2022/5/6 这里在退出时进行了统计数据缓存保存,在loadMain的时候进行了read缓存 ,后期需要清除 | // TODO: 2022/5/6 这里在退出时进行了统计数据缓存保存,在loadMain的时候进行了read缓存 ,后期需要清除 | ||||
| override fun onDestroy(owner : LifecycleOwner) { | override fun onDestroy(owner : LifecycleOwner) { | ||||
| val objectToBytes = FileUtil.objectToBytes(courseDetail) | |||||
| FileUtil.writeBytesToFile(FileUtil.getSaveDirPath("appcache"), | |||||
| "${course.subjectId}_${course.coursePackId}_${course.courseId}", objectToBytes) | |||||
| if (owner is CourseMainFragment) { | |||||
| LogUtil.e("${this.toString().substringAfterLast(".")} 保存文件 onDestroy") | |||||
| try { | |||||
| val objectToBytes = FileUtil.objectToBytes(courseDetail) | |||||
| FileUtil.writeBytesToFile(FileUtil.getSaveDirPath("appcache"), | |||||
| "${course.subjectId}_${course.coursePackId}_${course.courseId}", objectToBytes) | |||||
| } catch (e : Exception) { | |||||
| e.printStackTrace() | |||||
| LogUtil.e("${javaClass} 保存文件异常失败") | |||||
| } | |||||
| } | |||||
| super.onDestroy(owner) | super.onDestroy(owner) | ||||
| } | } | ||||
| import com.xkl.cdl.data.manager.CourseManager | import com.xkl.cdl.data.manager.CourseManager | ||||
| import com.xkl.cdl.databinding.FragmentCourseTotalTestBinding | import com.xkl.cdl.databinding.FragmentCourseTotalTestBinding | ||||
| import com.xkl.cdl.module.m_center_learn.CoursePackMainActivity | import com.xkl.cdl.module.m_center_learn.CoursePackMainActivity | ||||
| import java.util.* | |||||
| /** | /** | ||||
| * 课程总测试: 学前总,学后总 | * 课程总测试: 学前总,学后总 | ||||
| companion object { | companion object { | ||||
| @JvmStatic | @JvmStatic | ||||
| fun newInstance(totalTestType : Int) = CourseTotalTestFragment().apply { | |||||
| arguments = Bundle().apply { | |||||
| putInt(AppConfig.INTENT_1, totalTestType) | |||||
| fun newInstance(totalTestType : Int): CourseTotalTestFragment{ | |||||
| return CourseTotalTestFragment().apply { | |||||
| arguments = Bundle().apply { | |||||
| putInt(AppConfig.INTENT_1, totalTestType) | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| //传递过来的总测类型: 学前,学后 | //传递过来的总测类型: 学前,学后 | ||||
| private var totalTestType = 0 | private var totalTestType = 0 | ||||
| //测试的数据 | |||||
| private var testData : List<ExamBean> = emptyList() | |||||
| override fun initFragment() { | override fun initFragment() { | ||||
| totalTestType = requireArguments().getInt(AppConfig.INTENT_1) | totalTestType = requireArguments().getInt(AppConfig.INTENT_1) | ||||
| } | } | ||||
| override fun loadData() { | override fun loadData() { | ||||
| vm.loadTest(totalTestType).observe(this) { | |||||
| testData = it | |||||
| initView() | |||||
| when (totalTestType) { | |||||
| AppConstants.TEST_TYPE_BEFORE_TOTAL -> vm.loadTest(totalTestType).observe(this) { | |||||
| initTotalBeforeView(it) | |||||
| } | |||||
| AppConstants.TEST_TYPE_AFTER_TOTAL -> initTotalAfterView() | |||||
| } | } | ||||
| } | } | ||||
| private fun initView() { | |||||
| binding.tvCountTip.text = CourseManager.expectedTestTime(vm.course.courseType, totalTestType, testData!!) | |||||
| when (totalTestType) { | |||||
| AppConstants.TEST_TYPE_BEFORE_TOTAL -> { | |||||
| // TODO: 2022/4/21 需要把开始学习给取消了 | |||||
| binding.button1.visibility = View.VISIBLE | |||||
| //学前总测 | |||||
| binding.run { | |||||
| tvTitle.setText(R.string.test_total_before_title) | |||||
| button1.run { | |||||
| setText(R.string.start_learn) | |||||
| click { | |||||
| continueLearn(it) | |||||
| /** 学后测试初始 */ | |||||
| private fun initTotalAfterView() { | |||||
| binding.run { | |||||
| ivIcon.setImageResource(if (Random().nextBoolean()) R.mipmap.boy_2 else R.mipmap.girl_2) | |||||
| tvTitle.setText(R.string.tips_current_course_learn_over) | |||||
| tvMainTip.visibility = View.VISIBLE | |||||
| //根据测试成绩处理 | |||||
| vm.courseDetail.st_before.let { | |||||
| when (it) { | |||||
| AppConstants.NOT_DOING -> { //未测 | |||||
| tvMainTip.setText(R.string.test_total_after_tip_1) | |||||
| button2.run { | |||||
| setText(R.string.test_type_after_total) | |||||
| click { view -> | |||||
| startTest(view) | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| //按钮初始 | |||||
| button2.run { | |||||
| setText(R.string.start_test) | |||||
| click { view -> | |||||
| startTest(view) | |||||
| else -> { //有成绩,直接完成 | |||||
| if (it >= AppConstants.TEST_SCORE_LEVEL_2) { | |||||
| tvMainTip.setHtml("你已完成学后总测试,上次得分: <font color=\'#5082E6\'>$it</font>") | |||||
| } else { | |||||
| tvMainTip.setHtml("你已完成学后总测试,上次得分: <font color=\'#F26255\'>$it</font>") | |||||
| } | } | ||||
| } | |||||
| } | |||||
| } | |||||
| AppConstants.TEST_TYPE_AFTER_TOTAL -> { | |||||
| //学后总测 | |||||
| binding.run { | |||||
| ivIcon.setImageResource(if (java.util.Random().nextBoolean()) R.mipmap.boy_2 else R.mipmap.girl_2) | |||||
| tvTitle.setText(R.string.tips_current_course_learn_over) | |||||
| tvMainTip.visibility = View.VISIBLE | |||||
| //根据测试成绩处理 | |||||
| vm.courseDetail.st_before.let { | |||||
| when (it) { | |||||
| AppConstants.NOT_DOING -> { //未测 | |||||
| tvMainTip.setText(R.string.test_total_after_tip_1) | |||||
| button2.run { | |||||
| setText(R.string.test_type_after_total) | |||||
| click { view -> | |||||
| startTest(view) | |||||
| } | |||||
| } | |||||
| tvTips.visibility = View.VISIBLE | |||||
| tvCountTip.visibility = View.GONE | |||||
| button1.run { | |||||
| visibility = View.VISIBLE | |||||
| setText(R.string.test_again) | |||||
| click { view -> | |||||
| startTest(view) | |||||
| } | } | ||||
| else -> { //有成绩,直接完成 | |||||
| if (it >= AppConstants.TEST_SCORE_LEVEL_2) { | |||||
| tvMainTip.setHtml("你已完成学后总测试,上次得分: <font color=\'#5082E6\'>$it</font>") | |||||
| }else { | |||||
| tvMainTip.setHtml("你已完成学后总测试,上次得分: <font color=\'#F26255\'>$it</font>") | |||||
| } | |||||
| tvTips.visibility = View.VISIBLE | |||||
| tvCountTip.visibility = View.GONE | |||||
| button1.run { | |||||
| visibility = View.VISIBLE | |||||
| setText(R.string.test_again) | |||||
| click { view -> | |||||
| startTest(view) | |||||
| } | |||||
| } | |||||
| button2.run { | |||||
| setText(R.string.continue_learn) | |||||
| click { view -> | |||||
| continueLearn(view) | |||||
| } | |||||
| } | |||||
| tvClearLearnRecord.visibility = View.VISIBLE | |||||
| tvClearLearnRecord.click { | |||||
| (activity as CoursePackMainActivity).showCourseRelearnDialog() | |||||
| } | |||||
| } | |||||
| button2.run { | |||||
| setText(R.string.continue_learn) | |||||
| click { view -> | |||||
| continueLearn(view) | |||||
| } | } | ||||
| } | } | ||||
| //清空学习记录 | |||||
| tvClearLearnRecord.visibility = View.VISIBLE | |||||
| tvClearLearnRecord.click { | |||||
| (activity as CoursePackMainActivity).showCourseRelearnDialog() | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /** 学前测试初始 */ | |||||
| private fun initTotalBeforeView(testData : List<ExamBean>) { | |||||
| // TODO: 2022/4/21 需要把开始学习给取消了 | |||||
| binding.tvCountTip.text = CourseManager.expectedTestTime(vm.course.courseType, totalTestType, testData) | |||||
| binding.button1.visibility = View.VISIBLE | |||||
| //学前总测 | |||||
| binding.run { | |||||
| tvTitle.setText(R.string.test_total_before_title) | |||||
| button1.run { | |||||
| setText(R.string.start_learn) | |||||
| click { | |||||
| continueLearn(it) | |||||
| } | |||||
| } | |||||
| //按钮初始 | |||||
| button2.run { | |||||
| setText(R.string.start_test) | |||||
| click { view -> | |||||
| startTest(view) | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| /**继续学习*/ | /**继续学习*/ | ||||
| private fun continueLearn(view : View) { | private fun continueLearn(view : View) { | ||||
| (requireParentFragment() as CourseMainFragment).changeFragment(1) | (requireParentFragment() as CourseMainFragment).changeFragment(1) | ||||
| * | * | ||||
| */ | */ | ||||
| private fun startTest(view : View) { | private fun startTest(view : View) { | ||||
| //生成数据 | |||||
| val examData = ExamData(vm.course.subjectId, totalTestType, vm.course.courseTitle, vm.course.courseTitle).apply { | |||||
| coursePackId = vm.course.coursePackId | |||||
| coursePackType = vm.course.coursePackType | |||||
| courseId = vm.course.courseId | |||||
| courseType = vm.course.courseType | |||||
| this.testData = this@CourseTotalTestFragment.testData | |||||
| mExamWRMap = if (examType == AppConstants.TEST_TYPE_BEFORE_TOTAL) vm.courseDetail.exam_w_r_list else null | |||||
| vm.loadTest(totalTestType).observe(this) { | |||||
| //生成数据 | |||||
| val examData = ExamData(vm.course.subjectId, totalTestType, vm.course.courseTitle, vm.course.courseTitle).apply { | |||||
| coursePackId = vm.course.coursePackId | |||||
| coursePackType = vm.course.coursePackType | |||||
| courseId = vm.course.courseId | |||||
| courseType = vm.course.courseType | |||||
| this.testData = it | |||||
| mExamWRMap = if (examType == AppConstants.TEST_TYPE_BEFORE_TOTAL) vm.courseDetail.exam_w_r_list else null | |||||
| } | |||||
| (parentFragment as CourseMainFragment).startExam(examData) | |||||
| } | } | ||||
| (parentFragment as CourseMainFragment).startExam(examData) | |||||
| } | } | ||||
| } | } |
| <!-- app:constraint_referenced_ids="tv_title,inc_statistics_number,tv_learn_over_tip,tv_learn_over_for_after_count_time,tv_left,vSplit"/>--> | <!-- app:constraint_referenced_ids="tv_title,inc_statistics_number,tv_learn_over_tip,tv_learn_over_for_after_count_time,tv_left,vSplit"/>--> | ||||
| <!--课时学后测试结束绑定的布局组 --> | <!--课时学后测试结束绑定的布局组 --> | ||||
| <!-- <androidx.constraintlayout.widget.Group | |||||
| <!--<androidx.constraintlayout.widget.Group | |||||
| android:layout_width="wrap_content" | android:layout_width="wrap_content" | ||||
| android:layout_height="wrap_content" | android:layout_height="wrap_content" | ||||
| app:constraint_referenced_ids="tv_score,tv_tip,tv_title,inc_statistics_number,tv_top,tv_left,vSplit,tv_top_1" | |||||
| app:constraint_referenced_ids="tv_score,tv_tip,tv_title,inc_statistics_number,tv_top,tv_left,vSplit" | |||||
| />--> | />--> | ||||
| buildTypes { | buildTypes { | ||||
| release { | release { | ||||
| buildConfigField("Boolean","LOG_ENABLE","false") | buildConfigField("Boolean","LOG_ENABLE","false") | ||||
| buildConfigField("Boolean","SHOW_LIFECYCLER_LOG","false") | |||||
| minifyEnabled false | minifyEnabled false | ||||
| proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' | ||||
| } | } | ||||
| debug { | debug { | ||||
| buildConfigField("Boolean","LOG_ENABLE","true") | buildConfigField("Boolean","LOG_ENABLE","true") | ||||
| buildConfigField("Boolean","SHOW_LIFECYCLER_LOG","false") | |||||
| minifyEnabled false | minifyEnabled false | ||||
| proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' | ||||
| } | } |
| import androidx.viewbinding.ViewBinding | import androidx.viewbinding.ViewBinding | ||||
| import com.suliang.common.extension.initBinding | import com.suliang.common.extension.initBinding | ||||
| import com.suliang.common.util.LogUtil | |||||
| /** | /** |
| import android.os.Bundle | import android.os.Bundle | ||||
| import androidx.appcompat.app.AppCompatActivity | import androidx.appcompat.app.AppCompatActivity | ||||
| import com.suliang.common.BuildConfig | |||||
| import com.suliang.common.util.LogUtil | import com.suliang.common.util.LogUtil | ||||
| /** | /** | ||||
| * Describe: 打印生命周期的Activity | * Describe: 打印生命周期的Activity | ||||
| */ | */ | ||||
| open class LifecycleLogActivity : AppCompatActivity() { | open class LifecycleLogActivity : AppCompatActivity() { | ||||
| // override fun onCreate(savedInstanceState: Bundle?) { | |||||
| // super.onCreate(savedInstanceState) | |||||
| // LogUtil.e("onCreate()") | |||||
| // } | |||||
| // | |||||
| // override fun onRestart() { | |||||
| // super.onRestart() | |||||
| // LogUtil.e("onRestart()") | |||||
| // } | |||||
| // | |||||
| // override fun onStart() { | |||||
| // super.onStart() | |||||
| // LogUtil.e("onStart()") | |||||
| // } | |||||
| // | |||||
| // override fun onResume() { | |||||
| // super.onResume() | |||||
| // LogUtil.e("onResume()") | |||||
| // } | |||||
| // | |||||
| // override fun onPause() { | |||||
| // super.onPause() | |||||
| // LogUtil.e("onPause()") | |||||
| // } | |||||
| // | |||||
| // override fun onStop() { | |||||
| // super.onStop() | |||||
| // LogUtil.e("onStop()") | |||||
| // } | |||||
| // | |||||
| // override fun onDestroy() { | |||||
| // super.onDestroy() | |||||
| // LogUtil.e("onDestroy()") | |||||
| // } | |||||
| // | |||||
| // override fun onSaveInstanceState(outState: Bundle) { | |||||
| // super.onSaveInstanceState(outState) | |||||
| // LogUtil.e("onSaveInstanceState()") | |||||
| // } | |||||
| // | |||||
| // override fun onRestoreInstanceState(savedInstanceState: Bundle) { | |||||
| // super.onRestoreInstanceState(savedInstanceState) | |||||
| // LogUtil.e("onRestoreInstanceState()") | |||||
| // } | |||||
| override fun onCreate(savedInstanceState : Bundle?) { | |||||
| super.onCreate(savedInstanceState) | |||||
| if (BuildConfig.SHOW_LIFECYCLER_LOG) LogUtil.e("${this.toString().substringAfterLast(".")} onCreate()") | |||||
| } | |||||
| override fun onRestart() { | |||||
| super.onRestart() | |||||
| if (BuildConfig.SHOW_LIFECYCLER_LOG) LogUtil.e("${this.toString().substringAfterLast(".")} onRestart()") | |||||
| } | |||||
| override fun onStart() { | |||||
| super.onStart() | |||||
| if (BuildConfig.SHOW_LIFECYCLER_LOG) LogUtil.e("${this.toString().substringAfterLast(".")} onStart()") | |||||
| } | |||||
| override fun onResume() { | |||||
| super.onResume() | |||||
| if (BuildConfig.SHOW_LIFECYCLER_LOG) LogUtil.e("${this.toString().substringAfterLast(".")} onResume()") | |||||
| } | |||||
| override fun onPause() { | |||||
| super.onPause() | |||||
| if (BuildConfig.SHOW_LIFECYCLER_LOG) LogUtil.e("${this.toString().substringAfterLast(".")} onPause()") | |||||
| } | |||||
| override fun onStop() { | |||||
| super.onStop() | |||||
| if (BuildConfig.SHOW_LIFECYCLER_LOG) LogUtil.e("${this.toString().substringAfterLast(".")} onStop()") | |||||
| } | |||||
| override fun onDestroy() { | |||||
| super.onDestroy() | |||||
| if (BuildConfig.SHOW_LIFECYCLER_LOG) LogUtil.e("${this.toString().substringAfterLast(".")} onDestroy()") | |||||
| } | |||||
| override fun onSaveInstanceState(outState : Bundle) { | |||||
| super.onSaveInstanceState(outState) | |||||
| if (BuildConfig.SHOW_LIFECYCLER_LOG) LogUtil.e("onSaveInstanceState()") | |||||
| } | |||||
| override fun onRestoreInstanceState(savedInstanceState : Bundle) { | |||||
| super.onRestoreInstanceState(savedInstanceState) | |||||
| if (BuildConfig.SHOW_LIFECYCLER_LOG) LogUtil.e("onRestoreInstanceState()") | |||||
| } | |||||
| } | } |
| } ?: size | } ?: size | ||||
| mData.add(startPosition,data) | mData.add(startPosition,data) | ||||
| notifyItemInserted(startPosition) | notifyItemInserted(startPosition) | ||||
| notifyItemRangeChanged(startPosition,mData.size + 1) | |||||
| notifyItemRangeChanged(startPosition,mData.size) | |||||
| } | } | ||||
| } | } | ||||
| //通知有新的item插入进来了 | //通知有新的item插入进来了 | ||||
| notifyItemInserted(startPosition) | notifyItemInserted(startPosition) | ||||
| //范围性更新,直接调用onBindViewHolder | //范围性更新,直接调用onBindViewHolder | ||||
| notifyItemRangeChanged(startPosition, mData.size + 1 ) | |||||
| notifyItemRangeChanged(startPosition, mData.size) | |||||
| } | } | ||||
| } | } | ||||
| fun removeData(position:Int){ | fun removeData(position:Int){ | ||||
| if(mData.size >= position){ | if(mData.size >= position){ | ||||
| mData.removeAt(position) | mData.removeAt(position) | ||||
| notifyItemRangeChanged(position,mData.size-position) | |||||
| notifyItemRemoved(position) | |||||
| notifyItemRangeChanged(0,mData.size) | |||||
| } | } | ||||
| } | } | ||||
| * | * | ||||
| * @property VB : ViewDataBinding | * @property VB : ViewDataBinding | ||||
| */ | */ | ||||
| abstract class BaseFragment<VB : ViewBinding> : Fragment(),ViewBehavior { | |||||
| abstract class BaseFragment<VB : ViewBinding> : LifecycleLogFragment(), ViewBehavior { | |||||
| private var _binding: VB? = null | private var _binding: VB? = null | ||||
| import android.content.Context | import android.content.Context | ||||
| import android.os.Bundle | import android.os.Bundle | ||||
| import android.util.Log | |||||
| import com.suliang.common.BuildConfig | |||||
| import android.view.LayoutInflater | import android.view.LayoutInflater | ||||
| import android.view.View | import android.view.View | ||||
| import android.view.ViewGroup | import android.view.ViewGroup | ||||
| * create 2022/3/7 14:14 | * create 2022/3/7 14:14 | ||||
| * Describe: Fragment生命周期日志打印 | * Describe: Fragment生命周期日志打印 | ||||
| */ | */ | ||||
| class LifecycleLogFragment : Fragment() { | |||||
| override fun onAttach(context: Context) { | |||||
| open class LifecycleLogFragment : Fragment() { | |||||
| override fun onAttach(context : Context) { | |||||
| super.onAttach(context) | super.onAttach(context) | ||||
| LogUtil.d("onAttach") | |||||
| if (BuildConfig.SHOW_LIFECYCLER_LOG) LogUtil.e( | |||||
| "${this.toString().substringAfterLast(".").substringBeforeLast(" (")} onAttach()") | |||||
| } | } | ||||
| override fun onCreate(savedInstanceState: Bundle?) { | |||||
| override fun onCreate(savedInstanceState : Bundle?) { | |||||
| super.onCreate(savedInstanceState) | super.onCreate(savedInstanceState) | ||||
| LogUtil.d("onCreate") | |||||
| if (BuildConfig.SHOW_LIFECYCLER_LOG) LogUtil.e( | |||||
| "${this.toString().substringAfterLast(".").substringBeforeLast(" (")} onCreate()") | |||||
| } | } | ||||
| override fun onCreateView( | |||||
| inflater: LayoutInflater, | |||||
| container: ViewGroup?, | |||||
| savedInstanceState: Bundle? | |||||
| ): View? { | |||||
| LogUtil.d("onCreateView") | |||||
| override fun onCreateView(inflater : LayoutInflater, container : ViewGroup?, savedInstanceState : Bundle?) : View? { | |||||
| if (BuildConfig.SHOW_LIFECYCLER_LOG) LogUtil.e( | |||||
| "${this.toString().substringAfterLast(".").substringBeforeLast(" (")} onCreateView()") | |||||
| return super.onCreateView(inflater, container, savedInstanceState) | return super.onCreateView(inflater, container, savedInstanceState) | ||||
| } | } | ||||
| override fun onViewCreated(view: View, savedInstanceState: Bundle?) { | |||||
| override fun onViewCreated(view : View, savedInstanceState : Bundle?) { | |||||
| super.onViewCreated(view, savedInstanceState) | super.onViewCreated(view, savedInstanceState) | ||||
| LogUtil.d("onViewCreated") | |||||
| if (BuildConfig.SHOW_LIFECYCLER_LOG) LogUtil.e( | |||||
| "${this.toString().substringAfterLast(".").substringBeforeLast(" (")} onCreateView()") | |||||
| } | } | ||||
| // override fun onActivityCreated(savedInstanceState: Bundle?) { | |||||
| // super.onActivityCreated(savedInstanceState) | |||||
| // LogUtil.d("onActivityCreated") | |||||
| // } | |||||
| override fun onActivityCreated(savedInstanceState : Bundle?) { | |||||
| super.onActivityCreated(savedInstanceState) | |||||
| if (BuildConfig.SHOW_LIFECYCLER_LOG) LogUtil.d("onActivityCreated") | |||||
| } | |||||
| override fun onStart() { | override fun onStart() { | ||||
| super.onStart() | super.onStart() | ||||
| LogUtil.d("onStart") | |||||
| if (BuildConfig.SHOW_LIFECYCLER_LOG) LogUtil.e( | |||||
| "${this.toString().substringAfterLast(".").substringBeforeLast(" (")} onStart()") | |||||
| } | } | ||||
| override fun onResume() { | override fun onResume() { | ||||
| super.onResume() | super.onResume() | ||||
| LogUtil.d("onResume") | |||||
| if (BuildConfig.SHOW_LIFECYCLER_LOG) LogUtil.e( | |||||
| "${this.toString().substringAfterLast(".").substringBeforeLast(" (")} onResume()") | |||||
| } | } | ||||
| override fun onStop() { | override fun onStop() { | ||||
| super.onStop() | super.onStop() | ||||
| LogUtil.d("onStop") | |||||
| if (BuildConfig.SHOW_LIFECYCLER_LOG) LogUtil.e( | |||||
| "${this.toString().substringAfterLast(".").substringBeforeLast(" (")} onStop()") | |||||
| } | } | ||||
| override fun onDestroyView() { | override fun onDestroyView() { | ||||
| super.onDestroyView() | super.onDestroyView() | ||||
| LogUtil.d("onDestroyView") | |||||
| if (BuildConfig.SHOW_LIFECYCLER_LOG) LogUtil.e( | |||||
| "${this.toString().substringAfterLast(".").substringBeforeLast(" (")} onDestroyView()") | |||||
| } | } | ||||
| override fun onDetach() { | override fun onDetach() { | ||||
| super.onDetach() | super.onDetach() | ||||
| LogUtil.d("onDetach") | |||||
| if (BuildConfig.SHOW_LIFECYCLER_LOG) LogUtil.e( | |||||
| "${this.toString().substringAfterLast(".").substringBeforeLast(" (")} onDetach()") | |||||
| } | } | ||||
| override fun onDestroy() { | override fun onDestroy() { | ||||
| super.onDestroy() | super.onDestroy() | ||||
| LogUtil.d("onDestroy") | |||||
| if (BuildConfig.SHOW_LIFECYCLER_LOG) LogUtil.e( | |||||
| "${this.toString().substringAfterLast(".").substringBeforeLast(" (")} onDestroy()") | |||||
| } | } | ||||
| override fun onHiddenChanged(hidden: Boolean) { | |||||
| override fun onHiddenChanged(hidden : Boolean) { | |||||
| super.onHiddenChanged(hidden) | super.onHiddenChanged(hidden) | ||||
| LogUtil.d("onHiddenChanged : hidden -> : $hidden" ) | |||||
| if (BuildConfig.SHOW_LIFECYCLER_LOG) LogUtil.e( | |||||
| "${this.toString().substringAfterLast(".").substringBeforeLast(" (")} onHiddenChanged() : hidden -> : $hidden") | |||||
| } | } | ||||
| override fun setUserVisibleHint(isVisibleToUser: Boolean) { | |||||
| override fun setUserVisibleHint(isVisibleToUser : Boolean) { | |||||
| super.setUserVisibleHint(isVisibleToUser) | super.setUserVisibleHint(isVisibleToUser) | ||||
| LogUtil.d("setUserVisibleHint: isVisibleToUser -> $isVisibleToUser ") | |||||
| if (BuildConfig.SHOW_LIFECYCLER_LOG) LogUtil.e("${ | |||||
| this.toString() | |||||
| .substringAfterLast(".") | |||||
| .substringBeforeLast(" (") | |||||
| } setUserVisibleHint(): isVisibleToUser -> $isVisibleToUser") | |||||
| } | } | ||||
| override fun onSaveInstanceState(outState: Bundle) { | |||||
| override fun onSaveInstanceState(outState : Bundle) { | |||||
| super.onSaveInstanceState(outState) | super.onSaveInstanceState(outState) | ||||
| LogUtil.d(javaClass.simpleName + " onSaveInstanceState()") | |||||
| if (BuildConfig.SHOW_LIFECYCLER_LOG) LogUtil.e( | |||||
| "${this.toString().substringAfterLast(".").substringBeforeLast(" (")} onSaveInstanceState()") | |||||
| } | } | ||||
| override fun onViewStateRestored(savedInstanceState: Bundle?) { | |||||
| override fun onViewStateRestored(savedInstanceState : Bundle?) { | |||||
| super.onViewStateRestored(savedInstanceState) | super.onViewStateRestored(savedInstanceState) | ||||
| LogUtil.d(javaClass.simpleName + " onViewStateRestored()") | |||||
| if (BuildConfig.SHOW_LIFECYCLER_LOG) LogUtil.e( | |||||
| "${this.toString().substringAfterLast(".").substringBeforeLast(" (")} onViewStateRestored()") | |||||
| } | } | ||||
| } | } |
| package com.suliang.common.base.viewmodel | package com.suliang.common.base.viewmodel | ||||
| import android.widget.Toast | |||||
| import androidx.lifecycle.LifecycleOwner | |||||
| import androidx.lifecycle.MutableLiveData | import androidx.lifecycle.MutableLiveData | ||||
| import androidx.lifecycle.ViewModel | import androidx.lifecycle.ViewModel | ||||
| import com.suliang.common.BuildConfig | |||||
| import com.suliang.common.base.ViewBehavior | import com.suliang.common.base.ViewBehavior | ||||
| import com.suliang.common.base.activity.ToastEvent | import com.suliang.common.base.activity.ToastEvent | ||||
| import com.suliang.common.util.LogUtil | import com.suliang.common.util.LogUtil | ||||
| * Describe: | * Describe: | ||||
| */ | */ | ||||
| open class BaseViewModel : ViewModel(), ViewModelLifecycle, ViewBehavior { | open class BaseViewModel : ViewModel(), ViewModelLifecycle, ViewBehavior { | ||||
| override fun onCreate(owner: LifecycleOwner) { | |||||
| super.onCreate(owner) | |||||
| LogUtil.i("${javaClass.name}_${hashCode()} onCreate() ") | |||||
| } | |||||
| override fun onStart(owner: LifecycleOwner) { | |||||
| super.onStart(owner) | |||||
| LogUtil.i("${javaClass.name}_${hashCode()} onStart() ") | |||||
| } | |||||
| override fun onResume(owner: LifecycleOwner) { | |||||
| super.onResume(owner) | |||||
| LogUtil.i("${javaClass.name}_${hashCode()} onResume() ") | |||||
| } | |||||
| override fun onPause(owner: LifecycleOwner) { | |||||
| super.onPause(owner) | |||||
| LogUtil.i("${javaClass.name}_${hashCode()} onPause() ") | |||||
| } | |||||
| override fun onStop(owner: LifecycleOwner) { | |||||
| super.onStop(owner) | |||||
| LogUtil.i("${javaClass.name}_${hashCode()} onStop() ") | |||||
| } | |||||
| override fun onDestroy(owner: LifecycleOwner) { | |||||
| super.onDestroy(owner) | |||||
| LogUtil.i("${javaClass.name}_${hashCode()} onDestroy() ") | |||||
| } | |||||
| override fun onCleared() { | override fun onCleared() { | ||||
| super.onCleared() | super.onCleared() | ||||
| LogUtil.i("${javaClass.name}_${hashCode()} onCleared() ") | |||||
| if (BuildConfig.SHOW_LIFECYCLER_LOG) LogUtil.e("${this.toString().substringAfterLast(".")} onCleared() ") | |||||
| } | } | ||||
| val loadingEvent = MutableLiveData<Boolean>() | val loadingEvent = MutableLiveData<Boolean>() | ||||
| val toastEvent = MutableLiveData<ToastEvent>() | val toastEvent = MutableLiveData<ToastEvent>() | ||||
| val pageEvent = MutableLiveData<Class<*>>() | val pageEvent = MutableLiveData<Class<*>>() | ||||
| override fun showHideLoading(isShow: Boolean) { | |||||
| override fun showHideLoading(isShow : Boolean) { | |||||
| loadingEvent.postValue(isShow) | loadingEvent.postValue(isShow) | ||||
| } | } | ||||
| override fun showToast(msg: ToastEvent) { | |||||
| override fun showToast(msg : ToastEvent) { | |||||
| toastEvent.postValue(msg) | toastEvent.postValue(msg) | ||||
| } | } | ||||
| override fun startActivity(clazz: Class<*>) { | |||||
| override fun startActivity(clazz : Class<*>) { | |||||
| pageEvent.postValue(clazz) | pageEvent.postValue(clazz) | ||||
| } | } | ||||
| } | } | ||||
| package com.suliang.common.base.viewmodel | package com.suliang.common.base.viewmodel | ||||
| import androidx.lifecycle.DefaultLifecycleObserver | import androidx.lifecycle.DefaultLifecycleObserver | ||||
| import androidx.lifecycle.LifecycleOwner | |||||
| import com.suliang.common.BuildConfig | |||||
| import com.suliang.common.util.LogUtil | |||||
| /** | /** | ||||
| * author suliang | |||||
| * create 2022/3/17 11:22 | |||||
| * Describe: ViewModel生命周期 与 Activity/Fragment同步 | |||||
| */ | |||||
| * author suliang | |||||
| * create 2022/3/17 11:22 | |||||
| * Describe: ViewModel生命周期 与 Activity/Fragment同步 | |||||
| * // DefaultLifecycleObserver | |||||
| */ | |||||
| interface ViewModelLifecycle : DefaultLifecycleObserver { | interface ViewModelLifecycle : DefaultLifecycleObserver { | ||||
| override fun onCreate(owner : LifecycleOwner) { | |||||
| if (BuildConfig.SHOW_LIFECYCLER_LOG) LogUtil.e("${this.toString().substringAfterLast(".")} onCreate() ") | |||||
| } | |||||
| override fun onStart(owner : LifecycleOwner) { | |||||
| if (BuildConfig.SHOW_LIFECYCLER_LOG) LogUtil.i("${this.toString().substringAfterLast(".")} onStart() ") | |||||
| } | |||||
| override fun onResume(owner : LifecycleOwner) { | |||||
| if (BuildConfig.SHOW_LIFECYCLER_LOG) LogUtil.i("${this.toString().substringAfterLast(".")} onResume() ") | |||||
| } | |||||
| override fun onPause(owner : LifecycleOwner) { | |||||
| if (BuildConfig.SHOW_LIFECYCLER_LOG) LogUtil.i("${this.toString().substringAfterLast(".")} onPause() ") | |||||
| } | |||||
| override fun onStop(owner : LifecycleOwner) { | |||||
| if (BuildConfig.SHOW_LIFECYCLER_LOG) LogUtil.i("${this.toString().substringAfterLast(".")} onStop() ") | |||||
| } | |||||
| override fun onDestroy(owner : LifecycleOwner) { | |||||
| if (BuildConfig.SHOW_LIFECYCLER_LOG) LogUtil.e("${this.toString().substringAfterLast(".")} onDestroy() ") | |||||
| } | |||||
| } | } |
| private fun log(logType: String, message: String) { | private fun log(logType: String, message: String) { | ||||
| if (!LogEnable) return | if (!LogEnable) return | ||||
| val stackTraceElement = Thread.currentThread().stackTrace[5] | val stackTraceElement = Thread.currentThread().stackTrace[5] | ||||
| val out = "==${stackTraceElement.methodName} : ${stackTraceElement.lineNumber} --- $message ===== " | |||||
| val className = stackTraceElement.className.substringAfterLast(".") | |||||
| val out = "==> \n${className}_${stackTraceElement.methodName.substringAfterLast(".")}_${stackTraceElement.lineNumber} \n$message" | |||||
| when(logType){ | when(logType){ | ||||
| "v" -> Log.v(stackTraceElement.className,out) | |||||
| "d" -> Log.d(stackTraceElement.className,out) | |||||
| "e" -> Log.e(stackTraceElement.className,out) | |||||
| "i" -> Log.i(stackTraceElement.className,out) | |||||
| "w" -> Log.w(stackTraceElement.className,out) | |||||
| "v" -> Log.v(className,out) | |||||
| "d" -> Log.d(className,out) | |||||
| "e" -> Log.e(className,out) | |||||
| "i" -> Log.i(className,out) | |||||
| "w" -> Log.w(className,out) | |||||
| } | } | ||||
| } | } | ||||
| /** 异步准备完毕 ,开始播放*/ | /** 异步准备完毕 ,开始播放*/ | ||||
| private fun handlePrepared() { | private fun handlePrepared() { | ||||
| if (currentState == EMediaState.PREPARED) { //修改为播放状态,调用播放 | if (currentState == EMediaState.PREPARED) { //修改为播放状态,调用播放 | ||||
| LogUtil.i("准备完成,开始播放") | |||||
| // LogUtil.i("准备完成,开始播放") | |||||
| mediaPlayer?.start() | mediaPlayer?.start() | ||||
| currentState = EMediaState.RUNNING | currentState = EMediaState.RUNNING | ||||
| handleListener() | handleListener() | ||||
| } | } | ||||
| override fun onPrepared(mp: MediaPlayer?) { | override fun onPrepared(mp: MediaPlayer?) { | ||||
| LogUtil.i("mOnPreparedLister 回调") | |||||
| // LogUtil.i("mOnPreparedLister 回调") | |||||
| if (currentState == EMediaState.INITIALIZED || currentState == EMediaState.PREPARING) { | if (currentState == EMediaState.INITIALIZED || currentState == EMediaState.PREPARING) { | ||||
| currentState = EMediaState.PREPARED | currentState = EMediaState.PREPARED | ||||
| handlePrepared() | handlePrepared() |
| //根据资源Id获取相应的尺寸 | //根据资源Id获取相应的尺寸 | ||||
| statusBarHeight = resources.getDimensionPixelSize(resourceId) | statusBarHeight = resources.getDimensionPixelSize(resourceId) | ||||
| } | } | ||||
| LogUtil.d(" 状态栏高度 navigationBarHeight = $statusBarHeight") | |||||
| // LogUtil.d(" 状态栏高度 navigationBarHeight = $statusBarHeight") | |||||
| return statusBarHeight | return statusBarHeight | ||||
| } | } | ||||