Browse Source

courepack_main,course_main

master
suliang 2 years ago
parent
commit
9787d5fe31
100 changed files with 2984 additions and 248 deletions
  1. 13
    0
      .idea/codeStyles/Project.xml
  2. 20
    0
      .idea/misc.xml
  3. 2
    1
      ProjectErrors.md
  4. 8
    0
      README.md
  5. 4
    0
      app/build.gradle
  6. BIN
      app/libs/mobile_cache.aar
  7. 22
    1
      app/src/main/AndroidManifest.xml
  8. BIN
      app/src/main/assets/52d3b7f2-fff2-11eb-9677-7cd30aeb7e40.db
  9. BIN
      app/src/main/assets/course-pack.db
  10. BIN
      app/src/main/assets/course_spoken.db
  11. BIN
      app/src/main/assets/d166b57b-21c7-4c58-a78d-748a57941052.db
  12. 45
    0
      app/src/main/java/com/xkl/cdl/adapter/AdapterAutoPlaySelectRepeat.kt
  13. 9
    15
      app/src/main/java/com/xkl/cdl/adapter/AdapterCoursePackWithLearCenter.kt
  14. 135
    0
      app/src/main/java/com/xkl/cdl/adapter/AdapterLesson.kt
  15. 63
    10
      app/src/main/java/com/xkl/cdl/data/AppConstants.kt
  16. 35
    0
      app/src/main/java/com/xkl/cdl/data/DataTransferHolder.kt
  17. 64
    0
      app/src/main/java/com/xkl/cdl/data/bean/BaseWord.kt
  18. 12
    0
      app/src/main/java/com/xkl/cdl/data/bean/IntentLearnData.kt
  19. 44
    0
      app/src/main/java/com/xkl/cdl/data/bean/LearnWord.kt
  20. 0
    19
      app/src/main/java/com/xkl/cdl/data/bean/Lesson.kt
  21. 4
    4
      app/src/main/java/com/xkl/cdl/data/bean/course/Course.kt
  22. 38
    0
      app/src/main/java/com/xkl/cdl/data/bean/course/CourseDetail.kt
  23. 3
    1
      app/src/main/java/com/xkl/cdl/data/bean/course/CoursePack.kt
  24. 69
    0
      app/src/main/java/com/xkl/cdl/data/bean/course/Lesson.kt
  25. 1
    5
      app/src/main/java/com/xkl/cdl/data/binding/BindingAdapter.kt
  26. 27
    7
      app/src/main/java/com/xkl/cdl/data/manager/CourseManager.kt
  27. 36
    0
      app/src/main/java/com/xkl/cdl/data/manager/FilePathManager.kt
  28. 0
    10
      app/src/main/java/com/xkl/cdl/data/manager/db/CompositionDbManager.kt
  29. 146
    7
      app/src/main/java/com/xkl/cdl/data/manager/db/DBCourseManager.kt
  30. 12
    0
      app/src/main/java/com/xkl/cdl/data/manager/db/DbControlBase.kt
  31. 15
    9
      app/src/main/java/com/xkl/cdl/data/manager/db/DbCoursePackManager.kt
  32. 0
    11
      app/src/main/java/com/xkl/cdl/data/manager/db/EnglishDbManager.kt
  33. 0
    32
      app/src/main/java/com/xkl/cdl/data/manager/db/IDB.kt
  34. 37
    0
      app/src/main/java/com/xkl/cdl/data/repository/AudioCache.kt
  35. 51
    0
      app/src/main/java/com/xkl/cdl/data/repository/DataRepository.kt
  36. 87
    0
      app/src/main/java/com/xkl/cdl/dialog/LearnDialog.kt
  37. 22
    0
      app/src/main/java/com/xkl/cdl/module/learn/LearnBaseActivity.kt
  38. 12
    0
      app/src/main/java/com/xkl/cdl/module/learn/LearnBaseViewModel.kt
  39. 3
    6
      app/src/main/java/com/xkl/cdl/module/learn/LearnCReadingActivity.kt
  40. 12
    0
      app/src/main/java/com/xkl/cdl/module/learn/LearnCTaskActivity.kt
  41. 12
    0
      app/src/main/java/com/xkl/cdl/module/learn/LearnCVideoActivity.kt
  42. 12
    0
      app/src/main/java/com/xkl/cdl/module/learn/LearnExamSpellActivity.kt
  43. 12
    0
      app/src/main/java/com/xkl/cdl/module/learn/LearnExamWordActivity.kt
  44. 12
    0
      app/src/main/java/com/xkl/cdl/module/learn/LearnSpellActivity.kt
  45. 12
    0
      app/src/main/java/com/xkl/cdl/module/learn/LearnWordActivity.kt
  46. 0
    13
      app/src/main/java/com/xkl/cdl/module/m_center_learn/CourseMainActivityViewModel.kt
  47. 6
    6
      app/src/main/java/com/xkl/cdl/module/m_center_learn/CoursePackFragment.kt
  48. 1
    1
      app/src/main/java/com/xkl/cdl/module/m_center_learn/CoursePackFragmentViewModel.kt
  49. 283
    0
      app/src/main/java/com/xkl/cdl/module/m_center_learn/CoursePackMainActivity.kt
  50. 21
    0
      app/src/main/java/com/xkl/cdl/module/m_center_learn/CoursePackMainActivityViewModel.kt
  51. 3
    3
      app/src/main/java/com/xkl/cdl/module/m_center_learn/LearnCenterFragmentViewModel.kt
  52. 86
    0
      app/src/main/java/com/xkl/cdl/module/m_center_learn/coursechildren/CourseLessonFragment.kt
  53. 79
    0
      app/src/main/java/com/xkl/cdl/module/m_center_learn/coursechildren/CourseMainFragment.kt
  54. 90
    0
      app/src/main/java/com/xkl/cdl/module/m_center_learn/coursechildren/CourseMainFragmentViewModel.kt
  55. 46
    0
      app/src/main/java/com/xkl/cdl/module/m_center_learn/coursechildren/CourseReviewFragment.kt
  56. 133
    0
      app/src/main/java/com/xkl/cdl/module/m_center_learn/coursechildren/CourseTotalTestFragment.kt
  57. 49
    13
      app/src/main/java/com/xkl/cdl/module/splash/SplashActivity.kt
  58. 6
    0
      app/src/main/res/color/selectpress_maintextcolor_to_themcolor.xml
  59. 5
    0
      app/src/main/res/drawable/shape_rounder_12_white.xml
  60. 12
    7
      app/src/main/res/layout/activity_course_main.xml
  61. 9
    0
      app/src/main/res/layout/activity_exam_learn_spell.xml
  62. 9
    0
      app/src/main/res/layout/activity_learn_creading.xml
  63. 9
    0
      app/src/main/res/layout/activity_learn_ctask.xml
  64. 9
    0
      app/src/main/res/layout/activity_learn_cvideo.xml
  65. 9
    0
      app/src/main/res/layout/activity_learn_exam_word.xml
  66. 9
    0
      app/src/main/res/layout/activity_learn_spell.xml
  67. 9
    0
      app/src/main/res/layout/activity_learn_word.xml
  68. 54
    0
      app/src/main/res/layout/dialog_bottom_auto_play_select.xml
  69. 64
    0
      app/src/main/res/layout/dialog_bottom_course_more.xml
  70. 25
    0
      app/src/main/res/layout/dialog_item_select_repeat.xml
  71. 204
    0
      app/src/main/res/layout/dialog_lesson_learn.xml
  72. 65
    0
      app/src/main/res/layout/fragment_course_lesson.xml
  73. 9
    0
      app/src/main/res/layout/fragment_course_main.xml
  74. 66
    0
      app/src/main/res/layout/fragment_course_review.xml
  75. 136
    0
      app/src/main/res/layout/fragment_course_total_test.xml
  76. 76
    0
      app/src/main/res/layout/inc_over_number.xml
  77. 55
    48
      app/src/main/res/layout/include_main_learn_center_course_progress.xml
  78. 12
    3
      app/src/main/res/layout/include_main_learn_center_course_type_title.xml
  79. 7
    3
      app/src/main/res/layout/include_title_bar.xml
  80. 98
    0
      app/src/main/res/layout/item_course_lesson.xml
  81. 1
    1
      app/src/main/res/layout/main_item_coursepack.xml
  82. BIN
      app/src/main/res/mipmap-xxhdpi/boy_1.png
  83. BIN
      app/src/main/res/mipmap-xxhdpi/boy_2.png
  84. BIN
      app/src/main/res/mipmap-xxhdpi/boy_3.png
  85. BIN
      app/src/main/res/mipmap-xxhdpi/girl_1.png
  86. BIN
      app/src/main/res/mipmap-xxhdpi/girl_2.png
  87. 3
    0
      app/src/main/res/values-land/dimens.xml
  88. 3
    0
      app/src/main/res/values-w1240dp/dimens.xml
  89. 3
    0
      app/src/main/res/values-w600dp/dimens.xml
  90. 13
    0
      app/src/main/res/values/colors.xml
  91. 3
    0
      app/src/main/res/values/dimens.xml
  92. 37
    0
      app/src/main/res/values/strings.xml
  93. 26
    0
      app/src/main/res/values/styles.xml
  94. 15
    6
      app/src/main/res/values/themes.xml
  95. 4
    1
      build.gradle
  96. 4
    0
      lib/common/build.gradle
  97. 1
    1
      lib/common/src/main/java/com/suliang/common/AppConfig.kt
  98. 3
    1
      lib/common/src/main/java/com/suliang/common/base/BaseDialogFragment.kt
  99. 3
    3
      lib/common/src/main/java/com/suliang/common/base/LoadingDialog.kt
  100. 0
    0
      lib/common/src/main/java/com/suliang/common/base/activity/BaseActivity.kt

+ 13
- 0
.idea/codeStyles/Project.xml View File

@@ -25,6 +25,12 @@
</formatting-settings>
</DBN-SQL>
<JetCodeStyleSettings>
<option name="CONTINUATION_INDENT_IN_PARAMETER_LISTS" value="true" />
<option name="CONTINUATION_INDENT_FOR_EXPRESSION_BODIES" value="true" />
<option name="CONTINUATION_INDENT_IN_SUPERTYPE_LISTS" value="true" />
<option name="WRAP_EXPRESSION_BODY_FUNCTIONS" value="0" />
<option name="WRAP_ELVIS_EXPRESSIONS" value="0" />
<option name="IF_RPAREN_ON_NEW_LINE" value="false" />
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
</JetCodeStyleSettings>
<DBN-PSQL>
@@ -168,6 +174,13 @@
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
<option name="RIGHT_MARGIN" value="120" />
<option name="KEEP_LINE_BREAKS" value="false" />
<option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" />
<option name="ALIGN_MULTILINE_METHOD_BRACKETS" value="true" />
<option name="CALL_PARAMETERS_LPAREN_ON_NEXT_LINE" value="false" />
<option name="CALL_PARAMETERS_RPAREN_ON_NEXT_LINE" value="false" />
<option name="METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE" value="false" />
<option name="METHOD_PARAMETERS_RPAREN_ON_NEXT_LINE" value="false" />
<option name="EXTENDS_LIST_WRAP" value="0" />
</codeStyleSettings>
</code_scheme>
</component>

+ 20
- 0
.idea/misc.xml View File

@@ -7,6 +7,7 @@
<entry key="..\:/Work/XKL/XKL/XklLocal/app/drawable/svg/drawable/ic_discern.xml" value="0.3223958333333333" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/drawable/svg/drawable/ic_nav_learn_center.xml" value="0.3223958333333333" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/drawable/svg/drawable/ic_nav_my.xml" value="0.3223958333333333" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/dialog_bottom_bg.xml" value="0.5140625" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/et_search_bg.xml" value="0.175" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/ic_delete.xml" value="0.30520833333333336" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/ic_discern.xml" value="0.30520833333333336" />
@@ -22,18 +23,35 @@
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/nav_service.xml" value="0.30520833333333336" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/nav_statistics.xml" value="0.1" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/progress_center.xml" value="0.287962962962963" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/shape_rounder_12_white.xml" value="0.5140625" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/shape_rounder_toplr_24_white.xml" value="0.5061538461538462" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/spoken_autoplay_btn_text_color_.xml" value="0.5140625" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/theme_splash_bg.xml" value="0.30520833333333336" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout-v23/include_main_learn_center_course_type_title.xml" value="0.4963768115942029" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/activity_course_main.xml" value="0.33" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/activity_learn_base.xml" value="0.4979166666666667" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/activity_learn_word2.xml" value="0.4979166666666667" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/activity_main.xml" value="0.5" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/activity_splash.xml" value="0.4921875" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/content_learn_base.xml" value="0.4979166666666667" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/dialog_bottom_auto_play_select.xml" value="0.4979166666666667" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/dialog_bottom_course_more.xml" value="0.33" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/dialog_item_select_repeat.xml" value="0.4979166666666667" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/dialog_lesson_learn.xml" value="0.4144927536231884" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/fragment_course_lesson.xml" value="0.33" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/fragment_course_main.xml" value="0.4979166666666667" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/fragment_course_pack.xml" value="0.34427083333333336" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/fragment_course_review.xml" value="0.12802768166089964" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/fragment_course_total_test.xml" value="0.33" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/fragment_first.xml" value="0.4979166666666667" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/fragment_learn_center.xml" value="0.25" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/fragment_my.xml" value="0.28229166666666666" />
<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/include_main_learn_center_course_progress.xml" value="0.503125" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/include_main_learn_center_course_type_title.xml" value="0.67" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/include_recyclerview_smart_refresh_layout.xml" value="0.4979166666666667" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/include_title_bar.xml" value="0.25052083333333336" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/item_course_lesson.xml" value="0.4785615491009682" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/item_empty.xml" value="0.4979166666666667" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/main_item_course_progress.xml" value="0.25" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/main_item_coursepack.xml" value="0.43500866551126516" />
@@ -42,6 +60,7 @@
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/textview.xml" value="0.49773550724637683" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/textview_only.xml" value="0.49773550724637683" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/statedrawable/drawable/ic_nav_learn_center.xml" value="0.44166666666666665" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/svg/drawable/ic_arrow_right.xml" value="0.29814814814814816" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/svg/drawable/ic_discern.xml" value="0.5061538461538462" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/svg/drawable/ic_icon___.xml" value="0.287962962962963" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/svg/drawable/ic_nav_learn_center.xml" value="0.44166666666666665" />
@@ -55,6 +74,7 @@
<entry key="..\:/Work/XKL/XKL/XklLocal/lib/common/src/main/res/drawable/ic_back.xml" value="0.4148148148148148" />
<entry key="..\:/Work/XKL/XKL/XklLocal/lib/common/src/main/res/drawable/ic_search.xml" value="0.19814814814814816" />
<entry key="..\:/Work/XKL/XKL/XklLocal/lib/common/src/main/res/drawable/loading_bg.xml" value="0.5061538461538462" />
<entry key="..\:/Work/XKL/XKL/XklLocal/lib/common/src/main/res/layout/item_empty.xml" value="0.34427083333333336" />
<entry key="..\:/Work/XKL/XKL/XklLocal/lib/common/src/main/res/layout/lib_dialog_loading.xml" value="0.4979166666666667" />
<entry key="..\:/Work/XKL/XKL/XklLocal/lib/common/src/main/res/layout/lib_layout_custom_title.xml" value="0.4979166666666667" />
<entry key="..\:/Work/XKL/XKL/XklLocal/lib/common/src/main/res/layout/loadding_fragment.xml" value="0.4817708333333333" />

+ 2
- 1
ProjectErrors.md View File

@@ -45,4 +45,5 @@ google 给与的唯一标识符最佳做法:
3、尽一切可能针对防欺诈支付和电话以外的所有其他用例使用实例 ID 或私密存储的 GUID。对于绝大多数非广告用例,使用实例 ID 或 GUID 应已足够。
4、使用适合您的用例的 API 以尽量降低隐私权风险

如何实现防快速点击 aspectJ
如何实现防快速点击 aspectJ


+ 8
- 0
README.md View File

@@ -43,3 +43,11 @@ Kotlin的单例模式: https://developer.aliyun.com/article/642618
饿汉式(直接获取实例)、懒汉式(一次判空获取实例)、双重校验锁
object 声明: 为饿汉式单例,即直接实例
数字精度格式: https://www.jianshu.com/p/5286a44ed9b1
Material Design Components 组件使用 https://www.jianshu.com/p/bc71b4179cb2

// Android Gradle 插件 4.0,下述配置不再是必需的,并且会导致构建失败。外部原生 build 现在会自动打包这些库,因此使用 jniLibs 明确打包库会导致重复。
// sourceSets {
// main {
// jniLibs.srcDirs = ['libs']
// }
// }

+ 4
- 0
app/build.gradle View File

@@ -68,6 +68,7 @@ android {
}

dependencies {
implementation fileTree(include: ['*.jar',"*.aar"], dir: 'libs')
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation project(path: ':lib:common')
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.1'
@@ -75,6 +76,9 @@ dependencies {
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.3.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.5'
implementation 'androidx.navigation:navigation-ui-ktx:2.3.5'

rootProject.ext.dependencies_required.each{ k, v -> implementation v}
testImplementation rootProject.ext.dependencies_testImplementation.junit
rootProject.ext.dependencies_androidTestImplementation.each{ k,v -> androidTestImplementation v}

BIN
app/libs/mobile_cache.aar View File


+ 22
- 1
app/src/main/AndroidManifest.xml View File

@@ -13,7 +13,28 @@
android:theme="@style/Theme.XklLocal"
tools:ignore="LockedOrientationActivity">
<activity
android:name=".module.m_center_learn.CourseMainActivity"
android:name=".module.learn.LearnCTaskActivity"
android:exported="true" />
<activity
android:name=".module.learn.LearnCReadingActivity"
android:exported="true" />
<activity
android:name=".module.learn.LearnCVideoActivity"
android:exported="true" />
<activity
android:name=".module.learn.LearnExamSpellActivity"
android:exported="true" />
<activity
android:name=".module.learn.LearnExamWordActivity"
android:exported="true" />
<activity
android:name=".module.learn.LearnSpellActivity"
android:exported="true" />
<activity
android:name=".module.learn.LearnWordActivity"
android:exported="true" />
<activity
android:name=".module.m_center_learn.CoursePackMainActivity"
android:exported="true" />
<activity
android:name=".module.splash.SplashActivity"

BIN
app/src/main/assets/52d3b7f2-fff2-11eb-9677-7cd30aeb7e40.db View File


BIN
app/src/main/assets/course-pack.db View File


BIN
app/src/main/assets/course_spoken.db View File


BIN
app/src/main/assets/d166b57b-21c7-4c58-a78d-748a57941052.db View File


+ 45
- 0
app/src/main/java/com/xkl/cdl/adapter/AdapterAutoPlaySelectRepeat.kt View File

@@ -0,0 +1,45 @@
package com.xkl.cdl.adapter

import android.view.ViewGroup
import com.suliang.common.base.adapter.BaseAdapterViewHolder
import androidx.viewbinding.ViewBinding
import com.suliang.common.base.adapter.BaseAdapter
import com.suliang.common.extension.click
import com.xkl.cdl.R
import com.xkl.cdl.databinding.DialogItemSelectRepeatBinding

/**
* author suliang
* create 2020/6/29 13:44
* Describe: 自动播放弹窗列表选择适配器
*/
class AdapterAutoPlaySelectRepeat : BaseAdapter<Void?>() {
override fun coverEmptyViewHolder(parent: ViewGroup): BaseAdapterViewHolder {
return BaseAdapterViewHolder(inflateBinding(parent, R.layout.item_empty))
}

override fun onBindEmptyViewHolder(holder: BaseAdapterViewHolder) {}

override fun getItemCount(): Int {
return 5
}

override fun coverViewHolder(parent: ViewGroup, viewType: Int): BaseAdapterViewHolder {
val binding = inflateBinding(parent, R.layout.dialog_item_select_repeat)
return BaseAdapterViewHolder(binding)
}

override fun onBindVH(holder: BaseAdapterViewHolder, position: Int) {
val binding = holder.binding as DialogItemSelectRepeatBinding
when (position) {
0 -> binding.tvOption.setText(R.string.auto_play_repeat_1)
1 -> binding.tvOption.setText(R.string.auto_play_repeat_2)
2 -> binding.tvOption.setText(R.string.auto_play_repeat_3)
3 -> binding.tvOption.setText(R.string.auto_play_repeat_4)
4 -> binding.tvOption.setText(R.string.auto_play_repeat_5)
}
binding.root.click {
onItemClick.invoke(it,position,null)
}
}
}

+ 9
- 15
app/src/main/java/com/xkl/cdl/adapter/AdapterCoursePackWithLearCenter.kt View File

@@ -1,15 +1,14 @@
package com.xkl.cdl.adapter

import android.opengl.Visibility
import android.view.View
import android.view.ViewGroup
import com.suliang.common.base.adapter.BaseAdapterVM
import com.suliang.common.base.adapter.BaseAdapterViewHolder
import com.suliang.common.databinding.ItemEmptyBinding
import com.suliang.common.extension.click
import com.xkl.cdl.R
import com.xkl.cdl.data.Constants
import com.xkl.cdl.data.course.CoursePack
import com.xkl.cdl.databinding.ItemEmptyBinding
import com.xkl.cdl.data.AppConstants
import com.xkl.cdl.data.bean.course.CoursePack
import com.xkl.cdl.databinding.MainItemCoursepackBinding
import com.xkl.cdl.module.m_center_learn.CoursePackFragmentViewModel

@@ -21,11 +20,6 @@ import com.xkl.cdl.module.m_center_learn.CoursePackFragmentViewModel
class AdapterCoursePackWithLearCenter(vm: CoursePackFragmentViewModel) :
BaseAdapterVM<CoursePack, CoursePackFragmentViewModel>(vm) {


override fun coverEmptyViewHolder(parent: ViewGroup): BaseAdapterViewHolder {
return BaseAdapterViewHolder(inflateBinding(parent, R.layout.item_empty))
}

override fun onBindEmptyViewHolder(holder: BaseAdapterViewHolder) {
(holder.binding as ItemEmptyBinding).apply {
val nullOrEmpty = vm.learnCenterFragmentViewModel.mCoursePackSearchValueMap[vm.projectId].isNullOrEmpty()
@@ -46,8 +40,8 @@ class AdapterCoursePackWithLearCenter(vm: CoursePackFragmentViewModel) :
imageViewTypeVoice.visibility = View.GONE
coursePack = getItem(position).also { cp ->
when (vm.projectId) {
Constants.SUBJECT_ENGLISH -> initEnglish(this, cp, position)
Constants.SUBJECT_CHINESE -> initChinese(this, cp, position)
AppConstants.SUBJECT_ENGLISH -> initEnglish(this, cp, position)
AppConstants.SUBJECT_CHINESE -> initChinese(this, cp, position)
}
root.click {
onItemClick.invoke(it, position, cp)
@@ -65,15 +59,15 @@ class AdapterCoursePackWithLearCenter(vm: CoursePackFragmentViewModel) :
//图标
coursePack.childrenCourses.forEach {
when(it.courseType){
Constants.COURSE_TYPE_ENGLISH_DISCERN -> imageViewTypeDiscern.visibility = View.VISIBLE
Constants.COURSE_TYPE_ENGLISH_SPELL -> imageViewTypeSpell.visibility = View.VISIBLE
Constants.COURSE_TYPE_ENGLISH_VOICE -> {
AppConstants.COURSE_TYPE_ENGLISH_DISCERN -> imageViewTypeDiscern.visibility = View.VISIBLE
AppConstants.COURSE_TYPE_ENGLISH_SPELL -> imageViewTypeSpell.visibility = View.VISIBLE
AppConstants.COURSE_TYPE_ENGLISH_VOICE -> {
imageViewTypeVoice.run {
visibility = View.VISIBLE
setImageResource(R.drawable.ic_voice)
}
}
Constants.COURSE_TYPE_ENGLISH_SPOKEN -> {
AppConstants.COURSE_TYPE_ENGLISH_SPOKEN -> {
imageViewTypeVoice.run{
visibility = View.VISIBLE
setImageResource(R.drawable.ic_spoken)

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

@@ -0,0 +1,135 @@
package com.xkl.cdl.adapter

import android.content.res.ColorStateList
import android.view.View
import android.view.ViewGroup
import androidx.core.content.ContextCompat
import com.suliang.common.base.adapter.BaseAdapterVM
import com.suliang.common.base.adapter.BaseAdapterViewHolder
import com.suliang.common.extension.click
import com.xkl.cdl.R
import com.xkl.cdl.data.AppConstants
import com.xkl.cdl.data.bean.course.Lesson
import com.xkl.cdl.databinding.ItemCourseLessonBinding
import com.xkl.cdl.module.m_center_learn.coursechildren.CourseMainFragmentViewModel


/**
* author suliang
* create 2022/3/29 16:43
* Describe: 课程课时列表适配器
*/
class AdapterLesson(vm: CourseMainFragmentViewModel) : BaseAdapterVM<Lesson, CourseMainFragmentViewModel>(vm) {

/** 选中item的位置 */
var selectPos = -1

override fun coverViewHolder(parent: ViewGroup, viewType: Int): BaseAdapterViewHolder {
return BaseAdapterViewHolder(inflateBinding(parent, R.layout.item_course_lesson))
}

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
}
//执行
executePendingBindings()
initColor(position, lesson)
when(lesson.lessonType){
AppConstants.LESSON_TYPE_COMPOSITION_VIDEO -> { // 作文视频
}
AppConstants.LESSON_TYPE_COMPOSITION_EXAM -> { //作文章节测试

}
AppConstants.LESSON_TYPE_COMPOSITION_READING -> { //作文课堂练习

}
AppConstants.LESSON_TYPE_COMPOSITION_TASK -> { //作文课外练习

}
AppConstants.LESSON_TYPE_DIALOGUE -> { //口语对话

}

else -> { } // 其他课时类型为布局的正常显示
}





//事件: 将章节名称的点击事件取消了
layoutContent.click {
//选中项非当前项,则需要改变选中颜色,直接通知更新,调用对应位置的notfy
if (selectPos != position) {
notifyItemChanged(selectPos)
selectPos = position
notifyItemChanged(selectPos)
}
notifyItemChanged(position)
notifyItemChanged(position, null)
onItemClick.invoke(it, position, lesson)
}
}
}

/**
* 处理颜色 选中色 未选中色(学习完成/学习未完成)
* @receiver ItemCourseLessonBinding
* @param position Int
* @param lesson Lesson
*/
private fun ItemCourseLessonBinding.initColor(position: Int, lesson: Lesson) {
val normalColorNotLearnOver = ContextCompat.getColor(context, R.color.gray_2) //学习未完成未选中时的颜色
val normalColorLearnOver = ContextCompat.getColor(context, R.color.gray_1) //学习已完成未选中时的颜色
val mainTextColor = ContextCompat.getColor(context, R.color.main_text_color) //选中颜色
val translationColor = ContextCompat.getColor(context, R.color.translation) //透明颜色
//item的背景和状态设置
if (selectPos == position) { //选中,背景设置
layoutContent.setBackgroundColor(ContextCompat.getColor(context, R.color.gray_3)) //选中背景
tvLessonName.run {
setTextColor(mainTextColor) //课时名称颜色
paint.isFakeBoldText = true//加粗
}
tvLessonNumber.setTextColor(normalColorNotLearnOver) //数量颜色
//箭头
ivArrowRight.apply {
setBackgroundColor(ContextCompat.getColor(context, R.color.theme_color))
imageTintList = ColorStateList.valueOf(ContextCompat.getColor(context, R.color.white))
strokeColor = ColorStateList.valueOf(translationColor)
}
} else { //未选中:根据学习情况判断
layoutContent.setBackgroundColor(translationColor) //未选中背景透明
if (lesson.learnIsOver) {
tvLessonName.run {
setTextColor(normalColorLearnOver) //课时名称颜色
paint.isFakeBoldText = false //加粗
}
tvLessonNumber.setTextColor(normalColorLearnOver) //数量颜色
ivArrowRight.run {
setBackgroundColor(translationColor)
imageTintList = ColorStateList.valueOf(ContextCompat.getColor(context, R.color.theme_color))
strokeColor = ColorStateList.valueOf(ContextCompat.getColor(context, R.color.theme_color))
}
} else {
tvLessonName.run {
setTextColor(normalColorNotLearnOver) //课时名称颜色
paint.isFakeBoldText = false //加粗
}
tvLessonNumber.setTextColor(normalColorNotLearnOver) //数量颜色
ivArrowRight.run {
setBackgroundColor(translationColor)
imageTintList = ColorStateList.valueOf(normalColorNotLearnOver)
strokeColor = ColorStateList.valueOf(normalColorNotLearnOver)
}
}
}
}
}

app/src/main/java/com/xkl/cdl/data/Constants.kt → app/src/main/java/com/xkl/cdl/data/AppConstants.kt View File

@@ -5,61 +5,114 @@ package com.xkl.cdl.data
* create 2022/3/18 9:34
* Describe:
*/
object Constants {
object AppConstants {


/** 项目: 英语 */
const val SUBJECT_ENGLISH = 3

/** 项目: 语文*/
const val SUBJECT_CHINESE = 1

/**课程包类型: categoryId -> 英语单词课程 */
const val COURSEPACK_TYPE_ENGLISH_WORD = 1

/**课程包类型: categoryId -> 英语音标课程 */
const val COURSEPACK_TYPE_ENGLISH_SOUNDMARK = 4

/**课程包类型: categoryId -> 英语口语 */
const val COURSEPACK_TYPE_ENGLISH_SPOKEN = 13

/**课程包类型: categoryId -> 语文作文 */
const val COURSEPACK_TYPE_CHINESE_COMPOSITION = 2

/**课程包类型: categoryId -> 语文识字 */
const val COURSEPACK_TYPE_CHINESE_LITERACY = 3

/**课程包类型: categoryId -> 语文拼音 */
const val COURSEPACK_TYPE_CHINESE_PINYIN = 1


/**课程类型: typeId 英语认读*/
const val COURSE_TYPE_ENGLISH_DISCERN = 1

/**课程类型: typeId 英语辨音*/
const val COURSE_TYPE_ENGLISH_VOICE = 2

/**课程类型: typeId 英语拼写*/
const val COURSE_TYPE_ENGLISH_SPELL = 3

/**课程类型: typeId 英语音标*/
const val COURSE_TYPE_ENGLISH_SOUNDMARK = 6

/**课程类型: typeId 英语口语*/
const val COURSE_TYPE_ENGLISH_SPOKEN = 8

/**课程类型: typeId 语文作文*/
const val COURSE_TYPE_CHINESE_COMPOSITION = 4

/**课程类型: typeId 语文识字*/
const val COURSE_TYPE_CHINESE_LITERACY = 5

/**课程类型: typeId 语文拼音*/
const val COURSE_TYPE_CHINESE_PINYIN = 7



/**课时类型: 词汇, 口语词汇*/
const val LESSON_TYPE_WORD = 1
const val LESSON_TYPE_WORD = 6

/**课时类型: 口语句型*/
const val LESSON_TYPE_SENTENCE = 2
const val LESSON_TYPE_SENTENCE = 7

/**课时类型: 口语对话*/
const val LESSON_TYPE_DIALOGUE = 3
const val LESSON_TYPE_DIALOGUE = 8

/**课时类型: 作文视频*/
const val COMPOSITION_TYPE_VIDEO = 4 //视频
const val LESSON_TYPE_COMPOSITION_VIDEO = 1 //视频

/**课时类型: 作文知识点学习*/
const val COMPOSITION_TYPE_KNOWLEDGE = 5 //知识点学习
const val LESSON_TYPE_COMPOSITION_KNOWLEDGE = 2 //知识点学习

/**课时类型: 作文知识点测试*/
const val COMPOSITION_TYPE_EXAM = 6 //知识点测试
const val LESSON_TYPE_COMPOSITION_EXAM = 3 //知识点测试

/**课时类型: 作文课堂练习*/
const val COMPOSITION_TYPE_READING = 7 //课堂练习
const val LESSON_TYPE_COMPOSITION_READING = 4 //课堂练习

/**课时类型: 作文课外练习*/
const val COMPOSITION_TYPE_TASK = 8 //课外练习
const val LESSON_TYPE_COMPOSITION_TASK = 5 //课外练习


// 分组(1:普通测试(词汇测试,不做redis统计关联) 2:章节学前测试 3:章节学后测试 4:学前总测试 5:学后总测试 6:备忘录测试(不做redis统计关联);7:作文知识点测试,8:服务中心的课程测试)
/**普通测试(词汇测试,不做redis统计关联)*/
const val TEST_TYPE_NORMAL = 1

/**学前测试*/
const val TEST_TYPE_BEFORE = 2

/**学后测试*/
const val TEST_TYPE_AFTER = 3

/**学前总测试*/
const val TEST_TYPE_BEFORE_TOTAL = 4

/**学后总测试*/
const val TEST_TYPE_AFTER_TOTAL = 5

/**备忘录测试*/
const val TEST_TYPE_MEMO = 6

/**作文知识点测试*/
const val TEST_TYPE_COMPOSITION = 7

/**服务中心的课程测试*/
const val TEST_TYPE_SERVICE_CENTER = 8

/** 未做测试,没有做等用-1表示的内容 */
const val NOT_DOING = -1.0

/** 测试通过:>80 < 90 继续加油 <80 悲伤 */
const val TEST_SCORE_LEVEL_1 = 80
/** 测试通过 >= 太棒了 */
const val TEST_SCORE_LEVEL_2 = 90
}

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

@@ -0,0 +1,35 @@
package com.xkl.cdl.data

import com.suliang.common.AppConfig

/**
* author suliang
* create 2022/3/28 9:52
* Describe: 用于数据传递
*/
class DataTransferHolder private constructor(){

companion object{
val instance by lazy(LazyThreadSafetyMode.SYNCHRONIZED) {
DataTransferHolder()
}
}

private val dataMap = hashMapOf<String,Any>()

fun <T : Any> putData(t : T){
dataMap.put(AppConfig.INTENT_1,t)
}

@Suppress("UNCHECKED_CAST")
fun <T> getData() : T{
return dataMap.get(AppConfig.INTENT_1) as T
}

fun clear(){
dataMap.clear()
}



}

+ 64
- 0
app/src/main/java/com/xkl/cdl/data/bean/BaseWord.kt View File

@@ -0,0 +1,64 @@
package com.xkl.cdl.data.bean

import com.xkl.cdl.R

/**
* 数据基类
* @property subjectId Long 项目id
* @property coursePackId Long 课程包id
* @property courseId Long 课程id
* @property coursePackType Int 课程包类型
* @property courseType Int 课程类型
* @property chapterId Long 章节id
* @property lessonId Long 课时id
* @property wordId Long 内容id
* @property first Boolean 是否第一次出现
* @property reviewNum Int 大七次次数
* @property reviewTime Long 复习时间
* @property createTime Long 创建时间
* @property repeatNum Int 小七次次数
* @property showColor Int 显示颜色
* @property lessonType Int 课时类型
* @constructor
*/
open class BaseWord(val subjectId: Int,
val coursePackId: Long,
val courseId: Long,
val coursePackType: Int,
val courseType: Int,
val chapterId: Long,
val lessonId: Long,
val wordId: Long,
val first: Boolean,
val lessonType: Int) {
/** 大复习次数 */
var reviewNum: Int = 0

/**复习时间*/
var reviewTime: Long = 0

/** 创建时间 */
var createTime: Long = 0


/**重复的次数*/
var repeatNum: Int = 0

/**显示颜色*/
var showColor: Int = 0
get() {
return when (repeatNum) {
0 -> R.color.num0
1 -> R.color.num1
2 -> R.color.num2
3 -> R.color.num3
4 -> R.color.num4
5 -> R.color.num5
6 -> R.color.num6
7 -> R.color.num7
else -> R.color.num0
}
}
private set

}

+ 12
- 0
app/src/main/java/com/xkl/cdl/data/bean/IntentLearnData.kt View File

@@ -0,0 +1,12 @@
package com.xkl.cdl.data.bean

import com.xkl.cdl.data.bean.course.Lesson

/**
* author suliang
* create 2022/4/2 14:55
* Describe: 课时学习时的传参
*/
class IntentLearnData(val lesson: Lesson) {

}

+ 44
- 0
app/src/main/java/com/xkl/cdl/data/bean/LearnWord.kt View File

@@ -0,0 +1,44 @@
package com.xkl.cdl.data.bean

/**
* author suliang
* create 2022/3/31 17:52
* Describe: 用于学习的数据
*/
class LearnWord(subjectId: Int,
coursePackId: Long,
courseId: Long,
coursePackType: Int,
courseType: Int,
chapterId: Long,
lessonId: Long,
wordId: Long,
first: Boolean,
lessonType: Int) : BaseWord(subjectId,
coursePackId,
courseId,
coursePackType,
courseType,
chapterId,
lessonId,
wordId,
first,
lessonType) {


var word: String? = null //词汇
var phonetic_uk: String? = null // 英式音标
var phonetic_us: String? = null // 美式音标
var phonetic_cn: String? = null // 中文拼音
var photo: String? = null // 图片
var audio: String? = null // 音频
var basic_explanation: String? = null //基本释义
var all_explanation: String? = null //扩展释义
var phrase: String? = null //词组
var example: String? = null //例句
var reference: String? = null //参考
var literacyIspolyphone = false //识字课程,是否是多音字标识
var pattern: String? = null //口语: 语法


}

+ 0
- 19
app/src/main/java/com/xkl/cdl/data/bean/Lesson.kt View File

@@ -1,19 +0,0 @@
package com.xkl.cdl.data.bean

/**
* author suliang
* create 2022/3/21 17:10
* Describe:
*/
data class Lesson(
val subjectId: Long,
val coursePackId:Long,
val courseId:Long,
val chapterId:Long,
val chapterName: String,
val lessonId:Long,
val lessonName:String
) {
/** 课时类型 */
var lessonType : Int = 0
}

app/src/main/java/com/xkl/cdl/data/course/Course.kt → app/src/main/java/com/xkl/cdl/data/bean/course/Course.kt View File

@@ -1,6 +1,4 @@
package com.xkl.cdl.data.course

import com.xkl.cdl.data.bean.Lesson
package com.xkl.cdl.data.bean.course

/**
* author suliang
@@ -26,7 +24,9 @@ data class Course(
val totalWords: Int,
val dbPathName: String
) {
var allLesson: ArrayList<Lesson>? = null
var courseLearnProgress : Double = 0.0 //课程学习进度
var courseReviewNumber : Int = 0 //课程复习数


}

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

@@ -0,0 +1,38 @@
package com.xkl.cdl.data.bean.course

import android.R.bool


/**
* author suliang
* create 2022/3/29 9:52
* Describe: 课程学习的详情
*/
class CourseDetail {
var courseLearnProgress: Double = 0.0 //课程学习进度
var st_before: Double = -1.0 //学前总成绩 : -1代表没有进行学前总测试
var st_after: Double = -1.0 //学后总成绩 : -1代表没有进行学后总测试
var before: HashMap<String, Double> = hashMapOf() //章节学前测试成绩,key=>{chapter_id}_{lesson_id} value=>成绩
var after: HashMap<String, Double> = hashMapOf() //章节学后测试成绩,key=>{chapter_id}_{lesson_id} value=>成绩
var right = hashMapOf<String, Int>() //正确条目数,key=>{chapter_id}_{lesson_id} value=>条目数量
var wrong: HashMap<String, Int> = hashMapOf() //错误条目数,key=>{chapter_id}_{lesson_id} value=>条目数量
var lesson_learn_point: HashMap<String, Long> = hashMapOf() //章节学习点 key=>{chapter_id}_{lesson_id} value=>{entity_id)
var exam_w_r_list: HashMap<String, bool> = hashMapOf() //课程/课时学前测试正确错误列表 key=> {chapter_id}_{lesson_id}_{entity_id} value=>正确 true;错误 false
var course_learn_point: String = "" //课程学习进度点 {chapter_id}_{lesson_id}_{entity_id}


var rl: Int = 0 //课程重学次数;有值表示是重新学,默认不是重新学习,对应数值表示第几次重学 用于辨音,拼写判断是否解锁,
var chapter_rl: HashMap<String, Long> = hashMapOf() //章节重学次数,key =>{chapter_id}_{lesson_id} value=> relearn times
var ct: Long = 0 //课程已学词汇量
var e = 0.0 //学习效率
var valid: HashMap<Long, Long> = hashMapOf() //有效学习时长,单位毫秒 key=>分时标记,value=>时长
var review: HashMap<Long, Long> = hashMapOf() //有效复习时长,单位毫秒 key=>分时标记,value=>时长
var total: HashMap<Long, Long> = hashMapOf() //总时长,单位毫秒 key=>分时标记,value=>时长

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() //课程练习进度(仅作文有效)

}

app/src/main/java/com/xkl/cdl/data/course/CoursePack.kt → app/src/main/java/com/xkl/cdl/data/bean/course/CoursePack.kt View File

@@ -1,4 +1,4 @@
package com.xkl.cdl.data.course
package com.xkl.cdl.data.bean.course

import androidx.databinding.BaseObservable
import androidx.databinding.Bindable
@@ -25,6 +25,8 @@ data class CoursePack(
val subjectId: Int,
val coursePackType: Int,
) : BaseObservable() {
//在CourseManger中的subjectWithCoursePackMap对应subject下的list中所在的位置
var inCoursePackPosition : Int = 0

var childrenCourses = mutableListOf<Course>()


+ 69
- 0
app/src/main/java/com/xkl/cdl/data/bean/course/Lesson.kt View File

@@ -0,0 +1,69 @@
package com.xkl.cdl.data.bean.course

import androidx.databinding.BaseObservable
import androidx.databinding.Bindable
import com.suliang.common.BR
import com.xkl.cdl.data.AppConstants

/**
* author suliang
* create 2022/3/21 17:10
* Describe: 课时,通过lessonType判断课时类型
*/
data class Lesson(
val subjectId: Int,
val coursePackId:Long,
val courseId:Long,
var courseType: Int,
val chapterId:Long,
val chapterName: String,
val lessonId:Long,
val lessonName:String
):BaseObservable() {
/** 课时类型 : 默认为单词类型 */
var lessonType : Int = 0
/** 课时在列表中的位置 */
var lessonPositionInList : Int = 0
/** 该课时的总数据 或者作文关联的数据,如视频关联的内容*/
var wordIds = mutableListOf<Long>()
/** 学习进度位置,为医学下标的位置,在作文课堂练习时,学习取当前条,其他取下一条*/
var learnedIndex: Int = 0
/**课时学前测试成绩 */
var beforeTestScore = -1.0
/** 课时学后测试 */
var afterTestScore = -1.0
/**是否学习完成: 为学习内容是否完成,不包含学前,学后测试*/
var learnIsOver = false
/**是否是最后一个课时 */
var lastLesson : Boolean = false

//总数量
@get:Bindable
var totalNumber:Int = 0
set(value) {
field = value
notifyPropertyChanged(BR.totalNumber)
}
//正确数
@get:Bindable
var correctNumber:Int = 0
set(value) {
field = value
notifyPropertyChanged(BR.correctNumber)
}
//错误数
@get:Bindable
var errorNumber:Int = 0
set(value) {
field = value
notifyPropertyChanged(BR.errorNumber)
}


//作文视频使用
/** 视频播放时长 */
var videoPlayTime : Int = 0
/** 视频总时长 */
var videoTotalTime : Int = 0

}

+ 1
- 5
app/src/main/java/com/xkl/cdl/data/binding/BindingAdapter.kt View File

@@ -1,17 +1,13 @@
package com.xkl.cdl.data.binding

import android.graphics.BitmapFactory
import android.graphics.drawable.Drawable
import android.widget.ImageView
import android.widget.TextView
import androidx.core.graphics.drawable.DrawableCompat
import androidx.databinding.BindingAdapter
import com.suliang.common.util.DrawableUti
import com.suliang.common.util.image.ImageLoader
import com.suliang.common.util.image.ImageLoaderOption
import com.xkl.cdl.R
import kotlinx.coroutines.NonCancellable.start
import org.w3c.dom.Text
import java.math.BigDecimal
import java.math.RoundingMode
import java.text.DecimalFormat
@@ -36,7 +32,7 @@ object BindingAdapter {
// view.setImageBitmap(BitmapFactory.decodeByteArray(imageByteArray, 0, imageByteArray.size))
}

@BindingAdapter(value = ["imgByteArray","blur"])
@BindingAdapter(value = ["imgBytes","blur"])
@JvmStatic
fun imageByteArray(view:ImageView,imgByteArray:ByteArray,blur:Boolean){
ImageLoader.loadImage(ImageLoaderOption().apply {

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

@@ -1,9 +1,11 @@
package com.xkl.cdl.data.manager

import com.suliang.common.util.file.FileUtil
import com.xkl.cdl.data.course.Course
import com.xkl.cdl.data.course.CoursePack
import com.xkl.cdl.data.bean.course.CoursePack
import java.io.File
import java.math.BigDecimal
import java.math.RoundingMode
import java.text.DecimalFormat

/**
* author suliang
@@ -73,20 +75,38 @@ object CourseManager {
* 检查课程包下课程的db数据文件是否存在,不存在,则复制过去
*/
fun checkCourseDb() {
subjectWithCoursePackMap.forEach{entry ->
entry.value.forEach{ coursePack ->
subjectWithCoursePackMap.forEach { entry ->
entry.value.forEach { coursePack ->
coursePack.childrenCourses.forEach {
val file = File(
FileUtil.getSaveDirPath("db"),
"${entry.key}/${coursePack.coursePackId}/${it.courseId}/${it.dbPathName}"
"${entry.key}/${coursePack.coursePackId}/${it.courseId}/course.db"
)
//不存在,复制,存在则不操作
if (!file.exists()){
FileUtil.copyAsset(it.dbPathName,file)
if (!file.exists()) {
FileUtil.copyAsset(it.dbPathName, file)
}
}
}
}
}

/**
* 用于显示的进度
* @param progress Double 课程的进度
* @return String
*/
@JvmStatic
fun useToShowProgress(progress: Double): String {
return when {
progress == 0.0 -> "0"
progress < 0.1 -> "0.1"
progress < 100 -> DecimalFormat("#.#").apply {
//直接舍弃
roundingMode = RoundingMode.DOWN
}.format(BigDecimal(progress))
else -> "100"
}
}

}

+ 36
- 0
app/src/main/java/com/xkl/cdl/data/manager/FilePathManager.kt View File

@@ -0,0 +1,36 @@
package com.xkl.cdl.data.manager

import com.suliang.common.util.file.FileUtil
import com.xkl.cdl.data.manager.db.DbControlBase
import java.io.File

/**
* author suliang
* create 2022/4/1 11:23
* Describe: 地址管理
*/
class FilePathManager {

companion object{
/**
* 获取课程包目录数据所在的地址
* @return File
*/
@JvmStatic
fun getCoursePackDbPath(): File{
return File(FileUtil.getSaveDirPath("db"), "course-pack.db")
}
/** 获取课程数据地址 */
@JvmStatic
fun getCourseDbPath(base:DbControlBase): File{
return File(FileUtil.getSaveDirPath("db"), "${base.subjectId}/${base.coursePackId}/${base.courseId}/course.db")
}
/** 获取课程数据地址 */
@JvmStatic
fun getCourseDbPath(subjectId:Int,coursePackId:Long,courseId:Long): File{
return File(FileUtil.getSaveDirPath("db"), "subjectId/coursePackId/courseId/course.db")
}

}

}

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

@@ -1,10 +0,0 @@
package com.xkl.cdl.data.manager.db

/**
* author suliang
* create 2022/3/21 16:10
* Describe: 作文数据库
*/
object CompositionDbManager : IDB {

}

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

@@ -1,7 +1,14 @@
package com.xkl.cdl.data.manager.db

import com.xkl.cdl.data.Constants
import com.xkl.cdl.data.bean.Lesson
import android.annotation.SuppressLint
import android.widget.Toast
import com.suliang.common.util.AppGlobals
import com.suliang.common.util.thread.AppExecutors
import com.xkl.cdl.data.AppConstants
import com.xkl.cdl.data.bean.course.CourseDetail
import com.xkl.cdl.data.bean.course.Lesson
import com.xkl.cdl.data.manager.FilePathManager
import net.sqlcipher.database.SQLiteDatabase

/**
* author suliang
@@ -9,19 +16,151 @@ import com.xkl.cdl.data.bean.Lesson
* Describe: 课程数据库管理类,主要用于读取数据
*/
object DBCourseManager {
private var currentBase = DbControlBase()
private const val NORMAL = "XKL_COURSE_DATA_KEY"
private const val SPOKEN = "XKL_SPOKEN_COURSE_DATA_KEY"
private const val COMPOSITION = "XKL_LOCAL_COMPOSITION_DATA_KEY"
private const val LITERACY = "XKL_LOCAL_CHINESE_COURSE_KEY"
private var mDataBase: SQLiteDatabase? = null

fun getDb(subjectId:Int,coursePackId:Long,courseId:Long):IDB{
return if (subjectId == Constants.SUBJECT_ENGLISH){
EnglishDbManager
}else{
CompositionDbManager
private fun open(base: DbControlBase) {
synchronized(DBCourseManager) {
if (mDataBase != null && currentBase != base) {
mDataBase?.close()
mDataBase = null
}
if (mDataBase == null) {
currentBase = base
val p = when (base.courseType) {
AppConstants.COURSE_TYPE_CHINESE_COMPOSITION -> COMPOSITION
AppConstants.COURSE_TYPE_ENGLISH_SPOKEN -> SPOKEN
AppConstants.COURSE_TYPE_CHINESE_LITERACY -> LITERACY
else -> NORMAL
}
mDataBase = SQLiteDatabase.openDatabase(FilePathManager.getCourseDbPath(currentBase).path,
p,
null,
SQLiteDatabase.OPEN_READONLY)
}
if (mDataBase == null) {
AppExecutors.mainThread.run {
Toast.makeText(AppGlobals.application, "课程数据获取失败,请重启应用或联系业务员", Toast.LENGTH_LONG)
}
}
}
}

/**获取该课程的所有课时
* @param base DbControlBase
* @param detail CourseDetail 课程信息
* @return List<Lesson>
*/

@SuppressLint("Range")
fun queryAllLesson(base: DbControlBase, detail: CourseDetail): List<Lesson> {
val mutableList = mutableListOf<Lesson>()
open(base)
//聚合所有课时,先所有chapter_sort和word_sort排序,然后根据leesonId分组并聚合leeson_id到
val rawQurySql = when (base.courseType) {
AppConstants.COURSE_TYPE_CHINESE_COMPOSITION -> {
"SELECT * FROM chapter ORDER by chapter_sort asc"
}
AppConstants.COURSE_TYPE_ENGLISH_SPOKEN -> { //口语查询暂时与 单词一致
"SELECT *,group_concat(word_id,',') as wordIds FROM (select * from chapter ORDER By chapter_sort asc, word_sort asc) GROUP by lesson_id"
}
else -> {
"SELECT *,group_concat(word_id,',') as wordIds FROM (select * from chapter ORDER By chapter_sort asc, word_sort asc) GROUP by lesson_id" // ORDER By chapter_sort asc, word_sort asc "
}
}
var positionIndex = 0
mDataBase?.rawQuery(rawQurySql, null)?.let {
while (it.moveToNext()) {
val chapterId: Long = it.getLong(it.getColumnIndex("chapter_id"))
val chapterName: String = it.getString(it.getColumnIndex("chapter_title"))
val lessonId = it.getLong(it.getColumnIndex("lesson_id"))
val lessonName = when (base.courseType) {
AppConstants.COURSE_TYPE_CHINESE_COMPOSITION -> it.getString(it.getColumnIndex("lesson_title"))
else -> it.getString(it.getColumnIndex("lesson"))
}
val wordIds = when (base.courseType) {
AppConstants.COURSE_TYPE_CHINESE_COMPOSITION -> it.getString(it.getColumnIndex("relation_id"))
.split(",")
else -> it.getString(it.getColumnIndex("wordIds")).split(",")
}.map { value -> value.toLong() }.toMutableList()
val lessonType: Int = when (base.courseType) {
AppConstants.COURSE_TYPE_CHINESE_COMPOSITION -> it.getInt(it.getColumnIndex("type"))
AppConstants.COURSE_TYPE_ENGLISH_SPOKEN -> it.getInt(it.getColumnIndex("lesson_type"))
else -> AppConstants.LESSON_TYPE_WORD
}
val key = "${chapterId}_${lessonId}"

val learnIndex = wordIds.indexOf(detail.lesson_learn_point.getOrElse(key, { -1 })) //学习位置,当前位置为已学

// 注:针对口语对话课时,如果没有学习完,是不会设置进度点的。
val learnIsOver = wordIds.size - 1 == learnIndex

val lesson = Lesson(base.subjectId,
base.coursePackId,
base.courseId,
base.courseType,
chapterId,
chapterName,
lessonId,
lessonName).apply {
lessonPositionInList = positionIndex
this.wordIds = wordIds //内容
totalNumber = this.wordIds.size //总数
correctNumber = detail.right.getOrElse(key, { 0 }) //正确数
errorNumber = detail.wrong.getOrElse(key, { 0 }) //错误数
beforeTestScore = detail.before.getOrElse(key, { -1.0 }) //课时学前测试成绩
afterTestScore = detail.after.getOrElse(key, { -1.0 }) //课时学后测试成绩
this.learnedIndex = learnIndex //学习位置,当前位置为已学
this.learnIsOver = learnIsOver
this.lessonType = lessonType
}
mutableList.add(lesson)
positionIndex += 1
}
it.close()
}
mutableList.last().lastLesson = true
return mutableList.toList()
}

/** 获取总测试的数据 */
fun queryTotalTest(coursePackId: Long, courseId: Long) {

}

/** 获取课时测试数据 */
fun queryLessonTest(coursePackId: Long, courseId: Long, chapterId: Long, lessonId: Long, courseType: Long) {

}

/** 获取指定课时(指定数据源wordIds)的随机个数测试数据 */
fun queryLessonTestRandomSize(coursePackId: Long,
courseId: Long,
chapterId: Long,
lessonId: Long,
courseType: Long,
limitSize: Int,
wordIds: ArrayList<Long>? = null) {

}

/** 获取课时学习内容 */
fun queryLessonLearnData(coursePackId: Long,
courseId: Long,
chapterId: Long,
lessonId: Long,
wordIds: ArrayList<Long>) {

}

/** 获取课程今日需要复习的数据 */
fun queryCourseReviewDatas(coursePackId: Long, courseId: Long, wordIds: ArrayList<Long>) {

}


}

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

@@ -0,0 +1,12 @@
package com.xkl.cdl.data.manager.db

/**
* author suliang
* create 2022/4/1 11:06
* Describe: 用于查询数据库需要的基本信息
*/
data class DbControlBase(
val subjectId: Int = 0,
val coursePackId: Long = 0,
val courseId: Long = 0,
var courseType: Int = 0)

+ 15
- 9
app/src/main/java/com/xkl/cdl/data/manager/db/DbCoursePackManager.kt View File

@@ -1,13 +1,13 @@
package com.xkl.cdl.data.manager.db

import com.suliang.common.util.file.FileUtil
import com.xkl.cdl.data.Constants
import com.xkl.cdl.data.course.Course
import com.xkl.cdl.data.course.CoursePack
import com.xkl.cdl.data.AppConstants
import com.xkl.cdl.data.bean.course.Course
import com.xkl.cdl.data.bean.course.CoursePack
import com.xkl.cdl.data.manager.CourseManager
import com.xkl.cdl.data.manager.FilePathManager
import net.sqlcipher.database.SQLiteDatabase
import net.sqlcipher.database.SQLiteDatabase.OPEN_READONLY
import java.io.File

/**
* author suliang
@@ -20,8 +20,12 @@ class DbCoursePackManager {
private val database: SQLiteDatabase

init {
val coursePackDbPath = FileUtil.getSaveDirPath("db") + File.separator + "course-pack.db"
database = SQLiteDatabase.openDatabase(coursePackDbPath, "XUEKAOLE_COURSE_LIST_KEY", null, OPEN_READONLY)
//数据文件是否存在
val coursePackFile = FilePathManager.getCoursePackDbPath()
if (!coursePackFile.exists()) {
val copyAssetResult = FileUtil.copyAsset("course-pack.db", coursePackFile)
}
database = SQLiteDatabase.openDatabase(coursePackFile.path, "XUEKAOLE_COURSE_LIST_KEY", null, OPEN_READONLY)
}

/***
@@ -66,16 +70,18 @@ class DbCoursePackManager {
cursor.close()
}
}
if (subjectId == Constants.SUBJECT_ENGLISH) {
if (subjectId == AppConstants.SUBJECT_ENGLISH) {
coursePack.inCoursePackPosition = englishCoursePack.size
englishCoursePack.add(coursePack)
} else {
coursePack.inCoursePackPosition = englishCoursePack.size
chineseCoursePack.add(coursePack)
}
}
it.close()
}
CourseManager.subjectWithCoursePackMap[Constants.SUBJECT_ENGLISH] = englishCoursePack.toList()
CourseManager.subjectWithCoursePackMap[Constants.SUBJECT_CHINESE] = chineseCoursePack.toList()
CourseManager.subjectWithCoursePackMap[AppConstants.SUBJECT_ENGLISH] = englishCoursePack.toList()
CourseManager.subjectWithCoursePackMap[AppConstants.SUBJECT_CHINESE] = chineseCoursePack.toList()
database.close()
return true
}

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

@@ -1,11 +0,0 @@
package com.xkl.cdl.data.manager.db

/**
* author suliang
* create 2022/3/21 16:09
* Describe: 英语数据库
*/
object EnglishDbManager : IDB {


}

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

@@ -1,32 +0,0 @@
package com.xkl.cdl.data.manager.db

/**
* author suliang
* create 2022/3/21 16:34
* Describe: 英语数据库接口
*/
interface IDB {


// fun open(subjectId:Long,coursePackId:Long,courseId:Long)
//
// /**获取该课程的所有课时*/
// fun queryAllLesson()
//
// /** 获取总测试的数据 */
// fun queryTotalTest(coursePackId: Long,courseId: Long)
// /** 获取课时测试数据 */
// fun queryLessonTest(coursePackId: Long,courseId: Long,chapterId:Long,lessonId:Long,courseType:Long)
// /** 获取指定课时(指定数据源wordIds)的随机个数测试数据 */
// fun queryLessonTestRandomSize(coursePackId: Long,courseId: Long,chapterId: Long,lessonId: Long,courseType: Long,limitSize:Int,wordIds:ArrayList<Long>? = null)
//
// /** 获取课时学习内容 */
// fun queryLessonLearnData(coursePackId: Long,courseId: Long,chapterId: Long,lessonId: Long,wordIds:ArrayList<Long>)
//
// /** 获取课程今日需要复习的数据 */
// fun queryCourseReviewDatas(coursePackId: Long,courseId: Long,wordIds: ArrayList<Long>)




}

+ 37
- 0
app/src/main/java/com/xkl/cdl/data/repository/AudioCache.kt View File

@@ -0,0 +1,37 @@
package com.xkl.cdl.data.repository

import android.graphics.Bitmap
import android.util.LruCache
import java.security.Key

/**
* author suliang
* create 2022/4/1 9:53
* Describe: 音频缓存获取规则
*/
object AudioCache {

var lruCache : LruCache<String, ByteArray>

init {
lruCache = object : LruCache<String,ByteArray>((Runtime.getRuntime().maxMemory()/16).toInt()){
//告知每个对象的存储大小
override fun sizeOf(key: String?, value: ByteArray?): Int {
if (value == null){
return 0
}
return value.size
}
}
}

/**
* 获取对应音频
* @param key String
* @return ByteArray?
*/
fun get(key:String) : ByteArray? {
return null
}

}

+ 51
- 0
app/src/main/java/com/xkl/cdl/data/repository/DataRepository.kt View File

@@ -0,0 +1,51 @@
package com.xkl.cdl.data.repository

import com.xkl.cdl.data.bean.course.CourseDetail
import com.xkl.cdl.data.bean.course.Lesson
import com.xkl.cdl.data.manager.db.DBCourseManager
import com.xkl.cdl.data.manager.db.DbControlBase
import io.reactivex.rxjava3.core.Observable

/**
* author suliang
* create 2022/3/29 10:24
* Describe: 数据提供
*/
object DataRepository {

/** 获取课程的收藏本 */
fun getCourseCollect() : Observable<HashMap<String,Long>>{
return Observable.create{
it.onNext(hashMapOf())
it.onComplete()
}
}

/** 获取复习的内容 */
fun getReviewData() : Observable<Array<String>> {
return Observable.create{
mutableListOf<String>()
it.onNext(Array<String>(1){"1"})
it.onComplete()
}
}

/** 获取课程的详情 */
fun getCourseStatistics(): Observable<CourseDetail>{
return Observable.create{
val courseDetail = CourseDetail()
it.onNext(courseDetail)
it.onComplete()
}
}

/** 获取课程课时 */
fun getCourseAllLesson(base: DbControlBase,courseDetail: CourseDetail):Observable<List<Lesson>>{
return Observable.create{
it.onNext(DBCourseManager.queryAllLesson(base,courseDetail))
it.onComplete()
}
}


}

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

@@ -0,0 +1,87 @@
package com.xkl.cdl.dialog

import android.view.View
import com.suliang.common.base.BaseDialogFragment
import com.suliang.common.extension.click
import com.suliang.common.util.LogUtil
import com.xkl.cdl.R
import com.xkl.cdl.databinding.DialogLessonLearnBinding

/**
* author suliang
* create 2022/4/2 15:47
* Describe: 学习的通用弹窗
*/
class LearnDialog : BaseDialogFragment<DialogLessonLearnBinding>() {

private lateinit var dialogListener : DialogFragmentListener

override fun initFragment() {
initClick()
// initLessonBeforeTest()
initLessonBeforeTestOver()
}

fun initClick(){
dialogListener = if (parentFragment != null){
parentFragment as DialogFragmentListener
}else{
activity as DialogFragmentListener
}
}

fun initLessonBeforeTest(){
binding.tvTitle.text = "课时学前测试"
binding.tvLessonName.text = "章节课时名称"
binding.tvCountTime.text = "测试题目时间"
binding.tvRight.text = "开始测试"
binding.tvLeft.visibility = View.VISIBLE
binding.tvLeft.text = "随便设置"

binding.tvRight.click {
LogUtil.e("Dialog -- > show()")
dialogListener.rightClick()
}

binding.tvLeft.click {
LogUtil.e("Dialog -- > hide()")
dialogListener.leftClick()
}
}

fun initLessonBeforeTestOver(){
binding.tvScore.run {
visibility = View.VISIBLE
text = "100分"
}
binding.tvTip.visibility = View.VISIBLE
binding.tvTitle.text = "恭喜你,完成了课时学前测试"
binding.tvLessonName.visibility = View.GONE
binding.tvCountTime.visibility = View.GONE
binding.tvTip1.visibility = View.VISIBLE
binding.tvTip1.setText(resources.getString(R.string.test_before_test_over_tip))
binding.incStatisticsNumber.root.visibility = View.VISIBLE
binding.tvLeft.visibility = View.GONE
binding.tvRight.setText(resources.getString(R.string.start_learn))
binding.tvRight.click {
// TODO: 2022/4/2 开始学习
}

}
fun initLessonAfterTestOver(){
//未通过

//已通过

//已通过的再通过

}



public interface DialogFragmentListener{
fun rightClick()
fun leftClick()
}

}

+ 22
- 0
app/src/main/java/com/xkl/cdl/module/learn/LearnBaseActivity.kt View File

@@ -0,0 +1,22 @@
package com.xkl.cdl.module.learn

import androidx.viewbinding.ViewBinding
import com.suliang.common.base.activity.BaseActivityVM

abstract class LearnBaseActivity<vb:ViewBinding,vm: LearnBaseViewModel> : BaseActivityVM<vb,vm>() {


override fun onRestart() {
super.onRestart()
}

override fun onResume() {
super.onResume()
}

override fun onPause() {
super.onPause()
}


}

+ 12
- 0
app/src/main/java/com/xkl/cdl/module/learn/LearnBaseViewModel.kt View File

@@ -0,0 +1,12 @@
package com.xkl.cdl.module.learn

import com.suliang.common.base.viewmodel.BaseViewModel

/**
* author suliang
* create 2022/4/2 14:06
* Describe: 学习基类: 实现统一流程接口和计时实现
*/
abstract class LearnBaseViewModel : BaseViewModel() {

}

app/src/main/java/com/xkl/cdl/module/m_center_learn/CourseMainActivity.kt → app/src/main/java/com/xkl/cdl/module/learn/LearnCReadingActivity.kt View File

@@ -1,15 +1,12 @@
package com.xkl.cdl.module.m_center_learn
package com.xkl.cdl.module.learn

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.xkl.cdl.R

/**
* 课程中心
*/
class CourseMainActivity : AppCompatActivity() {
class LearnCReadingActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_course_main)
setContentView(R.layout.activity_learn_creading)
}
}

+ 12
- 0
app/src/main/java/com/xkl/cdl/module/learn/LearnCTaskActivity.kt View File

@@ -0,0 +1,12 @@
package com.xkl.cdl.module.learn

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.xkl.cdl.R

class LearnCTaskActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_learn_ctask)
}
}

+ 12
- 0
app/src/main/java/com/xkl/cdl/module/learn/LearnCVideoActivity.kt View File

@@ -0,0 +1,12 @@
package com.xkl.cdl.module.learn

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.xkl.cdl.R

class LearnCVideoActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_learn_cvideo)
}
}

+ 12
- 0
app/src/main/java/com/xkl/cdl/module/learn/LearnExamSpellActivity.kt View File

@@ -0,0 +1,12 @@
package com.xkl.cdl.module.learn

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.xkl.cdl.R

class LearnExamSpellActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_exam_learn_spell)
}
}

+ 12
- 0
app/src/main/java/com/xkl/cdl/module/learn/LearnExamWordActivity.kt View File

@@ -0,0 +1,12 @@
package com.xkl.cdl.module.learn

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.xkl.cdl.R

class LearnExamWordActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_learn_exam_word)
}
}

+ 12
- 0
app/src/main/java/com/xkl/cdl/module/learn/LearnSpellActivity.kt View File

@@ -0,0 +1,12 @@
package com.xkl.cdl.module.learn

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.xkl.cdl.R

class LearnSpellActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_learn_spell)
}
}

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

@@ -0,0 +1,12 @@
package com.xkl.cdl.module.learn

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.xkl.cdl.R

class LearnWordActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_learn_word)
}
}

+ 0
- 13
app/src/main/java/com/xkl/cdl/module/m_center_learn/CourseMainActivityViewModel.kt View File

@@ -1,13 +0,0 @@
package com.xkl.cdl.module.m_center_learn

import com.suliang.common.base.viewmodel.BaseViewModel
import com.xkl.cdl.data.course.Course

/**
* author suliang
* create 2022/3/24 17:42
* Describe: 课程主页
*/
class CourseMainActivityViewModel(val course: Course) : BaseViewModel() {

}

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

@@ -7,11 +7,10 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import com.suliang.common.Config
import com.suliang.common.AppConfig
import com.suliang.common.base.fragment.BaseFragmentVM
import com.suliang.common.util.LogUtil
import com.xkl.cdl.R
import com.xkl.cdl.data.course.CoursePack
import com.xkl.cdl.databinding.FragmentCoursePackBinding
import com.xkl.cdl.module.main.MainActivityViewModel

@@ -25,13 +24,13 @@ class CoursePackFragment : BaseFragmentVM<FragmentCoursePackBinding,CoursePackFr
@JvmStatic
fun newInstance(projectId: Int) = CoursePackFragment().apply {
arguments = Bundle().apply {
putInt(Config.INTENT_1,projectId)
putInt(AppConfig.INTENT_1,projectId)
}
}
}

override fun initViewModel(): CoursePackFragmentViewModel {
val projectId = requireArguments().getInt(Config.INTENT_1)
val projectId = requireArguments().getInt(AppConfig.INTENT_1)
return ViewModelProvider(this,ViewModelFactory(projectId)).get(CoursePackFragmentViewModel::class.java).apply {
this.mainActivityViewModel = ViewModelProvider(requireActivity()).get(MainActivityViewModel::class.java)
this.learnCenterFragmentViewModel = ViewModelProvider(requireParentFragment()).get(LearnCenterFragmentViewModel::class.java)
@@ -50,8 +49,9 @@ class CoursePackFragment : BaseFragmentVM<FragmentCoursePackBinding,CoursePackFr
binding.contentLayout.recyclerView.apply {
layoutManager = LinearLayoutManager(requireContext(),LinearLayoutManager.VERTICAL,false)
adapter = vm.adpater.apply {
onItemClick = { v,position,courePack ->

//点击时事件,跳转
onItemClick = { v,position,coursePack ->
CoursePackMainActivity.newInstance(requireContext(),coursePack.subjectId,coursePack.inCoursePackPosition)
}
}
//分割线

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

@@ -3,7 +3,7 @@ package com.xkl.cdl.module.m_center_learn
import androidx.lifecycle.MutableLiveData
import com.suliang.common.base.viewmodel.BaseViewModel
import com.xkl.cdl.adapter.AdapterCoursePackWithLearCenter
import com.xkl.cdl.data.course.CoursePack
import com.xkl.cdl.data.bean.course.CoursePack
import com.xkl.cdl.data.manager.CourseManager
import com.xkl.cdl.module.main.MainActivityViewModel


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

@@ -0,0 +1,283 @@
package com.xkl.cdl.module.m_center_learn

import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.os.Bundle
import android.view.View
import androidx.core.content.ContextCompat
import androidx.core.content.res.ResourcesCompat
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.viewpager2.widget.ViewPager2
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.suliang.common.AppConfig
import com.suliang.common.base.activity.BaseActivityVM
import com.suliang.common.extension.click
import com.suliang.common.util.LogUtil
import com.suliang.common.util.os.ScreenUtil
import com.xkl.cdl.R
import com.xkl.cdl.adapter.AdapterAutoPlaySelectRepeat
import com.xkl.cdl.adapter.ViewPagerAdapter
import com.xkl.cdl.data.AppConstants
import com.xkl.cdl.data.binding.BindingAdapter
import com.xkl.cdl.data.manager.CourseManager
import com.xkl.cdl.databinding.ActivityCourseMainBinding
import com.xkl.cdl.databinding.DialogBottomAutoPlaySelectBinding
import com.xkl.cdl.databinding.DialogBottomCourseMoreBinding
import com.xkl.cdl.module.m_center_learn.coursechildren.CourseMainFragment
import com.zackratos.ultimatebarx.ultimatebarx.statusBarOnly

/**
* 课程中心
*/
class CoursePackMainActivity : BaseActivityVM<ActivityCourseMainBinding, CoursePackMainActivityViewModel>() {

companion object {
@JvmStatic
fun newInstance(context: Context, subjectId: Int, coursePackInPosition: Int) {
context.startActivity(Intent(context, CoursePackMainActivity::class.java).apply {
putExtra(AppConfig.INTENT_1, subjectId)
putExtra(AppConfig.INTENT_2, coursePackInPosition)
})
}
}

//子课程对应的Fragment
private var childFragments = mutableListOf<Fragment>()

//更多按钮的弹窗显示
private var moreDialog: BottomSheetDialog? = null

//自动播放次数的弹窗选择
private var autoPlaySeletDialog: BottomSheetDialog? = null

override fun initViewModel(): CoursePackMainActivityViewModel {
val subjectId = intent.getIntExtra(AppConfig.INTENT_1, 0)
val coursePackInListPosition = intent.getIntExtra(AppConfig.INTENT_2, 0)
return ViewModelProvider(
this, ViewModelFactory(subjectId, coursePackInListPosition)
)[CoursePackMainActivityViewModel::class.java]
}

override fun initStatusBar() {
statusBarOnly {
fitWindow = false //布局是否侵入状态栏
color = Color.TRANSPARENT //透明
light = true
}
}

override fun initActivity(savedInstanceState: Bundle?) {
LogUtil.e("CoursePackMainActivity coursePackMainActivityVM hashCode -> ${vm.hashCode()}")
//设置布局数据
binding.coursePack = vm.coursePack
//状态栏高度设置
binding.statusBarView.layoutParams.height = ScreenUtil.getStatusBarHeight()
//设置简介的箭头大小
ResourcesCompat.getDrawable(resources, R.drawable.ic_arrow_right, null)?.apply {
setBounds(0, 0, 36, 36)
binding.textViewIntroduction.setCompoundDrawables(null, null, this, null)
}
//返回事件
binding.includeTitleBar.titleBar.run {
onBackClick = {_ -> finish() }
}

//初始化tab和viewPager
initTabAndViewPager()
}

private fun initTabAndViewPager() {
//英语课程包且为英语单词课程包才显示tab
if (vm.coursePack.subjectId == AppConstants.SUBJECT_ENGLISH && vm.coursePack.coursePackType == AppConstants.COURSEPACK_TYPE_ENGLISH_WORD) {
binding.includeCourseTypeTab.root.visibility = View.VISIBLE
vm.coursePack.childrenCourses.forEachIndexed { index, course ->
when (course.courseType) {
AppConstants.COURSE_TYPE_ENGLISH_DISCERN -> {
binding.includeCourseTypeTab.tabDiscern.visibility = View.VISIBLE
childFragments.add(CourseMainFragment.newInstance(index))
}
AppConstants.COURSE_TYPE_ENGLISH_SPELL -> {
binding.includeCourseTypeTab.ivArrow1.visibility = View.VISIBLE
binding.includeCourseTypeTab.tabSpell.visibility = View.VISIBLE
childFragments.add(CourseMainFragment.newInstance(index))
}
AppConstants.COURSE_TYPE_ENGLISH_VOICE -> {
binding.includeCourseTypeTab.ivArrow2.visibility = View.VISIBLE
binding.includeCourseTypeTab.tabVoice.visibility = View.VISIBLE
childFragments.add(CourseMainFragment.newInstance(index))
}
}
}
} else { //其他课程tab为空
binding.includeCourseTypeTab.root.visibility = View.GONE
childFragments.add(CourseMainFragment.newInstance(0))
}
//ViewPager初始
binding.viewPager2.apply {
adapter = ViewPagerAdapter(this@CoursePackMainActivity, childFragments)
//注册页面改变监听
registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
super.onPageSelected(position)
//改变tab的选中颜色
if (binding.includeCourseTypeTab.root.visibility == View.VISIBLE) { //可见,才做操作
binding.includeCourseTypeTab.apply {
tabDiscern.run {
setTextColor(
ContextCompat.getColor(
this@CoursePackMainActivity,
if (position == 0) R.color.theme_color else R.color.gray_2
)
)
BindingAdapter.loadVectorDrawable(
this, ContextCompat.getColor(
this@CoursePackMainActivity,
if (position == 0) R.color.theme_color else R.color.gray_2
)
)
}
tabSpell.run {
setTextColor(
ContextCompat.getColor(
this@CoursePackMainActivity,
if (position == 1) R.color.theme_color else R.color.gray_2
)
)
BindingAdapter.loadVectorDrawable(
this, ContextCompat.getColor(
this@CoursePackMainActivity,
if (position == 1) R.color.theme_color else R.color.gray_2
)
)
}
tabVoice.run {
setTextColor(
ContextCompat.getColor(
this@CoursePackMainActivity,
if (position == 2) R.color.theme_color else R.color.gray_2
)
)
BindingAdapter.loadVectorDrawable(
this, ContextCompat.getColor(
this@CoursePackMainActivity,
if (position == 2) R.color.theme_color else R.color.gray_2
)
)
}
}
}
//改变page后设置进度
vm.currentCourseProgress.value = vm.coursePack.childrenCourses[position].courseLearnProgress
}
})
}
//tab点击
binding.includeCourseTypeTab.apply {
tabDiscern.click { binding.viewPager2.currentItem = 0 }
tabSpell.click { binding.viewPager2.currentItem = 1 }
tabVoice.click { binding.viewPager2.currentItem = 2 }
}
//监听进度,设置进度
vm.currentCourseProgress.observe(this) {
binding.includeCourseProgress.apply {
//进度格式化
progressbar.progress = it.toInt()
tvProgress.text = if (binding.includeCourseTypeTab.root.visibility == View.VISIBLE) {
val format = when (binding.viewPager2.currentItem) {
0 -> "认读进度:%s"
1 -> "拼写进度:%s"
2 -> "辨音进度:%s"
else -> "进度:%s"
}
String.format(format, CourseManager.useToShowProgress(it))
} else {
String.format("进度:%s", CourseManager.useToShowProgress(it))
}
}
}
//更多按钮点击
binding.includeCourseProgress.ivMore.click {
showMoreDialog()
}
}

override fun loadData() {

}

/** 点击显示更多的弹窗 */
private fun showMoreDialog() {
if (moreDialog == null) {
moreDialog = BottomSheetDialog(this, R.style.dialog_style).apply {
val moreBinding = DataBindingUtil.inflate<DialogBottomCourseMoreBinding>(
layoutInflater, R.layout.dialog_bottom_course_more, null, false
)
setContentView(moreBinding.root)
//体验账号、拼些、口语课程、作文课程不显示自动播放
when (vm.coursePack.childrenCourses[binding.viewPager2.currentItem].courseType) {
AppConstants.COURSE_TYPE_ENGLISH_SPELL, AppConstants.COURSE_TYPE_ENGLISH_SPOKEN, AppConstants.COURSE_TYPE_CHINESE_COMPOSITION -> moreBinding.tvAutoPlay.visibility =
View.GONE
else -> moreBinding.tvAutoPlay.visibility = View.VISIBLE
}
moreBinding.ivCancel.click {
dismiss()
}
moreBinding.tvAutoPlay.click {
dismiss()
showAutoPlaySelectDialog()
}
moreBinding.tvClearLearnRecord.click {
dismiss()
// TODO: 2022/3/29 弹窗显示清除学习记录
}
}
}
moreDialog?.show()
}

/** 自动播放次数选择: 仅单词会有该选项 */
private fun showAutoPlaySelectDialog() {
if (autoPlaySeletDialog == null) {
autoPlaySeletDialog = BottomSheetDialog(this, R.style.dialog_style).apply {
val autoPlayBinding = DataBindingUtil.inflate<DialogBottomAutoPlaySelectBinding>(
layoutInflater, R.layout.dialog_bottom_auto_play_select, null, false
)
setContentView(autoPlayBinding.root)
autoPlayBinding.ivCancel.click { v -> dismiss() }

autoPlayBinding.rvRepeat.run {
adapter = AdapterAutoPlaySelectRepeat().apply {
onItemClick = { _, position, _ ->
dismiss()
startAutoPlay(position + 1)
}
}
}
}
}
autoPlaySeletDialog?.show()
}

/**
* 开始自动播放
* @param time Int
*/
private fun startAutoPlay(time: Int) {

}


/** ViewModel Factory工厂 */
inner class ViewModelFactory(private val subjectId: Int, private val coursePackInPosition: Int) :
ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
return CoursePackMainActivityViewModel(subjectId, coursePackInPosition) as T
}
}


}

+ 21
- 0
app/src/main/java/com/xkl/cdl/module/m_center_learn/CoursePackMainActivityViewModel.kt View File

@@ -0,0 +1,21 @@
package com.xkl.cdl.module.m_center_learn

import androidx.lifecycle.MutableLiveData
import com.suliang.common.base.viewmodel.BaseViewModel
import com.xkl.cdl.data.manager.CourseManager

/**
* author suliang
* create 2022/3/24 17:42
* Describe: 课程主页
*/
class CoursePackMainActivityViewModel(subjectId: Int , coursePackInPosition : Int) : BaseViewModel() {

//操作的课程包
val coursePack = CourseManager.subjectWithCoursePackMap[subjectId]!![coursePackInPosition]

//设置显示当前课程的进度值和显示内容
val currentCourseProgress = MutableLiveData<Double>()


}

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

@@ -4,7 +4,7 @@ import androidx.fragment.app.Fragment
import androidx.lifecycle.MutableLiveData
import com.suliang.common.base.viewmodel.BaseViewModel
import com.xkl.cdl.R
import com.xkl.cdl.data.Constants
import com.xkl.cdl.data.AppConstants
import com.xkl.cdl.module.main.MainActivityViewModel

/**
@@ -30,8 +30,8 @@ class LearnCenterFragmentViewModel : BaseViewModel() {
/** 实例化项目课程包Fragment和显示Title */
fun initLearnCenterFragment(){
if (mProjectFragments.isEmpty()){
mProjectFragments.add(CoursePackFragment.newInstance(Constants.SUBJECT_ENGLISH))
mProjectFragments.add(CoursePackFragment.newInstance(Constants.SUBJECT_CHINESE))
mProjectFragments.add(CoursePackFragment.newInstance(AppConstants.SUBJECT_ENGLISH))
mProjectFragments.add(CoursePackFragment.newInstance(AppConstants.SUBJECT_CHINESE))
}
if (mProjectTitles.isEmpty()){
mProjectTitles.add(R.string.project_english)

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

@@ -0,0 +1,86 @@
package com.xkl.cdl.module.m_center_learn.coursechildren

import android.view.View
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import com.suliang.common.base.fragment.BaseFragmentVM
import com.xkl.cdl.adapter.AdapterLesson
import com.xkl.cdl.data.AppConstants
import com.xkl.cdl.data.bean.course.Lesson
import com.xkl.cdl.databinding.FragmentCourseLessonBinding

/**
* 课程章节目录
*/
class CourseLessonFragment : BaseFragmentVM<FragmentCourseLessonBinding, CourseMainFragmentViewModel>() {

companion object {
@JvmStatic
fun newInstance() = CourseLessonFragment()
}
override fun initViewModel(): CourseMainFragmentViewModel {
return ViewModelProvider(requireParentFragment())[CourseMainFragmentViewModel::class.java]
}

override fun initFragment() {
//口语显示顶部的自动播放与跟读模式
if (vm.course.courseType == AppConstants.COURSE_TYPE_ENGLISH_SPOKEN){
binding.spokenTopLayout.visibility = View.VISIBLE
}
binding.recyclerView.apply {
layoutManager = LinearLayoutManager(requireContext(),LinearLayoutManager.VERTICAL,false)
adapter = AdapterLesson(vm).apply {
onItemClick = onLessonClick
}
}
//设置数据
(binding.recyclerView.adapter as AdapterLesson).setData(vm.allLesson.toMutableList())
}

override fun loadData() {

}

/** 课时点击实现 */
private val onLessonClick : (v:View,position: Int, leeson: Lesson) -> Unit = { view, position, entity ->
// TODO: 2022/3/31 根据情况具体跳转实现 学前、学习、学后
when(entity.lessonType){
AppConstants.LESSON_TYPE_WORD -> {
if (entity.beforeTestScore == AppConstants.NOT_DOING){

}else if (!entity.learnIsOver){

}else if (entity.afterTestScore != AppConstants.NOT_DOING){

}else{

}
}
AppConstants.LESSON_TYPE_SENTENCE -> {

}

AppConstants.LESSON_TYPE_DIALOGUE -> {

}
AppConstants.LESSON_TYPE_COMPOSITION_VIDEO -> {

}
AppConstants.LESSON_TYPE_COMPOSITION_KNOWLEDGE -> {

}
AppConstants.LESSON_TYPE_COMPOSITION_EXAM -> {

}
AppConstants.LESSON_TYPE_COMPOSITION_READING -> {

}
AppConstants.LESSON_TYPE_COMPOSITION_TASK -> {

}

}

}

}

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

@@ -0,0 +1,79 @@
package com.xkl.cdl.module.m_center_learn.coursechildren

import android.os.Bundle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.suliang.common.AppConfig
import com.suliang.common.base.fragment.BaseFragmentVM
import com.suliang.common.extension.replaceFragment
import com.suliang.common.util.LogUtil
import com.xkl.cdl.R
import com.xkl.cdl.data.manager.db.DbControlBase
import com.xkl.cdl.databinding.FragmentCourseMainBinding
import com.xkl.cdl.module.m_center_learn.CoursePackMainActivityViewModel

/**
* 学习中心@[LearnCenterFragment] @[CoursePackFragment]下课程包主页@[CoursePackMainActivity]下的
* 主课程Fragment[CourseMainFragment]
* 用于加载该课程的多种状态: 复习、章节目录、总测试
*/
class CourseMainFragment : BaseFragmentVM<FragmentCourseMainBinding, CourseMainFragmentViewModel>() {

companion object {
@JvmStatic
fun newInstance(courseIndex:Int) = CourseMainFragment().apply {
arguments = Bundle().apply {
putInt(AppConfig.INTENT_1,courseIndex)
}
}
}

override fun initViewModel(): CourseMainFragmentViewModel {
return ViewModelProvider(this,ViewModelFactory(requireArguments().getInt(AppConfig.INTENT_1)))[CourseMainFragmentViewModel::class.java].apply {
coursePackMainActivityVM = ViewModelProvider(requireActivity())[CoursePackMainActivityViewModel::class.java]
LogUtil.e("CourseMainFragment coursePackMainActivityVM hashCode -> ${coursePackMainActivityVM.hashCode()}")
}
}

override fun initFragment() {
//设置课程 和 需要操作的类型
vm.course = vm.coursePackMainActivityVM.coursePack.childrenCourses[vm.courseIndex].apply {
vm.dbControlBase = DbControlBase(subjectId,coursePackId,courseId,courseType)
}

}

override fun loadData() {
LogUtil.e("CourseMainFragment 加载数据 --》 ${vm.courseIndex}")

vm.loadMain().observe(this){
changeChildrenFragment()
}
}


/**
* 改变加载的子Fragment
*/
private fun changeChildrenFragment(){

// //加载复习
// replaceFragment(R.id.layout_root, CourseReviewFragment.newInstance())
// //学前总测
// replaceFragment(R.id.layout_root, CourseTotalTestFragment.newInstance(AppConstants.TEST_TYPE_BEFORE_TOTAL))
//学后总测
// replaceFragment(R.id.layout_root, CourseTotalTestFragment.newInstance(AppConstants.TEST_TYPE_AFTER_TOTAL))
//学习目录
replaceFragment(R.id.layout_root, CourseLessonFragment.newInstance())
}




inner class ViewModelFactory(private val courseIndex: Int) : ViewModelProvider.Factory{
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
return CourseMainFragmentViewModel(courseIndex) as T
}
}

}

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

@@ -0,0 +1,90 @@
package com.xkl.cdl.module.m_center_learn.coursechildren

import android.provider.ContactsContract
import androidx.lifecycle.MutableLiveData
import com.suliang.common.base.viewmodel.BaseViewModel
import com.suliang.common.extension.diskIo2DiskIo
import com.xkl.cdl.data.bean.course.Course
import com.xkl.cdl.data.bean.course.CourseDetail
import com.xkl.cdl.data.bean.course.Lesson
import com.xkl.cdl.data.manager.db.DbControlBase
import com.xkl.cdl.data.repository.DataRepository
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.Observer
import io.reactivex.rxjava3.disposables.Disposable
import java.util.*
import kotlin.collections.ArrayList
import kotlin.collections.HashMap

/**
* author suliang
* create 2022/3/28 15:26
* Describe:
* @property courseIndex 该课程在课程包的课程集合中的位置
*/
class CourseMainFragmentViewModel(val courseIndex: Int) : BaseViewModel() {
//课程包主页的ViewModel
lateinit var coursePackMainActivityVM: CoursePackMainActivityViewModel

lateinit var dbControlBase: DbControlBase

//当前操作课程
lateinit var course: Course


/** 课程的收藏本: 目前仅作用在口语课程会使用到该数据 */
lateinit var collectList: HashMap<String, Long>

/** 复习的数据 */
lateinit var reviewDataList: MutableList<String>

/** 课程所有课时 */
lateinit var allLesson: List<Lesson>

//课程的详细信息
lateinit var courseDetail: CourseDetail

//获取课程的统计信息
//课程收藏本: 主要用于口语对话学习的数据
//获取课程的复习数据
//获取课程的章节数据
fun loadMain() : MutableLiveData<Boolean> {
showHideLoading(true)
val mutableLiveData = MutableLiveData<Boolean>()
Observable.concat(
DataRepository.getCourseStatistics().flatMap {
courseDetail = it
return@flatMap DataRepository.getCourseAllLesson(dbControlBase, it)
}, DataRepository.getReviewData()
, DataRepository.getCourseCollect())
.compose(diskIo2DiskIo())
.subscribe(object :Observer<Any>{
override fun onSubscribe(d: Disposable?) {

}

override fun onNext(t: Any?) {
t?.let { it ->
if (it is List<*>){
allLesson = it as List<Lesson>
}
}
}

override fun onError(e: Throwable?) {
e?.printStackTrace()
}

override fun onComplete() {
showHideLoading(false)
mutableLiveData.postValue(true)
}

})
return mutableLiveData
}


}

+ 46
- 0
app/src/main/java/com/xkl/cdl/module/m_center_learn/coursechildren/CourseReviewFragment.kt View File

@@ -0,0 +1,46 @@
package com.xkl.cdl.module.m_center_learn.coursechildren

import android.os.Bundle
import androidx.lifecycle.ViewModelProvider
import com.suliang.common.AppConfig
import com.suliang.common.base.fragment.BaseFragmentVM
import com.suliang.common.extension.click
import com.xkl.cdl.data.AppConstants
import com.xkl.cdl.databinding.FragmentCourseLessonBinding
import com.xkl.cdl.databinding.FragmentCourseReviewBinding

/**
* 课程章节目录
* @property param1 String?
* @property param2 String?
*/
class CourseReviewFragment : BaseFragmentVM<FragmentCourseReviewBinding, CourseMainFragmentViewModel>() {

companion object {
@JvmStatic
fun newInstance() = CourseReviewFragment()
}

override fun initFragment() {
//根据课程类型进行显示
binding.tvTips.text = when(vm.course.courseType){
AppConstants.COURSE_TYPE_ENGLISH_DISCERN -> "你将进行 [认读] 课程智能复习"
AppConstants.COURSE_TYPE_ENGLISH_VOICE -> "你将进行 [辨音] 课程智能复习"
AppConstants.COURSE_TYPE_ENGLISH_SPELL -> "你将进行 [拼写] 课程智能复习"
else -> "你将进行课程智能复习"
}
binding.tvReviewCount.text = String.format("本次智能复习数%d",vm.course.courseReviewNumber)
//开始测试事件
binding.tvStartReview.click {
showToast("开始复习")
}
}

override fun loadData() {

}

override fun initViewModel(): CourseMainFragmentViewModel {
return ViewModelProvider(requireParentFragment())[CourseMainFragmentViewModel::class.java]
}
}

+ 133
- 0
app/src/main/java/com/xkl/cdl/module/m_center_learn/coursechildren/CourseTotalTestFragment.kt View File

@@ -0,0 +1,133 @@
package com.xkl.cdl.module.m_center_learn.coursechildren

import android.os.Bundle
import android.view.View
import androidx.lifecycle.ViewModelProvider
import com.suliang.common.AppConfig
import com.suliang.common.base.fragment.BaseFragmentVM
import com.suliang.common.extension.click
import com.suliang.common.extension.setHtml
import com.xkl.cdl.R
import com.xkl.cdl.data.AppConstants
import com.xkl.cdl.databinding.FragmentCourseTotalTestBinding

/**
* 课程总测试: 学前总,学后总
* @property param1 String?
* @property param2 String?
*/
class CourseTotalTestFragment : BaseFragmentVM<FragmentCourseTotalTestBinding, CourseMainFragmentViewModel>() {

companion object {
@JvmStatic
fun newInstance(totalTestType: Int) = CourseTotalTestFragment().apply {
arguments = Bundle().apply {
putInt(AppConfig.INTENT_1, totalTestType)
}
}
}

override fun initViewModel(): CourseMainFragmentViewModel {
return ViewModelProvider(requireParentFragment())[CourseMainFragmentViewModel::class.java]
}

//传递过来的总测类型: 学前,学后
private var totalTestType = 0

override fun initFragment() {
totalTestType = requireArguments().getInt(AppConfig.INTENT_1)
when (totalTestType) {
AppConstants.TEST_TYPE_BEFORE_TOTAL -> {
//学前总测
binding.run {
tvTitle.setText(R.string.test_total_before_title)
tvCountTip.text = "共25题,预计3分钟"
//按钮初始
button2.run {
setText(R.string.start_test)
click { view ->
startTest(view)
}
}
}
}

AppConstants.TEST_TYPE_AFTER_TOTAL -> {
//学后总测
binding.run {
ivIcon.setImageResource(if (java.util.Random().nextBoolean()) R.mipmap.boy_2 else R.mipmap.girl_2)
tvTitle.setText(R.string.tips_current_course_learn_over)
tvMainTip.visibility = View.VISIBLE
//根据测试成绩处理
vm.courseDetail.st_before = 81.0
vm.courseDetail.st_before.let {
when {
it == -1.0 -> { //未测
tvMainTip.setText(R.string.test_total_after_tip_1)
tvCountTip.text = "共25题,预计3分钟"
button2.run {
setText(R.string.test_type_after_total)
click { view ->
startTest(view)
}
}
}
it < AppConstants.TEST_SCORE_LEVEL_1 -> { //测试未通过
tvMainTip.setHtml("你还未通过学后总测试,上次得分: <font color=\'#F26255\'>$it</font>")

button1.run {
visibility = View.VISIBLE
setText(R.string.continue_learn)
click { view ->
continueLearn(view)
}
}
button2.run {
setText(R.string.start_test)
click { view ->
startTest(view)
}
}
}

it >= AppConstants.TEST_SCORE_LEVEL_1 -> { //测试通过
tvMainTip.setHtml("你已通过学后总测试,上次得分: <font color=\'#5082E6\'>$it</font>")
tvTips.visibility = View.VISIBLE
tvCountTip.visibility = View.GONE
button1.run {
visibility = View.VISIBLE
setText(R.string.test_again)
click { view ->
startTest(view)
}
}
button2.run {
setText(R.string.continue_learn)
click { view ->
continueLearn(view)
}
}
tvClearLearnRecord.visibility = View.VISIBLE
}
}
}
}
}
}
}

override fun loadData() {

}

/**继续学习*/
private fun continueLearn(view: View) {
showToast("继续学习")
}

/** 开始测试 */
private fun startTest(view: View) {
showToast("开始测试")
}

}

+ 49
- 13
app/src/main/java/com/xkl/cdl/module/splash/SplashActivity.kt View File

@@ -3,17 +3,23 @@ package com.xkl.cdl.module.splash
import android.annotation.SuppressLint
import android.os.Bundle
import com.suliang.common.base.activity.BaseActivity
import com.suliang.common.util.LogUtil
import com.suliang.common.util.file.FileUtil
import com.suliang.common.util.thread.AppExecutors
import com.xkl.cdl.data.manager.CourseManager
import com.xkl.cdl.data.manager.FilePathManager
import com.xkl.cdl.data.manager.db.DbCoursePackManager
import com.xkl.cdl.databinding.ActivitySplashBinding
import com.xkl.cdl.dialog.LearnDialog
import com.xkl.cdl.module.main.MainActivity
import mobile_cache.Mobile_cache


import java.io.File
import java.util.concurrent.TimeUnit

@SuppressLint("CustomSplashScreen")
class SplashActivity : BaseActivity<ActivitySplashBinding>() {
class SplashActivity : BaseActivity<ActivitySplashBinding>(), LearnDialog.DialogFragmentListener {

override fun onCreate(savedInstanceState: Bundle?) {
if (!isTaskRoot) {
@@ -28,28 +34,58 @@ class SplashActivity : BaseActivity<ActivitySplashBinding>() {
}

override fun loadData() {

// try {
// val file: String = File(FileUtil.getSaveDirFile("db"), "mydb").absolutePath
// val mobile = Mobile_cache.new_(file)
// mobile.delete()
// println(" -------------> " + mobile.get("abc"))
//
// } catch (e: Exception) {
// e.printStackTrace()
// }

learnDialog = LearnDialog().apply {
show(supportFragmentManager,javaClass.name)
}
LogUtil.e("Dialog -- > ${learnDialog.hashCode()}")
if (true) return


showHideLoading(true)
AppExecutors.io.execute {
//数据文件是否存在
val coursePackFile = File(FileUtil.getSaveDirPath("db"), "course-pack.db")
if (!coursePackFile.exists()) {
val copyAssetResult = FileUtil.copyAsset("course-pack.db", coursePackFile)
}

//读取课程数据
// TODO: 2022/3/22 读取当前app绑定的课程数据,
DbCoursePackManager().queryBindingCoursePack("262,261,264")
DbCoursePackManager().queryBindingCoursePack("262,261,264,136,547,615")
//复制课程的数据库到对应位置
CourseManager.checkCourseDb()
//定时跳跃到住主界面
AppExecutors.scheduledExecutor.schedule({
AppExecutors.mainThread.execute {
showHideLoading(false)
startActivity(MainActivity::class.java)
finish()
}
}, 1, TimeUnit.SECONDS)
AppExecutors.mainThread.execute {
showHideLoading(false)
startActivity(MainActivity::class.java)
finish()
}
}, 1, TimeUnit.SECONDS)
}
}


lateinit var learnDialog :LearnDialog
lateinit var learnDialog1: LearnDialog

override fun rightClick() {
if (!this::learnDialog1.isInitialized) {
learnDialog1 = LearnDialog()
}
LogUtil.e("Dialog 1 -- > ${learnDialog1.hashCode()}")
learnDialog1.show(supportFragmentManager,javaClass.name)
}

override fun leftClick() {
learnDialog1.dismiss()
}


}

+ 6
- 0
app/src/main/res/color/selectpress_maintextcolor_to_themcolor.xml View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--按钮:按下字体-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/theme_color" android:state_pressed="true"/>
<item android:color="@color/main_text_color" android:state_pressed="false"/>
</selector>

+ 5
- 0
app/src/main/res/drawable/shape_rounder_12_white.xml View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="12dp"/>
<solid android:color="@color/white"/>
</shape>

+ 12
- 7
app/src/main/res/layout/activity_course_main.xml View File

@@ -8,27 +8,30 @@

<variable
name="coursePack"
type="com.xkl.cdl.data.course.CoursePack" />
type="com.xkl.cdl.data.bean.course.CoursePack" />
<import type="android.view.View"/>
</data>

<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".module.m_center_learn.CourseMainActivity">
tools:context=".module.m_center_learn.CoursePackMainActivity"
android:background="@color/white">

<!--模糊图-->
<ImageView
android:id="@+id/img_course_pack_cover_blur"
android:layout_width="0dp"
android:layout_height="0dp"
android:scaleType="matrix"
bind:imgByteArray="@{coursePack.cover}"
bind:blur= "@{false}"
android:scaleType="fitXY"
bind:imgBytes="@{coursePack.cover}"
bind:blur= "@{true}"
app:layout_constraintBottom_toBottomOf="@+id/view_placeholder_1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:background="@color/gray_2" />
tools:background="@color/gray_2"
android:alpha="0.5"/>

<!--状态栏-->
<View
@@ -41,9 +44,11 @@

<include
android:id="@+id/include_title_bar"
android:layout_width="match_parent"
android:layout_height="@dimen/title_bar_height"
layout="@layout/include_title_bar"
app:layout_constraintTop_toBottomOf="@+id/status_bar_view"
bind:title="@string/course_detail" />
bind:titleValue="@{@string/course_detail}" />

<View
android:id="@+id/view_placeholder_1"

+ 9
- 0
app/src/main/res/layout/activity_exam_learn_spell.xml View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".module.learn.LearnExamSpellActivity">

</androidx.constraintlayout.widget.ConstraintLayout>

+ 9
- 0
app/src/main/res/layout/activity_learn_creading.xml View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".module.learn.LearnCReadingActivity">

</androidx.constraintlayout.widget.ConstraintLayout>

+ 9
- 0
app/src/main/res/layout/activity_learn_ctask.xml View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".module.learn.LearnCTaskActivity">

</androidx.constraintlayout.widget.ConstraintLayout>

+ 9
- 0
app/src/main/res/layout/activity_learn_cvideo.xml View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".module.learn.LearnCVideoActivity">

</androidx.constraintlayout.widget.ConstraintLayout>

+ 9
- 0
app/src/main/res/layout/activity_learn_exam_word.xml View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".module.learn.LearnExamWordActivity">

</androidx.constraintlayout.widget.ConstraintLayout>

+ 9
- 0
app/src/main/res/layout/activity_learn_spell.xml View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".module.learn.LearnSpellActivity">

</androidx.constraintlayout.widget.ConstraintLayout>

+ 9
- 0
app/src/main/res/layout/activity_learn_word.xml View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".module.learn.LearnWordActivity">

</androidx.constraintlayout.widget.ConstraintLayout>

+ 54
- 0
app/src/main/res/layout/dialog_bottom_auto_play_select.xml View File

@@ -0,0 +1,54 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">

<data>

</data>

<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/shape_rounder_toplr_24_white">

<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="46dp"
android:text="@string/please_select_the_operation_you_want_to_do"
android:textColor="@color/gray_2"
android:textSize="@dimen/smallSize"
android:gravity="center"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<ImageView
android:id="@+id/iv_cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="@id/tv_title"
app:layout_constraintBottom_toBottomOf="@+id/tv_title"
app:layout_constraintEnd_toEndOf="parent"
android:src="@drawable/ic_delete"
android:layout_marginEnd="24dp" />

<View
android:id="@+id/v_line"
android:layout_width="match_parent"
android:layout_height="@dimen/line_height"
android:background="@color/gray_1"
app:layout_constraintTop_toBottomOf="@+id/tv_title" />

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_repeat"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/v_line"
android:overScrollMode="never"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
android:orientation="vertical"/>


</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

+ 64
- 0
app/src/main/res/layout/dialog_bottom_course_more.xml View File

@@ -0,0 +1,64 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">

<data>

</data>

<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/shape_rounder_toplr_24_white">

<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="46dp"
android:gravity="center"
android:text="@string/please_select_the_operation_you_want_to_do"
android:textColor="@color/gray_2"
android:textSize="@dimen/smallSize"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<ImageView
android:id="@+id/iv_cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="24dp"
android:src="@drawable/ic_delete"
app:layout_constraintBottom_toBottomOf="@+id/tv_title"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/tv_title" />

<View
android:id="@+id/v_line"
android:layout_width="match_parent"
android:layout_height="@dimen/line_height"
android:background="@color/gray_1"
app:layout_constraintTop_toBottomOf="@+id/tv_title" />

<TextView
android:id="@+id/tv_auto_play"
android:layout_width="match_parent"
android:layout_height="48dp"
android:gravity="center"
android:text="@string/auto_play_the_words_learned"
android:textColor="@color/main_text_color"
android:textSize="@dimen/normalSize"
app:layout_constraintTop_toBottomOf="@+id/v_line" />

<TextView
android:id="@+id/tv_clear_learn_record"
android:layout_width="match_parent"
android:layout_height="48dp"
android:gravity="center"
android:text="@string/clear_learn_record"
android:textColor="@color/main_text_color"
android:textSize="@dimen/normalSize"
app:layout_constraintTop_toBottomOf="@+id/tv_auto_play" />

</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

+ 25
- 0
app/src/main/res/layout/dialog_item_select_repeat.xml View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?><!--重复播放次数加载框-->
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">

<data>

</data>

<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">

<TextView
android:id="@+id/tv_option"
android:layout_width="match_parent"
android:layout_height="48dp"
android:textColor="@color/gray_2"
android:textSize="@dimen/normalSize"
tools:text="重复次数"
android:gravity="center"
app:layout_constraintTop_toTopOf="parent"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

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

@@ -0,0 +1,204 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">

<data>

</data>

<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="300dp"
android:layout_height="wrap_content">


<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="76dp"
android:background="@drawable/shape_rounder_12_white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">

<ImageView
android:id="@+id/iv_close"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:src="@drawable/ic_delete"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:visibility="visible" />


<TextView
android:id="@+id/tv_score"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="80dp"
android:textColor="@color/theme_color"
android:textSize="28dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="%d分"
android:visibility="gone"
tools:visibility="visible"/>

<TextView
android:id="@+id/tv_tip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/current_test_score"
android:textColor="@color/gray_2"
android:textSize="@dimen/miniSize"
app:layout_constraintEnd_toEndOf="@+id/tv_score"
app:layout_constraintStart_toStartOf="@+id/tv_score"
app:layout_constraintTop_toBottomOf="@+id/tv_score"
android:visibility="gone"
tools:visibility="visible"/>

<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
app:layout_goneMarginTop="80dp"
android:textColor="@color/main_text_color"
android:textSize="@dimen/smallSize"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_tip"
tools:text="课时学前测试" />

<TextView
android:id="@+id/tv_lesson_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:gravity="center"
android:paddingStart="@dimen/global_spacing"
android:paddingEnd="@dimen/global_spacing"
android:textColor="@color/theme_color"
android:textSize="@dimen/miniSize"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_title"
tools:text="[%s%s]"/>

<TextView
android:id="@+id/tv_count_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:textColor="@color/gray_2"
android:textSize="@dimen/miniSize"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_lesson_name"
tools:text="@string/test_count_time_format"/>

<TextView
android:id="@+id/tv_tip_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:textColor="@color/gray_2"
android:textSize="@dimen/miniSize"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_title"
tools:text="@string/test_before_test_over_tip"
android:visibility="gone"
tools:visibility="visible"/>

<include
android:id="@+id/inc_statistics_number"
layout="@layout/inc_over_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_tip_1"
android:visibility="gone"/>



<androidx.constraintlayout.widget.Barrier
android:id="@+id/barrier"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="bottom"
app:barrierMargin="@dimen/miniSize"
app:constraint_referenced_ids="tv_count_time,inc_statistics_number" />

<View
android:id="@+id/bottom_top_line"
android:layout_width="wrap_content"
android:layout_height="@dimen/line_height"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:background="@color/gray_3"
app:layout_constraintTop_toBottomOf="@+id/barrier" />

<!--一直显示的按钮: 即常驻按钮 -->
<TextView
android:id="@+id/tv_right"
android:layout_width="0dp"
android:layout_height="40dp"
android:gravity="center"
android:text="@string/start_test"
android:textColor="@color/theme_color"
android:textSize="@dimen/smallSize"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/bottom_top_line"
app:layout_constraintStart_toEndOf="@id/vSplit"
/>

<View
android:id="@+id/vSplit"
android:layout_width="@dimen/line_height"
android:layout_height="0dp"
app:layout_constraintEnd_toStartOf="@+id/tv_right"
app:layout_constraintStart_toEndOf="@+id/tv_left"
android:background="@color/gray_3"
app:layout_constraintTop_toTopOf="@+id/tv_right"
app:layout_constraintBottom_toBottomOf="@+id/tv_right" />

<!--左边按钮-->
<TextView
android:id="@+id/tv_left"
android:layout_width="0dp"
android:layout_height="40dp"
android:gravity="center"
android:text="@string/start_test"
android:textColor="@color/main_text_color"
android:textSize="@dimen/smallSize"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@+id/vSplit"
app:layout_constraintTop_toTopOf="@+id/vSplit"
app:layout_constraintBottom_toBottomOf="@+id/vSplit"
android:visibility="gone"
/>

</androidx.constraintlayout.widget.ConstraintLayout>

<ImageView
android:id="@+id/img_iv"
android:layout_width="160dp"
android:layout_height="160dp"
android:layout_centerHorizontal="true"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:src="@mipmap/girl_2"
/>


</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

+ 65
- 0
app/src/main/res/layout/fragment_course_lesson.xml View File

@@ -0,0 +1,65 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">

<data>

</data>

<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".module.m_center_learn.coursechildren.CourseLessonFragment">
<!-- LinearLayout 仅在口语课程时显示-->
<LinearLayout
android:id="@+id/spoken_top_layout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@color/gray_3"
android:orientation="horizontal"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:visibility="visible">

<TextView
android:id="@+id/tv_auto_dialogue"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:text="@string/english_spoken_pattern_auto_play"
android:textColor="@color/selectpress_maintextcolor_to_themcolor"
android:textSize="@dimen/normalSize" />

<TextView
android:id="@+id/tv_follow_dialogue"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:text="@string/english_spoken_pattern_follow"
android:textColor="@color/selectpress_maintextcolor_to_themcolor"
android:textSize="@dimen/normalSize" />
</LinearLayout>


<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="0dp"
android:layout_height="0dp"
android:overScrollMode="never"
android:scrollbars="none"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/spoken_top_layout" />

</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

+ 9
- 0
app/src/main/res/layout/fragment_course_main.xml View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/layout_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".module.m_center_learn.coursechildren.CourseMainFragment">

</FrameLayout>

+ 66
- 0
app/src/main/res/layout/fragment_course_review.xml View File

@@ -0,0 +1,66 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">

<data>

</data>

<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".module.m_center_learn.coursechildren.CourseReviewFragment">

<ImageView
android:id="@+id/iv_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/boy_3"
app:layout_constraintBottom_toTopOf="@+id/tv_tips"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.497"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.2"
app:layout_constraintVertical_chainStyle="packed"/>

<TextView
android:id="@+id/tv_tips"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:textColor="@color/main_text_color"
android:textSize="@dimen/normalSize"
android:textStyle="bold"
app:layout_constraintBottom_toTopOf="@+id/tv_start_review"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/iv_icon"
tools:text="你将进行智能复习/你将进行[%s]课程智能复习" />

<TextView
android:id="@+id/tv_review_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:textColor="@color/main_text_color"
android:textSize="@dimen/smallSize"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_tips"
tools:text="本次智能复习数%d" />

<Button
android:id="@+id/tv_start_review"
style="@style/common_button_style"
android:text="@string/start_review"
app:cornerRadius="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_tips" />


</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

+ 136
- 0
app/src/main/res/layout/fragment_course_total_test.xml View File

@@ -0,0 +1,136 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">

<data>

</data>

<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
tools:context=".module.m_center_learn.coursechildren.CourseTotalTestFragment">

<ImageView
android:id="@+id/iv_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/boy_1"
app:layout_constraintBottom_toTopOf="@+id/tv_title"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.2"
app:layout_constraintVertical_chainStyle="packed" />

<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:text="@string/test_total_after_tip_1"
android:textColor="@color/main_text_color"
android:textSize="@dimen/normalSize"
android:textStyle="bold"
app:layout_constraintBottom_toTopOf="@+id/tv_main_tip"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/iv_icon"
android:visibility="visible" />


<TextView
android:id="@+id/tv_main_tip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:text="@string/test_total_before_title"
android:textColor="@color/main_text_color"
android:textSize="@dimen/normalSize"
app:layout_constraintBottom_toTopOf="@+id/tv_tips"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_title"
android:visibility="gone"
tools:visibility="visible"/>

<TextView
android:id="@+id/tv_tips"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:text="@string/test_total_after_tip_3"
android:textColor="@color/gray_2"
android:textSize="@dimen/smallSize"
app:layout_constraintBottom_toTopOf="@+id/tv_count_tip"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_main_tip"
android:visibility="gone"
tools:visibility="visible"/>

<TextView
android:id="@+id/tv_count_tip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:textColor="@color/theme_color"
android:textSize="@dimen/smallSize"
app:layout_constraintBottom_toTopOf="@+id/button_2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_tips"
tools:text="@string/test_count_time_format" />

<Button
android:id="@+id/button_1"
style="@style/Widget.MaterialComponents.Button.UnelevatedButton"
android:layout_width="0dp"
android:layout_height="@dimen/common_button_height"
android:layout_marginStart="@dimen/global_spacing"
android:insetTop="0dp"
android:insetBottom="0dp"
app:cornerRadius="8dp"
android:textColor="@color/theme_color"
android:textSize="@dimen/smallSize"
app:layout_constraintEnd_toStartOf="@+id/button_2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/button_2"
app:strokeColor="@color/theme_color"
app:strokeWidth="@dimen/line_height"
android:visibility="gone"
tools:visibility="visible"/>

<Button
android:id="@+id/button_2"
style="@style/common_button_style"
android:layout_width="0dp"
android:layout_height="@dimen/common_button_height"
android:layout_marginStart="12dp"
android:layout_marginTop="40dp"
android:layout_marginEnd="@dimen/global_spacing"
app:cornerRadius="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/button_1"
app:layout_constraintTop_toBottomOf="@+id/tv_count_tip"
app:layout_goneMarginStart="@dimen/global_spacing" />

<TextView
android:id="@+id/tv_clear_learn_record"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="@string/clear_learn_record"
android:textColor="@color/gray_2"
android:textSize="@dimen/smallSize"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button_2"
tools:visibility="visible"/>
</androidx.constraintlayout.widget.ConstraintLayout>

</layout>

+ 76
- 0
app/src/main/res/layout/inc_over_number.xml View File

@@ -0,0 +1,76 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">

<data>

</data>

<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:showIn="@layout/dialog_lesson_learn">


<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.5" />

<TextView
android:id="@+id/tv_correct_tip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginRight="28dp"
android:text="@string/correct"
android:textColor="@color/main_text_color"
android:textSize="@dimen/miniSize"
app:layout_constraintEnd_toEndOf="@+id/guideline_1"
app:layout_constraintTop_toTopOf="parent" />

<TextView
android:id="@+id/tv_error_tip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="28dp"
android:layout_marginTop="8dp"
android:text="@string/error"
android:textColor="@color/gray_2"
android:textSize="@dimen/miniSize"
app:layout_constraintStart_toEndOf="@+id/guideline_1"
app:layout_constraintTop_toTopOf="parent" />


<TextView
android:id="@+id/tv_correct_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:textColor="@color/green_1"
android:textSize="@dimen/bigSize"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="@+id/tv_correct_tip"
app:layout_constraintStart_toStartOf="@+id/tv_correct_tip"
app:layout_constraintTop_toBottomOf="@+id/tv_correct_tip"
tools:text="20" />

<TextView
android:id="@+id/tv_error_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:textColor="@color/red_1"
android:textSize="@dimen/bigSize"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="@+id/tv_error_tip"
app:layout_constraintStart_toStartOf="@+id/tv_error_tip"
app:layout_constraintTop_toBottomOf="@+id/tv_error_tip"
tools:text="0" />


</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

+ 55
- 48
app/src/main/res/layout/include_main_learn_center_course_progress.xml View File

@@ -1,52 +1,59 @@
<?xml version="1.0" encoding="utf-8"?>

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="28dp"
android:background="@color/gray_3"
android:paddingStart="@dimen/global_spacing"
android:paddingEnd="@dimen/global_spacing"
tools:showIn="@layout/activity_course_main">

<TextView
android:id="@+id/tv_progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/theme_color"
android:textSize="@dimen/miniSize"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="%s学习进度: %d%" />


<ProgressBar
android:id="@+id/progressbar"
style="@android:style/Widget.ProgressBar.Horizontal"
android:layout_width="0dp"
android:layout_height="4dp"
android:layout_marginStart="26dp"
android:layout_marginEnd="26dp"
android:layout_weight="1"
android:max="1000"
android:progressDrawable="@drawable/progress_center"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/iv_more"
app:layout_constraintStart_toEndOf="@+id/tv_progress"
app:layout_constraintTop_toTopOf="parent" />

<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/iv_more"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_more"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/progressbar"
app:layout_constraintTop_toTopOf="parent" />


</androidx.constraintlayout.widget.ConstraintLayout>
xmlns:tools="http://schemas.android.com/tools">

<data>

</data>

<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="28dp"
android:background="@color/gray_3"
android:paddingStart="@dimen/global_spacing"
android:paddingEnd="@dimen/global_spacing"
tools:showIn="@layout/activity_course_main">

<TextView
android:id="@+id/tv_progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/theme_color"
android:textSize="@dimen/miniSize"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="%s学习进度: %d%" />


<ProgressBar
android:id="@+id/progressbar"
style="@android:style/Widget.ProgressBar.Horizontal"
android:layout_width="0dp"
android:layout_height="4dp"
android:layout_marginStart="26dp"
android:layout_marginEnd="26dp"
android:layout_weight="1"
android:max="1000"
android:progressDrawable="@drawable/progress_center"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/iv_more"
app:layout_constraintStart_toEndOf="@+id/tv_progress"
app:layout_constraintTop_toTopOf="parent" />

<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/iv_more"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_more"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/progressbar"
app:layout_constraintTop_toTopOf="parent" />


</androidx.constraintlayout.widget.ConstraintLayout>
</layout>


+ 12
- 3
app/src/main/res/layout/include_main_learn_center_course_type_title.xml View File

@@ -21,12 +21,15 @@
android:drawableStart="@drawable/ic_discern"
android:text="认读"
bind:svgColor="@{@color/theme_color}"
android:textColor="@color/theme_color"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/iv_arrow_1"
android:gravity="center"
android:drawablePadding="4dp" />
android:drawablePadding="4dp"
android:visibility="gone"
tools:visibility="visible"/>

<ImageView
android:id="@+id/iv_arrow_1"
@@ -47,13 +50,16 @@
android:layout_height="match_parent"
android:drawableStart="@drawable/ic_spell"
bind:svgColor="@{@color/theme_color}"
android:textColor="@color/theme_color"
android:text="拼写"
app:layout_constraintStart_toEndOf="@+id/iv_arrow_1"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/iv_arrow_2"
android:gravity="center"
android:drawablePadding="4dp" />
android:drawablePadding="4dp"
android:visibility="gone"
tools:visibility="visible"/>

<ImageView
android:id="@+id/iv_arrow_2"
@@ -74,12 +80,15 @@
android:drawableStart="@drawable/ic_voice"
android:text="辨音"
bind:svgColor="@{@color/theme_color}"
android:textColor="@color/theme_color"
app:layout_constraintStart_toEndOf="@+id/iv_arrow_2"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:gravity="center"
android:drawablePadding="4dp" />
android:drawablePadding="4dp"
android:visibility="gone"
tools:visibility="visible"/>

</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

+ 7
- 3
app/src/main/res/layout/include_title_bar.xml View File

@@ -2,11 +2,14 @@
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto">
<!--使用bind添加属性值最好添加一个默认值,否则会将没有设置的属性设置未默认值,如:设置标题和颜色,如果没有设置颜色默认值,则标题将为透明色-->
<data>
<variable
name="title"
name="titleValue"
type="java.lang.String" />
<variable
name="titleColor"
type="Integer" />
</data>

<com.suliang.common.widget.TitleBar
@@ -16,7 +19,8 @@
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:titleTextValue="@{title}"
app:titleTextValue="@{titleValue}"
app:titleTextColor="@{titleColor??@color/main_text_color}"
/>

</layout>

+ 98
- 0
app/src/main/res/layout/item_course_lesson.xml View File

@@ -0,0 +1,98 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">

<data>
<variable
name="data"
type="com.xkl.cdl.data.bean.course.Lesson" />
</data>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">

<TextView
android:id="@+id/tv_chapter_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/gray_2"
android:textSize="@dimen/smallSize"
android:layout_marginStart="@dimen/global_spacing"
android:layout_marginEnd="@dimen/global_spacing"
android:paddingTop="8dp"
android:text="@{data.chapterName}"
tools:text="unit1"
android:visibility="gone"
tools:visibility="visible" />

<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/layout_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="5dp"
android:paddingBottom="5dp">

<TextView
android:id="@+id/tv_serial_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="01"
android:textSize="28dp"
android:textColor="@color/gray_1"
android:text='@{String.format("%02d",data.lessonPositionInList + 1)}'
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="@dimen/global_spacing"/>

<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/iv_arrow_right"
android:layout_width="36dp"
android:layout_height="36dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginEnd="@dimen/global_spacing"
android:scaleType="centerInside"
android:src="@drawable/ic_arrow_right"
app:shapeAppearance="@style/roundedCornerStyle"
app:strokeColor="@color/gray_2"
app:strokeWidth="@dimen/line_height"
android:padding="@dimen/line_height"
/>

<TextView
android:id="@+id/tv_lesson_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="单词体验课01"
android:textSize="@dimen/normalSize"
android:textColor="@color/gray_2"
android:layout_marginStart="@dimen/global_spacing"
app:layout_constraintStart_toEndOf="@+id/tv_serial_number"
app:layout_constraintEnd_toStartOf="@+id/iv_arrow_right"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@+id/tv_lesson_number"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintVertical_chainStyle="packed"
android:text="@{data.lessonName}"/>

<TextView
android:id="@+id/tv_lesson_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="@+id/tv_lesson_name"
app:layout_constraintTop_toBottomOf="@+id/tv_lesson_name"
app:layout_constraintEnd_toEndOf="@+id/iv_arrow_right"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="0"
tools:text="@string/lesson_number_format"
android:text="@{@string/lesson_number_format(data.totalNumber,data.correctNumber,data.errorNumber)}"/>

</androidx.constraintlayout.widget.ConstraintLayout>

</LinearLayout>
</layout>

+ 1
- 1
app/src/main/res/layout/main_item_coursepack.xml View File

@@ -7,7 +7,7 @@

<variable
name="coursePack"
type="com.xkl.cdl.data.course.CoursePack" />
type="com.xkl.cdl.data.bean.course.CoursePack" />

</data>


BIN
app/src/main/res/mipmap-xxhdpi/boy_1.png View File


BIN
app/src/main/res/mipmap-xxhdpi/boy_2.png View File


BIN
app/src/main/res/mipmap-xxhdpi/boy_3.png View File


BIN
app/src/main/res/mipmap-xxhdpi/girl_1.png View File


BIN
app/src/main/res/mipmap-xxhdpi/girl_2.png View File


+ 3
- 0
app/src/main/res/values-land/dimens.xml View File

@@ -0,0 +1,3 @@
<resources>
<dimen name="fab_margin">48dp</dimen>
</resources>

+ 3
- 0
app/src/main/res/values-w1240dp/dimens.xml View File

@@ -0,0 +1,3 @@
<resources>
<dimen name="fab_margin">200dp</dimen>
</resources>

+ 3
- 0
app/src/main/res/values-w600dp/dimens.xml View File

@@ -0,0 +1,3 @@
<resources>
<dimen name="fab_margin">48dp</dimen>
</resources>

+ 13
- 0
app/src/main/res/values/colors.xml View File

@@ -17,6 +17,7 @@
<color name="theme_color">#FF5082E6</color>
<color name="main_text_color">#323233</color>

<color name="translation">#00000000</color>
<color name="gray_1">#FFE6E6E6</color>
<color name="gray_2">#8A8A99</color>
<color name="white">#FFFFFFFF</color>
@@ -24,4 +25,16 @@
<color name="blue_1">#52CC52</color>
<color name="gray_3">#FAFAFA</color>
<color name="green_1">#40A540</color>
<color name="red_1">#FFF26255</color>


<color name="num0">#E50213</color>
<color name="num1">#E50251</color>
<color name="num2">#E4560F</color>
<color name="num3">#7D7530</color>
<color name="num4">#048F3A</color>
<color name="num5">#1680C4</color>
<color name="num6">#014262</color>
<color name="num7">#505050</color>

</resources>

+ 3
- 0
app/src/main/res/values/dimens.xml View File

@@ -10,6 +10,9 @@
<dimen name="biggerSize">20dp</dimen>
<dimen name="title_bar_height">44dp</dimen>
<dimen name="global_spacing">16dp</dimen>
<dimen name="common_button_height">44dp</dimen>
<dimen name="fab_margin">16dp</dimen>
<dimen name="common_dialog_width">300dp</dimen>


</resources>

+ 37
- 0
app/src/main/res/values/strings.xml View File

@@ -19,5 +19,42 @@
<string name="empty_nothing_search">没有搜索到任何内容</string>
<string name="course_detail">课程详情</string>
<string name="introduction">简介</string>
<string name="start_review">开始复习</string>
<string name="please_select_the_operation_you_want_to_do">请选择你要进行的操作</string>
<string name="auto_play_the_words_learned">自动播放已学单词</string>
<string name="clear_learn_record">清空学习记录</string>
<string name="auto_play_repeat_1">重复1次</string>
<string name="auto_play_repeat_2">重复2次</string>
<string name="auto_play_repeat_3">重复3次</string>
<string name="auto_play_repeat_4">重复4次</string>
<string name="auto_play_repeat_5">重复5次</string>
<string name="english_spoken_pattern_auto_play">自动播放</string>
<string name="english_spoken_pattern_follow">跟读模式</string>

<string name="lesson_number_format">条目%d - 正确%d | 错误%d</string>
<string name="test_total_before_title">我当前掌握的知识量量是?去学前总测试一下吧!</string>
<string name="test_count_time_format">共%1$d题,预计%2$d分钟</string>
<string name="tips_current_course_learn_over">本课程学习完毕</string>
<string name="test_total_after_tip_1">我的学习效果是?快去学后总测试吧!</string>
<string name="test_total_after_tip_2">你还未通过学后总测试,上次得分:</string>
<string name="test_total_after_tip_3">系统将为你安排智能复习</string>
<string name="start_test">开始测试</string>
<string name="continue_learn">继续学习</string>
<string name="test_again">再测一次</string>
<string name="test_type_after_total">学后总测试</string>
<string name="title_activity_learn_base">LearnBaseActivity</string>
<!-- Strings used for fragments for navigation -->
<string name="first_fragment_label">First Fragment</string>
<string name="second_fragment_label">Second Fragment</string>
<string name="next">Next</string>
<string name="previous">Previous</string>

<string name="hello_first_fragment">Hello first fragment</string>
<string name="hello_second_fragment">Hello second fragment. Arg: %1$s</string>
<string name="current_test_score">本次测试成绩</string>
<string name="test_before_test_over_tip">测试成绩不理想?别分心,学考乐让你快速提分!</string>
<string name="correct">正确</string>
<string name="error">错误</string>
<string name="start_learn">开始学习</string>

</resources>

+ 26
- 0
app/src/main/res/values/styles.xml View File

@@ -8,4 +8,30 @@
<item name="cornerSize">8dp</item>
</style>

<!--通用按钮style https://blog.csdn.net/weixin_42046829/article/details/110224702
https://www.jianshu.com/p/bc71b4179cb2-->
<style name="common_button_style" parent="Widget.MaterialComponents.Button.UnelevatedButton">
<item name="android:layout_width">0dp</item>
<item name="android:layout_height">@dimen/common_button_height</item>
<item name="android:gravity">center</item>
<item name="android:insetTop">0dp</item>
<item name="android:insetBottom">0dp</item>
<item name="android:textSize">@dimen/smallSize</item>
<item name="android:textColor">@color/white</item>
<item name="android:layout_marginStart">38dp</item>
<item name="android:layout_marginEnd">38dp</item>
<item name="android:layout_marginTop">66dp</item>
<item name="android:backgroundTint">@color/theme_color</item>
</style>

<!--dialog style -->
<style name="dialog_style" parent="@android:style/Theme.Dialog">
<item name="android:windowBackground">@android:color/transparent</item> <!--窗口背景透明-->
<item name="android:windowFrame">@null</item> <!--边框-->
<item name="android:windowNoTitle">true</item> <!--无标题-->
<item name="android:windowIsFloating">true</item> <!--是否浮现在activity之上-->
<item name="android:windowIsTranslucent">true</item> <!--是否半透明-->
<item name="android:backgroundDimEnabled">true</item> <!--模糊,背景透明是这个- 弹窗背景是否变暗 -->
</style>

</resources>

+ 15
- 6
app/src/main/res/values/themes.xml View File

@@ -3,13 +3,13 @@
<style name="Theme.XklLocal" parent="Theme.MaterialComponents.Light.DarkActionBar">
<!-- Primary brand color. -->
<item name="colorPrimary">@color/white</item> <!--AppBar背景色-->
<!-- <item name="colorPrimaryVariant">@color/white</item>-->
<!-- <item name="colorPrimaryVariant">@color/white</item>-->
<item name="colorOnPrimary">@color/black</item>
<!-- &lt;!&ndash; Secondary brand color. &ndash;&gt;-->
<!-- <item name="colorSecondary">@color/white</item>-->
<!-- <item name="colorSecondaryVariant">@color/white</item>-->
<!-- <item name="colorOnSecondary">@color/white</item>-->
<!-- &lt;!&ndash; Status bar color. &ndash;&gt;-->
<!-- &lt;!&ndash; Secondary brand color. &ndash;&gt;-->
<!-- <item name="colorSecondary">@color/white</item>-->
<!-- <item name="colorSecondaryVariant">@color/white</item>-->
<!-- <item name="colorOnSecondary">@color/white</item>-->
<!-- &lt;!&ndash; Status bar color. &ndash;&gt;-->
<item name="android:statusBarColor" tools:targetApi="l">@color/white</item>
<!-- Customize your theme here. -->
<item name="android:textAllCaps">false</item>
@@ -30,4 +30,13 @@
<item name="android:windowBackground">@drawable/theme_splash_bg</item>
</style>

<style name="Theme.XklLocal.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>

<style name="Theme.XklLocal.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />

<style name="Theme.XklLocal.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />

</resources>

+ 4
- 1
build.gradle View File

@@ -82,7 +82,10 @@ ext {
//SmartRefreshLayout
SmartRefreshLayout: "io.github.scwang90:refresh-layout-kernel:2.0.5",
//Lottie
Lottie : "com.airbnb.android:lottie:5.0.3"
Lottie : "com.airbnb.android:lottie:5.0.3",
//Rxjava RxAndroid
RxJava : "io.reactivex.rxjava3:rxjava:3.1.4",
RxAndroid: "io.reactivex.rxjava3:rxandroid:3.0.0"
]



+ 4
- 0
lib/common/build.gradle View File

@@ -43,6 +43,7 @@ android {
}

dependencies {
// implementation fileTree(include: ['*.jar',"*.aar"], dir: 'libs')
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
rootProject.ext.dependencies_required.each{ k, v -> implementation v}
testImplementation rootProject.ext.dependencies_testImplementation.junit
@@ -59,6 +60,9 @@ dependencies {
kapt customDependencies.GlideCompiler
//glide translation
api customDependencies.GlideTranslation
//RxJava RxAndroid
api customDependencies.RxJava
api customDependencies.RxAndroid




lib/common/src/main/java/com/suliang/common/Config.kt → lib/common/src/main/java/com/suliang/common/AppConfig.kt View File

@@ -5,7 +5,7 @@ package com.suliang.common
* create 2022/3/17 17:04
* Describe:
*/
object Config {
object AppConfig {
const val INTENT_1 = "intent_1"
const val INTENT_2 = "intent_2"
const val INTENT_3 = "intent_3"

+ 3
- 1
lib/common/src/main/java/com/suliang/common/base/BaseDialogFragment.kt View File

@@ -54,5 +54,7 @@ abstract class BaseDialogFragment<VB : ViewBinding> : DialogFragment() {
abstract fun initFragment()

/** 是否布局背景透明 */
abstract fun isTransparent():Boolean
open fun isTransparent():Boolean {
return true
}
}

+ 3
- 3
lib/common/src/main/java/com/suliang/common/base/LoadingDialog.kt View File

@@ -1,7 +1,7 @@
package com.suliang.common.base

import android.graphics.drawable.AnimationDrawable
import com.suliang.common.Config
import com.suliang.common.AppConfig
import com.suliang.common.databinding.LoadingFragmentBinding

/**
@@ -15,14 +15,14 @@ class LoadingDialog : BaseDialogFragment<LoadingFragmentBinding>() {
@JvmStatic
fun newInstance(msg : String): LoadingDialog {
return LoadingDialog().apply {
arguments?.putString(Config.INTENT_1,msg)
arguments?.putString(AppConfig.INTENT_1,msg)
}
}
}

override fun initFragment() {
//外部设置
arguments?.getString(Config.INTENT_1,null)?.let {
arguments?.getString(AppConfig.INTENT_1,null)?.let {
binding.loadText.text = it
}


+ 0
- 0
lib/common/src/main/java/com/suliang/common/base/activity/BaseActivity.kt View File


Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save