| /** 未做测试,没有做等用-1表示的内容 */ | /** 未做测试,没有做等用-1表示的内容 */ | ||||
| const val NOT_DOING = -1.0 | const val NOT_DOING = -1.0 | ||||
| const val DOING_OVER = 100.0 | |||||
| /** 测试通过:>80 < 90 继续加油 <80 悲伤 */ | /** 测试通过:>80 < 90 继续加油 <80 悲伤 */ | ||||
| const val TEST_SCORE_LEVEL_1 = 80 | const val TEST_SCORE_LEVEL_1 = 80 |
| package com.xkl.cdl.data.bean | package com.xkl.cdl.data.bean | ||||
| import androidx.annotation.ColorRes | |||||
| import com.xkl.cdl.R | import com.xkl.cdl.R | ||||
| import java.io.Serializable | import java.io.Serializable | ||||
| var repeatNum: Int = 0 | var repeatNum: Int = 0 | ||||
| /**显示颜色*/ | /**显示颜色*/ | ||||
| var showColor: Int = 0 | |||||
| @ColorRes | |||||
| var showColor:Int = 0 | |||||
| get() { | get() { | ||||
| return when (repeatNum) { | return when (repeatNum) { | ||||
| 0 -> R.color.num0 | 0 -> R.color.num0 |
| learnProgress == 0.0 -> view.resources.getString(R.string.start) | learnProgress == 0.0 -> view.resources.getString(R.string.start) | ||||
| learnProgress < 0.1 -> "0.1%" | learnProgress < 0.1 -> "0.1%" | ||||
| learnProgress < 100 -> { | learnProgress < 100 -> { | ||||
| DecimalFormat("#.#%").apply { | |||||
| DecimalFormat("#.##").apply { | |||||
| roundingMode = RoundingMode.DOWN | roundingMode = RoundingMode.DOWN | ||||
| }.format(BigDecimal(learnProgress)) | |||||
| }.format(learnProgress) + "%" | |||||
| } | } | ||||
| else -> "100%" | else -> "100%" | ||||
| } | } |
| val mSortInfoList = hashMapOf<Int, MutableList<AppApi.CourseSortedInfo.Builder>>() | val mSortInfoList = hashMapOf<Int, MutableList<AppApi.CourseSortedInfo.Builder>>() | ||||
| /** | |||||
| * 获取对应项目的课程数量 | |||||
| * @param subjectId Int 项目 | |||||
| * @return Int 课程数量 | |||||
| */ | |||||
| fun getSubjectForCourseSize(subjectId : Int) : Int { | |||||
| return subjectWithCoursePackMap[subjectId]?.let { | |||||
| var count = 0 | |||||
| it.forEach { coursePack -> | |||||
| count += coursePack.childrenCourses?.size ?: 0 | |||||
| } | |||||
| count | |||||
| } ?: 0 | |||||
| } | |||||
| /** | /** | ||||
| * 搜索项目下的课程包 | * 搜索项目下的课程包 | ||||
| * @param subjectId Int 项目id | * @param subjectId Int 项目id | ||||
| return when { | return when { | ||||
| progress == 0.0 -> "0" | progress == 0.0 -> "0" | ||||
| progress < 0.1 -> "0.1" | progress < 0.1 -> "0.1" | ||||
| progress < 100 -> DecimalFormat("#.#").apply { | |||||
| progress < 100 -> DecimalFormat("#.##").apply { | |||||
| //直接舍弃 | //直接舍弃 | ||||
| roundingMode = RoundingMode.DOWN | roundingMode = RoundingMode.DOWN | ||||
| }.format(BigDecimal(progress)) | }.format(BigDecimal(progress)) | ||||
| if (totalProgress == 0.0 ) return totalProgress | if (totalProgress == 0.0 ) return totalProgress | ||||
| var totalCourseSize = 0 | |||||
| subjectWithCoursePackMap.get(subjectId)?.forEach { | |||||
| totalCourseSize += it.childrenCourses.size | |||||
| } | |||||
| val totalCourseSize = getSubjectForCourseSize(subjectId) | |||||
| if (totalCourseSize == 0) return 0.0 | if (totalCourseSize == 0) return 0.0 | ||||
| return totalProgress / totalCourseSize | return totalProgress / totalCourseSize | ||||
| } | } | ||||
| if (totalProgress == 0.0 ) return totalProgress | if (totalProgress == 0.0 ) return totalProgress | ||||
| var totalCourseSize = 0 | |||||
| subjectWithCoursePackMap.get(subjectId)?.forEach { | |||||
| totalCourseSize += it.childrenCourses.size | |||||
| } | |||||
| val totalCourseSize = getSubjectForCourseSize(subjectId) | |||||
| if (totalCourseSize == 0) return 0.0 | if (totalCourseSize == 0) return 0.0 | ||||
| return totalProgress / totalCourseSize | return totalProgress / totalCourseSize | ||||
| } | } | ||||
| /** | |||||
| * 获取对应项目的课程数量 | |||||
| * @param subjectId Int 项目 | |||||
| * @return Int 课程数量 | |||||
| */ | |||||
| private fun getSubjectForCourseSize(subjectId : Int) : Int { | |||||
| return subjectWithCoursePackMap[subjectId]?.let { | |||||
| var count = 0 | |||||
| it.forEach { coursePack -> | |||||
| count += coursePack.childrenCourses.size ?: 0 | |||||
| } | |||||
| count | |||||
| } ?: 0 | |||||
| } | |||||
| } | } |
| private const val NORMAL = "XKL_COURSE_DATA_KEY" | private const val NORMAL = "XKL_COURSE_DATA_KEY" | ||||
| private const val SPOKEN = "XKL_SPOKEN_COURSE_DATA_KEY" | private const val SPOKEN = "XKL_SPOKEN_COURSE_DATA_KEY" | ||||
| private const val COMPOSITION = "XKL_LOCAL_COMPOSITION_DATA_KEY" | private const val COMPOSITION = "XKL_LOCAL_COMPOSITION_DATA_KEY" | ||||
| private const val LITERACY = "XKL_LOCAL_CHINESE_COURSE_KEY" | |||||
| private const val LITERACY_PINYING = "XKL_LOCAL_CHINESE_COURSE_KEY" | |||||
| private var mDataBase : SQLiteDatabase? = null | private var mDataBase : SQLiteDatabase? = null | ||||
| private fun open(base : DbControlBase) { | private fun open(base : DbControlBase) { | ||||
| val p = when (base.courseType) { | val p = when (base.courseType) { | ||||
| AppConstants.COURSE_TYPE_CHINESE_COMPOSITION -> COMPOSITION | AppConstants.COURSE_TYPE_CHINESE_COMPOSITION -> COMPOSITION | ||||
| AppConstants.COURSE_TYPE_ENGLISH_SPOKEN -> SPOKEN | AppConstants.COURSE_TYPE_ENGLISH_SPOKEN -> SPOKEN | ||||
| AppConstants.COURSE_TYPE_CHINESE_LITERACY -> LITERACY | |||||
| AppConstants.COURSE_TYPE_CHINESE_LITERACY,AppConstants.COURSE_TYPE_CHINESE_PINYIN -> LITERACY_PINYING | |||||
| else -> NORMAL | else -> NORMAL | ||||
| } | } | ||||
| mDataBase = SQLiteDatabase.openDatabase(FilePathManager.getCourseDbPath(currentBase).path, | mDataBase = SQLiteDatabase.openDatabase(FilePathManager.getCourseDbPath(currentBase).path, | ||||
| when (dbcb.courseType) { | when (dbcb.courseType) { | ||||
| AppConstants.COURSE_TYPE_CHINESE_LITERACY -> { | AppConstants.COURSE_TYPE_CHINESE_LITERACY -> { | ||||
| word = getString(getColumnIndex("word1")) | |||||
| literacyIspolyphone = getInt(getColumnIndex("polyphone")) > 0 | literacyIspolyphone = getInt(getColumnIndex("polyphone")) > 0 | ||||
| phonetic_cn = getString(getColumnIndex("phonetic")) | phonetic_cn = getString(getColumnIndex("phonetic")) | ||||
| } | } |
| import com.jeremyliao.liveeventbus.LiveEventBus | import com.jeremyliao.liveeventbus.LiveEventBus | ||||
| import com.suliang.common.base.activity.BaseActivityVM | import com.suliang.common.base.activity.BaseActivityVM | ||||
| import com.suliang.common.extension.click | import com.suliang.common.extension.click | ||||
| import com.suliang.common.extension.setHtml | |||||
| import com.suliang.common.util.DateUtil | import com.suliang.common.util.DateUtil | ||||
| import com.suliang.common.util.DrawableUti | import com.suliang.common.util.DrawableUti | ||||
| import com.suliang.common.util.image.ImageLoader | import com.suliang.common.util.image.ImageLoader | ||||
| //单词内容 | //单词内容 | ||||
| bindingWord.incWord.tvWord.apply { | bindingWord.incWord.tvWord.apply { | ||||
| //识字需单独处理 | //识字需单独处理 | ||||
| text = if (vm.learnData.lesson.courseType == AppConstants.COURSE_TYPE_CHINESE_LITERACY) ViewUtil.literacyToHtmlWord( | |||||
| learnWord.word, learnWord.showColor) else learnWord.word | |||||
| if (vm.learnData.lesson.courseType == AppConstants.COURSE_TYPE_CHINESE_LITERACY){ | |||||
| setHtml(ViewUtil.literacyToHtmlWord(learnWord.word, learnWord.showColor)) | |||||
| } else { | |||||
| text = learnWord.word | |||||
| } | |||||
| setTextColor(ContextCompat.getColor(this@LearnWordActivity, learnWord.showColor)) //单词显示颜色 | setTextColor(ContextCompat.getColor(this@LearnWordActivity, learnWord.showColor)) //单词显示颜色 | ||||
| } | } | ||||
| //音标 | //音标 | ||||
| //单词内容 | //单词内容 | ||||
| bindingWord.incWord.tvWord.apply { | bindingWord.incWord.tvWord.apply { | ||||
| //识字需单独处理 | //识字需单独处理 | ||||
| text = if (vm.learnData.lesson.courseType == AppConstants.COURSE_TYPE_CHINESE_LITERACY) ViewUtil.literacyToHtmlWord( | |||||
| learnWord.word, learnWord.showColor) else learnWord.word | |||||
| if (vm.learnData.lesson.courseType == AppConstants.COURSE_TYPE_CHINESE_LITERACY) { | |||||
| setHtml(ViewUtil.literacyToHtmlWord(learnWord.word, learnWord.showColor)) | |||||
| } else { | |||||
| text = learnWord.word | |||||
| } | |||||
| setTextColor(ContextCompat.getColor(this@LearnWordActivity, learnWord.showColor)) //单词显示颜色 | setTextColor(ContextCompat.getColor(this@LearnWordActivity, learnWord.showColor)) //单词显示颜色 | ||||
| } | } | ||||
| //音标 | //音标 | ||||
| binding.incControlButton.tvCenter.visibility = View.VISIBLE | binding.incControlButton.tvCenter.visibility = View.VISIBLE | ||||
| //音标,显示重读 | //音标,显示重读 | ||||
| when(vm.learnData.lesson.coursePackType){ | when(vm.learnData.lesson.coursePackType){ | ||||
| AppConstants.COURSEPACK_TYPE_ENGLISH_SOUNDMARK -> View.VISIBLE | |||||
| AppConstants.COURSEPACK_TYPE_ENGLISH_SOUNDMARK ->binding.incControlButton.tvRight.visibility = View.VISIBLE | |||||
| } | } | ||||
| } | } |
| when { | when { | ||||
| //学后总测试完成,默认无选中 | //学后总测试完成,默认无选中 | ||||
| courseDetail.st_after != AppConstants.NOT_DOING -> temposition = -1 | courseDetail.st_after != AppConstants.NOT_DOING -> temposition = -1 | ||||
| //进度100 | |||||
| courseDetail.courseLearnProgress == AppConstants.DOING_OVER -> temposition = -1 | |||||
| //有学习点 | //有学习点 | ||||
| courseDetail.course_learn_point.isNotEmpty() -> { | courseDetail.course_learn_point.isNotEmpty() -> { | ||||
| run m@{ | run m@{ | ||||
| allLesson.forEachIndexed { index, lesson -> | allLesson.forEachIndexed { index, lesson -> | ||||
| if ("${lesson.chapterId}_${lesson.lessonId}" == courseDetail.course_learn_point) { | |||||
| if (courseDetail.course_learn_point.startsWith("${lesson.chapterId}_${lesson.lessonId}_")) { | |||||
| temposition = index | temposition = index | ||||
| return@m | return@m | ||||
| } | } |
| } | } | ||||
| override fun loadData() { | override fun loadData() { | ||||
| when (totalTestType) { | |||||
| AppConstants.TEST_TYPE_BEFORE_TOTAL -> vm.loadTest(totalTestType).observe(this) { | |||||
| initTotalBeforeView(it) | |||||
| vm.loadTest(totalTestType).observe(this) { | |||||
| binding.tvCountTip.text = CourseManager.expectedTestTime(vm.course.courseType, totalTestType, it) | |||||
| when (totalTestType) { | |||||
| AppConstants.TEST_TYPE_BEFORE_TOTAL -> initTotalBeforeView(it) | |||||
| AppConstants.TEST_TYPE_AFTER_TOTAL -> initTotalAfterView() | |||||
| } | |||||
| } | |||||
| } | |||||
| /** 学前测试初始 */ | |||||
| private fun initTotalBeforeView(testData : List<ExamBean>) { | |||||
| //学前总测 | |||||
| binding.run { | |||||
| tvTitle.setText(R.string.test_total_before_title) | |||||
| // button1.run { | |||||
| // setText(R.string.start_learn) | |||||
| // visibility = View.VISIBLE | |||||
| // click { | |||||
| // continueLearn(it) | |||||
| // } | |||||
| // } | |||||
| //按钮初始 | |||||
| button2.run { | |||||
| setText(R.string.start_test) | |||||
| click { view -> | |||||
| startTest(view) | |||||
| } | |||||
| } | } | ||||
| AppConstants.TEST_TYPE_AFTER_TOTAL -> initTotalAfterView() | |||||
| } | } | ||||
| } | } | ||||
| tvTitle.setText(R.string.tips_current_course_learn_over) | tvTitle.setText(R.string.tips_current_course_learn_over) | ||||
| tvMainTip.visibility = View.VISIBLE | tvMainTip.visibility = View.VISIBLE | ||||
| //根据测试成绩处理 | //根据测试成绩处理 | ||||
| vm.courseDetail.st_before.let { | |||||
| vm.courseDetail.st_after.let { | |||||
| when (it) { | when (it) { | ||||
| AppConstants.NOT_DOING -> { //未测 | AppConstants.NOT_DOING -> { //未测 | ||||
| tvMainTip.setText(R.string.test_total_after_tip_1) | tvMainTip.setText(R.string.test_total_after_tip_1) | ||||
| button1.run { | |||||
| visibility = View.VISIBLE | |||||
| setText(R.string.start_learn) | |||||
| click { | |||||
| continueLearn(it) | |||||
| } | |||||
| } | |||||
| button2.run { | button2.run { | ||||
| setText(R.string.test_type_after_total) | setText(R.string.test_type_after_total) | ||||
| click { view -> | click { view -> | ||||
| } | } | ||||
| } | } | ||||
| /** 学前测试初始 */ | |||||
| private fun initTotalBeforeView(testData : List<ExamBean>) { | |||||
| // TODO: 2022/4/21 需要把开始学习给取消了 | |||||
| binding.tvCountTip.text = CourseManager.expectedTestTime(vm.course.courseType, totalTestType, testData) | |||||
| binding.button1.visibility = View.VISIBLE | |||||
| //学前总测 | |||||
| binding.run { | |||||
| tvTitle.setText(R.string.test_total_before_title) | |||||
| button1.run { | |||||
| setText(R.string.start_learn) | |||||
| click { | |||||
| continueLearn(it) | |||||
| } | |||||
| } | |||||
| //按钮初始 | |||||
| button2.run { | |||||
| setText(R.string.start_test) | |||||
| click { view -> | |||||
| startTest(view) | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| /**继续学习*/ | /**继续学习*/ | ||||
| private fun continueLearn(view : View) { | private fun continueLearn(view : View) { |
| AppExecutors.io.execute { | AppExecutors.io.execute { | ||||
| //读取课程数据 | //读取课程数据 | ||||
| // TODO: 2022/5/16 读取课程的sort信息进行保存,针对作文课程,同时需要设置其课程包的进度 | |||||
| // TODO: 2022/3/22 读取当前app绑定的课程数据, | // TODO: 2022/3/22 读取当前app绑定的课程数据, | ||||
| DbCoursePackManager().queryBindingCoursePack("262,261,264,136,547,615,516,411") | DbCoursePackManager().queryBindingCoursePack("262,261,264,136,547,615,516,411") | ||||
| //复制课程的数据库到对应位置 | //复制课程的数据库到对应位置 |
| import android.text.Spanned | import android.text.Spanned | ||||
| import android.widget.TextView | import android.widget.TextView | ||||
| import androidx.annotation.ColorInt | import androidx.annotation.ColorInt | ||||
| import androidx.annotation.ColorRes | |||||
| import androidx.core.content.ContextCompat | |||||
| import com.suliang.common.util.AppGlobals | |||||
| import com.suliang.common.util.ColorUtil | import com.suliang.common.util.ColorUtil | ||||
| import com.suliang.common.util.os.ScreenUtil | import com.suliang.common.util.os.ScreenUtil | ||||
| import java.util.regex.Pattern | import java.util.regex.Pattern | ||||
| * @param colorId 处理的颜色id color.xml | * @param colorId 处理的颜色id color.xml | ||||
| * @return Spanned 你好 你为大写 | * @return Spanned 你好 你为大写 | ||||
| */ | */ | ||||
| fun literacyToHtmlWord(word : String, @ColorInt colorId : Int) : Spanned { | |||||
| fun literacyToHtmlWord(word : String, @ColorRes colorId : Int) : String { | |||||
| val m = Pattern.compile("\\([\u4e00-\u9fa5]\\)").matcher(word) | val m = Pattern.compile("\\([\u4e00-\u9fa5]\\)").matcher(word) | ||||
| val builder = StringBuffer() | val builder = StringBuffer() | ||||
| val color : String = ColorUtil.getHexWebString(colorId) | |||||
| val color : String = ColorUtil.getHexWebString(ContextCompat.getColor(AppGlobals.application,colorId)) | |||||
| var isFind = false | var isFind = false | ||||
| var previousEndPosition = 0 //下次循环开始的位置 | var previousEndPosition = 0 //下次循环开始的位置 | ||||
| while (m.find()) { | while (m.find()) { | ||||
| } else { | } else { | ||||
| builder.append("<font color=\"").append(color).append("\">").append(word).append("</font>") | builder.append("<font color=\"").append(color).append("\">").append(word).append("</font>") | ||||
| } | } | ||||
| println(builder.toString()) | |||||
| return Html.fromHtml(builder.toString()) | |||||
| return builder.toString() | |||||
| } | } | ||||
| /** | /** |
| app:layout_constraintTop_toTopOf="@+id/button_2" | app:layout_constraintTop_toTopOf="@+id/button_2" | ||||
| app:strokeColor="@color/theme_color" | app:strokeColor="@color/theme_color" | ||||
| app:strokeWidth="@dimen/line_height" | app:strokeWidth="@dimen/line_height" | ||||
| tools:text="@string/start_learn" | |||||
| android:visibility="gone" | |||||
| /> | /> | ||||
| <Button | <Button |
| package com.suliang.common.util | package com.suliang.common.util | ||||
| import androidx.annotation.ColorInt | |||||
| /** | /** | ||||
| * author suliang | * author suliang | ||||
| * create 2022/4/25 16:29 | * create 2022/4/25 16:29 | ||||
| companion object{ | companion object{ | ||||
| /** | /** | ||||
| * 把一个int颜色值转换成String | * 把一个int颜色值转换成String | ||||
| * @param color | |||||
| * @param color 非直接资源id,而是转换好的资源,getColor or Color.parse | |||||
| * @return | * @return | ||||
| */ | */ | ||||
| fun getHexWebString(color : Int) : String { | |||||
| fun getHexWebString(@ColorInt color : Int) : String { | |||||
| var s = "#" | var s = "#" | ||||
| val colorStr = color and -0x1000000 or (color and 0x00ff0000) or (color and 0x0000ff00) or (color and 0x000000ff) | |||||
| val colorStr = (color and 0xff000000.toInt()) or (color and 0x00ff0000) or (color and 0x0000ff00) or (color and 0x000000ff) | |||||
| var s1 = Integer.toHexString(colorStr) | var s1 = Integer.toHexString(colorStr) | ||||
| s1 = s1.substring(2, s1.length) | s1 = s1.substring(2, s1.length) | ||||
| s = s + s1 | s = s + s1 |