| <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/inc_exam_word_choose_content.xml" value="0.33" /> | <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/inc_exam_word_choose_content.xml" value="0.33" /> | ||||
| <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/inc_learn_spell.xml" value="0.4859375" /> | <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/inc_learn_spell.xml" value="0.4859375" /> | ||||
| <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/inc_learn_test_statistic.xml" value="0.5" /> | <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/inc_learn_test_statistic.xml" value="0.5" /> | ||||
| <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/inc_learn_title.xml" value="0.5784919653893696" /> | |||||
| <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/inc_learn_title.xml" value="0.25" /> | |||||
| <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/inc_learn_word.xml" value="0.390625" /> | <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/inc_learn_word.xml" value="0.390625" /> | ||||
| <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/inc_over_number.xml" value="0.4979166666666667" /> | <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/inc_over_number.xml" value="0.4979166666666667" /> | ||||
| <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/inc_spell_learn_tip.xml" value="0.67" /> | <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/inc_spell_learn_tip.xml" value="0.67" /> |
| const val DIALOG_TYPE_LESSON_ITEM_CLICK_COMPOSITION_KNOWLEDGE_OVER = 6 | const val DIALOG_TYPE_LESSON_ITEM_CLICK_COMPOSITION_KNOWLEDGE_OVER = 6 | ||||
| /** 作文知识点课时学习界面学习完成 */ | /** 作文知识点课时学习界面学习完成 */ | ||||
| const val DIALOG_TYPE_LESSON_COMPOSITION_KNOWLEDGE_LEARNING_OVER = 7 | const val DIALOG_TYPE_LESSON_COMPOSITION_KNOWLEDGE_LEARNING_OVER = 7 | ||||
| /** 复习完成 */ | |||||
| const val DIALOG_TYPE_REVIEW_OVER = 8 | |||||
| /**--- 总线动作 --------------------------------- */ | /**--- 总线动作 --------------------------------- */ | ||||
| /**action key 改变界面 到目录页 */ | /**action key 改变界面 到目录页 */ | ||||
| const val EVENT_LESSON_ACTION = "lesson_learn_action" | const val EVENT_LESSON_ACTION = "lesson_learn_action" | ||||
| /**总测数据与动作*/ | /**总测数据与动作*/ | ||||
| const val EVENT_TOTAL_TEST = "total_test" | const val EVENT_TOTAL_TEST = "total_test" | ||||
| /**复习结果*/ | |||||
| const val EVENT_REVIEW_DATA = "review" | |||||
| /** 事件动作:学前总测结束弹窗之 开始学习 */ | /** 事件动作:学前总测结束弹窗之 开始学习 */ | ||||
| const val DATA_COURSE_AFTER_TEST_OVER = 12 | const val DATA_COURSE_AFTER_TEST_OVER = 12 | ||||
| /** 作文测试完成动作,再测一次*/ | /** 作文测试完成动作,再测一次*/ | ||||
| const val ACTION_LESSON_COMPOSITION_TEST_AGAIN = 13 | const val ACTION_LESSON_COMPOSITION_TEST_AGAIN = 13 | ||||
| /**复习结束*/ | |||||
| const val DATA_REVIEW = 14 | |||||
| /**--- 弹窗动作 --------------------------------- */ | /**--- 弹窗动作 --------------------------------- */ | ||||
| /** 学前总测结束弹窗: 开始学习 ,课时学前测试开始弹窗*/ | /** 学前总测结束弹窗: 开始学习 ,课时学前测试开始弹窗*/ |
| */ | */ | ||||
| @Suppress("UNCHECKED_CAST") | @Suppress("UNCHECKED_CAST") | ||||
| fun <T> getData(key : String = AppConfig.INTENT_1) : T{ | fun <T> getData(key : String = AppConfig.INTENT_1) : T{ | ||||
| return dataMap[key] as T | |||||
| return (dataMap[key] as T).also { | |||||
| clear() | |||||
| } | |||||
| } | } | ||||
| /** | /** |
| * author suliang | * author suliang | ||||
| * create 2022/4/2 14:55 | * create 2022/4/2 14:55 | ||||
| * Describe: 课时学习时的传参 | * Describe: 课时学习时的传参 | ||||
| * @param lesson 课时学习是为课时数据,其他特殊时候,如自动播放,只是用以包装课程的基本信息如果项目id、课程包类型、课程类型等 | |||||
| * @param lesson 课时学习是为课时数据,其他特殊时候, | |||||
| * 如自动播放、复习,只是用以包装课程的基本信息如项目id、课程包类型、课程类型等 | |||||
| */ | */ | ||||
| class LearnData(val lesson: Lesson) { | class LearnData(val lesson: Lesson) { | ||||
| //作文课堂练习数据 | //作文课堂练习数据 | ||||
| var readingList : List<CompositionReadingBean> = mutableListOf() | var readingList : List<CompositionReadingBean> = mutableListOf() | ||||
| //是否是复习 | |||||
| var isReview = false | |||||
| } | } |
| var scoreValue = 0 //分数 | var scoreValue = 0 //分数 | ||||
| var newErrorMap : HashMap<String, Boolean>? = null //新错误单词列表 | var newErrorMap : HashMap<String, Boolean>? = null //新错误单词列表 | ||||
| //课时学前测试 除了学前总测传递数据,还需要课时位置数据, | |||||
| //课时学前测试 除了学前总测传递数据,还需要课时位置数据 在复习时,用以标记为最后复习的value位置 | |||||
| var leesonPositionIndex = 0 // lesson所在位置 | var leesonPositionIndex = 0 // lesson所在位置 | ||||
| import io.reactivex.rxjava3.annotations.NonNull | import io.reactivex.rxjava3.annotations.NonNull | ||||
| import net.sqlcipher.database.SQLiteDatabase | import net.sqlcipher.database.SQLiteDatabase | ||||
| import java.io.File | import java.io.File | ||||
| import java.util.* | |||||
| /** | /** | ||||
| * author suliang | * author suliang | ||||
| return result | return result | ||||
| } | } | ||||
| /** | |||||
| * 查询复习数据 | |||||
| * @param dbControlBase DbControlBase | |||||
| * @param reviewDataList MutableList<LearnWord> 复习数据 | |||||
| * @return Boolean 查询到有数据返回true,如果都没有查询到数据,则返回false | |||||
| */ | |||||
| @SuppressLint("Range") | |||||
| fun queryReviewData(dbControlBase : DbControlBase, reviewDataList : MutableList<LearnWord>) : Boolean { | |||||
| //没有查询到复习数据的位置集合 | |||||
| val notHaveData = arrayListOf<Int>() | |||||
| open(dbControlBase) | |||||
| reviewDataList.forEachIndexed{ index , learnWord -> | |||||
| val sql = "SELECT * FROM chapter WHERE chapter_id = ${learnWord.chapterId} and lesson_id = ${learnWord.lessonId} AND word_id = ${learnWord.wordId} " | |||||
| val rawQuery = mDataBase?.rawQuery(sql, null) | |||||
| rawQuery?.run { | |||||
| if (this.count == 0 ){ | |||||
| notHaveData.add(index) | |||||
| return@run | |||||
| } | |||||
| while (moveToNext()){ | |||||
| learnWord.word = getString(getColumnIndex("word")) | |||||
| learnWord.basic_explanation = getString(getColumnIndex("basic_explaination")) | |||||
| learnWord.extend_explanation = getString(getColumnIndex("all_explaination")) | |||||
| learnWord.phrase = getString(getColumnIndex("phrase")) | |||||
| learnWord.example = getString(getColumnIndex("example")) | |||||
| learnWord.reference = getString(getColumnIndex("reference")) | |||||
| when (dbControlBase.courseType) { | |||||
| AppConstants.COURSE_TYPE_CHINESE_LITERACY -> { | |||||
| learnWord.literacyIspolyphone = getInt(getColumnIndex("polyphone")) > 0 | |||||
| learnWord.phonetic_cn = getString(getColumnIndex("phonetic")) | |||||
| } | |||||
| AppConstants.COURSE_TYPE_CHINESE_PINYIN -> { | |||||
| learnWord.phonetic_cn = getString(getColumnIndex("phonetic")) | |||||
| } | |||||
| else -> { | |||||
| learnWord.phonetic_uk = getString(getColumnIndex("phonetic_uk")) | |||||
| learnWord.phonetic_us = getString(getColumnIndex("phonetic_us")) | |||||
| } | |||||
| } | |||||
| } | |||||
| }?: notHaveData.add(index) | |||||
| } | |||||
| if (notHaveData.size > 0 ){ | |||||
| //反序 | |||||
| Collections.reverse(notHaveData) | |||||
| notHaveData.forEach{ | |||||
| reviewDataList.removeAt(it) | |||||
| } | |||||
| } | |||||
| return reviewDataList.size > 0 | |||||
| } | |||||
| } | } |
| AppConstants.DIALOG_TYPE_LESSON_ITEM_CLICK_COMPOSITION_KNOWLEDGE_OVER -> initCompositionKnowledgeLearning(true) | AppConstants.DIALOG_TYPE_LESSON_ITEM_CLICK_COMPOSITION_KNOWLEDGE_OVER -> initCompositionKnowledgeLearning(true) | ||||
| /** 作文课时学习中完成弹窗 */ | /** 作文课时学习中完成弹窗 */ | ||||
| AppConstants.DIALOG_TYPE_LESSON_COMPOSITION_KNOWLEDGE_LEARNING_OVER -> initCompositionKnowledgeLearning(false) | AppConstants.DIALOG_TYPE_LESSON_COMPOSITION_KNOWLEDGE_LEARNING_OVER -> initCompositionKnowledgeLearning(false) | ||||
| /** 复习完成 */ | |||||
| AppConstants.DIALOG_TYPE_REVIEW_OVER -> initReviewOver() | |||||
| } | } | ||||
| } | } | ||||
| binding.tvLeft.click { onDialogListener(AppConstants.DIALOG_START_TEST,this) } | binding.tvLeft.click { onDialogListener(AppConstants.DIALOG_START_TEST,this) } | ||||
| binding.tvRight.click { onDialogListener(AppConstants.DIALOG_OVER,this) } | binding.tvRight.click { onDialogListener(AppConstants.DIALOG_OVER,this) } | ||||
| } | } | ||||
| /** | |||||
| * 复习完成 tv_title,tv_tip_1 | |||||
| */ | |||||
| private fun initReviewOver(){ | |||||
| binding.run { | |||||
| imgIv.setImageResource(if (Random.nextBoolean()) R.mipmap.boy_2 else R.mipmap.girl_2) | |||||
| tvTitle.visibility = View.VISIBLE | |||||
| tvTitle.text = "智能复习已完成,太棒了!" | |||||
| tvTip1.visibility = View.VISIBLE | |||||
| tvTip1.text = when{ | |||||
| learnDialogBean.errorNumber == 0 -> "我复习了${learnDialogBean.correctNumber}个词条" | |||||
| else -> "我复习了${learnDialogBean.correctNumber}个词条,词汇量增加了${learnDialogBean.errorNumber}" | |||||
| } | |||||
| tvRight.text = "完成" | |||||
| } | |||||
| binding.tvRight.click { onDialogListener(AppConstants.DIALOG_OVER,this) } | |||||
| } | |||||
| } | } |
| private lateinit var bindingWord : IncLearnWordBinding | private lateinit var bindingWord : IncLearnWordBinding | ||||
| //详情布局 | //详情布局 | ||||
| private lateinit var incWorcDetailBinding: IncWordDetailBinding | |||||
| private lateinit var incWorcDetailBinding : IncWordDetailBinding | |||||
| //拼写内容布局 | //拼写内容布局 | ||||
| private lateinit var bindingSpell : IncLearnSpellBinding | private lateinit var bindingSpell : IncLearnSpellBinding | ||||
| //拼写前的提示 | //拼写前的提示 | ||||
| private lateinit var incSpellTipBinding : IncSpellLearnTipBinding | private lateinit var incSpellTipBinding : IncSpellLearnTipBinding | ||||
| setBackgroundColor(Color.parseColor("#1A5082E6")) | setBackgroundColor(Color.parseColor("#1A5082E6")) | ||||
| setTextColor(ContextCompat.getColor(this@LearnWordActivity, R.color.theme_color)) | setTextColor(ContextCompat.getColor(this@LearnWordActivity, R.color.theme_color)) | ||||
| } | } | ||||
| } else if (vm.learnData.isReview) { | |||||
| binding.tvBanner.apply { | |||||
| visibility = View.VISIBLE | |||||
| setText(R.string.smart_reviewing) | |||||
| setBackgroundColor(Color.parseColor("#1A5082E6")) | |||||
| setTextColor(ContextCompat.getColor(this@LearnWordActivity, R.color.theme_color)) | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| /** 标题初始 */ | /** 标题初始 */ | ||||
| private fun initTitle() { | private fun initTitle() { | ||||
| binding.incLearnTitle.run { | binding.incLearnTitle.run { | ||||
| showProgress = false | |||||
| //复习时显示复习正确的进度,学习、自动播放不显示进度 | |||||
| showProgress = vm.learnData.isReview | |||||
| imgBack.click { onBackPressed() } | imgBack.click { onBackPressed() } | ||||
| tvTitle.text = vm.learnData.lesson.lessonName | tvTitle.text = vm.learnData.lesson.lessonName | ||||
| when (vm.learnData.lesson.coursePackType) { | when (vm.learnData.lesson.coursePackType) { | ||||
| /** 历史轨迹初始 */ | /** 历史轨迹初始 */ | ||||
| private fun initHistoricalRoute() { | private fun initHistoricalRoute() { | ||||
| val initCourseType = when{ | |||||
| val initCourseType = when { | |||||
| //自动播放时,将历史轨迹的课时类型修改为单词类型,避免辨音课程自动播放时显示横线 | //自动播放时,将历史轨迹的课时类型修改为单词类型,避免辨音课程自动播放时显示横线 | ||||
| vm.learnData.isAutoPlay -> AppConstants.COURSE_TYPE_ENGLISH_DISCERN | |||||
| vm.learnData.isAutoPlay -> AppConstants.COURSE_TYPE_ENGLISH_DISCERN | |||||
| else -> vm.learnData.lesson.courseType | else -> vm.learnData.lesson.courseType | ||||
| } | } | ||||
| adapterHistorical = AdapterHistoricalRoute(initCourseType).apply { | adapterHistorical = AdapterHistoricalRoute(initCourseType).apply { | ||||
| //拼写纠错按钮 点击事件 | //拼写纠错按钮 点击事件 | ||||
| bindingSpell.tvControlError.click { | bindingSpell.tvControlError.click { | ||||
| when (it.tag as Int) { | when (it.tag as Int) { | ||||
| SPELL_TAG_ALL_RIGHT -> vm.currentSpellIsCorrect = false | |||||
| SPELL_TAG_ALL_RIGHT -> vm.currentSpellIsCorrect = false | |||||
| SPELL_TAG_IN_ERROR -> { | SPELL_TAG_IN_ERROR -> { | ||||
| vm.currentSpellIsCorrect = true | vm.currentSpellIsCorrect = true | ||||
| //下一条显示 | //下一条显示 | ||||
| } | } | ||||
| bindingSpell.incWord.tvWord.click { | bindingSpell.incWord.tvWord.click { | ||||
| //拼写完成点击才有效,拼写中点击无效 | //拼写完成点击才有效,拼写中点击无效 | ||||
| if (!spellAdapter.isSpelling) | |||||
| readWord() | |||||
| if (!spellAdapter.isSpelling) readWord() | |||||
| } | } | ||||
| } | } | ||||
| AppConstants.COURSE_TYPE_ENGLISH_VOICE -> { | AppConstants.COURSE_TYPE_ENGLISH_VOICE -> { | ||||
| incWorcDetailBinding.root.visibility = it | incWorcDetailBinding.root.visibility = it | ||||
| } | } | ||||
| } | } | ||||
| if (vm.learnData.lesson.courseType == AppConstants.COURSE_TYPE_CHINESE_COMPOSITION){ | |||||
| if (vm.learnData.lesson.courseType == AppConstants.COURSE_TYPE_CHINESE_COMPOSITION) { | |||||
| bindingWord.imgWord.visibility = View.GONE | bindingWord.imgWord.visibility = View.GONE | ||||
| val layoutParams = bindingWord.incWord.root.layoutParams as ConstraintLayout.LayoutParams | |||||
| val layoutParams = bindingWord.incWord.root.layoutParams as ConstraintLayout.LayoutParams | |||||
| layoutParams.goneTopMargin = ScreenUtil.dp2px(12f).toInt() | layoutParams.goneTopMargin = ScreenUtil.dp2px(12f).toInt() | ||||
| bindingWord.incWord.root.requestLayout() | bindingWord.incWord.root.requestLayout() | ||||
| } | } | ||||
| //初始化按钮 | //初始化按钮 | ||||
| private fun initControlButton() { | private fun initControlButton() { | ||||
| //自动播放隐藏操作按钮 | //自动播放隐藏操作按钮 | ||||
| if (vm.learnData.isAutoPlay){ | |||||
| binding.incControlButton.root.visibility= View.GONE | |||||
| if (vm.learnData.isAutoPlay) { | |||||
| binding.incControlButton.root.visibility = View.GONE | |||||
| return | return | ||||
| } | } | ||||
| //其他课程默认按钮全部隐藏 | //其他课程默认按钮全部隐藏 | ||||
| } | } | ||||
| //最底部 | //最底部 | ||||
| private fun initBottom(){ | |||||
| private fun initBottom() { | |||||
| //有效时间 | //有效时间 | ||||
| vm.validTime.observe(this){ | |||||
| binding.tvValidTime.text = "本次学习 ${DateUtil.formatGMT(it,DateUtil.FORMAT_2)}" | |||||
| vm.validTime.observe(this) { | |||||
| binding.tvValidTime.text = "本次学习 ${DateUtil.formatGMT(it, DateUtil.FORMAT_2)}" | |||||
| } | } | ||||
| if (vm.learnData.isAutoPlay){ | |||||
| if (vm.learnData.isAutoPlay) { | |||||
| binding.tvPlay.run { | binding.tvPlay.run { | ||||
| visibility = View.VISIBLE | visibility = View.VISIBLE | ||||
| tag = 1 | tag = 1 | ||||
| } | } | ||||
| binding.tvPlay.click { | binding.tvPlay.click { | ||||
| when(binding.tvPlay.tag as Int){ | |||||
| when (binding.tvPlay.tag as Int) { | |||||
| 1 -> { //暂停播放 | 1 -> { //暂停播放 | ||||
| vm.isAutoPlaying = false | vm.isAutoPlaying = false | ||||
| binding.tvPlay.apply { | binding.tvPlay.apply { | ||||
| binding.tvBanner.apply { | binding.tvBanner.apply { | ||||
| setText(R.string.auto_play_banner_paused) | setText(R.string.auto_play_banner_paused) | ||||
| setBackgroundColor(Color.parseColor("#1AF26255")) | setBackgroundColor(Color.parseColor("#1AF26255")) | ||||
| setTextColor(ContextCompat.getColor(this@LearnWordActivity,R.color.red_1)) | |||||
| setTextColor(ContextCompat.getColor(this@LearnWordActivity, R.color.red_1)) | |||||
| } | } | ||||
| } | } | ||||
| 2 -> { //继续播放 | 2 -> { //继续播放 | ||||
| } | } | ||||
| } | } | ||||
| //停止播放 | //停止播放 | ||||
| binding.tvPlayStop.click {onBackPressed()} | |||||
| binding.tvPlayStop.click { onBackPressed() } | |||||
| } | } | ||||
| } | } | ||||
| /** 发音监听 */ | /** 发音监听 */ | ||||
| private val impListener = object : IMPListener { | private val impListener = object : IMPListener { | ||||
| override fun onMpState(state : EMediaState) { | override fun onMpState(state : EMediaState) { | ||||
| when{ | |||||
| vm.learnData.isAutoPlay -> when (state) { | |||||
| when { | |||||
| vm.learnData.isAutoPlay -> when (state) { | |||||
| EMediaState.COMPLETE, EMediaState.ERROR -> { | EMediaState.COMPLETE, EMediaState.ERROR -> { | ||||
| //播放次数+1 | //播放次数+1 | ||||
| vm.currentPlayTime ++ | |||||
| vm.currentPlayTime++ | |||||
| //继续播放,或获取下一条 | //继续播放,或获取下一条 | ||||
| LiveEventBus.get<Int>("auto_play").postDelay(0,700) | |||||
| LiveEventBus.get<Int>("auto_play").postDelay(0, 700) | |||||
| } | } | ||||
| } | } | ||||
| else -> when (state) { | else -> when (state) { | ||||
| override fun loadData() { | override fun loadData() { | ||||
| vm.loadNext() | vm.loadNext() | ||||
| //如果自动播放,监听信息 | //如果自动播放,监听信息 | ||||
| if (vm.learnData.isAutoPlay){ | |||||
| LiveEventBus.get<Int>("auto_play").observe(this){ | |||||
| if (vm.learnData.isAutoPlay) { | |||||
| LiveEventBus.get<Int>("auto_play").observe(this) { | |||||
| if (!vm.isAutoPlaying) return@observe | if (!vm.isAutoPlaying) return@observe | ||||
| when(vm.currentPlayTime){ | |||||
| when (vm.currentPlayTime) { | |||||
| vm.learnData.autoPlayTime -> vm.loadNext() | vm.learnData.autoPlayTime -> vm.loadNext() | ||||
| else -> readWord() | else -> readWord() | ||||
| } | } | ||||
| //发音数据 | //发音数据 | ||||
| AudioCache.initAudioLiveData().observe(this) { | AudioCache.initAudioLiveData().observe(this) { | ||||
| //自动播放的单词音频数据 | //自动播放的单词音频数据 | ||||
| if (vm.learnData.isAutoPlay){ | |||||
| if (vm.learnData.isAutoPlay) { | |||||
| it?.run { | it?.run { | ||||
| MPManager.play(it,listener = impListener) | |||||
| }?:let { | |||||
| MPManager.play(it, listener = impListener) | |||||
| } ?: let { | |||||
| showToast("未找到发音文件") | showToast("未找到发音文件") | ||||
| //获取下一条 | //获取下一条 | ||||
| vm.loadNext() | vm.loadNext() | ||||
| } | } | ||||
| 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("未找到发音文件") | ||||
| } | } | ||||
| //图片数据 | //图片数据 | ||||
| PhotoCache.initPhotoLiveData().observe(this) { | PhotoCache.initPhotoLiveData().observe(this) { | ||||
| it?.run { | it?.run { | ||||
| if(vm.learnData.isAutoPlay)bindingWord.imgWord.visibility = View.VISIBLE | |||||
| if (vm.learnData.isAutoPlay) bindingWord.imgWord.visibility = View.VISIBLE | |||||
| ImageLoader.loadImage(bindingWord.imgWord, it) | ImageLoader.loadImage(bindingWord.imgWord, it) | ||||
| } ?: let { bindingWord.imgWord.visibility = View.GONE } | } ?: let { bindingWord.imgWord.visibility = View.GONE } | ||||
| } | } | ||||
| adapterHistorical.addData(it) | adapterHistorical.addData(it) | ||||
| binding.rvHistoricalRoute.scrollToPosition(adapterHistorical.itemCount - 1) | binding.rvHistoricalRoute.scrollToPosition(adapterHistorical.itemCount - 1) | ||||
| } | } | ||||
| if (vm.learnData.isAutoPlay){ | |||||
| //自动播放界面初始 | |||||
| if (vm.learnData.isAutoPlay) { | |||||
| initAutoPlayWord(it) | initAutoPlayWord(it) | ||||
| return@observe | return@observe | ||||
| } | } | ||||
| //上传数据后的处理 | //上传数据后的处理 | ||||
| vm.saveDataLiveData.observe(this) { | vm.saveDataLiveData.observe(this) { | ||||
| when { | when { | ||||
| //学习完成的保存数据 | |||||
| //学习完成的保存数据后显示学习完成弹窗 | |||||
| it -> showLearnOverDialog() | it -> showLearnOverDialog() | ||||
| //学习未完成的保存数据 | |||||
| //学习未完成的保存数据,直接关闭 | |||||
| else -> finish() | else -> finish() | ||||
| } | } | ||||
| } | } | ||||
| //单词内容 | //单词内容 | ||||
| bindingWord.incWord.tvWord.apply { | bindingWord.incWord.tvWord.apply { | ||||
| //识字需单独处理 | //识字需单独处理 | ||||
| if (vm.learnData.lesson.courseType == AppConstants.COURSE_TYPE_CHINESE_LITERACY){ | |||||
| setHtml(ViewUtil.literacyToHtmlWord(learnWord.word, learnWord.showColor)) | |||||
| if (vm.learnData.lesson.courseType == AppConstants.COURSE_TYPE_CHINESE_LITERACY) { | |||||
| setHtml(ViewUtil.literacyToHtmlWord(learnWord.word, learnWord.showColor)) | |||||
| } else { | } else { | ||||
| text = learnWord.word | |||||
| text = learnWord.word | |||||
| } | } | ||||
| setTextColor(ContextCompat.getColor(this@LearnWordActivity, learnWord.showColor)) //单词显示颜色 | setTextColor(ContextCompat.getColor(this@LearnWordActivity, learnWord.showColor)) //单词显示颜色 | ||||
| } | } | ||||
| } | } | ||||
| binding.incControlButton.tvCenter.visibility = View.INVISIBLE | binding.incControlButton.tvCenter.visibility = View.INVISIBLE | ||||
| binding.incControlButton.tvRight.visibility = when (vm.learnData.lesson.coursePackType) { | binding.incControlButton.tvRight.visibility = when (vm.learnData.lesson.coursePackType) { | ||||
| AppConstants.COURSEPACK_TYPE_CHINESE_COMPOSITION,AppConstants.COURSEPACK_TYPE_ENGLISH_SOUNDMARK -> View.INVISIBLE | |||||
| AppConstants.COURSEPACK_TYPE_CHINESE_COMPOSITION, AppConstants.COURSEPACK_TYPE_ENGLISH_SOUNDMARK -> View.INVISIBLE | |||||
| else -> View.VISIBLE | else -> View.VISIBLE | ||||
| } | } | ||||
| } | } | ||||
| binding.incControlButton.tvCenter.visibility = View.VISIBLE | binding.incControlButton.tvCenter.visibility = View.VISIBLE | ||||
| //音标,显示重读 | //音标,显示重读 | ||||
| when(vm.learnData.lesson.coursePackType){ | |||||
| AppConstants.COURSEPACK_TYPE_ENGLISH_SOUNDMARK ->binding.incControlButton.tvRight.visibility = View.VISIBLE | |||||
| when (vm.learnData.lesson.coursePackType) { | |||||
| AppConstants.COURSEPACK_TYPE_ENGLISH_SOUNDMARK -> binding.incControlButton.tvRight.visibility = View.VISIBLE | |||||
| } | } | ||||
| } | } | ||||
| /**点击下一条*/ | /**点击下一条*/ | ||||
| private fun clickNext() { | private fun clickNext() { | ||||
| //拼写,需要处理历史轨迹 和在下一条的时候保存当前学习数据 | //拼写,需要处理历史轨迹 和在下一条的时候保存当前学习数据 | ||||
| if (vm.learnData.lesson.courseType == AppConstants.COURSE_TYPE_ENGLISH_SPELL){ | |||||
| if (vm.learnData.lesson.courseType == AppConstants.COURSE_TYPE_ENGLISH_SPELL) { | |||||
| adapterHistorical.currentLearnOver() | adapterHistorical.currentLearnOver() | ||||
| when{ | |||||
| when { | |||||
| //正确 | //正确 | ||||
| vm.currentSpellIsCorrect -> { | vm.currentSpellIsCorrect -> { | ||||
| //传递正确 | //传递正确 | ||||
| vm.clickCorrect(adapterHistorical.currentIsLastSelect) | vm.clickCorrect(adapterHistorical.currentIsLastSelect) | ||||
| val value = vm.currentLearnWord.value!! | val value = vm.currentLearnWord.value!! | ||||
| // 正常第一次不需要移除,第一个表达式则判断为第一次出现但是为学前测试错误 ,第二个表达式为小循环但不为小循环最后一次且后面还有数据则需要移除 | // 正常第一次不需要移除,第一个表达式则判断为第一次出现但是为学前测试错误 ,第二个表达式为小循环但不为小循环最后一次且后面还有数据则需要移除 | ||||
| if ((value.first && value.repeatNum == 1) || (!value.first && value.repeatNum <vm.learnRuleUtil.insertInterval.size && vm.learnRuleUtil.isHaveNext)) | |||||
| adapterHistorical.spellNeedRemoveCurrent() | |||||
| if ((value.first && value.repeatNum == 1) || (!value.first && value.repeatNum < vm.learnRuleUtil.insertInterval.size && vm.learnRuleUtil.isHaveNext)) adapterHistorical.spellNeedRemoveCurrent() | |||||
| } | } | ||||
| else -> { | else -> { | ||||
| vm.clickError(adapterHistorical.currentIsLastSelect) | vm.clickError(adapterHistorical.currentIsLastSelect) | ||||
| } | } | ||||
| //当前数据为历史轨迹点击 且 最后一条学习未完成 且不为最后一条 | //当前数据为历史轨迹点击 且 最后一条学习未完成 且不为最后一条 | ||||
| if (!adapterHistorical.currentIsLastSelect && vm.currentIsHistoricalItemClick && !adapterHistorical.lastIsLearnOver) { | |||||
| if (!adapterHistorical.currentIsLastSelect && vm.currentIsHistoricalItemClick && !adapterHistorical.lastIsLearnOver) { | |||||
| skipToHistoricalLastItem() | skipToHistoricalLastItem() | ||||
| } else { | } else { | ||||
| vm.loadNext() | vm.loadNext() | ||||
| /** 滑动到最后一项进行点击 */ | /** 滑动到最后一项进行点击 */ | ||||
| private fun skipToHistoricalLastItem() { | private fun skipToHistoricalLastItem() { | ||||
| binding.rvHistoricalRoute.post{ | |||||
| binding.rvHistoricalRoute.post { | |||||
| val position = adapterHistorical.itemCount - 1 //最后item的位置 | val position = adapterHistorical.itemCount - 1 //最后item的位置 | ||||
| val last = historicalLayoutManager.findLastCompletelyVisibleItemPosition() //最后完全可见 | val last = historicalLayoutManager.findLastCompletelyVisibleItemPosition() //最后完全可见 | ||||
| if (position > last ){ //需要操作的位置大于当前最后显示的位置,则进行滚动 | |||||
| if (position > last) { //需要操作的位置大于当前最后显示的位置,则进行滚动 | |||||
| binding.rvHistoricalRoute.addOnScrollListener(historicalScrollListener) | binding.rvHistoricalRoute.addOnScrollListener(historicalScrollListener) | ||||
| binding.rvHistoricalRoute.smoothScrollToPosition(position) | binding.rvHistoricalRoute.smoothScrollToPosition(position) | ||||
| }else { //position view 可见 | |||||
| } else { //position view 可见 | |||||
| historicalLayoutManager.findViewByPosition(position)?.performClick() | historicalLayoutManager.findViewByPosition(position)?.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) | ||||
| private val itemSpellRecoveryClick = { showValue : SpannableStringBuilder, isOver : Boolean, nextPosition : Int -> | private val itemSpellRecoveryClick = { showValue : SpannableStringBuilder, isOver : Boolean, nextPosition : Int -> | ||||
| bindingSpell.incWord.tvWord.text = showValue | bindingSpell.incWord.tvWord.text = showValue | ||||
| //纠错完成 | //纠错完成 | ||||
| if (isOver){ | |||||
| if (isOver) { | |||||
| binding.incControlButton.tvLeft.visibility = View.VISIBLE | binding.incControlButton.tvLeft.visibility = View.VISIBLE | ||||
| } | } | ||||
| bindingSpell.spellRecyclerView.scrollToPosition(nextPosition) | bindingSpell.spellRecyclerView.scrollToPosition(nextPosition) | ||||
| override fun dispatchTouchEvent(ev : MotionEvent?) : Boolean { | override fun dispatchTouchEvent(ev : MotionEvent?) : Boolean { | ||||
| //执行有效计时 | //执行有效计时 | ||||
| when{ | |||||
| when { | |||||
| //自动播放只有在非播放时触摸有效 | //自动播放只有在非播放时触摸有效 | ||||
| vm.learnData.isAutoPlay -> when{ | |||||
| vm.learnData.isAutoPlay -> when { | |||||
| !vm.isAutoPlaying -> vm.executeLearnValidTime() | !vm.isAutoPlaying -> vm.executeLearnValidTime() | ||||
| } | } | ||||
| else -> vm.executeLearnValidTime() | else -> vm.executeLearnValidTime() | ||||
| /** 返回 */ | /** 返回 */ | ||||
| override fun onBackPressed() { | override fun onBackPressed() { | ||||
| when { | |||||
| vm.isAllOver -> finish() | |||||
| else -> when { | |||||
| vm.learnData.isAutoPlay -> autoPlayBackDialog() | |||||
| vm.isHasLearned -> learnBackDialog() | |||||
| else -> finish() | |||||
| } | |||||
| backDialog() | |||||
| } | |||||
| private fun backDialog() { | |||||
| vm.showOrDismissBackDialogForTime(true) | |||||
| val commonDialogBean = when { | |||||
| vm.learnData.isAutoPlay -> CommonDialogBean(titleText = R.string.quit_auto_play_title, leftText = R.string.cancel, | |||||
| rightText = R.string.quit) | |||||
| else -> CommonDialogBean(titleText = R.string.quit_learn_title, contentText = R.string.quit_learn_content, | |||||
| leftText = R.string.quit, rightText = R.string.cancel) | |||||
| } | } | ||||
| CommonDialog.newInstance(commonDialogBean).apply { | |||||
| onCommonDialogButtonClickListener = { dialog, isRightClick -> | |||||
| dialog.dismissAllowingStateLoss() | |||||
| when { | |||||
| //自动播放 | |||||
| vm.learnData.isAutoPlay -> when { | |||||
| isRightClick -> vm.saveData() | |||||
| else -> { | |||||
| vm.showOrDismissBackDialogForTime(false) | |||||
| LiveEventBus.get<Int>("auto_play").post(0) | |||||
| } | |||||
| } | |||||
| //学习、复习 | |||||
| else -> when { | |||||
| isRightClick -> vm.showOrDismissBackDialogForTime(false) | |||||
| else -> vm.saveData() | |||||
| } | |||||
| } | |||||
| } | |||||
| }.show(supportFragmentManager, "learn_word_activity") | |||||
| } | } | ||||
| /** 学习时的返回弹窗 */ | |||||
| /* */ | |||||
| /** 学习时的返回弹窗 *//* | |||||
| private fun learnBackDialog() { | private fun learnBackDialog() { | ||||
| vm.showOrDismissBackDialogForTime(true) | vm.showOrDismissBackDialogForTime(true) | ||||
| CommonDialog.newInstance( | CommonDialog.newInstance( | ||||
| } | } | ||||
| }.show(supportFragmentManager, "learn_back_dialog") | }.show(supportFragmentManager, "learn_back_dialog") | ||||
| } | } | ||||
| /** 自动播放时的返回弹窗 */ | |||||
| */ | |||||
| /** 自动播放时的返回弹窗 *//* | |||||
| private fun autoPlayBackDialog() { | private fun autoPlayBackDialog() { | ||||
| vm.showOrDismissBackDialogForTime(true) | vm.showOrDismissBackDialogForTime(true) | ||||
| CommonDialog.newInstance( | CommonDialog.newInstance( | ||||
| } | } | ||||
| } | } | ||||
| }.show(supportFragmentManager, "auto_play_back_dialog") | }.show(supportFragmentManager, "auto_play_back_dialog") | ||||
| } | |||||
| }*/ | |||||
| /** 学习完成 */ | /** 学习完成 */ | ||||
| private fun showLearnOverDialog() { | private fun showLearnOverDialog() { | ||||
| when{ | |||||
| when { | |||||
| //自动播放完成弹窗 | //自动播放完成弹窗 | ||||
| vm.learnData.isAutoPlay -> showAutoPlayOverDialog() | vm.learnData.isAutoPlay -> showAutoPlayOverDialog() | ||||
| //复习完成 | |||||
| vm.learnData.isReview -> showReviewOverDialog() | |||||
| //作文知识点完成 | //作文知识点完成 | ||||
| vm.learnData.lesson.courseType == AppConstants.COURSE_TYPE_CHINESE_COMPOSITION -> showCompositionKnowLeageLearningOver() | |||||
| vm.learnData.lesson.courseType == AppConstants.COURSE_TYPE_CHINESE_COMPOSITION -> showCompositionKnowLeageLearningOver() | |||||
| //其他单词类,带学后测试的课时完成 | //其他单词类,带学后测试的课时完成 | ||||
| else -> showLessonWordLearningOver() | |||||
| else -> showLessonWordLearningOver() | |||||
| } | } | ||||
| } | } | ||||
| dialog.dismissAllowingStateLoss() | dialog.dismissAllowingStateLoss() | ||||
| //发送动作 : 学后测试 | //发送动作 : 学后测试 | ||||
| LiveEventBus.get<LearnEventData>(AppConstants.EVENT_LESSON_ACTION) | LiveEventBus.get<LearnEventData>(AppConstants.EVENT_LESSON_ACTION) | ||||
| .post(LearnEventData(vm.learnData.lesson.subjectId, vm.learnData.lesson.courseId, AppConstants.ACTION_LESSON_AFTER_TEST_AGAIN).apply { | |||||
| .post(LearnEventData(vm.learnData.lesson.subjectId, vm.learnData.lesson.courseId, | |||||
| AppConstants.ACTION_LESSON_AFTER_TEST_AGAIN).apply { | |||||
| leesonPositionIndex = vm.learnData.lesson.lessonPositionInList | leesonPositionIndex = vm.learnData.lesson.lessonPositionInList | ||||
| }) | }) | ||||
| finish() | finish() | ||||
| * 自动播放完成弹窗 | * 自动播放完成弹窗 | ||||
| */ | */ | ||||
| private fun showAutoPlayOverDialog() { | private fun showAutoPlayOverDialog() { | ||||
| val drawable = DrawableUti.changeSvgSizeAndColor(resources, R.drawable.ic_right, R.color.theme_color,3) | |||||
| CommonDialog.newInstance(CommonDialogBean(titleText = R.string.quit_auto_play_title_over, | |||||
| rightText = R.string.sure),drawable).apply { | |||||
| val drawable = DrawableUti.changeSvgSizeAndColor(resources, R.drawable.ic_right, R.color.theme_color, 3) | |||||
| CommonDialog.newInstance(CommonDialogBean(titleText = R.string.quit_auto_play_title_over, rightText = R.string.sure), | |||||
| drawable).apply { | |||||
| onCommonDialogButtonClickListener = { dialog, _ -> | onCommonDialogButtonClickListener = { dialog, _ -> | ||||
| dialog.dismissAllowingStateLoss() | dialog.dismissAllowingStateLoss() | ||||
| finish() | finish() | ||||
| }.show(supportFragmentManager, "auto_play_back_dialog") | }.show(supportFragmentManager, "auto_play_back_dialog") | ||||
| } | } | ||||
| /** | |||||
| * 复习完成弹窗 | |||||
| */ | |||||
| private fun showReviewOverDialog() { | |||||
| LearnDialog.newInstance(LearnDialogBean(AppConstants.DIALOG_TYPE_REVIEW_OVER).apply { | |||||
| correctNumber = vm.currentLessonLearnedPosition + 1 //本次已复习完成数量 | |||||
| errorNumber = vm.newVocabularyList.size //大循环复习完成数量 | |||||
| }).apply { | |||||
| onDialogListener = { action, dialog -> | |||||
| //完成 关闭,不处理 | |||||
| dialog.dismissAllowingStateLoss() | |||||
| finish() | |||||
| } | |||||
| }.show(supportFragmentManager, "review_over") | |||||
| } | |||||
| /** | /** | ||||
| * 作文知识点学习完成弹窗 | * 作文知识点学习完成弹窗 | ||||
| */ | */ | ||||
| private fun showCompositionKnowLeageLearningOver(){ | |||||
| private fun showCompositionKnowLeageLearningOver() { | |||||
| LearnDialog.newInstance(LearnDialogBean(AppConstants.DIALOG_TYPE_LESSON_COMPOSITION_KNOWLEDGE_LEARNING_OVER).apply { | LearnDialog.newInstance(LearnDialogBean(AppConstants.DIALOG_TYPE_LESSON_COMPOSITION_KNOWLEDGE_LEARNING_OVER).apply { | ||||
| correctNumber = vm.learnData.lesson.correctNumber | correctNumber = vm.learnData.lesson.correctNumber | ||||
| errorNumber = vm.learnData.lesson.errorNumber | errorNumber = vm.learnData.lesson.errorNumber | ||||
| }).apply { | }).apply { | ||||
| onDialogListener = { action, dialog -> | onDialogListener = { action, dialog -> | ||||
| when(action){ | |||||
| when (action) { | |||||
| //重学,重学弹窗提示 | //重学,重学弹窗提示 | ||||
| AppConstants.DIALOG_LESSON_RELEARN -> lessonRelearnDialog(dialog) | |||||
| AppConstants.DIALOG_LESSON_RELEARN -> lessonRelearnDialog(dialog) | |||||
| //完成 关闭,不处理 | //完成 关闭,不处理 | ||||
| AppConstants.DIALOG_OVER -> { | AppConstants.DIALOG_OVER -> { | ||||
| dialog.dismissAllowingStateLoss() | dialog.dismissAllowingStateLoss() | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| }.show(supportFragmentManager,"composition_knowledge_learn_over") | |||||
| }.show(supportFragmentManager, "composition_knowledge_learn_over") | |||||
| } | } | ||||
| /*** | /*** | ||||
| dialog.dismissAllowingStateLoss() | dialog.dismissAllowingStateLoss() | ||||
| //发送动作 : 重新学习 | //发送动作 : 重新学习 | ||||
| LiveEventBus.get<LearnEventData>(AppConstants.EVENT_LESSON_ACTION) | LiveEventBus.get<LearnEventData>(AppConstants.EVENT_LESSON_ACTION) | ||||
| .post(LearnEventData(vm.learnData.lesson.subjectId, vm.learnData.lesson.courseId, AppConstants.ACTION_LESSON_AFTER_TEST_RELEARN).apply { | |||||
| .post(LearnEventData(vm.learnData.lesson.subjectId, vm.learnData.lesson.courseId, | |||||
| AppConstants.ACTION_LESSON_AFTER_TEST_RELEARN).apply { | |||||
| leesonPositionIndex = vm.learnData.lesson.lessonPositionInList | leesonPositionIndex = vm.learnData.lesson.lessonPositionInList | ||||
| }) | }) | ||||
| finish() | finish() | ||||
| }.show(dialog.childFragmentManager, "lesson_relearn_tip") | }.show(dialog.childFragmentManager, "lesson_relearn_tip") | ||||
| } | } | ||||
| } | } |
| //是否需要显示单词图片 | //是否需要显示单词图片 | ||||
| var isNeedLoadPhoto = when (learnData.lesson.coursePackType) { | var isNeedLoadPhoto = when (learnData.lesson.coursePackType) { | ||||
| AppConstants.COURSEPACK_TYPE_ENGLISH_WORD, | |||||
| AppConstants.COURSEPACK_TYPE_ENGLISH_SOUNDMARK, | |||||
| AppConstants.COURSEPACK_TYPE_CHINESE_LITERACY, | |||||
| AppConstants.COURSEPACK_TYPE_CHINESE_PINYIN -> true | |||||
| AppConstants.COURSEPACK_TYPE_ENGLISH_WORD, AppConstants.COURSEPACK_TYPE_ENGLISH_SOUNDMARK, AppConstants.COURSEPACK_TYPE_CHINESE_LITERACY, AppConstants.COURSEPACK_TYPE_CHINESE_PINYIN -> true | |||||
| else -> false | else -> false | ||||
| } | } | ||||
| //当前单词的自动播放次数 | //当前单词的自动播放次数 | ||||
| var currentPlayTime = 0 | var currentPlayTime = 0 | ||||
| //当前复习时,大七次复习完成的集合,即新增词汇量集合 | |||||
| val newVocabularyList : MutableList<String> by lazy { | |||||
| mutableListOf() | |||||
| } | |||||
| //复习只保留一条数据,正确只添加第一次出现的最后一条,错误时直接覆盖 | |||||
| val reviewMap : MutableMap<String, LearnEntity.Builder> by lazy { | |||||
| mutableMapOf() | |||||
| } | |||||
| /** | /** | ||||
| * 定义有效时间 | * 定义有效时间 | ||||
| * 学习和自动播放有一点不一样哟 | * 学习和自动播放有一点不一样哟 | ||||
| /** | /** | ||||
| * 保存当前学习数据 | * 保存当前学习数据 | ||||
| * @param item LearnWord | |||||
| * @param isLastItem Boolean | |||||
| * @param isCorrect Boolean | |||||
| * @param item LearnWord 当前item | |||||
| * @param isLastItem Boolean 是否是最后一个即非其他历史记录 | |||||
| * @param isCorrect Boolean 学习结果是否正确 | |||||
| */ | */ | ||||
| private fun saveCurrentLearnData(item : LearnWord, isLastItem : Boolean, isCorrect : Boolean) { | private fun saveCurrentLearnData(item : LearnWord, isLastItem : Boolean, isCorrect : Boolean) { | ||||
| val key = "${item.chapterId}_${item.lessonId}_${item.wordId}" | val key = "${item.chapterId}_${item.lessonId}_${item.wordId}" | ||||
| //正确 | //正确 | ||||
| isCorrect -> when { | isCorrect -> when { | ||||
| //第一次正确 | //第一次正确 | ||||
| isLastItem && item.first -> record.addEntity(createBaseLearnEntity(item.wordId).apply { | |||||
| if (learnRuleUtil.isInExamErrorMap(key)) { | |||||
| isOnlySavePoint = true //设置仅保存学习点 | |||||
| isLastItem && item.first -> when { | |||||
| //复习正确 | |||||
| learnData.isReview -> { | |||||
| reviewMap[key] = createBaseLearnEntity(item).apply { | |||||
| reviewNum = item.reviewNum + 1L | |||||
| } | |||||
| if (item.reviewNum == 7) { | |||||
| newVocabularyList.add(key) | |||||
| } | |||||
| } | } | ||||
| }) | |||||
| //学习正确 | |||||
| else -> record.addEntity(createBaseLearnEntity(item).apply { | |||||
| if (learnRuleUtil.isInExamErrorMap(key)) { | |||||
| isOnlySavePoint = true //设置仅保存学习点 | |||||
| } | |||||
| }) | |||||
| } | |||||
| } | } | ||||
| //错误 | //错误 | ||||
| else -> { | else -> { | ||||
| val newEntityBuilder = createBaseLearnEntity(item.wordId) | |||||
| val newEntityBuilder = createBaseLearnEntity(item) | |||||
| when { | when { | ||||
| //复习错误,直接放入集合,如果前面有数据将直接覆盖数据,只保存一条数据 | |||||
| learnData.isReview -> { | |||||
| reviewMap[key] = createBaseLearnEntity(item).apply { | |||||
| reviewNum = 1 //必须大于0,否则会被当作为第一次学习 | |||||
| isError = true | |||||
| lastReviewDate = this.created | |||||
| } | |||||
| //如果在复习完成的集合中,进行移除 | |||||
| if (newVocabularyList.contains(key)) { | |||||
| newVocabularyList.remove(key) | |||||
| } | |||||
| //return避免record添加newEntityBuilder | |||||
| return | |||||
| } | |||||
| //第一次错误 | //第一次错误 | ||||
| isLastItem && item.first -> when { | isLastItem && item.first -> when { | ||||
| //在错误列表中 | //在错误列表中 | ||||
| learnRuleUtil.isInExamErrorMap(key) -> newEntityBuilder.setIsOnlySavePoint(true) | |||||
| .setIsError(true) | |||||
| .setReviewNum(1).lastReviewDate = getCurrentDateWithString() | |||||
| learnRuleUtil.isInExamErrorMap(key) -> newEntityBuilder.apply { | |||||
| isOnlySavePoint = true | |||||
| isError = true | |||||
| reviewNum = 1 | |||||
| lastReviewDate = getCurrentDateWithString() | |||||
| } | |||||
| else -> newEntityBuilder.isError = true | else -> newEntityBuilder.isError = true | ||||
| } | } | ||||
| //历史轨迹错误 | //历史轨迹错误 | ||||
| } | } | ||||
| /** 生成一个基本的LearnEntity */ | /** 生成一个基本的LearnEntity */ | ||||
| private fun createBaseLearnEntity(wordId : Long) : LearnEntity.Builder { | |||||
| private fun createBaseLearnEntity(item : LearnWord) : LearnEntity.Builder { | |||||
| return Struct.LearnEntity.newBuilder().apply { | return Struct.LearnEntity.newBuilder().apply { | ||||
| learnData.lesson.let { | |||||
| projectId = it.subjectId.toLong() | |||||
| packId = it.coursePackId | |||||
| courseId = it.courseId | |||||
| chapterId = it.chapterId | |||||
| lessonId = it.lessonId | |||||
| entityId = wordId | |||||
| } | |||||
| projectId = item.subjectId.toLong() | |||||
| packId = item.coursePackId | |||||
| courseId = item.courseId | |||||
| chapterId = item.chapterId | |||||
| lessonId = item.lessonId | |||||
| entityId = item.wordId | |||||
| tag = "android" | tag = "android" | ||||
| created = getCurrentDateWithString() | created = getCurrentDateWithString() | ||||
| } | } | ||||
| Observable.create<Boolean> { | Observable.create<Boolean> { | ||||
| // record 已经实例化并已经将数据保存 | // record 已经实例化并已经将数据保存 | ||||
| if (!saveInit) { | if (!saveInit) { | ||||
| //自动播放不修改课时信息 | |||||
| if (!learnData.isAutoPlay) { | |||||
| //自动播放与复习不修改课时信息 | |||||
| if (!learnData.isAutoPlay || !learnData.isReview) { | |||||
| learnData.lesson.apply { | learnData.lesson.apply { | ||||
| learnedIndex = currentLessonLearnedPosition | learnedIndex = currentLessonLearnedPosition | ||||
| correctNumber += learnRuleUtil.currentCorrectMap.size | correctNumber += learnRuleUtil.currentCorrectMap.size | ||||
| //添加到错误本集合中,主要用于小游戏练习(学前总 课时都没有添加,从这里添加到集合后发送出去,添加到集合) | //添加到错误本集合中,主要用于小游戏练习(学前总 课时都没有添加,从这里添加到集合后发送出去,添加到集合) | ||||
| learnData.examErrorMap?.putAll(learnRuleUtil.currentErrorMap) | learnData.examErrorMap?.putAll(learnRuleUtil.currentErrorMap) | ||||
| } | } | ||||
| //如果是复习,数据是走reviewMap获取 | |||||
| if (learnData.isReview) { | |||||
| reviewMap.forEach { entry -> | |||||
| record.addEntity(entry.value) | |||||
| } | |||||
| } | |||||
| record.addDuration(saveCurrentLearnDuration()) | record.addDuration(saveCurrentLearnDuration()) | ||||
| saveInit = true | saveInit = true | ||||
| } | } | ||||
| }.compose(diskIo2Main()).subscribe({ | }.compose(diskIo2Main()).subscribe({ | ||||
| showHideLoading(false) | showHideLoading(false) | ||||
| sendEventBus() //返回发送数据 | sendEventBus() //返回发送数据 | ||||
| //数据保存完成后,通过数据为空进行通知,测试完成 | |||||
| //数据保存完成后,通过数据为空进行通知,完成 | |||||
| saveDataLiveData.value = isAllOver | saveDataLiveData.value = isAllOver | ||||
| }, { | }, { | ||||
| showHideLoading(false) | showHideLoading(false) | ||||
| private fun sendEventBus() { | private fun sendEventBus() { | ||||
| //自动播放不发送信息通知 | //自动播放不发送信息通知 | ||||
| if (learnData.isAutoPlay) return | if (learnData.isAutoPlay) return | ||||
| //复习发送事件,接收复习结果 | |||||
| if (learnData.isReview) { | |||||
| LiveEventBus.get<LearnEventData>(AppConstants.EVENT_REVIEW_DATA) | |||||
| .post(LearnEventData(learnData.lesson.subjectId, learnData.lesson.courseId, AppConstants.DATA_REVIEW).apply { | |||||
| this.leesonPositionIndex = currentLessonLearnedPosition | |||||
| }) | |||||
| return | |||||
| } | |||||
| //学习发送结果 | |||||
| LiveEventBus.get<LearnEventData>(AppConstants.EVENT_LESSON_DATA) | LiveEventBus.get<LearnEventData>(AppConstants.EVENT_LESSON_DATA) | ||||
| .post(LearnEventData(learnData.lesson.subjectId, learnData.lesson.courseId, | .post(LearnEventData(learnData.lesson.subjectId, learnData.lesson.courseId, | ||||
| AppConstants.DATA_LESSON_LEARN_OVER).apply { | AppConstants.DATA_LESSON_LEARN_OVER).apply { |
| import com.xkl.cdl.adapter.ViewPagerAdapter | import com.xkl.cdl.adapter.ViewPagerAdapter | ||||
| 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.course.Course | |||||
| import com.xkl.cdl.data.bean.course.Lesson | import com.xkl.cdl.data.bean.course.Lesson | ||||
| import com.xkl.cdl.data.bean.intentdata.LearnData | import com.xkl.cdl.data.bean.intentdata.LearnData | ||||
| import com.xkl.cdl.data.binding.BindingAdapter | import com.xkl.cdl.data.binding.BindingAdapter | ||||
| } | } | ||||
| } | } | ||||
| /** | |||||
| * 启动复习 | |||||
| * @param course Course | |||||
| * @param reviewData MutableList<LearnWord> | |||||
| */ | |||||
| fun startReview(course: Course, reviewData: MutableList<LearnWord>){ | |||||
| val lesson = Lesson(course.subjectId, course.coursePackId, course.coursePackType, | |||||
| course.courseId, course.courseType, 0, "", 0, course.courseTitle) | |||||
| DataTransferHolder.instance.putData(value = LearnData(lesson).apply { | |||||
| learnWordList = reviewData | |||||
| isReview = true | |||||
| }) | |||||
| startActivity(LearnWordActivity::class.java) | |||||
| } | |||||
| /** ViewModel Factory工厂 */ | /** ViewModel Factory工厂 */ | ||||
| inner class ViewModelFactory(private val subjectId : Int, private val coursePackInPosition : Int) : | inner class ViewModelFactory(private val subjectId : Int, private val coursePackInPosition : Int) : |
| override fun loadData() { | override fun loadData() { | ||||
| vm.loadMain().observe(this) { | vm.loadMain().observe(this) { | ||||
| when (vm.course.courseType) { | |||||
| //作文只有一个目录结构 | |||||
| AppConstants.COURSE_TYPE_CHINESE_COMPOSITION -> changeChildrenFragmentForComposition() | |||||
| else -> changeChildrenFragmentForWord() | |||||
| } | |||||
| changeChildren() | |||||
| } | } | ||||
| } | } | ||||
| fun changeChildren() { | |||||
| when (vm.course.courseType) { | |||||
| //作文只有一个目录结构 | |||||
| AppConstants.COURSE_TYPE_CHINESE_COMPOSITION -> changeChildrenFragmentForComposition() | |||||
| else -> changeChildrenFragmentForWord() | |||||
| } | |||||
| } | |||||
| /** | /** | ||||
| * 改变加载的子Fragment 单词类 | * 改变加载的子Fragment 单词类 |
| import com.xkl.cdl.data.repository.DataRepository | import com.xkl.cdl.data.repository.DataRepository | ||||
| import com.xkl.cdl.module.XKLApplication | import com.xkl.cdl.module.XKLApplication | ||||
| import com.xkl.cdl.module.m_center_learn.CoursePackMainActivityViewModel | import com.xkl.cdl.module.m_center_learn.CoursePackMainActivityViewModel | ||||
| import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers | |||||
| import io.reactivex.rxjava3.core.Observable | import io.reactivex.rxjava3.core.Observable | ||||
| import io.reactivex.rxjava3.functions.BiFunction | import io.reactivex.rxjava3.functions.BiFunction | ||||
| import io.reactivex.rxjava3.schedulers.Schedulers | import io.reactivex.rxjava3.schedulers.Schedulers | ||||
| //获取课程的复习数据 | //获取课程的复习数据 | ||||
| //获取课程的章节数据 | //获取课程的章节数据 | ||||
| fun loadMain() : MutableLiveData<Boolean> { | fun loadMain() : MutableLiveData<Boolean> { | ||||
| isAssignmentReviewData = false | |||||
| val mutableLiveData = MutableLiveData<Boolean>() | val mutableLiveData = MutableLiveData<Boolean>() | ||||
| Observable.zip(DataRepository.getCourseDetails(course.subjectId, course.coursePackId, course.courseId).flatMap { | Observable.zip(DataRepository.getCourseDetails(course.subjectId, course.coursePackId, course.courseId).flatMap { | ||||
| courseDetail = it | courseDetail = it | ||||
| return result | return result | ||||
| } | } | ||||
| /** 查询复习课程的详细数据 */ | |||||
| fun queryReviewForDb():MutableLiveData<Boolean> { | |||||
| val result = MutableLiveData<Boolean>() | |||||
| Observable.fromCallable<Boolean> { | |||||
| return@fromCallable DBCourseManager.queryReviewData(dbControlBase,reviewDataList) | |||||
| }.subscribeOn(Schedulers.from(AppExecutors.diskIO)) | |||||
| .subscribe{ | |||||
| result.postValue(it) | |||||
| } | |||||
| return result | |||||
| } | |||||
| } | } |
| import android.os.Bundle | import android.os.Bundle | ||||
| import android.view.View | import android.view.View | ||||
| import androidx.lifecycle.ViewModelProvider | import androidx.lifecycle.ViewModelProvider | ||||
| import com.jeremyliao.liveeventbus.LiveEventBus | |||||
| import com.suliang.common.AppConfig | import com.suliang.common.AppConfig | ||||
| import com.suliang.common.base.fragment.BaseFragmentVM | import com.suliang.common.base.fragment.BaseFragmentVM | ||||
| import com.suliang.common.extension.click | import com.suliang.common.extension.click | ||||
| import com.xkl.cdl.data.AppConstants | import com.xkl.cdl.data.AppConstants | ||||
| import com.xkl.cdl.data.DataTransferHolder | |||||
| import com.xkl.cdl.data.bean.course.Lesson | |||||
| import com.xkl.cdl.data.bean.intentdata.LearnData | |||||
| import com.xkl.cdl.data.event.LearnEventData | |||||
| import com.xkl.cdl.data.repository.DataRepository | |||||
| import com.xkl.cdl.databinding.FragmentCourseReviewBinding | import com.xkl.cdl.databinding.FragmentCourseReviewBinding | ||||
| import com.xkl.cdl.module.learn.LearnWordActivity | |||||
| import com.xkl.cdl.module.m_center_learn.CoursePackMainActivity | |||||
| /** | /** | ||||
| * 复习界面 | * 复习界面 | ||||
| } | } | ||||
| //开始复习 | //开始复习 | ||||
| binding.tvStartReview.click { | binding.tvStartReview.click { | ||||
| showToast("开始复习") | |||||
| if (vm.isAssignmentReviewData){ //已经赋值,直接赋值跳转 | if (vm.isAssignmentReviewData){ //已经赋值,直接赋值跳转 | ||||
| (requireActivity() as CoursePackMainActivity).startReview(vm.course,vm.reviewDataList) | |||||
| }else{ //没有赋值,需要进行 | }else{ //没有赋值,需要进行 | ||||
| vm.queryReviewForDb().observe(this){ | |||||
| vm.isAssignmentReviewData = true | |||||
| if (it){ | |||||
| (requireActivity() as CoursePackMainActivity).startReview(vm.course,vm.reviewDataList) | |||||
| }else{ | |||||
| showToast("复习数据查询失败") | |||||
| //如果是学习中心跳转过来,直接进行状态页 | |||||
| if (pageSource == 0 ){ | |||||
| (requireParentFragment() as CourseMainFragment).changeChildren() | |||||
| } | |||||
| } | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| //查看备忘本 | //查看备忘本 | ||||
| } | } | ||||
| override fun loadData() { | override fun loadData() { | ||||
| LiveEventBus.get<LearnEventData>(AppConstants.EVENT_REVIEW_DATA).observe(this){ | |||||
| if (it.subjectId != vm.course.subjectId || it.courseId != vm.course.courseId) return@observe | |||||
| when(it.actionFlag){ | |||||
| AppConstants.DATA_REVIEW -> { | |||||
| //复习完成 | |||||
| if (it.leesonPositionIndex == vm.reviewDataList.size - 1){ | |||||
| //清空 | |||||
| vm.reviewDataList.clear() | |||||
| //切换界面 | |||||
| val pageSource = arguments?.getInt(AppConfig.INTENT_1) ?: 0 | |||||
| if ( pageSource == 0 ){ | |||||
| (requireParentFragment() as CourseMainFragment).changeChildren() | |||||
| }else{ // TODO: 2022/6/6 备忘本需隐藏复习按钮,修改文字 | |||||
| initMemoData() | |||||
| binding.tvStartReview.visibility = View.GONE | |||||
| } | |||||
| }else { // 复习未完成 todo 需要验证一下 sublist().clear() | |||||
| vm.reviewDataList.subList(0, it.leesonPositionIndex + 1).clear() | |||||
| initReviewData() | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| } | } | ||||
| override fun initViewModel() : CourseMainFragmentViewModel { | override fun initViewModel() : CourseMainFragmentViewModel { |
| it.onNext(wordList) | it.onNext(wordList) | ||||
| it.onComplete() | it.onComplete() | ||||
| }.compose(diskIo2DiskIo()).subscribe({ | }.compose(diskIo2DiskIo()).subscribe({ | ||||
| AppApi.GetWordListResponse.parseFrom(it).wrongList?.forEach { wrong -> | AppApi.GetWordListResponse.parseFrom(it).wrongList?.forEach { wrong -> | ||||
| <!--标题头部导航--> | <!--标题头部导航--> | ||||
| <include | <include | ||||
| android:id="@+id/inc_learn_title" | android:id="@+id/inc_learn_title" | ||||
| layout="@layout/inc_learn_title" | |||||
| app:showProgress="@{false}" /> | |||||
| layout="@layout/inc_learn_title" /> | |||||
| <View | <View | ||||
| android:layout_width="match_parent" | android:layout_width="match_parent" |
| <!-- android:layout_height="wrap_content"--> | <!-- android:layout_height="wrap_content"--> | ||||
| <!-- app:constraint_referenced_ids="tv_score,tv_tip,tv_title,inc_statistics_number,tv_left,vSplit"--> | <!-- app:constraint_referenced_ids="tv_score,tv_tip,tv_title,inc_statistics_number,tv_left,vSplit"--> | ||||
| <!-- />--> | <!-- />--> | ||||
| <!--复习结束--> | |||||
| <!-- <androidx.constraintlayout.widget.Group | |||||
| android:layout_width="wrap_content" | |||||
| android:layout_height="wrap_content" | |||||
| app:constraint_referenced_ids="tv_title,tv_tip_1"/>--> | |||||
| </androidx.constraintlayout.widget.ConstraintLayout> | </androidx.constraintlayout.widget.ConstraintLayout> |
| app:layout_constraintEnd_toEndOf="parent" | app:layout_constraintEnd_toEndOf="parent" | ||||
| app:layout_constraintStart_toEndOf="@id/tv_title" | app:layout_constraintStart_toEndOf="@id/tv_title" | ||||
| app:layout_constraintTop_toTopOf="parent" | app:layout_constraintTop_toTopOf="parent" | ||||
| tools:visibility="gone"/> | |||||
| tools:visibility="visible"/> | |||||
| <com.xkl.cdl.widget.VoiceSwitch | <com.xkl.cdl.widget.VoiceSwitch |
| <string name="quit_auto_play_title_over">本课程自动播放完毕</string> | <string name="quit_auto_play_title_over">本课程自动播放完毕</string> | ||||
| <string name="course_introduction">课程简介</string> | <string name="course_introduction">课程简介</string> | ||||
| <string name="start_see_memo">查看备忘本</string> | <string name="start_see_memo">查看备忘本</string> | ||||
| <string name="smart_reviewing">智能复习中</string> | |||||
| </resources> | </resources> |