Browse Source

作文知识点学习、知识点测试

master
suliang 2 years ago
parent
commit
11a487fdd4

+ 1
- 0
ProjectErrors.md View File

@@ -53,3 +53,4 @@ DialogFragment原理
BottomSheetDialog 固定高度和原理
BottomSheetDialog中使用TextView滑动的冲突?
Behavior
MMKV实现和保存原理

+ 32
- 21
app/src/main/java/com/xkl/cdl/adapter/AdapterLesson.kt View File

@@ -19,27 +19,38 @@ import com.xkl.cdl.module.m_center_learn.coursechildren.CourseMainFragmentViewMo
* create 2022/3/29 16:43
* Describe: 课程课时列表适配器
*/
class AdapterLesson(vm: CourseMainFragmentViewModel) : BaseRVAdapterVM<Lesson, CourseMainFragmentViewModel>(vm) {
class AdapterLesson(vm : CourseMainFragmentViewModel) : BaseRVAdapterVM<Lesson, CourseMainFragmentViewModel>(vm) {
/** 选中item的位置 */
var selectPos = -1
override fun coverViewHolder(parent: ViewGroup, viewType: Int): BaseAdapterViewHolder {
override fun coverViewHolder(parent : ViewGroup, viewType : Int) : BaseAdapterViewHolder {
return BaseAdapterViewHolder(inflateBinding(parent, R.layout.item_course_lesson))
}
override fun onBindVH(holder: BaseAdapterViewHolder, position: Int) {
override fun onBindVH(holder : BaseAdapterViewHolder, position : Int) {
val lesson = getItem(position)
(holder.binding as ItemCourseLessonBinding).run {
data = lesson
//章节名称是否显示
if (position == 0 || lesson.chapterId != getItem(position - 1).chapterId) { //不为第一个个且与上一个章节id相同
tvChapterName.visibility = View.VISIBLE
} else {
tvChapterName.visibility = View.GONE
}
//章节名称是否显示 不为第一个个且与上一个章节id相同
tvChapterName.visibility = if (position == 0 || lesson.chapterId != getItem(
position - 1).chapterId) View.VISIBLE else View.GONE
//执行
executePendingBindings()
//作文的每个课时的显示都不一样
when (lesson.courseType) {
AppConstants.COURSE_TYPE_CHINESE_COMPOSITION -> when (lesson.lessonType) {
// 作文视频、 作文章节测试、作文课堂练习、作文课外练习 不显示条目
AppConstants.LESSON_TYPE_COMPOSITION_VIDEO,
AppConstants.LESSON_TYPE_COMPOSITION_EXAM,
AppConstants.LESSON_TYPE_COMPOSITION_READING,
AppConstants.LESSON_TYPE_COMPOSITION_TASK -> tvLessonNumber.visibility = View.GONE
AppConstants.LESSON_TYPE_COMPOSITION_KNOWLEDGE -> tvLessonNumber.visibility = View.VISIBLE //作文知识点与 英语单词一致,需要显示条目
}
}
initColor(position, lesson)
//事件
@@ -60,18 +71,18 @@ class AdapterLesson(vm: CourseMainFragmentViewModel) : BaseRVAdapterVM<Lesson, C
private val normalColorNotLearnOver by lazy {
ContextCompat.getColor(context, R.color.gray_2) //学习未完成未选中时的颜色
}
private val normalColorLearnOver by lazy { ContextCompat.getColor(context, R.color.gray_1) } //学习已完成未选中时的颜色
private val mainTextColor by lazy {ContextCompat.getColor(context, R.color.main_text_color) } //选中颜色
private val translationColor by lazy {ContextCompat.getColor(context, R.color.translation) } //透明颜色
private val themeColor by lazy { ContextCompat.getColor(context,R.color.theme_color) } //主题颜色
private val normalColorLearnOver by lazy { ContextCompat.getColor(context, R.color.gray_1) } //学习已完成未选中时的颜色
private val mainTextColor by lazy { ContextCompat.getColor(context, R.color.main_text_color) } //选中颜色
private val translationColor by lazy { ContextCompat.getColor(context, R.color.translation) } //透明颜色
private val themeColor by lazy { ContextCompat.getColor(context, R.color.theme_color) } //主题颜色
/**
* 处理颜色 选中色 未选中色(学习完成/学习未完成)
* @receiver ItemCourseLessonBinding
* @param position Int
* @param lesson Lesson
*/
private fun ItemCourseLessonBinding.initColor(position: Int, lesson: Lesson) {
private fun ItemCourseLessonBinding.initColor(position : Int, lesson : Lesson) {
//item的背景和状态设置
if (selectPos == position) { //选中,背景设置
layoutContent.setBackgroundColor(ContextCompat.getColor(context, R.color.gray_3)) //选中背景
@@ -89,13 +100,13 @@ class AdapterLesson(vm: CourseMainFragmentViewModel) : BaseRVAdapterVM<Lesson, C
} else { //未选中:根据学习情况判断
layoutContent.setBackgroundColor(translationColor) //未选中背景透明
//根据课时类型判断当前课时是否完全完成
val lessonLearnOver = when(lesson.lessonType){
AppConstants.LESSON_TYPE_WORD -> lesson.learnIsOver && lesson.afterTestScore != AppConstants.NOT_DOING
val lessonLearnOver = when (lesson.lessonType) {
AppConstants.LESSON_TYPE_WORD -> lesson.learnIsOver && lesson.afterTestScore != AppConstants.NOT_DOING
AppConstants.LESSON_TYPE_COMPOSITION_VIDEO -> lesson.learnIsOver // 作文视频
AppConstants.LESSON_TYPE_COMPOSITION_EXAM -> lesson.learnIsOver //作文章节测试
AppConstants.LESSON_TYPE_COMPOSITION_READING -> lesson.learnIsOver //作文课堂练习
AppConstants.LESSON_TYPE_COMPOSITION_TASK -> lesson.learnIsOver //作文课外练习
AppConstants.LESSON_TYPE_DIALOGUE -> lesson.learnIsOver //口语对话
AppConstants.LESSON_TYPE_DIALOGUE -> lesson.learnIsOver //口语对话
else -> false // 其他课时类型为布局的正常显示
}

+ 6
- 0
app/src/main/java/com/xkl/cdl/data/AppConstants.kt View File

@@ -159,6 +159,10 @@ object AppConstants {
const val DIALOG_TYPE_LESSON_ITEM_CLICK_ALL_OVER = 4
/**课时列表item点击: 课时未做学后测试*/
const val DIALOG_TYPE_LESSON_ITEM_CLICK_NOT_DOING_AFTER_TEST = 5
/** 作文知识点课时学习完成 : lesson的item点击提示使用 */
const val DIALOG_TYPE_LESSON_ITEM_CLICK_COMPOSITION_KNOWLEDGE_OVER = 6
/** 作文知识点课时学习界面学习完成 */
const val DIALOG_TYPE_LESSON_COMPOSITION_KNOWLEDGE_LEARNING_OVER = 7
/**--- 总线动作 --------------------------------- */
/**action key 改变界面 到目录页 */
@@ -195,6 +199,8 @@ object AppConstants {
const val ACTION_COURSE_TEST_AFTER_TOTAL_OVER = 11
/**学后总测结束,传递数据*/
const val DATA_COURSE_AFTER_TEST_OVER = 12
/** 作文测试完成动作,再测一次*/
const val ACTION_LESSON_COMPOSITION_TEST_AGAIN = 13
/**--- 弹窗动作 --------------------------------- */
/** 学前总测结束弹窗: 开始学习 ,课时学前测试开始弹窗*/

+ 4
- 3
app/src/main/java/com/xkl/cdl/data/bean/course/CourseDetail.kt View File

@@ -20,7 +20,9 @@ class CourseDetail:Serializable{
var lesson_learn_point: HashMap<String, Long> = hashMapOf() //章节学习点 key=>{chapter_id}_{lesson_id} value=>{entity_id)
var exam_w_r_list: HashMap<String, Boolean> = hashMapOf() //课程/课时学前测试正确错误列表 key=> {chapter_id}_{lesson_id}_{entity_id} value=>正确 true;错误 false
var course_learn_point: String = "" //课程学习进度点 {chapter_id}_{lesson_id}_{entity_id}

var vp: HashMap<Long, String> = hashMapOf() //视频播放点,记录最新的就行 时间点 key=>video_id value=>{时间点}
var exercise_schedule: HashMap<Long, Double> = hashMapOf() //课程练习进度(仅作文有效)

var rl: Int = 0 //课程重学次数;有值表示是重新学,默认不是重新学习,对应数值表示第几次重学 用于辨音,拼写判断是否解锁,
var chapter_rl: HashMap<String, Long> = hashMapOf() //章节重学次数,key =>{chapter_id}_{lesson_id} value=> relearn times
@@ -33,7 +35,6 @@ class CourseDetail:Serializable{
var current_week_total_durations: Long = 0
var last_e: Double = 0.0 //上周期学习效率
var temporary_words: HashMap<String, String> = hashMapOf() //课程错误本,重学会删除 key=>{chapter_id}_{lesson_id}_{entity_id} value=> first learn time
var vp: HashMap<Long, String> = hashMapOf() //视频播放点,记录最新的就行 时间点 key=>video_id value=>{时间点}
var exercise_schedule: HashMap<Long, Double> = hashMapOf() //课程练习进度(仅作文有效)

}

+ 3
- 1
app/src/main/java/com/xkl/cdl/data/event/LearnEventData.kt View File

@@ -9,7 +9,6 @@ package com.xkl.cdl.data.event
* @param actionFlag 动作id 动作(action开头) 或 传递数据(data开头)
*/
class LearnEventData(val subjectId : Int, var courseId : Long, val actionFlag : Int) {

//学前总测结束传递数据
var scoreValue = 0 //分数
@@ -20,4 +19,7 @@ class LearnEventData(val subjectId : Int, var courseId : Long, val actionFlag :
//学习结束 newErrorMap 保存为所有的错误,包含学前和课程前的测试,主要用与后面进行小游戏的数据加载
//视频播放结束,数据传递的播放时间点
val videoPlayTime : String = ""
}

+ 69
- 22
app/src/main/java/com/xkl/cdl/data/manager/CourseManager.kt View File

@@ -25,7 +25,6 @@ object CourseManager {
val mSortInfoList = hashMapOf<Int, MutableList<AppApi.CourseSortedInfo.Builder>>()

/**
* 搜索项目下的课程包
* @param subjectId Int 项目id
@@ -151,7 +150,7 @@ object CourseManager {
AppConstants.TEST_TYPE_AFTER -> "课时学后测试"
AppConstants.TEST_TYPE_AFTER_TOTAL -> "学后总测试"
AppConstants.TEST_TYPE_MEMO -> "备忘本测试"
AppConstants.TEST_TYPE_COMPOSITION -> "作文知识点测试"
AppConstants.TEST_TYPE_COMPOSITION -> "知识点测试"
AppConstants.TEST_TYPE_SERVICE_CENTER -> "课程测试"
AppConstants.TEST_TYPE_NORMAL -> "词汇量测试"
else -> ""
@@ -183,17 +182,62 @@ object CourseManager {
}
/**
* 作文课程进度计算
* 作文课程进度计算 : 章节平分进度, 课时平分章节进度,课时单独计算进度
* @param allLesson List<Lesson> 所有课时
* @param isRelearn Boolean 是否重学课时的计算
* @param relearnLessonPosition Int 需要重学的课时在集合中的位置
*/
fun calculateCompositionCourseProgess(allLesson : List<Lesson>,
isRelearn : Boolean = false,
relearnLessonPosition : Int = -1) : Double {
// TODO: 2022/4/29 计算作文课程的进度
return 0.0
fun calculateCompositionCourseProgress(allLesson : List<Lesson>,
isRelearn : Boolean = false,
relearnLessonPosition : Int = -1) : Double {
//课时总章节数
var chapterTotalSize = 0
//总进度
var totalProgress = 0.0
//标记上一章节id
var previousChapterId = 0L
//单章节的总进度 :章节进度之和
var chapterProgress = 0.0
//单章节的课时数
var chapterLessonSize = 0
//循环
allLesson.forEach {
when {
//新章节
it.chapterId != previousChapterId -> {
//新章节需要将上一个章节的进度加入总进度
if (previousChapterId != 0L) {
totalProgress += chapterProgress / chapterLessonSize
}
//设置上一章节的id
previousChapterId = it.chapterId
//当前章节课时数
chapterLessonSize = if (it.lessonType != AppConstants.LESSON_TYPE_COMPOSITION_TASK) {
chapterTotalSize++ //章节总数添加
1
} else 0
}
//同一章节
else -> {
chapterLessonSize += if (it.lessonType != AppConstants.LESSON_TYPE_COMPOSITION_TASK) 1 else 0 //当前章节课时数+1
}
}
//单章节内的进度累加
if (it.lessonType != AppConstants.LESSON_TYPE_COMPOSITION_TASK) {
//重学的时候跳过该课时的进度,即记录该课时进度为0
if (!isRelearn && it.lessonPositionInList != relearnLessonPosition) {
//章节添加课时进度
chapterProgress += if (it.learnIsOver) 1.0 else if (it.lessonType == AppConstants.LESSON_TYPE_COMPOSITION_KNOWLEDGE) {
//知识点的进度设置,设置该课时总进度为 1
if (it.learnedIndex == -1) 0.0 else (it.learnedIndex + 1.0) / it.wordIds.size
} else 0.0
}
}
}
//循环完成,再计算一下最后一个章节的总进度
totalProgress += chapterProgress / chapterLessonSize
//计算总进度
return totalProgress / chapterTotalSize * 100
}
/**
@@ -205,7 +249,7 @@ object CourseManager {
*/
fun calculateSpokenCourseProgress(allLesson : List<Lesson>,
isRelearn : Boolean = false,
relearnLessonPosition : Int = -1):Double{
relearnLessonPosition : Int = -1) : Double {
// TODO: 2022/4/29 计算口语课程的进度
return 0.0
}
@@ -237,7 +281,7 @@ object CourseManager {
}
mSortInfoList.put(subjectId, mutableListOf(newCourseSortedInfoBuilder))
}
if (totalProgress == 0.0 ) return totalProgress
if (totalProgress == 0.0) return totalProgress
var totalCourseSize = 0
subjectWithCoursePackMap.get(subjectId)?.forEach {
@@ -254,19 +298,19 @@ object CourseManager {
* @param courseId Long 重学的课程
* @return Double 项目的总进度
*/
fun calculateSubjectProgressWithCourseRelearn(subjectId : Int,coursePackId:Long, courseId : Long) : Double {
fun calculateSubjectProgressWithCourseRelearn(subjectId : Int, coursePackId : Long, courseId : Long) : Double {
val totalProgress = mSortInfoList.get(subjectId)?.let {
var tempProgress = 0.0
it.forEach {
if (it.packId == coursePackId && it.courseId == courseId){
if (it.packId == coursePackId && it.courseId == courseId) {
return@forEach
}
tempProgress += it.s
}
tempProgress
}?: 0.0
} ?: 0.0
if (totalProgress == 0.0 ) return totalProgress
if (totalProgress == 0.0) return totalProgress
val totalCourseSize = getSubjectForCourseSize(subjectId)
if (totalCourseSize == 0) return 0.0
@@ -280,23 +324,26 @@ object CourseManager {
* @param courseProgress Double 被重学课时的课程进度
* @return Double 项目的总进度
*/
fun calculateSubjectProgressWithCourseLessonRelearn(subjectId : Int,coursePackId:Long, courseId : Long,courseProgress:Double) : Double {
fun calculateSubjectProgressWithCourseLessonRelearn(subjectId : Int,
coursePackId : Long,
courseId : Long,
courseProgress : Double) : Double {
val totalProgress = mSortInfoList.get(subjectId)?.let {
var tempProgress = 0.0
it.forEach {
if (it.packId == coursePackId && it.courseId == courseId){
if (it.packId == coursePackId && it.courseId == courseId) {
tempProgress += courseProgress
return@forEach
}else {
} else {
tempProgress += it.s
}
}
tempProgress
}?: 0.0
} ?: 0.0
if (totalProgress == 0.0 ) return totalProgress
if (totalProgress == 0.0) return totalProgress
val totalCourseSize = getSubjectForCourseSize(subjectId)
val totalCourseSize = getSubjectForCourseSize(subjectId)
if (totalCourseSize == 0) return 0.0
return totalProgress / totalCourseSize
}
@@ -306,7 +353,7 @@ object CourseManager {
* @param subjectId Int 项目
* @return Int 课程数量
*/
private fun getSubjectForCourseSize(subjectId : Int) : Int {
private fun getSubjectForCourseSize(subjectId : Int) : Int {
return subjectWithCoursePackMap[subjectId]?.let {
var count = 0
it.forEach { coursePack ->

+ 19
- 0
app/src/main/java/com/xkl/cdl/data/manager/db/DBCourseManager.kt View File

@@ -164,6 +164,9 @@ object DBCourseManager {
else -> 0
}
val sql = when (base.courseType) {
//作文知识点测试
AppConstants.COURSE_TYPE_CHINESE_COMPOSITION -> "SELECT * FROM exam WHERE chapter_id = ${lesson!!.chapterId} AND exam_id in (${Joiner.on(",").join(lesson.wordIds)}) ORDER BY random()"
AppConstants.COURSE_TYPE_ENGLISH_DISCERN, AppConstants.COURSE_TYPE_ENGLISH_VOICE,
AppConstants.COURSE_TYPE_ENGLISH_SOUNDMARK, AppConstants.COURSE_TYPE_CHINESE_LITERACY,
AppConstants.COURSE_TYPE_CHINESE_PINYIN,
@@ -200,6 +203,22 @@ object DBCourseManager {
mDataBase?.rawQuery(sql, null)?.run {
when (base.courseType) {
//作文知识点测试
AppConstants.COURSE_TYPE_CHINESE_COMPOSITION -> while (moveToNext()) {
result.add(ExamBean().apply {
id = getLong(3)
word_id = getLong(2)
word = getString(4)
correct = getString(5)
error1 = getString(6)
error2 = getString(7)
error3 = getString(8)
type = AppConstants.TEST_QUEST_TYPE_CHOICE // 为1
chapterId = lesson!!.chapterId
lessonId = lesson.lessonId
})
}
AppConstants.COURSE_TYPE_ENGLISH_DISCERN, AppConstants.COURSE_TYPE_ENGLISH_VOICE,
AppConstants.COURSE_TYPE_CHINESE_LITERACY,
AppConstants.COURSE_TYPE_CHINESE_PINYIN -> while (moveToNext()) {

+ 57
- 1
app/src/main/java/com/xkl/cdl/dialog/LearnDialog.kt View File

@@ -65,6 +65,8 @@ class LearnDialog private constructor() : BaseDialogFragment<DialogLessonLearnBi
AppConstants.TEST_TYPE_AFTER -> initLessonAfterTestOver()
//学后总测试结束弹窗
AppConstants.TEST_TYPE_AFTER_TOTAL -> initCourseAfterTestOver()
//作文知识点测试结束
AppConstants.TEST_TYPE_COMPOSITION -> initCompositionExamLessonTestOver()
}
//学习结束弹窗
AppConstants.DIALOG_TYPE_LEARNING_OVER -> initLessonLearningOver(false)
@@ -72,6 +74,10 @@ class LearnDialog private constructor() : BaseDialogFragment<DialogLessonLearnBi
AppConstants.DIALOG_TYPE_LESSON_ITEM_CLICK_ALL_OVER -> initLessonItemClickLessonOver()
/** 课时列表item点击 */
AppConstants.DIALOG_TYPE_LESSON_ITEM_CLICK_NOT_DOING_AFTER_TEST -> initLessonLearningOver(true)
/** 作文课时item学习完成滴点击 */
AppConstants.DIALOG_TYPE_LESSON_ITEM_CLICK_COMPOSITION_KNOWLEDGE_OVER -> initCompositionKnowledgeLearning(true)
/** 作文课时学习中完成弹窗 */
AppConstants.DIALOG_TYPE_LESSON_COMPOSITION_KNOWLEDGE_LEARNING_OVER -> initCompositionKnowledgeLearning(false)
}
}
@@ -186,7 +192,6 @@ class LearnDialog private constructor() : BaseDialogFragment<DialogLessonLearnBi
* @param isShowCloseImg 是否需要显示关闭按钮
*/
private fun initLessonLearningOver(isShowCloseImg:Boolean){
initNumber()
binding.run {
imgIv.setImageResource(if (Random.nextBoolean()) R.mipmap.boy_2 else R.mipmap.girl_2)
@@ -339,4 +344,55 @@ class LearnDialog private constructor() : BaseDialogFragment<DialogLessonLearnBi
binding.tvRight.click { onDialogListener(AppConstants.DIALOG_START_TEST, this) }
}
/**
* 作文知识点课时学习完成
* @param isShowCloseImg 是否需要显示关闭按钮
*/
private fun initCompositionKnowledgeLearning(isShowCloseImg:Boolean){
initNumber()
binding.run {
imgIv.setImageResource(if (Random.nextBoolean()) R.mipmap.boy_2 else R.mipmap.girl_2)
tvTitle.visibility = View.VISIBLE
tvTitle.text = "恭喜你,本课时学习完成!"
incStatisticsNumber.root.visibility = View.VISIBLE
tvLearnOverTip.visibility = View.VISIBLE
tvLearnOverTip.text = "你可重新学习本课时,重新学习将清除原学习记录"
tvLeft.visibility = View.VISIBLE
tvLeft.text = "重新学习"
vSplit.visibility = View.VISIBLE
tvRight.text = "完成"
}
binding.tvLeft.click { onDialogListener(AppConstants.DIALOG_LESSON_RELEARN, this) }
//学习中的完成,同时需要关闭学习页
binding.tvRight.click { onDialogListener(AppConstants.DIALOG_OVER, this) }
if (isShowCloseImg){
binding.ivClose.visibility = View.VISIBLE
binding.ivClose.click { dismissAllowingStateLoss() }
}
}
/**
* 作文知识点测试完成
* tv_score,tv_tip,tv_title,inc_statistics_number,tv_left,vSplit
*/
private fun initCompositionExamLessonTestOver() {
initScore()
initNumber()
binding.run {
imgIv.setImageResource(if (Random.nextBoolean()) R.mipmap.boy_2 else R.mipmap.girl_2)
tvScore.visibility = View.VISIBLE
tvTip.visibility = View.VISIBLE
tvTitle.visibility = View.VISIBLE
incStatisticsNumber.root.visibility = View.VISIBLE
tvTitle.text = "恭喜你,完成了知识点测试!"
tvLeft.visibility = View.VISIBLE
tvLeft.text = "再测一次"
tvRight.text = "完成"
}
binding.tvLeft.click { onDialogListener(AppConstants.DIALOG_START_TEST,this) }
binding.tvRight.click { onDialogListener(AppConstants.DIALOG_OVER,this) }
}
}

+ 84
- 77
app/src/main/java/com/xkl/cdl/module/learn/LearnExamActivity.kt View File

@@ -122,7 +122,8 @@ class LearnExamActivity : BaseActivityVM<ActivityLearnExamBinding, LearnExamView
EMediaState.ERROR -> showToast("播放异常")
EMediaState.COMPLETE -> if (wordChooseBinding.ivVoice.visibility == View.VISIBLE) {
wordChooseBinding.ivVoice.postDelayed({
LogUtil.e("------开始重复播放----------------------------------------")
LogUtil.e(
"------开始重复播放----------------------------------------")
wordChooseBinding.ivVoice.performClick()
}, 700)
}
@@ -136,14 +137,10 @@ class LearnExamActivity : BaseActivityVM<ActivityLearnExamBinding, LearnExamView
private fun initNewWordRead(it : ExamBean) {
when (vm.intentData.courseType) {
//拼写初始不发音,作文不发音, 音标课程测试不发音
AppConstants.COURSE_TYPE_ENGLISH_SOUNDMARK,
AppConstants.COURSE_TYPE_ENGLISH_SPELL, AppConstants.COURSE_TYPE_CHINESE_COMPOSITION -> {
AppConstants.COURSE_TYPE_ENGLISH_SOUNDMARK, AppConstants.COURSE_TYPE_ENGLISH_SPELL, AppConstants.COURSE_TYPE_CHINESE_COMPOSITION -> {
}
//英语认读,英语音标,英语口语,语文识字,语文拼音 出现即发音一次
AppConstants.COURSE_TYPE_ENGLISH_DISCERN,
AppConstants.COURSE_TYPE_ENGLISH_SPOKEN,
AppConstants.COURSE_TYPE_CHINESE_LITERACY,
AppConstants.COURSE_TYPE_CHINESE_PINYIN,
AppConstants.COURSE_TYPE_ENGLISH_DISCERN, AppConstants.COURSE_TYPE_ENGLISH_SPOKEN, AppConstants.COURSE_TYPE_CHINESE_LITERACY, AppConstants.COURSE_TYPE_CHINESE_PINYIN,
// 英语辨音 重复播放
AppConstants.COURSE_TYPE_ENGLISH_VOICE -> {
wordChooseBinding.ivVoice.performClick()
@@ -265,8 +262,7 @@ class LearnExamActivity : BaseActivityVM<ActivityLearnExamBinding, LearnExamView
* */
private fun initChooseQuestionListener() {
when (vm.intentData.courseType) {
AppConstants.COURSE_TYPE_ENGLISH_SOUNDMARK,
AppConstants.COURSE_TYPE_ENGLISH_SPELL, AppConstants.COURSE_TYPE_CHINESE_COMPOSITION -> {
AppConstants.COURSE_TYPE_ENGLISH_SOUNDMARK, AppConstants.COURSE_TYPE_ENGLISH_SPELL, AppConstants.COURSE_TYPE_CHINESE_COMPOSITION -> {
}
else -> {
wordChooseBinding.incWord.tvWord.setOnClickListener(ivVoiceClick)
@@ -537,7 +533,7 @@ class LearnExamActivity : BaseActivityVM<ActivityLearnExamBinding, LearnExamView
//是否口语总测试
private fun isSpokenTotalTest() =
vm.intentData.courseType == AppConstants.COURSE_TYPE_ENGLISH_SPOKEN && (vm.intentData.examType == AppConstants.TEST_TYPE_BEFORE_TOTAL || vm.intentData.examType == AppConstants.TEST_TYPE_AFTER_TOTAL)
vm.intentData.courseType == AppConstants.COURSE_TYPE_ENGLISH_SPOKEN && (vm.intentData.examType == AppConstants.TEST_TYPE_BEFORE_TOTAL || vm.intentData.examType == AppConstants.TEST_TYPE_AFTER_TOTAL)
/**
* 拼写时的点击事件
@@ -547,25 +543,24 @@ class LearnExamActivity : BaseActivityVM<ActivityLearnExamBinding, LearnExamView
* @param correctValue 正确的拼写值,但未选中的赋值了颜色
* @param errorSize 错误的个数,拼写完成后才会有这个值
*/
private val itemSpellingClick =
{ selectedValue : SpannableStringBuilder, nextPosition : Int, isOver : Boolean, correctValue : SpannableStringBuilder, errorSize : Int ->
when {
isOver -> { //拼写结束
//设置正确的值
spellBinding.incWord.tvWord.setTextColor(ContextCompat.getColor(this, R.color.red_1))
spellBinding.incWord.tvWord.text = correctValue
//拼写结束
vm.spellOver(selectedValue.toString(), errorSize)
//执行当前的单词发音 延迟发音
spellBinding.incWord.tvWord.postDelayed({ ivVoiceClick(spellBinding.incWord.tvWord) }, 200)
}
else -> {
//设置为选中的值
spellBinding.incWord.tvWord.text = selectedValue
}
private val itemSpellingClick = { selectedValue : SpannableStringBuilder, nextPosition : Int, isOver : Boolean, correctValue : SpannableStringBuilder, errorSize : Int ->
when {
isOver -> { //拼写结束
//设置正确的值
spellBinding.incWord.tvWord.setTextColor(ContextCompat.getColor(this, R.color.red_1))
spellBinding.incWord.tvWord.text = correctValue
//拼写结束
vm.spellOver(selectedValue.toString(), errorSize)
//执行当前的单词发音 延迟发音
spellBinding.incWord.tvWord.postDelayed({ ivVoiceClick(spellBinding.incWord.tvWord) }, 200)
}
else -> {
//设置为选中的值
spellBinding.incWord.tvWord.text = selectedValue
}
spellBinding.spellRecyclerView.scrollToPosition(nextPosition)
}
spellBinding.spellRecyclerView.scrollToPosition(nextPosition)
}
override fun onBackPressed() {
@@ -580,8 +575,7 @@ class LearnExamActivity : BaseActivityVM<ActivityLearnExamBinding, LearnExamView
vm.showOrDismissBackDialogForTime(true)
CommonDialog.newInstance(CommonDialogBean(titleText = R.string.dialog_test_not_over,
contentText = R.string.dialog_test_not_over_tip,
leftText = R.string.quit,
rightText = R.string.cancel)).apply {
leftText = R.string.quit, rightText = R.string.cancel)).apply {
onCommonDialogButtonClickListener = { dialog, isRightClick ->
dialog.dismissAllowingStateLoss()
when {
@@ -597,6 +591,7 @@ class LearnExamActivity : BaseActivityVM<ActivityLearnExamBinding, LearnExamView
/** 测试完成 : 弹窗显示 */
private fun testOver() {
// TODO: 2022/5/17 作文测试弹窗
//对话框信息实体
val learnDialogBean = LearnDialogBean(AppConstants.DIALOG_TYPE_EXAM_OVER).apply {
examType = vm.intentData.examType
@@ -612,9 +607,9 @@ class LearnExamActivity : BaseActivityVM<ActivityLearnExamBinding, LearnExamView
AppConstants.DIALOG_START_LEARN -> {
dialog.dismissAllowingStateLoss()
//发送动作 : 继续学习
LiveEventBus.get<LearnEventData>(AppConstants.EVENT_CHANGE_PAGE).post(LearnEventData(vm.intentData.subjectId,
vm.intentData.courseId,
AppConstants.ACTION_COURSE_TEST_START_LEARN))
LiveEventBus.get<LearnEventData>(AppConstants.EVENT_CHANGE_PAGE)
.post(LearnEventData(vm.intentData.subjectId, vm.intentData.courseId,
AppConstants.ACTION_COURSE_TEST_START_LEARN))
finish()
}
}
@@ -623,83 +618,95 @@ class LearnExamActivity : BaseActivityVM<ActivityLearnExamBinding, LearnExamView
AppConstants.DIALOG_START_LEARN -> {
dialog.dismissAllowingStateLoss()
//发送动作 : 开始学习
LiveEventBus.get<LearnEventData>(AppConstants.EVENT_LESSON_ACTION).post(
LearnEventData(vm.intentData.subjectId,
vm.intentData.courseId,
AppConstants.ACTION_LESSON_BEFORE_TEST_OVER_START_LEARN).apply {
leesonPositionIndex = vm.intentData.lesson?.lessonPositionInList!!
})
LiveEventBus.get<LearnEventData>(AppConstants.EVENT_LESSON_ACTION)
.post(LearnEventData(vm.intentData.subjectId, vm.intentData.courseId,
AppConstants.ACTION_LESSON_BEFORE_TEST_OVER_START_LEARN).apply {
leesonPositionIndex = vm.intentData.lesson?.lessonPositionInList!!
})
finish()
}
}
//课时学后测试结束弹窗动作
AppConstants.TEST_TYPE_AFTER -> when(action){
AppConstants.TEST_TYPE_AFTER -> when (action) {
//重新学习
AppConstants.DIALOG_LESSON_RELEARN -> {
CommonDialog.newInstance(CommonDialogBean(titleText = R.string.lesson_relearn_title,
contentText = R.string.lesson_relearn_content,
leftText = R.string.cancel,
rightText = R.string.sure))
.apply {
onCommonDialogButtonClickListener = { relearnDialog, isRightClick ->
relearnDialog.dismissAllowingStateLoss()
if (isRightClick){
dialog.dismissAllowingStateLoss()
//发送动作 : 重新学习
LiveEventBus.get<LearnEventData>(AppConstants.EVENT_LESSON_ACTION).post(
LearnEventData(vm.intentData.subjectId,
vm.intentData.courseId,
AppConstants.ACTION_LESSON_AFTER_TEST_RELEARN).apply {
leesonPositionIndex = vm.intentData.lesson?.lessonPositionInList!!
})
finish()
leftText = R.string.cancel, rightText = R.string.sure))
.apply {
onCommonDialogButtonClickListener = { relearnDialog, isRightClick ->
relearnDialog.dismissAllowingStateLoss()
if (isRightClick) {
dialog.dismissAllowingStateLoss()
//发送动作 : 重新学习
LiveEventBus.get<LearnEventData>(AppConstants.EVENT_LESSON_ACTION)
.post(LearnEventData(vm.intentData.subjectId, vm.intentData.courseId,
AppConstants.ACTION_LESSON_AFTER_TEST_RELEARN).apply {
leesonPositionIndex = vm.intentData.lesson?.lessonPositionInList!!
})
finish()
}
}
}
}.show(childFragmentManager,"lesson_relearn_tip")
.show(childFragmentManager, "lesson_relearn_tip")
}
//再测一次
AppConstants.DIALOG_LESSON_AFTER_TEST_AGAIN -> {
//发送动作 : 再测一次
LiveEventBus.get<LearnEventData>(AppConstants.EVENT_LESSON_ACTION).post(
LearnEventData(vm.intentData.subjectId,
vm.intentData.courseId,
AppConstants.ACTION_LESSON_AFTER_TEST_AGAIN).apply {
leesonPositionIndex = vm.intentData.lesson?.lessonPositionInList!!
})
LiveEventBus.get<LearnEventData>(AppConstants.EVENT_LESSON_ACTION)
.post(LearnEventData(vm.intentData.subjectId, vm.intentData.courseId,
AppConstants.ACTION_LESSON_AFTER_TEST_AGAIN).apply {
leesonPositionIndex = vm.intentData.lesson?.lessonPositionInList!!
})
finish()
}
//下一步
AppConstants.DIALOG_LESSON_AFTER_TEST_NEXT -> {
//发送动作 : 下一步
LiveEventBus.get<LearnEventData>(AppConstants.EVENT_LESSON_ACTION).post(
LearnEventData(vm.intentData.subjectId,
vm.intentData.courseId,
AppConstants.ACTION_LESSON_AFTER_TEST_NEXT).apply {
leesonPositionIndex = vm.intentData.lesson?.lessonPositionInList!!
})
LiveEventBus.get<LearnEventData>(AppConstants.EVENT_LESSON_ACTION)
.post(LearnEventData(vm.intentData.subjectId, vm.intentData.courseId,
AppConstants.ACTION_LESSON_AFTER_TEST_NEXT).apply {
leesonPositionIndex = vm.intentData.lesson!!.lessonPositionInList!!
})
finish()
}
}
//学后总测试结束
AppConstants.TEST_TYPE_AFTER_TOTAL -> when(action){
AppConstants.TEST_TYPE_AFTER_TOTAL -> when (action) {
//测试完成,切换到目录页
AppConstants.DIALOG_OVER -> {
AppConstants.DIALOG_OVER -> {
dialog.dismissAllowingStateLoss()
//发送动作 : 继续学习
LiveEventBus.get<LearnEventData>(AppConstants.EVENT_CHANGE_PAGE).post(
LearnEventData(vm.intentData.subjectId,
vm.intentData.courseId,
AppConstants.ACTION_COURSE_TEST_AFTER_TOTAL_OVER))
LiveEventBus.get<LearnEventData>(AppConstants.EVENT_CHANGE_PAGE)
.post(LearnEventData(vm.intentData.subjectId, vm.intentData.courseId,
AppConstants.ACTION_COURSE_TEST_AFTER_TOTAL_OVER))
finish()
}
//再测一次
AppConstants.DIALOG_AFTER_TOTAL_TEST_AGAIN -> {
dialog.dismissAllowingStateLoss()
//发送动作 : 再测一次
LiveEventBus.get<LearnEventData>(AppConstants.EVENT_CHANGE_PAGE).post(
LearnEventData(vm.intentData.subjectId,
vm.intentData.courseId,
AppConstants.ACTION_COURSE_TEST_AFTER_TOTAL_AGAIN))
LiveEventBus.get<LearnEventData>(AppConstants.EVENT_CHANGE_PAGE)
.post(LearnEventData(vm.intentData.subjectId, vm.intentData.courseId,
AppConstants.ACTION_COURSE_TEST_AFTER_TOTAL_AGAIN))
finish()
}
}
AppConstants.TEST_TYPE_COMPOSITION -> when (action) {
//测试完成,关闭
AppConstants.DIALOG_OVER -> {
dismissAllowingStateLoss()
finish()
}
//再测一次
AppConstants.DIALOG_START_TEST -> {
dismissAllowingStateLoss()
//发送动作,再测一次
LiveEventBus.get<LearnEventData>(AppConstants.EVENT_LESSON_ACTION)
.post(LearnEventData(vm.intentData.subjectId, vm.intentData.courseId,
AppConstants.ACTION_LESSON_COMPOSITION_TEST_AGAIN).apply {
leesonPositionIndex = vm.intentData.lesson!!.lessonPositionInList
})
finish()
}
}

+ 37
- 5
app/src/main/java/com/xkl/cdl/module/learn/LearnExamViewModel.kt View File

@@ -263,7 +263,7 @@ class LearnExamViewModel : LearnBaseViewModel() {
initChooseOption(nextExam)
currentMaxTime = if (intentData.courseType == AppConstants.COURSE_TYPE_ENGLISH_VOICE) 0 else Math.max(
AppConstants.TEST_MIN_TIME,
(nextExam.word.length + nextExam.correct.length) * 200)
(nextExam.word.length + nextExam.correct.length) * if (intentData.courseType == AppConstants.COURSE_TYPE_CHINESE_COMPOSITION) 400 else 200)
// LogUtil.e("------currentMaxTime = $currentMaxTime")
currentSuplusTime.value = currentMaxTime
}
@@ -382,8 +382,10 @@ class LearnExamViewModel : LearnBaseViewModel() {
currentExamRecord!!.answerStatus = AppConstants.TEST_UN_ANSWER
chooseResult = AppConstants.TEST_UN_ANSWER
}
//创建错误记录
createErrorRecord()
//创建错误记录,作文知识点测试不创建错误记录
if (intentData.examType != AppConstants.TEST_TYPE_COMPOSITION) {
createErrorRecord()
}
}
currentChooseResultLiveData.value = chooseResult
}
@@ -594,9 +596,27 @@ class LearnExamViewModel : LearnBaseViewModel() {
//最终上传数据
record.addExam(learnExam) //测试试卷
//时间
if (examType == AppConstants.TEST_TYPE_BEFORE_TOTAL || examType == AppConstants.TEST_TYPE_BEFORE || examType == AppConstants.TEST_TYPE_AFTER || examType == AppConstants.TEST_TYPE_AFTER_TOTAL) {
//时间 学习中心的测试需要添加为学习时间
if (examType == AppConstants.TEST_TYPE_BEFORE_TOTAL
|| examType == AppConstants.TEST_TYPE_BEFORE
|| examType == AppConstants.TEST_TYPE_AFTER
|| examType == AppConstants.TEST_TYPE_AFTER_TOTAL
|| examType == AppConstants.TEST_TYPE_COMPOSITION) {
record.addDuration(saveCurrentLearnDuration())
//作文知识点测试,添加一个单词,用以设置课程的进度点
if (examType == AppConstants.TEST_TYPE_COMPOSITION){
record.addEntity(LearnEntity.newBuilder().apply {
projectId = intentData.subjectId.toLong()
packId = intentData.coursePackId
courseId = intentData.courseId
chapterId = intentData.lesson!!.chapterId
lessonId = intentData.lesson!!.lessonId
entityId = intentData.testData!![0].id
created = DateUtil.format(System.currentTimeMillis(), DateUtil.FORMAT_1)
tag = "android"
isOnlySavePoint = true
})
}
}
if (mLearnEntities.size != 0) {
record.addAllEntity(mLearnEntities)
@@ -633,6 +653,10 @@ class LearnExamViewModel : LearnBaseViewModel() {
DataRepository.saveRecord(record)
// record 已经实例化并已经将数据保存
// LogUtil.e(JsonFormat.printToString(record.build()))
//知识点测试,标记当前课时为完成
if (intentData.examType == AppConstants.TEST_TYPE_COMPOSITION){
intentData.lesson!!.learnIsOver = true
}
}.compose(diskIo2Main()).subscribe({
showHideLoading(false)
@@ -686,6 +710,14 @@ class LearnExamViewModel : LearnBaseViewModel() {
this.scoreValue = this@LearnExamViewModel.scoreValue
})
}
AppConstants.TEST_TYPE_COMPOSITION -> { //知识点测试结束发送数据,当做学习完成处理
LiveEventBus.get<LearnEventData>(AppConstants.EVENT_LESSON_DATA).post(LearnEventData(
intentData.subjectId,
intentData.courseId,
AppConstants.DATA_LESSON_LEARN_OVER).apply {
leesonPositionIndex = intentData.lesson!!.lessonPositionInList
})
}
}
}

+ 88
- 36
app/src/main/java/com/xkl/cdl/module/learn/LearnWordActivity.kt View File

@@ -2,12 +2,16 @@ package com.xkl.cdl.module.learn

import android.annotation.SuppressLint
import android.graphics.Color
import android.opengl.Visibility
import android.os.Bundle
import android.text.SpannableStringBuilder
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat
import androidx.fragment.app.FragmentManager
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
@@ -24,6 +28,7 @@ import com.suliang.common.util.image.ImageLoader
import com.suliang.common.util.media.EMediaState
import com.suliang.common.util.media.IMPListener
import com.suliang.common.util.media.MPManager
import com.suliang.common.util.os.ScreenUtil
import com.xkl.cdl.R
import com.xkl.cdl.adapter.AdapterHistoricalRoute
import com.xkl.cdl.adapter.AdapterSpell
@@ -217,6 +222,12 @@ class LearnWordActivity : BaseActivityVM<ActivityLearnWordBinding, LearnWordView
incWorcDetailBinding.root.visibility = it
}
}
if (vm.learnData.lesson.courseType == AppConstants.COURSE_TYPE_CHINESE_COMPOSITION){
bindingWord.imgWord.visibility = View.GONE
val layoutParams = bindingWord.incWord.root.layoutParams as ConstraintLayout.LayoutParams
layoutParams.goneTopMargin = ScreenUtil.dp2px(12f).toInt()
bindingWord.incWord.root.requestLayout()
}
}
//初始化按钮
@@ -807,19 +818,20 @@ class LearnWordActivity : BaseActivityVM<ActivityLearnWordBinding, LearnWordView
/** 学习完成 */
private fun showLearnOverDialog() {
//自动播放完成弹窗
if (vm.learnData.isAutoPlay){
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, isRightClick ->
dialog.dismissAllowingStateLoss()
finish()
}
}.show(supportFragmentManager, "auto_play_back_dialog")
return
when{
//自动播放完成弹窗
vm.learnData.isAutoPlay -> showAutoPlayOverDialog()
//作文知识点完成
vm.learnData.lesson.courseType == AppConstants.COURSE_TYPE_CHINESE_COMPOSITION -> showCompositionKnowLeageLearningOver()
//其他单词类,带学后测试的课时完成
else -> showLessonWordLearningOver()
}
}
/**
* 单词类学习完成
*/
private fun showLessonWordLearningOver() {
vm.loadAfterTest().observe(this) { showTimeCount ->
LearnDialog.newInstance(LearnDialogBean(AppConstants.DIALOG_TYPE_LEARNING_OVER).apply {
correctNumber = vm.learnData.lesson.correctNumber
@@ -829,34 +841,13 @@ class LearnWordActivity : BaseActivityVM<ActivityLearnWordBinding, LearnWordView
onDialogListener = { action, dialog ->
when (action) {
//重学动作
AppConstants.DIALOG_LESSON_RELEARN -> CommonDialog.newInstance(CommonDialogBean(titleText = R.string.lesson_relearn_title,
contentText = R.string.lesson_relearn_content,
leftText = R.string.cancel,
rightText = R.string.sure))
.apply {
onCommonDialogButtonClickListener = { relearnDialog, isRightClick ->
relearnDialog.dismissAllowingStateLoss()
if (isRightClick){
dialog.dismissAllowingStateLoss()
//发送动作 : 重新学习
LiveEventBus.get<LearnEventData>(AppConstants.EVENT_LESSON_ACTION).post(
LearnEventData(vm.learnData.lesson.subjectId,
vm.learnData.lesson.courseId,
AppConstants.ACTION_LESSON_AFTER_TEST_RELEARN).apply {
leesonPositionIndex = vm.learnData.lesson.lessonPositionInList
})
finish()
}
}
}.show(childFragmentManager,"lesson_relearn_tip")
AppConstants.DIALOG_LESSON_RELEARN -> lessonRelearnDialog(dialog)
// 开始学后测试
AppConstants.DIALOG_START_TEST -> {
dialog.dismissAllowingStateLoss()
//发送动作 : 学后测试
LiveEventBus.get<LearnEventData>(AppConstants.EVENT_LESSON_ACTION).post(
LearnEventData(vm.learnData.lesson.subjectId,
vm.learnData.lesson.courseId,
AppConstants.ACTION_LESSON_AFTER_TEST_AGAIN).apply {
LiveEventBus.get<LearnEventData>(AppConstants.EVENT_LESSON_ACTION)
.post(LearnEventData(vm.learnData.lesson.subjectId, vm.learnData.lesson.courseId, AppConstants.ACTION_LESSON_AFTER_TEST_AGAIN).apply {
leesonPositionIndex = vm.learnData.lesson.lessonPositionInList
})
finish()
@@ -867,5 +858,66 @@ class LearnWordActivity : BaseActivityVM<ActivityLearnWordBinding, LearnWordView
}
}
/**
* 自动播放完成弹窗
*/
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 {
onCommonDialogButtonClickListener = { dialog, _ ->
dialog.dismissAllowingStateLoss()
finish()
}
}.show(supportFragmentManager, "auto_play_back_dialog")
}
/**
* 作文知识点学习完成弹窗
*/
private fun showCompositionKnowLeageLearningOver(){
LearnDialog.newInstance(LearnDialogBean(AppConstants.DIALOG_TYPE_LESSON_COMPOSITION_KNOWLEDGE_LEARNING_OVER).apply {
correctNumber = vm.learnData.lesson.correctNumber
errorNumber = vm.learnData.lesson.errorNumber
}).apply {
onDialogListener = { action, dialog ->
when(action){
//重学,重学弹窗提示
AppConstants.DIALOG_LESSON_RELEARN -> lessonRelearnDialog(dialog)
//完成 关闭,不处理
AppConstants.DIALOG_OVER -> {
dialog.dismissAllowingStateLoss()
finish()
}
}
}
}.show(supportFragmentManager,"composition_knowledge_learn_over")
}
/***
* 课时重学确认弹窗
* @param dialog LearnDialog 触发重学弹窗显示的弹窗
*/
private fun lessonRelearnDialog(dialog : LearnDialog) {
CommonDialog.newInstance(
CommonDialogBean(titleText = R.string.lesson_relearn_title, contentText = R.string.lesson_relearn_content,
leftText = R.string.cancel, rightText = R.string.sure)).apply {
onCommonDialogButtonClickListener = { relearnDialog, isRightClick ->
relearnDialog.dismissAllowingStateLoss()
if (isRightClick) {
dialog.dismissAllowingStateLoss()
//发送动作 : 重新学习
LiveEventBus.get<LearnEventData>(AppConstants.EVENT_LESSON_ACTION)
.post(LearnEventData(vm.learnData.lesson.subjectId, vm.learnData.lesson.courseId, AppConstants.ACTION_LESSON_AFTER_TEST_RELEARN).apply {
leesonPositionIndex = vm.learnData.lesson.lessonPositionInList
})
finish()
}
}
}.show(dialog.childFragmentManager, "lesson_relearn_tip")
}

}

+ 4
- 1
app/src/main/java/com/xkl/cdl/module/learn/LearnWordViewModel.kt View File

@@ -47,7 +47,10 @@ class LearnWordViewModel : LearnBaseViewModel() {
//是否需要显示单词图片
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
}

+ 1
- 1
app/src/main/java/com/xkl/cdl/module/m_center_learn/CoursePackMainActivity.kt View File

@@ -173,7 +173,7 @@ class CoursePackMainActivity : BaseActivityVM<ActivityCourseMainBinding, CourseP
tabSpell.click { binding.viewPager2.currentItem = 1 }
tabVoice.click { binding.viewPager2.currentItem = 2 }
}
//监听进度,设置进度
//监听进度,设置进度 进度为百分制,已经乘了100了
vm.currentCourseProgress.observe(this) {
binding.includeCourseProgress.apply {
//进度格式化

+ 132
- 70
app/src/main/java/com/xkl/cdl/module/m_center_learn/coursechildren/CourseLessonFragment.kt View File

@@ -7,6 +7,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.jeremyliao.liveeventbus.LiveEventBus
import com.suliang.common.base.fragment.BaseFragmentVM
import com.suliang.common.util.LogUtil
import com.xkl.cdl.R
import com.xkl.cdl.adapter.AdapterLesson
import com.xkl.cdl.data.AppConstants
@@ -90,35 +91,78 @@ class CourseLessonFragment : BaseFragmentVM<FragmentCourseLessonBinding, CourseM
adapterLesson.notifyItemChanged(learnEventData.leesonPositionIndex)
vm.allLesson[learnEventData.leesonPositionIndex].let {
val key = "${it.chapterId}_${it.lessonId}"
//更新错误数
vm.courseDetail.wrong.put(key, it.errorNumber)
//更新正确数
vm.courseDetail.right.put(key, it.correctNumber)
//添加到错误本中,现在主要用于小游戏取值
learnEventData.newErrorMap?.forEach {
vm.courseDetail.temporary_words.put(it.key, "")
when (it.lessonType) {
//单词类
AppConstants.LESSON_TYPE_WORD ->{
vm.courseDetail.run {
wrong[key] = it.errorNumber //更新错误数
right[key] = it.correctNumber //更新正确数
lesson_learn_point[key] = it.wordIds[it.learnedIndex] //更新课时学习点
course_learn_point = "${key}_${it.wordIds[it.learnedIndex]}" //更新课程学习点
}
// TODO: 2022/5/17 如果不需要小游戏,则这个可以取消,存放的value为time,暂时感觉没必要,所以直接用空内容数据
//添加到错误本中,现在主要用于小游戏取值
learnEventData.newErrorMap?.forEach {
vm.courseDetail.temporary_words[it.key] = ""
}
}
AppConstants.LESSON_TYPE_SENTENCE -> {
}
AppConstants.LESSON_TYPE_DIALOGUE -> {
}
//视频
AppConstants.LESSON_TYPE_COMPOSITION_VIDEO -> vm.courseDetail.run {
val relationId = it.wordIds[0]
//更新视频播放点
vp[relationId] = learnEventData.videoPlayTime
//更新课程学习点
lesson_learn_point[key] = relationId //更新课时学习点
course_learn_point = "${key}_${relationId}" //更新课程学习点
}
//知识点
AppConstants.LESSON_TYPE_COMPOSITION_KNOWLEDGE -> vm.courseDetail.run {
wrong[key] = it.errorNumber //更新错误数
right[key] = it.correctNumber //更新正确数
lesson_learn_point[key] = it.wordIds[it.learnedIndex] //更新课时学习点
course_learn_point = "${key}_${it.wordIds[it.learnedIndex]}" //更新课程学习点
}
//测试
AppConstants.LESSON_TYPE_COMPOSITION_EXAM -> vm.courseDetail.run {
course_learn_point = "${key}_0}" //更新课程学习点
}
//课堂练习
AppConstants.LESSON_TYPE_COMPOSITION_READING -> vm.courseDetail.run {
lesson_learn_point[key] = it.wordIds[it.learnedIndex] //更新课时学习点
course_learn_point = "${key}_${it.wordIds[it.learnedIndex]}" //更新课程学习点
}
//课外练习 不操作,不计算
AppConstants.LESSON_TYPE_COMPOSITION_TASK -> { }
else -> {}
}
//更新课时学习点
vm.courseDetail.lesson_learn_point.put("${it.chapterId}_${it.lessonId}", it.wordIds[it.learnedIndex])
//更新课程学习点
vm.courseDetail.course_learn_point = "${it.chapterId}_${it.lessonId}_${it.wordIds[it.learnedIndex]}"
}
//课程进度
val courseProgress = when (vm.course.coursePackType) {
AppConstants.COURSEPACK_TYPE_CHINESE_COMPOSITION -> CourseManager.calculateCompositionCourseProgess(
AppConstants.COURSEPACK_TYPE_CHINESE_COMPOSITION -> CourseManager.calculateCompositionCourseProgress(
vm.allLesson)
AppConstants.COURSEPACK_TYPE_ENGLISH_SPOKEN -> CourseManager.calculateSpokenCourseProgress(vm.allLesson)
else -> CourseManager.calculateEnglishCourseProgress(vm.allLesson)
}
vm.courseDetail.courseLearnProgress = courseProgress
vm.course.courseLearnProgress = courseProgress
vm.coursePackMainActivityVM.currentCourseProgress.value = courseProgress
//项目总进度
val subjectProgress = CourseManager.calculateSubjectProgress(vm.course.subjectId, vm.course.coursePackId,
vm.course.courseId, courseProgress)
//保存
vm.updateLearnSchedule(courseProgress, subjectProgress)
//与本地进度不同,则需要保存修改
if (vm.courseDetail.courseLearnProgress != courseProgress) {
LogUtil.i("修改保存课程与项目进度")
vm.courseDetail.courseLearnProgress = courseProgress
vm.course.courseLearnProgress = courseProgress
vm.coursePackMainActivityVM.currentCourseProgress.value = courseProgress
//项目总进度
val subjectProgress = CourseManager.calculateSubjectProgress(vm.course.subjectId, vm.course.coursePackId,
vm.course.courseId, courseProgress)
//保存
vm.updateLearnSchedule(courseProgress, subjectProgress)
}
}
//学后测试结束传递数据回来更新数据
@@ -204,6 +248,23 @@ class CourseLessonFragment : BaseFragmentVM<FragmentCourseLessonBinding, CourseM
}
}
}
/*作文知识点测试的再测一次*/
AppConstants.ACTION_LESSON_COMPOSITION_TEST_AGAIN -> {
// 滑动到指定课时,进行动态设置点击
val linearLayoutManager = binding.recyclerView.layoutManager as LinearLayoutManager
val findFirstVisibleItemPosition = linearLayoutManager.findFirstVisibleItemPosition() //第一个可见位置
val findLastVisibleItemPosition = linearLayoutManager.findLastVisibleItemPosition() //最后一个可见位置
if (learnEventData.leesonPositionIndex in findFirstVisibleItemPosition .. findLastVisibleItemPosition) {
linearLayoutManager.findViewByPosition(learnEventData.leesonPositionIndex)
?.findViewById<ConstraintLayout>(R.id.layout_content)
?.performClick()
} else {
recycleViewScrollListener.lessonPosition = learnEventData.leesonPositionIndex
binding.recyclerView.addOnScrollListener(recycleViewScrollListener)
binding.recyclerView.smoothScrollToPosition(learnEventData.leesonPositionIndex)
}
}
}
}
}
@@ -247,18 +308,41 @@ class CourseLessonFragment : BaseFragmentVM<FragmentCourseLessonBinding, CourseM
AppConstants.LESSON_TYPE_DIALOGUE -> {
}
//视频
AppConstants.LESSON_TYPE_COMPOSITION_VIDEO -> {
}
AppConstants.LESSON_TYPE_COMPOSITION_KNOWLEDGE -> {
//知识点 : 直接进入学习,没有学前学后测试 判断学习是否完成,完成的情况下需要弹窗提示
AppConstants.LESSON_TYPE_COMPOSITION_KNOWLEDGE -> when{
//学习完成,弹窗提示
entity.learnIsOver -> LearnDialog.newInstance(LearnDialogBean(AppConstants.DIALOG_TYPE_LESSON_ITEM_CLICK_COMPOSITION_KNOWLEDGE_OVER).apply {
errorNumber = entity.errorNumber
correctNumber = entity.correctNumber
}).apply {
onDialogListener = { action, dialog ->
when(action){
//重学,重学弹窗提示
AppConstants.DIALOG_LESSON_RELEARN -> lessonRelearnDialog(dialog,entity)
//完成 关闭,不处理
AppConstants.DIALOG_OVER -> dialog.dismissAllowingStateLoss()
}
}
}.show(childFragmentManager,"composition_knowledge_learn_over")
//未完成
else -> startLearn(entity)
}
AppConstants.LESSON_TYPE_COMPOSITION_EXAM -> {
//测试: 直接进入测试,类型为作文知识点测试
AppConstants.LESSON_TYPE_COMPOSITION_EXAM -> {
vm.loadTest(AppConstants.TEST_TYPE_COMPOSITION,entity).observe(this){
startLessonTest(entity,AppConstants.TEST_TYPE_COMPOSITION,it)
}
}
//课堂练习
AppConstants.LESSON_TYPE_COMPOSITION_READING -> {
}
//课外练习
AppConstants.LESSON_TYPE_COMPOSITION_TASK -> {
}
@@ -302,16 +386,6 @@ class CourseLessonFragment : BaseFragmentVM<FragmentCourseLessonBinding, CourseM
when (lesson.lessonType) {
AppConstants.LESSON_TYPE_WORD -> {
startLessonLearnForWord(lesson)
/* if (entity.beforeTestScore == AppConstants.NOT_DOING){ //课时学前测试,没有做
//弹窗显示学前测试提示
showLessonBeforeTestStartDialog(entity)
}else if (!entity.learnIsOver){ //当前课时未学完,直接开始学习
startLearn(entity)
}else if (entity.afterTestScore != AppConstants.NOT_DOING){
loadLessonAfterTest(entity)
}else{ //当前课时学习完成的弹窗
showLessonAllOverDialog(entity)
}*/
}
AppConstants.LESSON_TYPE_SENTENCE -> {
@@ -324,7 +398,7 @@ class CourseLessonFragment : BaseFragmentVM<FragmentCourseLessonBinding, CourseM
}
AppConstants.LESSON_TYPE_COMPOSITION_KNOWLEDGE -> {
startLessonLearnForWord(lesson)
}
AppConstants.LESSON_TYPE_COMPOSITION_EXAM -> {
@@ -353,25 +427,7 @@ class CourseLessonFragment : BaseFragmentVM<FragmentCourseLessonBinding, CourseM
onDialogListener = { action, dialog ->
when (action) {
//重学动作
AppConstants.DIALOG_LESSON_RELEARN -> CommonDialog.newInstance(CommonDialogBean(titleText = R.string.lesson_relearn_title,
contentText = R.string.lesson_relearn_content,
leftText = R.string.cancel,
rightText = R.string.sure))
.apply {
onCommonDialogButtonClickListener = { relearnDialog, isRightClick ->
relearnDialog.dismissAllowingStateLoss()
if (isRightClick){
dialog.dismissAllowingStateLoss()
//发送动作 : 重新学习
LiveEventBus.get<LearnEventData>(AppConstants.EVENT_LESSON_ACTION).post(
LearnEventData(lesson.subjectId,
lesson.courseId,
AppConstants.ACTION_LESSON_AFTER_TEST_RELEARN).apply {
leesonPositionIndex = lesson.lessonPositionInList
})
}
}
}.show(childFragmentManager,"lesson_relearn_tip")
AppConstants.DIALOG_LESSON_RELEARN -> lessonRelearnDialog(dialog, lesson)
// 开始学后测试
AppConstants.DIALOG_START_TEST -> {
dialog.dismissAllowingStateLoss()
@@ -421,23 +477,7 @@ class CourseLessonFragment : BaseFragmentVM<FragmentCourseLessonBinding, CourseM
onDialogListener = { action, dialog ->
when (action) {
//重学动作
AppConstants.DIALOG_LESSON_RELEARN -> CommonDialog.newInstance(
CommonDialogBean(titleText = R.string.lesson_relearn_title,
contentText = R.string.lesson_relearn_content, leftText = R.string.cancel,
rightText = R.string.sure)).apply {
onCommonDialogButtonClickListener = { relearnDialog, isRightClick ->
relearnDialog.dismissAllowingStateLoss()
if (isRightClick) {
dialog.dismissAllowingStateLoss()
//发送动作 : 重新学习
LiveEventBus.get<LearnEventData>(AppConstants.EVENT_LESSON_ACTION).post(
LearnEventData(lesson.subjectId, lesson.courseId,
AppConstants.ACTION_LESSON_AFTER_TEST_RELEARN).apply {
leesonPositionIndex = lesson.lessonPositionInList
})
}
}
}.show(childFragmentManager, "lesson_relearn_tip")
AppConstants.DIALOG_LESSON_RELEARN -> lessonRelearnDialog(dialog, lesson)
// 开始学后测试
AppConstants.DIALOG_START_TEST -> {
dialog.dismissAllowingStateLoss()
@@ -452,6 +492,28 @@ class CourseLessonFragment : BaseFragmentVM<FragmentCourseLessonBinding, CourseM
}.show(childFragmentManager, "learn_over_dialog")
}
/** 课时重学提示弹窗
* @param dialog LearnDialog 从其他弹窗点击提示的该弹窗
* @param lesson Lesson 需要重学的课时
*/
private fun lessonRelearnDialog(dialog : LearnDialog?, lesson : Lesson) {
CommonDialog.newInstance(
CommonDialogBean(titleText = R.string.lesson_relearn_title, contentText = R.string.lesson_relearn_content,
leftText = R.string.cancel, rightText = R.string.sure)).apply {
onCommonDialogButtonClickListener = { relearnDialog, isRightClick ->
relearnDialog.dismissAllowingStateLoss()
if (isRightClick) {
dialog?.dismissAllowingStateLoss()
//发送动作 : 重新学习
LiveEventBus.get<LearnEventData>(AppConstants.EVENT_LESSON_ACTION)
.post(LearnEventData(lesson.subjectId, lesson.courseId, AppConstants.ACTION_LESSON_AFTER_TEST_RELEARN).apply {
leesonPositionIndex = lesson.lessonPositionInList
})
}
}
}.show(childFragmentManager, "lesson_relearn_tip")
}
/**
* 显示课程学习完成的弹窗,在最后一个课时测试完成的下一步,相当于在课时目录页显示去学后总测试的弹窗
*/

+ 28
- 17
app/src/main/java/com/xkl/cdl/module/m_center_learn/coursechildren/CourseMainFragment.kt View File

@@ -27,8 +27,8 @@ class CourseMainFragment : BaseFragmentVM<FragmentCourseMainBinding, CourseMainF
companion object {
@JvmStatic
fun newInstance(courseIndex : Int):CourseMainFragment {
return CourseMainFragment().apply {
fun newInstance(courseIndex : Int) : CourseMainFragment {
return CourseMainFragment().apply {
arguments = Bundle().apply {
putInt(AppConfig.INTENT_1, courseIndex)
}
@@ -102,28 +102,39 @@ class CourseMainFragment : BaseFragmentVM<FragmentCourseMainBinding, CourseMainF
override fun loadData() {
vm.loadMain().observe(this) {
changeChildrenFragment()
when (vm.course.courseType) {
//作文只有一个目录结构
AppConstants.COURSE_TYPE_CHINESE_COMPOSITION -> changeChildrenFragmentForComposition()
else -> changeChildrenFragmentForWord()
}
}
}
/**
* 改变加载的子Fragment
* 改变加载的子Fragment 单词类
*/
private fun changeChildrenFragment() {
private fun changeChildrenFragmentForWord() {
// TODO: 2022/5/5 复习页面加载
vm.courseDetail.run {
if (st_before == AppConstants.NOT_DOING) { //学前总测未做
currentFragment = CourseTotalTestFragment.newInstance(AppConstants.TEST_TYPE_BEFORE_TOTAL)
replaceFragment(R.id.layout_root, currentFragment)
} else if (courseLearnProgress != 100.0) { //学习未完成
currentFragment = CourseLessonFragment.newInstance()
replaceFragment(R.id.layout_root, currentFragment)
} else { //学习完成,学后总测试界面
currentFragment = CourseTotalTestFragment.newInstance(AppConstants.TEST_TYPE_AFTER_TOTAL)
replaceFragment(R.id.layout_root,currentFragment)
currentFragment = vm.courseDetail.let {
when{
it.st_before == AppConstants.NOT_DOING -> CourseTotalTestFragment.newInstance(AppConstants.TEST_TYPE_BEFORE_TOTAL) //学前总测未做
it.courseLearnProgress != AppConstants.DOING_OVER -> CourseLessonFragment.newInstance() //学习未完成
else -> CourseTotalTestFragment.newInstance(AppConstants.TEST_TYPE_AFTER_TOTAL) //学习完成,学后总测试界面
}
}
replaceFragment(R.id.layout_root, currentFragment)
}
/**
* 改变加载的子Fragment 作文
*/
private fun changeChildrenFragmentForComposition() {
// TODO: 2022/5/5 复习页面加载 CourseReviewFragment.newInstance()
currentFragment = vm.courseDetail.let {
CourseLessonFragment.newInstance()
}
replaceFragment(R.id.layout_root, currentFragment)
}
/**
@@ -134,7 +145,7 @@ class CourseMainFragment : BaseFragmentVM<FragmentCourseMainBinding, CourseMainF
when (position) {
1 -> {
currentFragment = CourseLessonFragment.newInstance()
replaceFragment(R.id.layout_root,currentFragment )
replaceFragment(R.id.layout_root, currentFragment)
}
2 -> {
currentFragment = CourseTotalTestFragment.newInstance(AppConstants.TEST_TYPE_AFTER_TOTAL)
@@ -153,7 +164,7 @@ class CourseMainFragment : BaseFragmentVM<FragmentCourseMainBinding, CourseMainF
/** 课程重学方法 */
fun courseRelearn() {
//调用重学,重学重新加载数据,重新加载界面
vm.relearnCourse().observe(this){
vm.relearnCourse().observe(this) {
loadData()
}
}

+ 9
- 2
app/src/main/java/com/xkl/cdl/module/m_center_learn/coursechildren/CourseMainFragmentViewModel.kt View File

@@ -87,7 +87,10 @@ class CourseMainFragmentViewModel(val courseIndex : Int) : BaseViewModel() {
/** 课程包主页上的更多按钮点击是否有效 */
fun showMoreIsEnable() : Boolean {
return courseDetail.st_before != AppConstants.NOT_DOING
return when(course.courseType){
AppConstants.COURSE_TYPE_CHINESE_COMPOSITION -> courseDetail.courseLearnProgress > 0
else -> courseDetail.st_before != AppConstants.NOT_DOING
}
}
/**
@@ -200,7 +203,11 @@ class CourseMainFragmentViewModel(val courseIndex : Int) : BaseViewModel() {
fun relearnLesson(lessonPositionIndex : Int) : MutableLiveData<Boolean> {
val result = MutableLiveData<Boolean>()
//重学课时后课程的进度
val courseProgress = CourseManager.calculateEnglishCourseProgress(allLesson, true, lessonPositionIndex)
val courseProgress = when(course.subjectId){
AppConstants.SUBJECT_ENGLISH -> CourseManager.calculateEnglishCourseProgress(allLesson, true, lessonPositionIndex)
//作文的重学虚拟进度
else -> CourseManager.calculateCompositionCourseProgress(allLesson,true,lessonPositionIndex)
}
//重学课时后项目的总进度
val subjectProgress = CourseManager.calculateSubjectProgressWithCourseLessonRelearn(course.subjectId, course.coursePackId,
course.courseId, courseProgress)

+ 7
- 0
app/src/main/res/layout/dialog_lesson_learn.xml View File

@@ -297,6 +297,13 @@
app:constraint_referenced_ids="tv_score,tv_tip,tv_title,inc_statistics_number,tv_top,tv_left,vSplit"
/>-->

<!-- 作文测试结束绑定的布局组 -->
<!-- <androidx.constraintlayout.widget.Group-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- app:constraint_referenced_ids="tv_score,tv_tip,tv_title,inc_statistics_number,tv_left,vSplit"-->
<!-- />-->



</androidx.constraintlayout.widget.ConstraintLayout>

+ 4
- 2
app/src/main/res/layout/item_historical_route.xml View File

@@ -18,8 +18,10 @@
android:paddingLeft="4dp"
android:paddingRight="4dp"
android:textSize="@dimen/smallerSize"
android:maxLines="1"
android:text="hello"
android:lines="1"
android:ellipsize="end"
android:maxEms="10"
tools:text="hello"
tools:background="@drawable/shape_rounder_toplr_8_white"/>
</LinearLayout>
</layout>

Loading…
Cancel
Save