| XklLocal |
| import java.lang.Exception | import java.lang.Exception | ||||
| import java.math.BigDecimal | import java.math.BigDecimal | ||||
| import java.math.RoundingMode | import java.math.RoundingMode | ||||
| import java.text.DateFormat | |||||
| import java.text.DecimalFormat | import java.text.DecimalFormat | ||||
| import java.text.SimpleDateFormat | |||||
| import java.util.* | import java.util.* | ||||
| import java.util.zip.ZipFile | |||||
| import java.util.zip.ZipInputStream | import java.util.zip.ZipInputStream | ||||
| /** | /** | ||||
| } | } | ||||
| /** 获取课程的数量 */ | /** 获取课程的数量 */ | ||||
| fun getTotalCourseSize() : Int { | |||||
| fun getTotalCourseSize(projectId : Int) : Int { | |||||
| var result = 0 | var result = 0 | ||||
| subjectWithCoursePackMap.forEach { entry -> | |||||
| entry.value.forEach { coursePack -> | |||||
| result += coursePack.childrenCourses.size | |||||
| when(projectId){ | |||||
| 0 -> subjectWithCoursePackMap.forEach { entry -> | |||||
| entry.value.forEach { coursePack -> | |||||
| result += coursePack.childrenCourses.size | |||||
| } | |||||
| } | |||||
| AppConstants.SUBJECT_ENGLISH -> subjectWithCoursePackMap[AppConstants.SUBJECT_ENGLISH]?.forEach { | |||||
| result += it.childrenCourses.size | |||||
| } | |||||
| AppConstants.SUBJECT_CHINESE -> subjectWithCoursePackMap[AppConstants.SUBJECT_CHINESE]?.forEach { | |||||
| result += it.childrenCourses.size | |||||
| } | } | ||||
| } | } | ||||
| return result | return result |
| mutableList.add(lesson) | mutableList.add(lesson) | ||||
| positionIndex += 1 | positionIndex += 1 | ||||
| // TODO: 2022/5/9 对课时数量进行限制,课时太多,开发人员不好进行测试 | // TODO: 2022/5/9 对课时数量进行限制,课时太多,开发人员不好进行测试 | ||||
| // val needBreak = when (base.coursePackType) { | |||||
| // AppConstants.COURSEPACK_TYPE_CHINESE_COMPOSITION -> positionIndex == 10 //保留十个课时 | |||||
| // AppConstants.COURSEPACK_TYPE_ENGLISH_SPOKEN -> positionIndex == 6 //保留六个课时 | |||||
| // else -> positionIndex == 3 //保留三个课时 | |||||
| // } | |||||
| // if (needBreak) { | |||||
| // break | |||||
| // } | |||||
| val needBreak = when (base.coursePackType) { | |||||
| AppConstants.COURSEPACK_TYPE_CHINESE_COMPOSITION -> positionIndex == 10 //保留十个课时 | |||||
| AppConstants.COURSEPACK_TYPE_ENGLISH_SPOKEN -> positionIndex == 6 //保留六个课时 | |||||
| else -> positionIndex == 6 //保留六个课时 | |||||
| } | |||||
| if (needBreak) { | |||||
| break | |||||
| } | |||||
| } | } | ||||
| it.close() | it.close() | ||||
| } | } |
| /** 查询到播放数据过来 */ | /** 查询到播放数据过来 */ | ||||
| AudioCache.initAudioLiveData().observe(this) { | AudioCache.initAudioLiveData().observe(this) { | ||||
| if (it == null) { | |||||
| //发音文件为空 | |||||
| showToast("未找到发音文件") | |||||
| } else { | |||||
| MPManager.play(it, listener = impListener) | |||||
| //没有完成且非生命周期暂停 | |||||
| if (!vm.isAllOver && !vm.isLifecyclerPause) { | |||||
| if (it == null) { | |||||
| //发音文件为空 | |||||
| showToast("未找到发音文件") | |||||
| } else { | |||||
| MPManager.play(it, listener = impListener) | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| override fun onResume() { | |||||
| super.onResume() | |||||
| //继续播放 | |||||
| if (vm.isLifecyclerPause) { | |||||
| vm.isLifecyclerPause = false | |||||
| if (!vm.isAllOver && wordChooseBinding.ivVoice.visibility == View.VISIBLE) { | |||||
| wordChooseBinding.ivVoice.performClick() | |||||
| } | |||||
| } | |||||
| } | |||||
| override fun onPause() { | |||||
| super.onPause() | |||||
| vm.isLifecyclerPause = true | |||||
| //辨音测试,停止动画,停止播放 | |||||
| if (vm.intentData.courseType == AppConstants.COURSE_TYPE_ENGLISH_VOICE) { | |||||
| if (wordChooseBinding.ivVoice.visibility == View.VISIBLE) { | |||||
| wordChooseBinding.ivVoice.cancelAnimation() | |||||
| } | } | ||||
| } | } | ||||
| MPManager.removePlayListener() | |||||
| MPManager.stopPlay() | |||||
| } | } | ||||
| //播放监听 | //播放监听 | ||||
| /** 新单词来了的发音事件 */ | /** 新单词来了的发音事件 */ | ||||
| private fun initNewWordRead(it : ExamBean) { | private fun initNewWordRead(it : ExamBean) { | ||||
| //词汇量测试,新单词发音 | //词汇量测试,新单词发音 | ||||
| if (vm.intentData.examType == AppConstants.TEST_TYPE_NORMAL){ | |||||
| if (vm.intentData.examType == AppConstants.TEST_TYPE_NORMAL) { | |||||
| wordChooseBinding.ivVoice.performClick() | wordChooseBinding.ivVoice.performClick() | ||||
| return | return | ||||
| } | } | ||||
| } | } | ||||
| override fun loadData() { | override fun loadData() { | ||||
| //初始获取第一条数据 | |||||
| vm.loadFirst() | |||||
| //监听倒计时 | //监听倒计时 | ||||
| vm.currentSuplusTime.observe(this) { | vm.currentSuplusTime.observe(this) { | ||||
| when (vm.intentData.courseType) { | when (vm.intentData.courseType) { | ||||
| else -> vm.chooseResult(-1) | else -> vm.chooseResult(-1) | ||||
| } | } | ||||
| } | } | ||||
| //初始获取第一条数据 | |||||
| vm.loadFirst() | |||||
| } | } | ||||
| //口语的音频,有问题,与选项 直接获取其tag获取音频 | //口语的音频,有问题,与选项 直接获取其tag获取音频 | ||||
| currentPlayView?.cancelAnimation() | currentPlayView?.cancelAnimation() | ||||
| if (view is LottieAnimationView && view.visibility == View.VISIBLE) currentPlayView = view | if (view is LottieAnimationView && view.visibility == View.VISIBLE) currentPlayView = view | ||||
| when{ | |||||
| when { | |||||
| //词汇量测试 | //词汇量测试 | ||||
| vm.intentData.examType == AppConstants.TEST_TYPE_NORMAL -> AudioCache.getVocabularyVoice(it.word_id, vm.defaultSoundWay) | |||||
| vm.intentData.examType == AppConstants.TEST_TYPE_NORMAL -> AudioCache.getVocabularyVoice(it.word_id, | |||||
| vm.defaultSoundWay) | |||||
| //口语 | //口语 | ||||
| isSpokenTotalTest() -> AudioCache.getSpokenVoice(view.tag as String) | isSpokenTotalTest() -> AudioCache.getSpokenVoice(view.tag as String) | ||||
| //测试 | //测试 | ||||
| /** 测试完成 : 弹窗显示 */ | /** 测试完成 : 弹窗显示 */ | ||||
| private fun testOver() { | private fun testOver() { | ||||
| if (vm.intentData.examType == AppConstants.TEST_TYPE_NORMAL){ | |||||
| AudioCache.initAudioLiveData().removeObservers(this) | |||||
| if (vm.intentData.examType == AppConstants.TEST_TYPE_NORMAL) { | |||||
| vm.intentData.vocabularyItem?.let { | vm.intentData.vocabularyItem?.let { | ||||
| val createTime = DateUtil.format(System.currentTimeMillis(), DateUtil.FORMAT_1) | val createTime = DateUtil.format(System.currentTimeMillis(), DateUtil.FORMAT_1) | ||||
| VocabularyDialog.newInstance(it.level,createTime,vm.scoreValue,vm.vocabularyCoverange).apply { | |||||
| VocabularyDialog.newInstance(it.level, createTime, vm.scoreValue, vm.vocabularyCoverange).apply { | |||||
| onDialogListener = { action, dialog -> | onDialogListener = { action, dialog -> | ||||
| when(action){ | |||||
| when (action) { | |||||
| //完成 | //完成 | ||||
| AppConstants.DIALOG_OVER -> { | AppConstants.DIALOG_OVER -> { | ||||
| dialog.dismissAllowingStateLoss() | dialog.dismissAllowingStateLoss() | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| }.show(supportFragmentManager,"vocabulary") | |||||
| }.show(supportFragmentManager, "vocabulary") | |||||
| } | } | ||||
| return | return | ||||
| } | } | ||||
| }.show(supportFragmentManager, javaClass.name) | }.show(supportFragmentManager, javaClass.name) | ||||
| //如果是学前总测试完成,则标记本课程为已学课程 | //如果是学前总测试完成,则标记本课程为已学课程 | ||||
| if (vm.intentData.examType == AppConstants.TEST_TYPE_BEFORE_TOTAL){ | |||||
| if (vm.intentData.examType == AppConstants.TEST_TYPE_BEFORE_TOTAL) { | |||||
| vm.intentData.let { | vm.intentData.let { | ||||
| DataRepository.setLearnedCourseID(it.subjectId.toLong(), it.coursePackId, it.courseId) | DataRepository.setLearnedCourseID(it.subjectId.toLong(), it.coursePackId, it.courseId) | ||||
| } | } |
| } | } | ||||
| } | } | ||||
| } | } | ||||
| var isLifecyclerPause = false | |||||
| /** onResume | /** onResume | ||||
| * isAllOver = true 结束了,不处理了 | * isAllOver = true 结束了,不处理了 | ||||
| * 开启总计时 | * 开启总计时 | ||||
| /** onPause时,停止总计时 标记进入后台 如果弹窗显示,就只需要关闭总计时就可以了,否则关闭所有计时 */ | /** onPause时,停止总计时 标记进入后台 如果弹窗显示,就只需要关闭总计时就可以了,否则关闭所有计时 */ | ||||
| override fun onPause(owner : LifecycleOwner) { | override fun onPause(owner : LifecycleOwner) { | ||||
| super.onPause(owner) | super.onPause(owner) | ||||
| DictionaryFloatingWindowManager.getInstance().hide() | |||||
| isInBackground = true | isInBackground = true | ||||
| //测试完成,直接返回,已经停止计时了 | //测试完成,直接返回,已经停止计时了 | ||||
| if (isAllOver) return | if (isAllOver) return | ||||
| mHandler.removeCallbacks(currentCountingTimeRunnable) | mHandler.removeCallbacks(currentCountingTimeRunnable) | ||||
| } | } | ||||
| } | } | ||||
| DictionaryFloatingWindowManager.getInstance().hide() | |||||
| } | } | ||||
| override fun onDestroy(owner : LifecycleOwner) { | |||||
| super.onDestroy(owner) | |||||
| MPManager.removePlayListener() | |||||
| } | |||||
| /** 停止获取下一题 */ | /** 停止获取下一题 */ | ||||
| fun pauseToNext() { | fun pauseToNext() { |
| override fun loadData() { | override fun loadData() { | ||||
| vm.loadNext() | |||||
| //如果自动播放,监听信息 | //如果自动播放,监听信息 | ||||
| if (vm.learnData.isAutoPlay) { | if (vm.learnData.isAutoPlay) { | ||||
| LiveEventBus.get<Int>("auto_play").observe(this) { | LiveEventBus.get<Int>("auto_play").observe(this) { | ||||
| //自动播放的单词音频数据 | //自动播放的单词音频数据 | ||||
| if (vm.learnData.isAutoPlay) { | if (vm.learnData.isAutoPlay) { | ||||
| it?.run { | it?.run { | ||||
| MPManager.play(it, listener = impListener) | |||||
| MPManager.play(it, listener = if(vm.isAutoPlaying) impListener else null) | |||||
| } ?: let { | } ?: let { | ||||
| showToast("未找到发音文件") | showToast("未找到发音文件") | ||||
| //获取下一条 | //获取下一条 | ||||
| //上传数据后的处理 | //上传数据后的处理 | ||||
| vm.saveDataLiveData.observe(this) { | vm.saveDataLiveData.observe(this) { | ||||
| AudioCache.initAudioLiveData().removeObservers(this@LearnWordActivity) | |||||
| when { | when { | ||||
| //学习完成的保存数据后显示学习完成弹窗 | //学习完成的保存数据后显示学习完成弹窗 | ||||
| it -> showLearnOverDialog() | it -> showLearnOverDialog() | ||||
| else -> finish() | else -> finish() | ||||
| } | } | ||||
| } | } | ||||
| vm.loadNext() | |||||
| } | } | ||||
| /**新数据到来,自动播放界面显示*/ | /**新数据到来,自动播放界面显示*/ |
| import com.suliang.common.extension.createRandomNewChar | import com.suliang.common.extension.createRandomNewChar | ||||
| 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.media.MPManager | |||||
| import com.xkl.cdl.data.AppConstants | import com.xkl.cdl.data.AppConstants | ||||
| import com.xkl.cdl.data.DataTransferHolder | import com.xkl.cdl.data.DataTransferHolder | ||||
| import com.xkl.cdl.data.bean.LearnWord | import com.xkl.cdl.data.bean.LearnWord | ||||
| }) | }) | ||||
| } | } | ||||
| //自动播放时是否是生命周期影响的暂停,恢复后自动播放 | |||||
| private var isAutoPlayWithLifecyclerPause = false | |||||
| override fun onResume(owner : LifecycleOwner) { | override fun onResume(owner : LifecycleOwner) { | ||||
| super.onResume(owner) | super.onResume(owner) | ||||
| if (!isAllOver) { | if (!isAllOver) { | ||||
| //自动播放则手动恢复 | |||||
| if (learnData.isAutoPlay && isAutoPlayWithLifecyclerPause){ | |||||
| isAutoPlayWithLifecyclerPause = false | |||||
| isAutoPlaying = true | |||||
| //继续播放 | |||||
| LiveEventBus.get<Int>("auto_play").post(0) | |||||
| } | |||||
| if (!isShowBackDialog || (learnData.isAutoPlay && isAutoPlaying)) { | if (!isShowBackDialog || (learnData.isAutoPlay && isAutoPlaying)) { | ||||
| executeLearnValidTime() | executeLearnValidTime() | ||||
| } | } | ||||
| super.onPause(owner) | super.onPause(owner) | ||||
| stopTotalCountTing() | stopTotalCountTing() | ||||
| DictionaryFloatingWindowManager.getInstance().hide() | DictionaryFloatingWindowManager.getInstance().hide() | ||||
| //如果是自动播放未完成,且在播放中,手动暂停播放 | |||||
| if (!isAllOver && learnData.isAutoPlay ){ | |||||
| isAutoPlayWithLifecyclerPause = isAutoPlaying | |||||
| isAutoPlaying = false | |||||
| } | |||||
| MPManager.removePlayListener() | |||||
| } | } | ||||
| /** | /** |
| } | } | ||||
| } | } | ||||
| //学后总测结束传递数据回来。更新数据 | //学后总测结束传递数据回来。更新数据 | ||||
| AppConstants.DATA_COURSE_AFTER_TEST_OVER -> vm.courseDetail.st_after = it.scoreValue.toDouble() //学后总分 | |||||
| AppConstants.DATA_COURSE_AFTER_TEST_OVER -> { | |||||
| vm.courseDetail.st_after = it.scoreValue.toDouble() | |||||
| changeFragment(2) | |||||
| } //学后总分 | |||||
| //学后总测试结束动作: 再测一次 | //学后总测试结束动作: 再测一次 | ||||
| AppConstants.ACTION_COURSE_TEST_AFTER_TOTAL_AGAIN -> { | AppConstants.ACTION_COURSE_TEST_AFTER_TOTAL_AGAIN -> { |
| } | } | ||||
| else -> { //有成绩,直接完成 | else -> { //有成绩,直接完成 | ||||
| if (it >= AppConstants.TEST_SCORE_LEVEL_2) { | if (it >= AppConstants.TEST_SCORE_LEVEL_2) { | ||||
| tvMainTip.setHtml("你已完成学后总测试,上次得分: <font color=\'#5082E6\'>$it</font>") | |||||
| tvMainTip.setHtml("你已完成学后总测试,上次得分: <font color=\'#5082E6\'>${it.toInt()}</font>") | |||||
| } else { | } else { | ||||
| tvMainTip.setHtml("你已完成学后总测试,上次得分: <font color=\'#F26255\'>$it</font>") | |||||
| tvMainTip.setHtml("你已完成学后总测试,上次得分: <font color=\'#F26255\'>${it.toInt()}</font>") | |||||
| } | } | ||||
| tvTips.visibility = View.VISIBLE | tvTips.visibility = View.VISIBLE | ||||
| tvCountTip.visibility = View.GONE | tvCountTip.visibility = View.GONE |
| binding.tvTest.click { | binding.tvTest.click { | ||||
| val count = when (binding.rgNumber.checkedRadioButtonId) { | val count = when (binding.rgNumber.checkedRadioButtonId) { | ||||
| R.id.rb_smaller -> 20 | R.id.rb_smaller -> 20 | ||||
| R.id.rb_normal -> 20 | |||||
| R.id.rb_normal -> 50 | |||||
| R.id.rb_more -> 100 | R.id.rb_more -> 100 | ||||
| else -> 0 | else -> 0 | ||||
| } | } |
| binding.rankingEfficient.setProgressNumber(e.toFloat()) | binding.rankingEfficient.setProgressNumber(e.toFloat()) | ||||
| binding.tvEfficient.text = "${NumberUtils.formatHalfUp(e, "0.##")}%" | binding.tvEfficient.text = "${NumberUtils.formatHalfUp(e, "0.##")}%" | ||||
| binding.tvEfficientState.apply { | binding.tvEfficientState.apply { | ||||
| val instance = lastE - e | |||||
| val instance = e - lastE | |||||
| when { | when { | ||||
| //增长 | //增长 | ||||
| instance >= 0 -> { | instance >= 0 -> { |
| val result = TimeStatisticItem().apply { | val result = TimeStatisticItem().apply { | ||||
| backGround = R.drawable.shape_rounder_4_green_a5 | backGround = R.drawable.shape_rounder_4_green_a5 | ||||
| name = "已学课程" | name = "已学课程" | ||||
| unit = "/${CourseManager.getTotalCourseSize()}个" | |||||
| unit = "/${CourseManager.getTotalCourseSize(projectId)}个" | |||||
| time = "${statistics.sc}" | time = "${statistics.sc}" | ||||
| initIncr(this,statistics.scIncr.toDouble()) | initIncr(this,statistics.scIncr.toDouble()) | ||||
| //增量 | //增量 |