Browse Source

备忘本

master
suliang 2 years ago
parent
commit
8eb7dabe65
67 changed files with 3643 additions and 127 deletions
  1. 0
    1
      .idea/gradle.xml
  2. 36
    3
      .idea/misc.xml
  3. 3
    0
      README.md
  4. 5
    0
      app/build.gradle
  5. BIN
      app/libs/mobile_cache.aar
  6. 6
    0
      app/src/main/AndroidManifest.xml
  7. 49
    0
      app/src/main/java/com/xkl/cdl/adapter/AdapterCourseLessonTestChoose.kt
  8. 345
    0
      app/src/main/java/com/xkl/cdl/adapter/AdapterMemoDetailList.kt
  9. 126
    0
      app/src/main/java/com/xkl/cdl/adapter/AdapterTestDetail.kt
  10. 2
    0
      app/src/main/java/com/xkl/cdl/data/AppConstants.kt
  11. 2
    2
      app/src/main/java/com/xkl/cdl/data/bean/BaseWord.kt
  12. 1
    1
      app/src/main/java/com/xkl/cdl/data/bean/LearnDialogBean.kt
  13. 12
    0
      app/src/main/java/com/xkl/cdl/data/bean/MemoBean.kt
  14. 1
    0
      app/src/main/java/com/xkl/cdl/data/bean/intentdata/MemoData.kt
  15. 268
    21
      app/src/main/java/com/xkl/cdl/data/manager/db/DBCourseManager.kt
  16. 9
    0
      app/src/main/java/com/xkl/cdl/data/repository/DataRepository.kt
  17. 35
    0
      app/src/main/java/com/xkl/cdl/dialog/LearnDialog.kt
  18. 29
    0
      app/src/main/java/com/xkl/cdl/module/learn/LearnExamActivity.kt
  19. 4
    9
      app/src/main/java/com/xkl/cdl/module/learn/LearnExamViewModel.kt
  20. 0
    4
      app/src/main/java/com/xkl/cdl/module/learn/LearnWordViewModel.kt
  21. 1
    1
      app/src/main/java/com/xkl/cdl/module/m_center_learn/CoursePackMainActivityViewModel.kt
  22. 5
    6
      app/src/main/java/com/xkl/cdl/module/m_center_learn/coursechildren/CourseMainFragmentViewModel.kt
  23. 27
    17
      app/src/main/java/com/xkl/cdl/module/m_center_learn/coursechildren/CourseReviewFragment.kt
  24. 1
    1
      app/src/main/java/com/xkl/cdl/module/m_memo/MemoFragment.kt
  25. 239
    7
      app/src/main/java/com/xkl/cdl/module/m_memo/MemoListDetailActivity.kt
  26. 152
    1
      app/src/main/java/com/xkl/cdl/module/m_memo/MemoListDetailViewModel.kt
  27. 116
    0
      app/src/main/java/com/xkl/cdl/module/m_memo/MemoTestActivity.kt
  28. 151
    0
      app/src/main/java/com/xkl/cdl/module/m_memo/MemoTestViewModel.kt
  29. 66
    0
      app/src/main/java/com/xkl/cdl/module/m_service_center/TestDetailActivity.kt
  30. 36
    0
      app/src/main/java/com/xkl/cdl/module/m_service_center/TestDetailViewModel.kt
  31. 30
    0
      app/src/main/java/com/xkl/cdl/widget/CustomCalendarConstraintLayout.kt
  32. 231
    0
      app/src/main/java/com/xkl/cdl/widget/CustomMonthView.java
  33. 227
    0
      app/src/main/java/com/xkl/cdl/widget/CustomWeekView.java
  34. 5
    0
      app/src/main/res/drawable/choose_multiple.xml
  35. 5
    0
      app/src/main/res/drawable/choose_single.xml
  36. 10
    0
      app/src/main/res/drawable/selector_memo_review_bg.xml
  37. 15
    0
      app/src/main/res/drawable/selector_memo_test_bg.xml
  38. 7
    0
      app/src/main/res/drawable/shape_cicler_24_c3d69b.xml
  39. 7
    0
      app/src/main/res/drawable/shape_cicler_24_ffcc99.xml
  40. 5
    0
      app/src/main/res/drawable/shape_rounder_8_solid_green1.xml
  41. 5
    0
      app/src/main/res/drawable/shape_rounder_bottomlr_8_solider_white_1.xml
  42. 6
    0
      app/src/main/res/drawable/shape_rounder_toplr_8_white_1.xml
  43. 97
    0
      app/src/main/res/layout/_xpopup_ext_time_picker.xml
  44. 1
    1
      app/src/main/res/layout/activity_main.xml
  45. 180
    48
      app/src/main/res/layout/activity_memo_list_detail.xml
  46. 191
    0
      app/src/main/res/layout/activity_memo_test.xml
  47. 228
    0
      app/src/main/res/layout/activity_test_detail.xml
  48. 6
    1
      app/src/main/res/layout/dialog_lesson_learn.xml
  49. 22
    0
      app/src/main/res/layout/item_checkbox.xml
  50. 169
    0
      app/src/main/res/layout/item_memo_detail_list_english.xml
  51. 138
    0
      app/src/main/res/layout/item_memo_detail_list_literacy.xml
  52. 134
    0
      app/src/main/res/layout/item_memo_detail_list_pinyin.xml
  53. 69
    0
      app/src/main/res/layout/item_test_detail.xml
  54. 12
    0
      app/src/main/res/layout/item_test_detail_option_1.xml
  55. 1
    0
      app/src/main/res/values/colors.xml
  56. 3
    0
      app/src/main/res/values/strings.xml
  57. 12
    0
      app/svg/drawable/ic_checked_1.xml
  58. 12
    0
      app/svg/drawable/ic_checked_2.xml
  59. 12
    0
      app/svg/drawable/ic_checked_normal.xml
  60. 12
    0
      app/svg/drawable/ic_down.xml
  61. 20
    0
      app/svg/drawable/ic_horuns.xml
  62. 12
    0
      app/svg/drawable/ic_memo_review.xml
  63. 12
    0
      app/svg/drawable/ic_memo_test.xml
  64. 12
    0
      app/svg/drawable/ic_up.xml
  65. 6
    2
      build.gradle
  66. 1
    1
      lib/common/src/main/java/com/suliang/common/base/adapter/BaseRVAdapter.kt
  67. 1
    0
      lib/common/src/main/java/com/suliang/common/util/DateUtil.kt

+ 0
- 1
.idea/gradle.xml View File

@@ -20,6 +20,5 @@
<option name="resolveModulePerSourceSet" value="false" />
</GradleProjectSettings>
</option>
<option name="offlineMode" value="true" />
</component>
</project>

+ 36
- 3
.idea/misc.xml View File

@@ -7,6 +7,8 @@
<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/choose_multiple.xml" value="0.5010416666666667" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/choose_single.xml" value="0.5010416666666667" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/composition_note_cb.xml" value="0.4953125" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/detail_example_flag.xml" value="0.4546296296296296" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/detail_phrase_flag.xml" value="0.4546296296296296" />
@@ -29,12 +31,21 @@
<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/progress_statistics.xml" value="0.4425925925925926" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/progressbar_countdown_time.xml" value="0.45740740740740743" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/selector_memo_review_bg.xml" value="0.5010416666666667" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/selector_memo_test_bg.xml" value="0.5010416666666667" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/shape_cicler_24_c3d69b.xml" value="0.49333333333333335" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/shape_cicler_24_ffcc99.xml" value="0.49333333333333335" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/shape_o_red.xml" value="0.36203703703703705" />
<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_8_solid_green1.xml" value="0.5010416666666667" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/shape_rounder_8_solider_gray_1.xml" value="0.5010416666666667" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/shape_rounder_8_stroke_gray1.xml" value="0.503125" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/shape_rounder_8_stroke_gray2.xml" value="0.48055555555555557" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/shape_rounder_8_stroke_green1.xml" value="0.503125" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/shape_rounder_bottomlr_8_solider_white_1.xml" value="0.503125" />
<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/shape_rounder_toplr_8_white.xml" value="0.5010416666666667" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/shape_rounder_toplr_8_white_1.xml" value="0.503125" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/shape_switch_thumb.xml" value="0.14074074074074075" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/shape_switch_track.xml" value="0.26851851851851855" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/spoken_autoplay_btn_text_color_.xml" value="0.5140625" />
@@ -44,10 +55,11 @@
<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/drawable/video_tab_bg.xml" value="0.26851851851851855" />
<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/_xpopup_ext_time_picker.xml" value="0.23632218844984804" />
<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_exam_learn_spell.xml" value="0.47690217391304346" />
<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_creading.xml" value="0.5" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/activity_learn_creading.xml" value="0.4304093567251462" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/activity_learn_ctask.xml" value="0.23353596757852077" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/activity_learn_cvideo.xml" value="0.22407407407407406" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/activity_learn_exam.xml" value="0.25" />
@@ -56,8 +68,10 @@
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/activity_learn_word.xml" value="0.5" />
<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_memo_list_detail.xml" value="0.37222222222222223" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/activity_memo_list_detail.xml" value="0.3621621621621622" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/activity_memo_test.xml" value="0.25" />
<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/activity_test_detail.xml" value="0.33" />
<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" />
@@ -82,24 +96,40 @@
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/inc_learn_test_statistic.xml" value="0.5" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/inc_learn_title.xml" value="0.25" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/inc_learn_word.xml" value="0.390625" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/inc_memo_list_item_english_header.xml" value="0.5" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/inc_memo_list_item_literacy_header.xml" value="0.2776268115942029" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/inc_memo_list_item_pinyin_header.xml" value="0.2776268115942029" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/inc_over_number.xml" value="0.4979166666666667" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/inc_spell_learn_tip.xml" value="0.67" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/inc_word.xml" value="0.390625" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/inc_word_detail.xml" value="0.30538922155688625" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/inc_word_detail.xml" value="0.5" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/includ_test_option_item.xml" value="0.45153985507246375" />
<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.6002766251728907" />
<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_checkbox.xml" value="1.0" />
<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/item_historical_route.xml" value="0.4859375" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/item_memo.xml" value="0.67" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/item_memo_course_discern_detail_list_.xml" value="0.23632218844984804" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/item_memo_detail_list_english.xml" value="0.67" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/item_memo_detail_list_for_discern.xml" value="0.2776268115942029" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/item_memo_detail_list_for_literacy.xml" value="0.67" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/item_memo_detail_list_literacy.xml" value="0.5" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/item_memo_detail_list_pinyin.xml" value="0.67" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/item_spell_single_word.xml" value="0.23632218844984804" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/item_task_image.xml" value="0.23353596757852077" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/item_test_detail.xml" value="0.348731884057971" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/item_test_detail_option.xml" value="0.348731884057971" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/item_test_detail_option_2.xml" value="0.348731884057971" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/item_video_adapter.xml" value="0.67" />
<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" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/merge_memo_list_item_english_header.xml" value="0.2373353596757852" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/merge_memo_list_item_literacy_header.xml" value="0.5" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/merge_memo_list_item_pinyin_header.xml" value="0.5" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/merge_recyclerview_smart_refresh_layout.xml" value="0.34427083333333336" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/smart_refresh_header.xml" value="0.34427083333333336" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/textview.xml" value="0.49773550724637683" />
@@ -115,6 +145,8 @@
<entry key="..\:/Work/XKL/XKL/XklLocal/app/svg/drawable/ic_course_spoken.xml" value="0.30092592592592593" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/svg/drawable/ic_course_voice.xml" value="0.35555555555555557" />
<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_down.xml" value="0.503125" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/svg/drawable/ic_horuns.xml" value="0.503125" />
<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_menu.xml" value="0.4036458333333333" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/svg/drawable/ic_more.xml" value="0.35555555555555557" />
@@ -131,6 +163,7 @@
<entry key="..\:/Work/XKL/XKL/XklLocal/app/svg/drawable/ic_right.xml" value="0.4425925925925926" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/svg/drawable/ic_spell.xml" value="0.5061538461538462" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/svg/drawable/ic_spoken.xml" value="0.5061538461538462" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/svg/drawable/ic_up.xml" value="0.503125" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/svg/drawable/ic_voice.xml" value="0.5061538461538462" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/svg/drawable/ic_wrong.xml" value="0.4425925925925926" />
<entry key="..\:/Work/XKL/XKL/XklLocal/lib/common/src/main/res/drawable/ic_back.xml" value="0.4148148148148148" />

+ 3
- 0
README.md View File

@@ -76,6 +76,9 @@ Material Design Components 组件使用 https://www.jianshu.com/p/bc71b4179cb2
实现口语收藏、作文笔记收藏
CourseMainFragmentViewModel.loadmain()

测试的时候注意一下,如果课程包的数据库进行误删不存在的情况下,如何进行规避!
日历控件使用研究


计算当前词汇量,课程完成/重学的时候调用一下;重学直接程序帮忙调用
public native long calcCurrentVocabulary(long projectID) throws Exception;

+ 5
- 0
app/build.gradle View File

@@ -113,7 +113,12 @@ dependencies {
implementation customDependencies.grpc_stub
//XPopup
implementation customDependencies.XPopup
implementation customDependencies.XPopupExt

//精美日历 calendarview
implementation customDependencies.CalendarView
// FlexBoxLayoutManager
implementation customDependencies.FlexBoxLayoutManager


}

BIN
app/libs/mobile_cache.aar View File


+ 6
- 0
app/src/main/AndroidManifest.xml View File

@@ -12,6 +12,12 @@
android:supportsRtl="true"
android:theme="@style/Theme.XklLocal"
tools:ignore="LockedOrientationActivity">
<activity
android:name=".module.m_service_center.TestDetailActivity"
android:exported="true" />
<activity
android:name=".module.m_memo.MemoTestActivity"
android:exported="true" />
<activity
android:name=".module.m_memo.MemoListDetailActivity"
android:exported="true" />

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

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

import android.annotation.SuppressLint
import android.view.ViewGroup
import androidx.core.util.set
import com.suliang.common.base.adapter.BaseAdapterViewHolder
import com.suliang.common.base.adapter.BaseRVAdapterVM
import com.xkl.cdl.R
import com.xkl.cdl.data.bean.course.Lesson
import com.xkl.cdl.databinding.ItemCheckboxBinding
import com.xkl.cdl.module.m_memo.MemoTestViewModel

/**
* author suliang
* create 2022/6/17 14:30
* Describe:
*/
class AdapterCourseLessonTestChoose(vm:MemoTestViewModel): BaseRVAdapterVM<Lesson,MemoTestViewModel>(vm) {
override fun coverViewHolder(parent : ViewGroup, viewType : Int) : BaseAdapterViewHolder {
return BaseAdapterViewHolder(inflateBinding(parent, R.layout.item_checkbox))
}
@SuppressLint("SetTextI18n")
override fun onBindVH(holder : BaseAdapterViewHolder, position : Int) {
val item = getItem(position)
(holder.binding as ItemCheckboxBinding).cbItem.apply {
text = if (vm.isShowLessonName()) "${item.chapterName} ${item.lessonName}" else item.chapterName
//设置默认选择
isChecked = vm.checkLessonArray[position]
setOnCheckedChangeListener { _, isChecked ->
when{
isChecked -> {
vm.checkLessonArray[position] = true
if (vm.checkLessonArray.size() == itemCount) {
vm.isAllCheck.value = true
}
}
else -> {
vm.checkLessonArray.delete(position)
vm.isAllCheck.value = false
}
}
}
}
}
}

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

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

import android.view.View
import android.view.ViewGroup
import androidx.core.content.ContextCompat
import com.suliang.common.base.adapter.BaseAdapterViewHolder
import com.suliang.common.base.adapter.BaseRVAdapterVM
import com.suliang.common.databinding.ItemEmptyBinding
import com.suliang.common.extension.click
import com.suliang.common.extension.setHtml
import com.suliang.common.util.media.IMP
import com.suliang.common.util.media.MPManager
import com.xkl.cdl.R
import com.xkl.cdl.data.AppConstants
import com.xkl.cdl.data.bean.LearnWord
import com.xkl.cdl.data.bean.MemoBean
import com.xkl.cdl.data.manager.CourseManager
import com.xkl.cdl.data.repository.AudioCache
import com.xkl.cdl.databinding.IncWordDetailBinding
import com.xkl.cdl.databinding.ItemMemoDetailListEnglishBinding
import com.xkl.cdl.databinding.ItemMemoDetailListLiteracyBinding
import com.xkl.cdl.databinding.ItemMemoDetailListPinyinBinding
import com.xkl.cdl.initValue
import com.xkl.cdl.module.m_memo.MemoListDetailViewModel
import com.xkl.cdl.util.ViewUtil

/**
* author suliang
* create 2022/6/10 17:01
* Describe:
*/
class AdapterMemoDetailList(vm : MemoListDetailViewModel) : BaseRVAdapterVM<MemoBean, MemoListDetailViewModel>(vm) {
lateinit var soundListener : (wordId:Long,soundWay:Int) -> Unit
override fun getItemViewType(position : Int) : Int {
if (enableEmptyPosition(position)) {
return TYPE_EMPTY
}
//根据所属课程包类型,给予不同的布局
return when (vm.memoData.course.coursePackType) {
AppConstants.COURSEPACK_TYPE_CHINESE_LITERACY -> R.layout.item_memo_detail_list_literacy
AppConstants.COURSEPACK_TYPE_CHINESE_PINYIN -> R.layout.item_memo_detail_list_pinyin
else -> R.layout.item_memo_detail_list_english
}
}
override fun onBindEmptyViewHolder(holder : BaseAdapterViewHolder) {
(holder.binding as ItemEmptyBinding).apply {
val nullOrEmpty = vm.keyWordSearch.value.isNullOrEmpty()
imgEmpty.setImageResource(if (nullOrEmpty) R.mipmap.empty_nothing else R.mipmap.empty_nothing_search)
tvContent.setText(if (nullOrEmpty) R.string.empty_nothing else R.string.empty_nothing_search)
}
}
override fun coverViewHolder(parent : ViewGroup, viewType : Int) : BaseAdapterViewHolder {
return BaseAdapterViewHolder(inflateBinding(parent, viewType))
}
override fun onBindVH(holder : BaseAdapterViewHolder, position : Int) {
when (vm.memoData.course.coursePackType) {
AppConstants.COURSEPACK_TYPE_CHINESE_LITERACY -> initLiteracy(holder.binding as ItemMemoDetailListLiteracyBinding,
position)
AppConstants.COURSEPACK_TYPE_CHINESE_PINYIN -> initPinyin(holder.binding as ItemMemoDetailListPinyinBinding, position)
else -> initEnglish(holder.binding as ItemMemoDetailListEnglishBinding, position)
}
}

/** 识字课程 */
private fun initLiteracy(binding : ItemMemoDetailListLiteracyBinding, position : Int) {
val item = getItem(position)
binding.run {
item.learnWord.let {
tvLiteracy.text = ViewUtil.literacyGetWord(it.word)
tvExplainPnonetic.setHtml("<b><font color = \"#FF323232\">${it.basic_explanation}</font><b>&nbsp;&nbsp;&nbsp;&nbsp;<font color= \"#7F7F7F\">${it.phonetic_cn}</font>")
tvWord.text = ViewUtil.literacyGetMemoWord(it.word)
if (it.literacyIspolyphone){
tvCourseFlag.visibility = View.GONE
tvPolyphoneFlag.visibility = View.VISIBLE
}else{
tvCourseFlag.visibility = View.VISIBLE
tvPolyphoneFlag.visibility = View.GONE
}
}
rightIcon.click {
item.isExpend = !item.isExpend
initLiteracyExpend(binding,item.isExpend)
}
//发音
tvLiteracy.click { soundListener.invoke(item.learnWord.wordId,AppConstants.SOUND_TYPE_CN) }
}
initDetailValue(binding.incWordDetail, item)
initLiteracyExpend(binding,item.isExpend)
}
/**识字课程背完本展开状态*/
private fun initLiteracyExpend(binding:ItemMemoDetailListLiteracyBinding,isExpend:Boolean){
when{
isExpend -> {
binding.itemGroup.setBackgroundColor(ContextCompat.getColor(context,R.color.white_2))
binding.rightIcon.apply {
setImageResource(R.drawable.ic_up)
}
binding.tvExplainPnonetic.maxLines = Int.MAX_VALUE
binding.incWordDetail.root.visibility = View.VISIBLE
}
else -> {
binding.itemGroup.setBackgroundColor(ContextCompat.getColor(context,R.color.white))
binding.rightIcon.setImageResource(R.drawable.ic_down)
binding.tvExplainPnonetic.maxLines = 1
binding.incWordDetail.root.visibility = View.GONE
}
}
}
/** 拼音课程 */
private fun initPinyin(binding : ItemMemoDetailListPinyinBinding, position : Int) {
val item = getItem(position)
binding.run {
tvWord.text = item.learnWord.word
tvSoundForPinyin.text = item.learnWord.phonetic_cn
tvExplain.text = item.learnWord.basic_explanation
tvExtendExplain.text = "扩展释义:${item.learnWord.extend_explanation}"
rightIcon.click {
item.isExpend = !item.isExpend
initPinyinExpend(binding,item)
}
//发音
tvSoundForPinyin.click { soundListener.invoke(item.learnWord.wordId,AppConstants.SOUND_TYPE_CN) }
}
initDetailValue(binding.incWordDetail, item)
initPinyinExpend(binding,item)
}
private fun initPinyinExpend(binding : ItemMemoDetailListPinyinBinding, item : MemoBean) {
when{
item.isExpend -> {
binding.itemGroup.setBackgroundColor(ContextCompat.getColor(context,R.color.white_2))
binding.rightIcon.apply {
setImageResource(R.drawable.ic_up)
}
binding.tvWord.maxLines = Int.MAX_VALUE
binding.tvExplain.visibility = View.VISIBLE
binding.tvExtendExplain.visibility = if (item.learnWord.extend_explanation.isNullOrEmpty()) View.GONE else View.VISIBLE
binding.incWordDetail.root.visibility = View.VISIBLE
}
else -> {
binding.itemGroup.setBackgroundColor(ContextCompat.getColor(context,R.color.white))
binding.rightIcon.setImageResource(R.drawable.ic_down)
binding.tvWord.maxLines = 1
binding.tvExplain.visibility = View.GONE
binding.tvExtendExplain.visibility = View.GONE
binding.incWordDetail.root.visibility = View.GONE
}
}
}
/**
* 英语类型课程: 认读、拼写、辨音、作文知识点、口语
* @param binding ItemMemoDetailListEnglishBinding
* @param position Int
*/
private fun initEnglish(binding : ItemMemoDetailListEnglishBinding, position : Int) {
val item = getItem(position)
when (vm.memoData.course.courseType) {
AppConstants.COURSE_TYPE_ENGLISH_SPELL -> initSpell(binding,item)
AppConstants.COURSE_TYPE_CHINESE_COMPOSITION -> initComposition(binding,item)
AppConstants.COURSE_TYPE_ENGLISH_SPOKEN -> initSpoken(binding,item)
else -> initDiscernOrOther(binding,item)
}
initDetailValue(binding.incWordDetail, item)
}
private fun initSpoken(binding : ItemMemoDetailListEnglishBinding, item : MemoBean) {
}
/**拼写*/
private fun initSpell(binding : ItemMemoDetailListEnglishBinding, item : MemoBean) {
binding.run {
ivCourseFlag.setImageResource(R.drawable.ic_course_spell)
tvWord.text = item.learnWord.basic_explanation
tvWord1.text = item.learnWord.word
initEnglishPhonetic(item)
tvExplain.visibility = View.GONE
tvExtendExplain.text = item.learnWord.extend_explanation
rightIcon.click {
item.isExpend = !item.isExpend
initSpellExpend(binding,item)
}
initSpellExpend(this,item)
}
}
private fun initSpellExpend(binding : ItemMemoDetailListEnglishBinding, item : MemoBean) {
when{
item.isExpend -> {
binding.itemGroup.setBackgroundColor(ContextCompat.getColor(context,R.color.white_2))
binding.rightIcon.apply {
setImageResource(R.drawable.ic_up)
}
binding.tvWord.maxLines = Int.MAX_VALUE
binding.tvWord1.visibility = View.VISIBLE
binding.layoutPhonetic.visibility = View.VISIBLE
binding.tvExtendExplain.visibility = if (item.learnWord.extend_explanation.isNullOrEmpty()) View.GONE else View.VISIBLE
binding.incWordDetail.root.visibility = View.VISIBLE
}
else -> {
binding.itemGroup.setBackgroundColor(ContextCompat.getColor(context,R.color.white))
binding.rightIcon.setImageResource(R.drawable.ic_down)
binding.tvWord.maxLines = 1
binding.tvWord1.visibility = View.GONE
binding.layoutPhonetic.visibility = View.GONE
binding.tvExtendExplain.visibility = View.GONE
binding.incWordDetail.root.visibility = View.GONE
}
}
}
/**作文*/
private fun initComposition(binding : ItemMemoDetailListEnglishBinding, item : MemoBean) {
binding.run {
ivCourseFlag.setImageResource(R.drawable.ic_course_composition)
tvWord.text = item.learnWord.word
tvWord1.visibility = View.GONE
layoutPhonetic.visibility = View.GONE
tvExplain.text = item.learnWord.basic_explanation
tvExtendExplain.text = item.learnWord.extend_explanation
rightIcon.click {
item.isExpend = !item.isExpend
initCompositionExpend(binding,item)
}
initCompositionExpend(this,item)
}
}
private fun initCompositionExpend(binding : ItemMemoDetailListEnglishBinding, item : MemoBean) {
when{
item.isExpend -> {
binding.itemGroup.setBackgroundColor(ContextCompat.getColor(context,R.color.white_2))
binding.rightIcon.apply {
setImageResource(R.drawable.ic_up)
}
binding.tvWord.maxLines = Int.MAX_VALUE
binding.tvExplain.visibility = View.VISIBLE
binding.tvExtendExplain.visibility = if (item.learnWord.extend_explanation.isNullOrEmpty()) View.GONE else View.VISIBLE
binding.incWordDetail.root.visibility = View.VISIBLE
}
else -> {
binding.itemGroup.setBackgroundColor(ContextCompat.getColor(context,R.color.white))
binding.rightIcon.setImageResource(R.drawable.ic_down)
binding.tvWord.maxLines = 1
binding.tvExplain.visibility = View.GONE
binding.tvExtendExplain.visibility = View.GONE
binding.incWordDetail.root.visibility = View.GONE
}
}
}
/**认读、辨音、音标、*/
private fun initDiscernOrOther(binding : ItemMemoDetailListEnglishBinding, item : MemoBean) {
binding.run {
ivCourseFlag.setImageResource(when(vm.memoData.course.courseType){
AppConstants.COURSE_TYPE_ENGLISH_DISCERN -> {
R.drawable.ic_course_discern
}
AppConstants.COURSE_TYPE_ENGLISH_VOICE -> R.drawable.ic_course_voice
else -> R.drawable.ic_course_soundmark
})
tvWord.text = item.learnWord.word
tvWord1.visibility = View.GONE
initEnglishPhonetic(item)
tvExplain.text = item.learnWord.basic_explanation
tvExtendExplain.text = item.learnWord.extend_explanation
rightIcon.click {
item.isExpend = !item.isExpend
initDiscernOrOtherExpend(binding,item)
}
initDiscernOrOtherExpend(this,item)
}
}
private fun ItemMemoDetailListEnglishBinding.initEnglishPhonetic(item : MemoBean) {
tvPhoneticUk.apply {
text = item.learnWord.phonetic_uk
if (text.isNullOrEmpty()) {
visibility = View.GONE
}
click { soundListener.invoke(item.learnWord.wordId, AppConstants.SOUND_TYPE_UK) }
}
tvPhoneticUs.apply {
text = item.learnWord.phonetic_us
if (text.isNullOrEmpty()) {
visibility = View.GONE
}
click { soundListener.invoke(item.learnWord.wordId, AppConstants.SOUND_TYPE_US) }
}
}
private fun initDiscernOrOtherExpend(binding : ItemMemoDetailListEnglishBinding, item : MemoBean) {
when{
item.isExpend -> {
binding.itemGroup.setBackgroundColor(ContextCompat.getColor(context,R.color.white_2))
binding.rightIcon.apply {
setImageResource(R.drawable.ic_up)
}
binding.tvWord.maxLines = Int.MAX_VALUE
binding.tvExplain.visibility = View.VISIBLE
binding.tvExtendExplain.visibility = if (item.learnWord.extend_explanation.isNullOrEmpty()) View.GONE else View.VISIBLE
binding.incWordDetail.root.visibility = View.VISIBLE
}
else -> {
binding.itemGroup.setBackgroundColor(ContextCompat.getColor(context,R.color.white))
binding.rightIcon.setImageResource(R.drawable.ic_down)
binding.tvWord.maxLines = 1
binding.tvExplain.visibility = View.GONE
binding.tvExtendExplain.visibility = View.GONE
binding.incWordDetail.root.visibility = View.GONE
}
}
}
/**
* 详情内容设置
* @param binding IncWordDetailBinding
* @param memoBean MemoBean
*/
private fun initDetailValue(binding : IncWordDetailBinding, memoBean : MemoBean) {
val item = memoBean.learnWord
binding.initValue(item.phrase, item.example, item.reference)
}
}

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

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

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.core.content.ContextCompat
import com.google.gson.JsonParser
import com.suliang.common.base.adapter.BaseAdapterViewHolder
import com.suliang.common.base.adapter.BaseRVAdapterVM
import com.suliang.common.extension.setHtml
import com.xkl.cdl.R
import com.xkl.cdl.data.AppConstants
import com.xkl.cdl.databinding.ItemTestDetailBinding
import com.xkl.cdl.module.m_service_center.TestDetailViewModel
import mqComsumerV1.Struct

class AdapterTestDetail(vm : TestDetailViewModel) : BaseRVAdapterVM<Struct.ExamRecord,TestDetailViewModel>(vm) {
override fun getItemViewType(position : Int) : Int {
return getItem(position).questionType.toInt()
}
private val options = arrayOf("A","B","C","D")
override fun coverViewHolder(parent : ViewGroup, viewType : Int) : BaseAdapterViewHolder {
return BaseAdapterViewHolder(when(viewType){
//口语对话测试
AppConstants.TEST_QUEST_TYPE_SPOKEN_DIALOGUE.toInt() -> inflateBinding(parent,0)
//选择题
AppConstants.TEST_QUEST_TYPE_CHOICE.toInt() -> inflateBinding(parent, R.layout.item_test_detail)
//暂时没有其他类型,不会走这里
else -> inflateBinding(parent,0)
})
}
override fun onBindVH(holder : BaseAdapterViewHolder, position : Int) {
val item = getItem(position)
val binding = holder.binding as ItemTestDetailBinding
when(vm.courseType){
//口语课程
AppConstants.COURSE_TYPE_ENGLISH_SPOKEN -> {
}
//拼写
AppConstants.COURSE_TYPE_ENGLISH_SPELL -> {
binding.run {
tvMarkNumber.text = "${position + 1}"
tvAnswer.visibility = View.GONE
layoutOption.removeAllViews()
//拼写是否正确
var isNeedAddCorrectSpell = false
when(item.answerStatus){
AppConstants.TEST_UN_ANSWER,
AppConstants.TEST_ERROR -> {
isNeedAddCorrectSpell = true
val textView = LayoutInflater.from(context).inflate(R.layout.item_test_detail_option_1,layoutOption,false) as TextView
textView.setHtml("我的拼写:<font color=\'#f26255\'>${item.userAnswer}</font>")
layoutOption.addView(textView)
}
AppConstants.TEST_CORRECT -> {
val textView = LayoutInflater.from(context).inflate(R.layout.item_test_detail_option_1,layoutOption,false) as TextView
textView.setHtml("我的拼写:<font color=\'#52CC52\'>${item.userAnswer}</font>")
layoutOption.addView(textView)
}
}
//解析
try {
val jsonObject = JsonParser.parseString(item.question).asJsonObject
//拼写释义题目
tvTitle.text = jsonObject.get("question_describe").asString
//是否需要添加正确的拼写内容
if (isNeedAddCorrectSpell){
val jsonArray = jsonObject.get("sequence").asJsonArray
//词组添加选项
jsonArray.forEachIndexed { index , it ->
val option = it.asJsonObject.get("text").asString
val textView = LayoutInflater.from(context).inflate(R.layout.item_test_detail_option_1,layoutOption,false) as TextView
textView.setHtml("正确拼写:<font color=\'#52CC52\'>$option</font>")
layoutOption.addView(textView)
}
}
} catch (e : Exception) {
e.printStackTrace()
}
}
}
//选项
else -> {
binding.run {
tvMarkNumber.text = "${position + 1}"
tvAnswer.text = if (item.userAnswer.isEmpty()) "( )" else "(${item.userAnswer})" //A B C D
//选项位置
val answerPosition = options.indexOf(item.userAnswer)
layoutOption.removeAllViews()
//添加选项答案
try {
val jsonObject = JsonParser.parseString(item.question).asJsonObject
tvTitle.text = jsonObject.get("question_describe").asString
val jsonArray = jsonObject.get("sequence").asJsonArray
//词组添加选项
jsonArray.forEachIndexed { index , it ->
val option = it.asJsonObject.get("text").asString
val isCorrect = it.asJsonObject.get("isCorrect").asBoolean
val textView = LayoutInflater.from(context).inflate(R.layout.item_test_detail_option_1,layoutOption,false) as TextView
textView.text = "${options[index]}. $option"
if (isCorrect) {
textView.setTextColor(ContextCompat.getColor(context,R.color.blue_1))
}else if (answerPosition == index) { //错误位置
textView.setTextColor(ContextCompat.getColor(context,R.color.red_1))
}else{
textView.setTextColor(ContextCompat.getColor(context,R.color.gray_2))
}
layoutOption.addView(textView)
}
} catch (e : Exception) {
e.printStackTrace()
}
}
}
}
}
}

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

@@ -223,4 +223,6 @@ object AppConstants {
const val DIALOG_OVER = 6
/**课时学后总测的再测一次*/
const val DIALOG_AFTER_TOTAL_TEST_AGAIN = 7
/**弹窗动作: 备忘本测试结束查看详情*/
const val DIALOG_MEMO_TEST_DETAIL = 8
}

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

@@ -17,7 +17,7 @@ import java.io.Serializable
* @property first Boolean 是否第一次出现
* @property reviewNum Int 大七次次数
* @property reviewTime Long 复习时间
* @property createTime Long 创建时间
* @property createTime Long 创建时间 1 备忘本使用
* @property repeatNum Int 小七次次数
* @property showColor Int 显示颜色
* @property lessonType Int 课时类型
@@ -39,7 +39,7 @@ open class BaseWord(val subjectId: Int,
/**复习时间*/
var reviewTime: Long = 0

/** 创建时间 */
/** 创建时间 1 备忘本使用*/
var createTime: Long = 0



+ 1
- 1
app/src/main/java/com/xkl/cdl/data/bean/LearnDialogBean.kt View File

@@ -43,7 +43,7 @@ class LearnDialogBean(val dialogType:Int) :Parcelable {
/**章节课时名称: 第一章 第二课时 */
var chapter_lesson_name = ""
/** 题数与时间 */
/** 题数与时间 : 备忘本测试时用于显示课程的题目 */
var showTimeCount = ""
constructor(parcel : Parcel) : this(parcel.readInt()) {

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

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

/**
* author suliang
* create 2022/6/10 17:02
* Describe:
*/
class MemoBean(val learnWord:LearnWord) {
//是否展开
var isExpend = false
}

+ 1
- 0
app/src/main/java/com/xkl/cdl/data/bean/intentdata/MemoData.kt View File

@@ -6,5 +6,6 @@ import com.xkl.cdl.data.bean.course.Course
* author suliang
* create 2022/6/9 16:35
* Describe: 备忘本进入内容详情时,传递数据 MemoListDetailActivity
* memoList:String value 格式 {project_id}_{pack_id}_{course_id}_{chapter_id}_{lesson_id}_{entity_id}_{review_num}_{Y-m-d H:i:s}_{Y-m-d H:i:s}
*/
data class MemoData(val course : Course, val memoList: MutableList<String>)

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

@@ -10,16 +10,14 @@ import com.suliang.common.util.DateUtil
import com.suliang.common.util.file.FileUtil
import com.suliang.common.util.thread.AppExecutors
import com.xkl.cdl.data.AppConstants
import com.xkl.cdl.data.bean.CompositionReadingBean
import com.xkl.cdl.data.bean.CompositionTaskBean
import com.xkl.cdl.data.bean.LearnWord
import com.xkl.cdl.data.bean.VideoBean
import com.xkl.cdl.data.bean.*
import com.xkl.cdl.data.bean.course.CourseDetail
import com.xkl.cdl.data.bean.course.ExamBean
import com.xkl.cdl.data.bean.course.Lesson
import com.xkl.cdl.data.manager.FilePathManager
import com.xkl.videoplayer.bean.VideoAnchor
import io.reactivex.rxjava3.annotations.NonNull
import io.reactivex.rxjava3.core.Observable
import net.sqlcipher.database.SQLiteDatabase
import java.io.File
import java.util.*
@@ -132,7 +130,7 @@ object DBCourseManager {
wordIds.size - 1 == learnIndex
}
//视频
AppConstants.LESSON_TYPE_COMPOSITION_VIDEO -> {
AppConstants.LESSON_TYPE_COMPOSITION_VIDEO -> {
detail.lesson_learn_point[key]?.let { entityId ->
entityId < 0 //小于0 ,学习完成
} ?: false //否则未完成
@@ -272,7 +270,7 @@ object DBCourseManager {
lessonId = getLong(9)
})
}
AppConstants.COURSE_TYPE_CHINESE_LITERACY, AppConstants.COURSE_TYPE_CHINESE_PINYIN -> while (moveToNext()) {
AppConstants.COURSE_TYPE_CHINESE_LITERACY, AppConstants.COURSE_TYPE_CHINESE_PINYIN -> while (moveToNext()) {
result.add(ExamBean().apply {
id = getLong(0)
word_id = getLong(1)
@@ -745,25 +743,89 @@ object DBCourseManager {
*/
@SuppressLint("Range")
fun queryReviewData(dbControlBase : DbControlBase, reviewDataList : MutableList<LearnWord>) : Boolean {
//没有查询到复习数据的位置集合
val notHaveData = arrayListOf<Int>()
open(dbControlBase)
reviewDataList.forEachIndexed{ index , learnWord ->
val sql = "SELECT * FROM chapter WHERE chapter_id = ${learnWord.chapterId} and lesson_id = ${learnWord.lessonId} AND word_id = ${learnWord.wordId} "
reviewDataList.forEachIndexed { index, learnWord ->
val sql = when (dbControlBase.courseType) {
AppConstants.COURSE_TYPE_CHINESE_COMPOSITION -> "SELECT * FROM knowledge WHERE chapter_id = ${learnWord.chapterId} AND knowledge_id = ${learnWord.wordId}"
else -> "SELECT * FROM chapter WHERE chapter_id = ${learnWord.chapterId} and lesson_id = ${learnWord.lessonId} AND word_id = ${learnWord.wordId} "
}
val rawQuery = mDataBase?.rawQuery(sql, null)
rawQuery?.run {
if (this.count == 0 ){
notHaveData.add(index)
if (this.count == 0) {
return@run
}
while (moveToNext()){
while (moveToNext()) {
if (dbControlBase.courseType == AppConstants.COURSE_TYPE_CHINESE_COMPOSITION) {
learnWord.word = getString(getColumnIndex("title"))
learnWord.basic_explanation = getString(getColumnIndex("explaination"))
learnWord.example = getString(getColumnIndex("example"))
learnWord.reference = getString(getColumnIndex("reference"))
return@run
}
learnWord.word = getString(getColumnIndex("word"))
learnWord.basic_explanation = getString(getColumnIndex("basic_explaination"))
learnWord.extend_explanation = getString(getColumnIndex("all_explaination"))
learnWord.phrase = getString(getColumnIndex("phrase"))
learnWord.example = getString(getColumnIndex("example"))
learnWord.reference = getString(getColumnIndex("reference"))
when (dbControlBase.courseType) {
AppConstants.COURSE_TYPE_CHINESE_LITERACY -> {
learnWord.literacyIspolyphone = getInt(getColumnIndex("polyphone")) > 0
learnWord.phonetic_cn = getString(getColumnIndex("phonetic"))
}
AppConstants.COURSE_TYPE_CHINESE_PINYIN -> {
learnWord.phonetic_cn = getString(getColumnIndex("phonetic"))
}
else -> {
learnWord.phonetic_uk = getString(getColumnIndex("phonetic_uk"))
learnWord.phonetic_us = getString(getColumnIndex("phonetic_us"))
}
}
}
}
}
return reviewDataList.size > 0
}
/**
* 备忘本数据详情查询
* @param dbControlBase DbControlBase
* @param allMemoList MutableList<MemoBean> 已经有初始值的详情集合,需要查询详细数据
*/
@SuppressLint("Range")
fun queryMemoList(dbControlBase : DbControlBase, allMemoList : MutableList<MemoBean>) {
open(dbControlBase)
allMemoList.forEachIndexed { index, memoBean ->
val learnWord = memoBean.learnWord
val sql = when (dbControlBase.courseType) {
AppConstants.COURSE_TYPE_CHINESE_COMPOSITION -> "SELECT * FROM knowledge WHERE chapter_id = ${learnWord.chapterId} AND knowledge_id = ${learnWord.wordId}"
else -> "SELECT * FROM chapter WHERE chapter_id = ${learnWord.chapterId} and lesson_id = ${learnWord.lessonId} AND word_id = ${learnWord.wordId} "
}
val rawQuery = mDataBase?.rawQuery(sql, null)
rawQuery?.run {
if (this.count == 0) {
return@run
}
while (moveToNext()) {
if (dbControlBase.courseType == AppConstants.COURSE_TYPE_CHINESE_COMPOSITION) {
learnWord.word = getString(getColumnIndex("title"))
learnWord.basic_explanation = getString(getColumnIndex("explaination"))
learnWord.example = getString(getColumnIndex("example"))
learnWord.reference = getString(getColumnIndex("reference"))
return@run
}
learnWord.word = getString(getColumnIndex("word"))
learnWord.basic_explanation = getString(getColumnIndex("basic_explaination"))
learnWord.extend_explanation = getString(getColumnIndex("all_explaination"))
learnWord.phrase = getString(getColumnIndex("phrase"))
learnWord.example = getString(getColumnIndex("example"))
learnWord.reference = getString(getColumnIndex("reference"))
when (dbControlBase.courseType) {
AppConstants.COURSE_TYPE_CHINESE_LITERACY -> {
learnWord.literacyIspolyphone = getInt(getColumnIndex("polyphone")) > 0
@@ -778,17 +840,202 @@ object DBCourseManager {
}
}
}
}?: notHaveData.add(index)
}
}
if (notHaveData.size > 0 ){
//反序
Collections.reverse(notHaveData)
notHaveData.forEach{
reviewDataList.removeAt(it)
}
/** 获取备忘本可测试的课时 课时中的id为 备忘本中的错误id */
@SuppressLint("Range")
fun queryMemoLesson(base : DbControlBase, memoList : MutableList<String>) : List<Lesson> {
//备忘本可测试集合 : key: 课时id , value : 用于测试的内容id
val mutableMapOf = mutableMapOf<Long, MutableList<Long>>()
//循环分组
memoList.forEach {
val split = it.split("_")
val lessonId = split[4].toLong()
val itemId = split[5].toLong()
mutableMapOf[lessonId]?.add(itemId) ?: let {
mutableMapOf[lessonId] = mutableListOf(itemId)
}
}
return reviewDataList.size > 0
val memoLesson = mutableListOf<Lesson>()
open(base)
//聚合所有课时,先所有chapter_sort和word_sort排序,然后根据leesonId分组并聚合leeson_id到
val rawQuerySql = 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 "
}
}
mDataBase?.rawQuery(rawQuerySql, null)?.let { cursor ->
while (cursor.moveToNext()) {
val lessonId = cursor.getLong(cursor.getColumnIndex("lesson_id"))
mutableMapOf[lessonId]?.let { memoIds ->
val chapterId : Long = cursor.getLong(cursor.getColumnIndex("chapter_id"))
val chapterName : String = cursor.getString(cursor.getColumnIndex("chapter_title"))
val lessonName : String = when (base.courseType) {
AppConstants.COURSE_TYPE_CHINESE_COMPOSITION, AppConstants.COURSE_TYPE_CHINESE_LITERACY, AppConstants.COURSE_TYPE_CHINESE_PINYIN -> cursor.getString(
cursor.getColumnIndex("lesson_title"))
else -> cursor.getString(cursor.getColumnIndex("lesson"))
}
val lessonType : Int = when (base.courseType) {
AppConstants.COURSE_TYPE_CHINESE_COMPOSITION -> cursor.getInt(cursor.getColumnIndex("type"))
AppConstants.COURSE_TYPE_ENGLISH_SPOKEN -> cursor.getInt(cursor.getColumnIndex("lesson_type"))
else -> AppConstants.LESSON_TYPE_WORD
}
val lesson = Lesson(base.subjectId, base.coursePackId, base.coursePackType, base.courseId, base.courseType,
chapterId, chapterName, lessonId, lessonName)
lesson.wordIds = memoIds
lesson.lessonType = lessonType
memoLesson.add(lesson)
}
}
cursor.close()
}
return memoLesson
}
/** 获取备忘本测试
* @param base DbControlBase
* @param lessons :需要测试的课时
* @param count : 需要查询时获得的数量
* @return List<ExamBean> 返回数据
*/
fun queryMemoTest(base : DbControlBase, lessons : MutableList<Lesson>, count : Int) : List<ExamBean> {
open(base)
val result = mutableListOf<ExamBean>()
//循环获取课时中的测试内容
lessons.forEach {
val sql = when (base.courseType) {
//作文知识点测试
AppConstants.COURSE_TYPE_CHINESE_COMPOSITION -> "SELECT * FROM exam WHERE chapter_id = ${it.chapterId} AND knowledge_id in (${
Joiner.on(",").join(it.wordIds)
}) ORDER BY random()"
AppConstants.COURSE_TYPE_ENGLISH_DISCERN, AppConstants.COURSE_TYPE_ENGLISH_VOICE,
AppConstants.COURSE_TYPE_ENGLISH_SOUNDMARK, AppConstants.COURSE_TYPE_CHINESE_LITERACY,
AppConstants.COURSE_TYPE_CHINESE_PINYIN,
-> { //没有作文,作文没有学前总测
"SELECT exam.*, chapter_id,lesson_id,basic_explaination FROM chapter JOIN exam ON chapter.word_id = exam.word_id AND chapter.word_id IN (${
Joiner.on(",").join(it.wordIds)
}) AND exam.type = ${AppConstants.TEST_QUEST_TYPE_CHOICE} AND chapter_id = ${it.chapterId} AND lesson_id = ${it.lessonId} ORDER by random() LIMIT $count"
}
AppConstants.COURSE_TYPE_ENGLISH_SPELL -> { //拼写 不需要查询测试表,不需要选项
"SELECT id, word_id,word,chapter_id,lesson_id,basic_explaination FROM chapter WHERE word_id IN (${
Joiner.on(",").join(it.wordIds)
}) AND chapter_id = ${it.chapterId} AND lesson_id = ${it.lessonId} ORDER by random() LIMIT $count"
}
AppConstants.COURSE_TYPE_ENGLISH_SPOKEN -> { //口语
"SELECT exam.* FROM chapter JOIN exam on chapter.word_id = exam.word_id AND word_id IN (${
Joiner.on(",").join(it.wordIds)
}) AND exam.type = 1 AND chapter_id = ${it.chapterId} AND lesson_id = ${it.lessonId} ORDER by random() LIMIT $count"
}
else -> "" //没有任何课程,课程都特别写入类型,用于匹配
}
mDataBase?.rawQuery(sql, null)?.run {
when (base.courseType) {
//作文知识点测试
AppConstants.COURSE_TYPE_CHINESE_COMPOSITION -> while (moveToNext()) {
result.add(ExamBean().apply {
id = getLong(3)
word_id = getLong(2)
word = getString(4)
correct = getString(5)
error1 = getString(6)
error2 = getString(7)
error3 = getString(8)
type = AppConstants.TEST_QUEST_TYPE_CHOICE // 为1
chapterId = it.chapterId
lessonId = it.lessonId
})
}
AppConstants.COURSE_TYPE_ENGLISH_SPELL -> {
while (moveToNext()) {
result.add(ExamBean().apply {
id = getLong(0)
word_id = getLong(1)
word = getString(2)
chapterId = getLong(3)
lessonId = getLong(4)
correct = getString(5)
type = AppConstants.TEST_QUEST_TYPE_CHOICE // 为1
})
}
}
AppConstants.COURSE_TYPE_ENGLISH_DISCERN, AppConstants.COURSE_TYPE_ENGLISH_VOICE -> while (moveToNext()) {
result.add(ExamBean().apply {
id = getLong(0)
word_id = getLong(1)
word = getString(2)
correct = getString(3)
error1 = getString(4)
error2 = getString(5)
error3 = getString(6)
type = AppConstants.TEST_QUEST_TYPE_CHOICE // 为1
chapterId = getLong(8)
lessonId = getLong(9)
})
}
AppConstants.COURSE_TYPE_CHINESE_LITERACY, AppConstants.COURSE_TYPE_CHINESE_PINYIN -> while (moveToNext()) {
result.add(ExamBean().apply {
id = getLong(0)
word_id = getLong(1)
word = getString(2)
correct = getString(3)
error1 = getString(4)
error2 = getString(5)
error3 = getString(6)
type = AppConstants.TEST_QUEST_TYPE_CHOICE // 为1
chapterId = getLong(10)
lessonId = getLong(11)
})
}
AppConstants.COURSE_TYPE_ENGLISH_SOUNDMARK -> while (moveToNext()) {
result.add(ExamBean().apply {
id = getLong(0)
word_id = getLong(1)
word = getString(2)
correct = getString(3)
error1 = getString(4)
error2 = getString(5)
error3 = getString(6)
type = AppConstants.TEST_QUEST_TYPE_CHOICE // 为1
chapterId = getLong(11)
lessonId = getLong(12)
})
}
AppConstants.COURSE_TYPE_ENGLISH_SPOKEN -> {
while (moveToNext()) {
result.add(ExamBean().apply {
id = getLong(0)
word_id = getLong(1)
word = getString(2)
correct = getString(3)
error1 = getString(4)
error2 = getString(5)
error3 = getString(6)
type = AppConstants.TEST_QUEST_TYPE_CHOICE // 为1
chapterId = it.chapterId
lessonId = it.lessonId
})
}
}
}
close()
}
result.shuffle()
if (result.size > count){
result.removeAll(result.subList(count,result.size))
}
}
return result
}
}

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

@@ -197,4 +197,13 @@ object DataRepository {
it.onComplete()
}.compose(io2Io()).subscribe()
}
/** 获取备忘本可测试的课时 */
fun queryMemoLesson(base: DbControlBase,memoList: MutableList<String>):Observable<List<Lesson>>{
return Observable.create{
it.onNext(DBCourseManager.queryMemoLesson(base,memoList))
it.onComplete()
}
}
}

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

@@ -1,5 +1,6 @@
package com.xkl.cdl.dialog

import android.annotation.SuppressLint
import android.os.Bundle
import android.view.Gravity
import android.view.View
@@ -67,6 +68,8 @@ class LearnDialog private constructor() : BaseDialogFragment<DialogLessonLearnBi
AppConstants.TEST_TYPE_AFTER_TOTAL -> initCourseAfterTestOver()
//作文知识点测试结束
AppConstants.TEST_TYPE_COMPOSITION -> initCompositionExamLessonTestOver()
//备忘本测试
AppConstants.TEST_TYPE_MEMO -> initMemoTestOver()
}
//学习结束弹窗
AppConstants.DIALOG_TYPE_LEARNING_OVER -> initLessonLearningOver(false)
@@ -416,4 +419,36 @@ class LearnDialog private constructor() : BaseDialogFragment<DialogLessonLearnBi
binding.tvRight.click { onDialogListener(AppConstants.DIALOG_OVER,this) }
}
/**
* 备忘本测试结束 tv_score,tv_tip,tv_title,tv_tip_1,inc_statistics_number,tv_left,tv_top
*/
@SuppressLint("SetTextI18n")
private fun initMemoTestOver() {
binding.run {
imgIv.setImageResource(if (Random.nextBoolean()) R.mipmap.boy_2 else R.mipmap.girl_2)
tvScore.visibility = View.VISIBLE
tvTip.visibility = View.VISIBLE
tvTitle.visibility = View.VISIBLE
tvTitle.text = "恭喜你,完成备忘本测试!"
tvTip1.visibility = View.VISIBLE
tvTip1.text = "《${learnDialogBean.showTimeCount}》" //课程题目
incStatisticsNumber.root.visibility = View.VISIBLE
tvTop.visibility = View.VISIBLE
tvTop.text = "查看测试详情"
tvRight.text = "完成"
tvLeft.visibility = View.VISIBLE
tvLeft.text = "再测一次"
}
initScore()
initNumber()
//完成
binding.tvRight.click { onDialogListener(AppConstants.DIALOG_OVER,this) }
//查看测试详情
binding.tvTop.click { onDialogListener(AppConstants.DIALOG_MEMO_TEST_DETAIL,this) }
//再测一次
binding.tvLeft.click { onDialogListener(AppConstants.DIALOG_START_TEST,this) }
}
}

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

@@ -25,6 +25,7 @@ import com.xkl.cdl.R
import com.xkl.cdl.adapter.AdapterSpell
import com.xkl.cdl.adapter.itemdecoration.SpellItemDecoration
import com.xkl.cdl.data.AppConstants
import com.xkl.cdl.data.DataTransferHolder
import com.xkl.cdl.data.bean.LearnDialogBean
import com.xkl.cdl.data.bean.course.ExamBean
import com.xkl.cdl.data.event.LearnEventData
@@ -35,6 +36,7 @@ import com.xkl.cdl.databinding.*
import com.xkl.cdl.dialog.CommonDialog
import com.xkl.cdl.dialog.CommonDialogBean
import com.xkl.cdl.dialog.LearnDialog
import com.xkl.cdl.module.m_service_center.TestDetailActivity

/**
* author suliang
@@ -597,6 +599,10 @@ class LearnExamActivity : BaseActivityVM<ActivityLearnExamBinding, LearnExamView
score = vm.scoreValue
correctNumber = vm.correctLiveData.value!!
errorNumber = vm.errorLiveData.value!!
//备忘本需要显示课程名称
if (examType == AppConstants.TEST_TYPE_MEMO){
showTimeCount = vm.intentData.showTitle
}
}
LearnDialog.newInstance(learnDialogBean).apply {
onDialogListener = { action, dialog ->
@@ -691,6 +697,7 @@ class LearnExamActivity : BaseActivityVM<ActivityLearnExamBinding, LearnExamView
finish()
}
}
//作文知识点测试
AppConstants.TEST_TYPE_COMPOSITION -> when (action) {
//测试完成,关闭
AppConstants.DIALOG_OVER -> {
@@ -709,6 +716,28 @@ class LearnExamActivity : BaseActivityVM<ActivityLearnExamBinding, LearnExamView
finish()
}
}
//备忘本测试
AppConstants.TEST_TYPE_MEMO -> when(action){
//完成
AppConstants.DIALOG_OVER -> {
dialog.dismissAllowingStateLoss()
finish()
}
//再测一次
AppConstants.DIALOG_START_TEST -> {
dialog.dismissAllowingStateLoss()
finish()
LiveEventBus.get<Int>("memo_test_again").post(0)
}
//查看详情
AppConstants.DIALOG_MEMO_TEST_DETAIL -> {
// TODO: 2022/6/20 进入测试详情界面
vm.learnExam?.let {
DataTransferHolder.instance.putData(value = it.build())
startActivity(TestDetailActivity::class.java)
}
}
}
}
}
}.show(supportFragmentManager, javaClass.name)

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

@@ -3,7 +3,6 @@ package com.xkl.cdl.module.learn
import android.graphics.drawable.Drawable
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.jeremyliao.liveeventbus.LiveEventBus
import com.suliang.common.extension.createRandomNewChar
import com.suliang.common.extension.diskIo2Main
@@ -13,15 +12,12 @@ import com.xkl.cdl.data.AppConstants
import com.xkl.cdl.data.DataTransferHolder
import com.xkl.cdl.data.bean.SpellItemBean
import com.xkl.cdl.data.bean.course.ExamBean
import com.xkl.cdl.data.bean.course.Lesson
import com.xkl.cdl.data.bean.intentdata.ExamData
import com.xkl.cdl.data.event.LearnEventData
import com.xkl.cdl.data.manager.db.DbControlBase
import com.xkl.cdl.data.repository.DataRepository
import com.xkl.cdl.databinding.IncludTestOptionItemBinding
import io.reactivex.rxjava3.core.Observable
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import mqComsumerV1.Struct.*
import org.json.JSONArray
import org.json.JSONException
@@ -102,7 +98,7 @@ class LearnExamViewModel : LearnBaseViewModel() {
var vocabularyCoverange = 0 //词汇量测试的覆盖率
//测试结果试卷
private var learnExam : LearnExam.Builder? = null
var learnExam : LearnExam.Builder? = null
//当前测试的单词
private var currentExamRecord : ExamRecord.Builder? = null
@@ -360,12 +356,8 @@ class LearnExamViewModel : LearnBaseViewModel() {
}
//问题和选项
createQuestion()
currentClickPosition = position
var chooseResult = -1L
//添加到记录集合
mExamRecordList.add(currentExamRecord!!.build())
//进行结果判断,并为记录赋值
if (position == currentCorrectPosition) { //正确
correctLiveData.value = correctLiveData.value!!.plus(1)
@@ -388,6 +380,8 @@ class LearnExamViewModel : LearnBaseViewModel() {
createErrorRecord()
}
}
//添加到记录集合
mExamRecordList.add(currentExamRecord!!.build())
currentChooseResultLiveData.value = chooseResult
}
@@ -434,6 +428,7 @@ class LearnExamViewModel : LearnBaseViewModel() {
result = AppConstants.TEST_CORRECT
}
}
mExamRecordList.add(currentExamRecord!!.build())
//通知结果
currentSpellResultLiveData.value = result
}

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

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

import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.jeremyliao.liveeventbus.LiveEventBus
import com.suliang.common.extension.createRandomNewChar
import com.suliang.common.extension.diskIo2Main
import com.suliang.common.util.DateUtil
import com.suliang.common.util.LogUtil
import com.xkl.cdl.data.AppConstants
import com.xkl.cdl.data.DataTransferHolder
import com.xkl.cdl.data.bean.LearnWord
@@ -20,8 +18,6 @@ import com.xkl.cdl.data.manager.db.DbControlBase
import com.xkl.cdl.data.repository.DataRepository
import com.xkl.cdl.util.LearnRuleUtil
import io.reactivex.rxjava3.core.Observable
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import mqComsumerV1.Struct
import mqComsumerV1.Struct.LearnDuration
import mqComsumerV1.Struct.LearnEntity

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

@@ -30,7 +30,7 @@ class CoursePackMainActivityViewModel(subjectId: Int , coursePackInPosition : In
init {
if (isMemoSource){
DataTransferHolder.instance.getData<MemoCoursePack>().let {
coursePackChildrenMemo = it.coursePackChildrenMemo
// coursePackChildrenMemo = it.coursePackChildrenMemo
it.coursePack.childrenCourses.forEach { c ->
updateReviewNumber(c.courseType,it.coursePackChildrenReview.getOrDefault(c.courseId,0))
}

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

@@ -1,6 +1,5 @@
package com.xkl.cdl.module.m_center_learn.coursechildren

import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.MutableLiveData
import com.google.common.base.Joiner
import com.google.protobuf.ProtocolStringList
@@ -8,8 +7,6 @@ import com.suliang.common.base.viewmodel.BaseViewModel
import com.suliang.common.extension.diskIo2DiskIo
import com.suliang.common.extension.diskIo2Main
import com.suliang.common.util.DateUtil
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.AppConstants
import com.xkl.cdl.data.bean.CompositionReadingBean
@@ -25,14 +22,11 @@ import com.xkl.cdl.data.manager.db.DbControlBase
import com.xkl.cdl.data.repository.DataRepository
import com.xkl.cdl.module.XKLApplication
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.functions.BiFunction
import io.reactivex.rxjava3.schedulers.Schedulers
import mqComsumerV1.Struct
import java.io.File
import java.util.*
import kotlin.collections.ArrayList
import kotlin.collections.HashMap

/**
@@ -108,6 +102,11 @@ class CourseMainFragmentViewModel(val courseIndex : Int) : BaseViewModel() {
}
reviewDataList.clear()
//更新备忘本数据
if (coursePackMainActivityVM.isMemoSource){
coursePackMainActivityVM.coursePackChildrenMemo[course.courseId] = rev.toMutableList()
}
//当前时间戳
val currentTime = System.currentTimeMillis()
//日历

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

@@ -34,23 +34,7 @@ class CourseReviewFragment : BaseFragmentVM<FragmentCourseReviewBinding, CourseM
}
override fun initFragment() {
when{
//备忘本
vm.coursePackMainActivityVM.isMemoSource -> when{
vm.reviewDataList.size > 0 -> {
initReviewData()
binding.tvStartReview.visibility = View.VISIBLE
binding.tvSeeMemo.visibility = View.VISIBLE
}
else -> initMemoData()
}
//学习中心
else -> {
initReviewData()
binding.tvStartReview.visibility = View.VISIBLE
binding.tvSeeMemo.visibility = View.GONE
}
}
initShow()

//开始复习
binding.tvStartReview.click {
@@ -80,6 +64,26 @@ class CourseReviewFragment : BaseFragmentVM<FragmentCourseReviewBinding, CourseM
}
}
private fun initShow() {
when {
//备忘本
vm.coursePackMainActivityVM.isMemoSource -> when {
vm.reviewDataList.size > 0 -> {
initReviewData()
binding.tvStartReview.visibility = View.VISIBLE
binding.tvSeeMemo.visibility = View.VISIBLE
}
else -> initMemoData()
}
//学习中心
else -> {
initReviewData()
binding.tvStartReview.visibility = View.VISIBLE
binding.tvSeeMemo.visibility = View.GONE
}
}
}
private fun initReviewData() {
//根据课程类型进行显示
binding.tvTips.text = when (vm.course.courseType) {
@@ -136,6 +140,12 @@ class CourseReviewFragment : BaseFragmentVM<FragmentCourseReviewBinding, CourseM
}
//更新复习数
vm.coursePackMainActivityVM.updateReviewNumber(vm.course.courseType,vm.reviewDataList.size)
//如果是备忘本需要刷新更新
if (vm.coursePackMainActivityVM.isMemoSource){
vm.loadMain().observe(this){
initShow()
}
}
}
}
}

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

@@ -15,7 +15,7 @@ import com.xkl.cdl.module.main.MainActivityViewModel
* Describe: 备忘本
*/
class MemoFragment : BaseFragmentVM<FragmentMemoBinding, MemoFragmentViewModel>(){
// TODO: 2022/6/16 处理课程包的排序问题 应该是根据sort进行排序
companion object {
@JvmStatic
fun newInstance() = MemoFragment()

+ 239
- 7
app/src/main/java/com/xkl/cdl/module/m_memo/MemoListDetailActivity.kt View File

@@ -1,19 +1,43 @@
package com.xkl.cdl.module.m_memo

import android.annotation.SuppressLint
import android.app.TimePickerDialog
import android.os.Bundle
import android.view.View
import android.widget.TimePicker
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import com.haibin.calendarview.Calendar
import com.haibin.calendarview.CalendarView
import com.jeremyliao.liveeventbus.LiveEventBus
import com.lxj.xpopup.XPopup
import com.lxj.xpopupext.listener.TimePickerListener
import com.lxj.xpopupext.popup.TimePickerPopup
import com.suliang.common.base.activity.BaseActivityVM
import com.suliang.common.extension.click
import com.suliang.common.util.DateUtil
import com.suliang.common.util.DrawableUti
import com.suliang.common.util.media.MPManager
import com.xkl.cdl.R
import com.xkl.cdl.adapter.AdapterMemoDetailList
import com.xkl.cdl.data.AppConstants
import com.xkl.cdl.data.DataTransferHolder
import com.xkl.cdl.data.bean.course.Lesson
import com.xkl.cdl.data.bean.intentdata.LearnData
import com.xkl.cdl.data.event.LearnEventData
import com.xkl.cdl.data.repository.AudioCache
import com.xkl.cdl.databinding.ActivityMemoListDetailBinding
import com.xkl.cdl.module.learn.LearnWordActivity
import com.xkl.cdl.module.m_center_learn.coursechildren.CourseMainFragment
import java.util.*
import java.util.Calendar.*


/**
* author suliang
* create 2022/6/9 15:51
* Describe: 备忘本课程详情列表
*/
* author suliang
* create 2022/6/9 15:51
* Describe: 备忘本课程详情列表
*/
class MemoListDetailActivity : BaseActivityVM<ActivityMemoListDetailBinding, MemoListDetailViewModel>() {
override fun initViewModel() : MemoListDetailViewModel {
@@ -21,10 +45,11 @@ class MemoListDetailActivity : BaseActivityVM<ActivityMemoListDetailBinding, Mem
}
override fun initActivity(savedInstanceState : Bundle?) {
binding.vm = vm
//标题
binding.titleBar.run {
textViewTitle.text = vm.memoData.course.courseTitle
setRightSrc(DrawableUti.changeSvgSizeAndColor(resources,R.drawable.ic_search,R.color.main_text_color,1.33f))
setRightSrc(DrawableUti.changeSvgSizeAndColor(resources, R.drawable.ic_search, R.color.main_text_color, 1.33f))
onBackClick = {
finish()
}
@@ -36,18 +61,225 @@ class MemoListDetailActivity : BaseActivityVM<ActivityMemoListDetailBinding, Mem
}
//搜索取消
binding.tvSearchCache.click {
binding.tvSearchCache.visibility = View.VISIBLE
binding.etSearch.visibility = View.VISIBLE
binding.tvSearchCache.visibility = View.GONE
binding.etSearch.visibility = View.GONE
binding.etSearch.setText("")
}
binding.tvShowTime.text = "${binding.calendarView.curYear}年${binding.calendarView.curMonth}月"
//日历
initCalendarView()
//initRecyclerView
binding.rvMemo.run {
layoutManager = LinearLayoutManager(this@MemoListDetailActivity, LinearLayoutManager.VERTICAL, false)
adapter = AdapterMemoDetailList(vm).apply {
needShowEmptyView = true
//处理发音事件
soundListener = { wordId, soundWay ->
AudioCache.get(vm.dbControlBase, wordId, soundWay)
}
}
}
//日期选择
binding.tvShowTime.click {
showTimePickDialog()
}
//展开收起
binding.tvCalendarStatus.click {
when (binding.tvCalendarStatus.text) {
"展开" -> {
binding.tvCalendarStatus.text = "收起"
binding.layoutCalendar.expand()
}
else -> {
binding.tvCalendarStatus.text = "展开"
binding.layoutCalendar.shrink()
}
}
}
//复习备忘本
binding.tvReviewMemo.click {
val lesson = Lesson(vm.memoData.course.subjectId, vm.memoData.course.coursePackId, vm.memoData.course.coursePackType,
vm.memoData.course.courseId, vm.memoData.course.courseType, 0, "", 0,
vm.memoData.course.courseTitle)
DataTransferHolder.instance.putData(value = LearnData(lesson).apply {
learnWordList = vm.allNeedReviewList.value!!
isReview = true
})
startActivity(LearnWordActivity::class.java)
}
//测试备忘本
binding.tvTestMemo.click {
DataTransferHolder.instance.putData(value = vm.memoData)
startActivity(MemoTestActivity::class.java)
}
}
override fun loadData() {
vm.loadMain()
//日历map赋值
setCalendarWordData()
/**复习数显示*/
vm.allNeedReviewList.observe(this) {
binding.tvTodayReview.text = "今日需复习${it.size}条"
if (it.isEmpty()) {
binding.tvReviewMemo.isEnabled = false
}
}
/**显示备忘本内容 同时更新提示显示*/
vm.showMemoListLiveData.observe(this) {
(binding.rvMemo.adapter as AdapterMemoDetailList).setData(it)
binding.tvTodayMemo.text = if (vm.selectTime.value.isNullOrEmpty()) {
"全部时间,共${vm.showMemoTodayList.size}条"
} else {
val split = vm.selectTime.value!!.split("-")
"${split[0]}年${split[1]}月${split[2]}日,共${vm.showMemoTodayList.size}条"
}
}
vm.keyWordSearch.observe(this) {
vm.getTimeForMemoList()
}
/** 监听发音 */
AudioCache.initAudioLiveData().observe(this) {
it?.run {
MPManager.play(it)
} ?: let {
showToast("未找到发音文件")
}
}
//监听复习回调 : 此处复习回调,主要用于更新界面剩余数显示 同时更新备忘本数据的处理
LiveEventBus.get<LearnEventData>(AppConstants.EVENT_REVIEW_DATA).observe(this) {
if (it.subjectId != vm.memoData.course.subjectId || it.courseId != vm.memoData.course.courseId) return@observe
when (it.actionFlag) {
AppConstants.DATA_REVIEW -> {
//更新复习数据与显示
vm.allNeedReviewList.value?.let { reviewDataList ->
//复习完成
if (it.leesonPositionIndex == reviewDataList.size - 1) {
vm.allNeedReviewList.value = mutableListOf()
} else { // 复习未完成
vm.allNeedReviewList.value = reviewDataList.subList(it.leesonPositionIndex + 1, reviewDataList.size)
}
}
}
}
}
}
/** 初始化日历 */
private fun initCalendarView() {
binding.tvCalendarStatus.text = "展开"
binding.tvCalendarStatus.visibility = View.VISIBLE
//设置日历监听
setCalendarListener()
}
/** 设置日历监听 */
@SuppressLint("SetTextI18n")
private fun setCalendarListener() {
binding.calendarView.run {
//设置日历选择事件
setOnCalendarSelectListener(object : CalendarView.OnCalendarSelectListener {
//超出范围越界
override fun onCalendarOutOfRange(calendar : Calendar?) {}
//日期选择事件
override fun onCalendarSelect(calendar : Calendar, isClick : Boolean) {
//非点击,不处理
if (!isClick) return
//根据点击选中时间,处理数据
val clickTime = DateUtil.format(calendar.timeInMillis, DateUtil.FORMAT_4)
val selectTime = vm.selectTime.value!!
when (clickTime) {
selectTime -> {
vm.selectTime.value = ""
binding.calendarView.clearMultiSelect()
}
else -> vm.selectTime.value = clickTime
}
vm.getTimeForMemoList()
}
})
// 月份改变事件
setOnMonthChangeListener { year, month ->
binding.tvShowTime.text = "${year}年${month}月"
}
//周视图切换监听
setOnWeekChangeListener {
binding.tvShowTime.text = "${it[0].year}年${it[0].month}月"
}
//月周视图切换
setOnViewChangeListener { isMonthView ->
binding.tvCalendarStatus.text = if (isMonthView) "收起" else "展开"
}
// 屏蔽某些不可点击的日期,可根据自己的业务自行修改
// 添加日期拦截事件 使用此方法,只能基于select_mode = single_mode
// 否则的话,如果标记全部日期为不可点击,那是没有意义的, 框架本身也不可能在滑动的过程中全部去判断每个日期的可点击性
// setOnCalendarInterceptListener(object : CalendarView.OnCalendarInterceptListener {
// override fun onCalendarIntercept(calendar : Calendar) : Boolean {
// return false
// if (!isScrollCalendar){ //当选择移动到某个月份,判断当前月份是否可以选中
// return !calendar.hasScheme()
// }
// return false
// }
//
// override fun onCalendarInterceptClick(calendar : Calendar?, isClick : Boolean) {
//
// }
//
// })
}
}
/**日历map赋值*/
private fun setCalendarWordData() {
val map = mutableMapOf<String, Calendar>()
vm.calenderMap.forEach {
//key
val calendar = vm.getSchemeCalendar(it.key, it.value.size)
map[calendar.toString()] = calendar
}
//设置标记: 此方法在巨大的数据量上不影响遍历性能,推荐使用
binding.calendarView.setSchemeDate(map)
// 赋值后收起日历
binding.layoutCalendar.postDelayed({
binding.layoutCalendar.shrink()
}, 200)
}
/** 日期选择 */
private fun showTimePickDialog() {
val start = java.util.Calendar.getInstance()
start.timeInMillis = vm.allMemoList.last().learnWord.createTime
val end = java.util.Calendar.getInstance()
end.timeInMillis = vm.allMemoList.first().learnWord.createTime
val timePickPopup = TimePickerPopup(this)
.setMode(TimePickerPopup.Mode.YM)
.setDefaultDate(getInstance().apply { time = DateUtil.format(binding.tvShowTime.text.toString(),"yyyy年MM月")})
.setItemTextSize(16)
.setTimePickerListener(object : TimePickerListener {
override fun onTimeChanged(date : Date?) {
//时间改变
}
override fun onTimeConfirm(date : Date, view : View?) {
//点击确认时间
val split = DateUtil.format(date.time, DateUtil.FORMAT_4).split("-")
binding.calendarView.scrollToCalendar(split[0].toInt(), split[1].toInt(), split[2].toInt())
binding.calendarView.clearSingleSelect()
}
})
XPopup.Builder(this).asCustom(timePickPopup).show()
}
}

+ 152
- 1
app/src/main/java/com/xkl/cdl/module/m_memo/MemoListDetailViewModel.kt View File

@@ -1,11 +1,162 @@
package com.xkl.cdl.module.m_memo

import androidx.lifecycle.MutableLiveData
import com.suliang.common.base.activity.ToastEvent
import com.suliang.common.base.viewmodel.BaseViewModel
import com.suliang.common.extension.diskIo2Main
import com.suliang.common.util.DateUtil
import com.xkl.cdl.data.AppConstants
import com.xkl.cdl.data.DataTransferHolder
import com.xkl.cdl.data.bean.LearnWord
import com.xkl.cdl.data.bean.MemoBean
import com.xkl.cdl.data.bean.intentdata.MemoData
import com.xkl.cdl.data.manager.CourseManager
import com.xkl.cdl.data.manager.db.DBCourseManager
import com.xkl.cdl.data.manager.db.DbControlBase
import io.reactivex.rxjava3.core.Observable
import java.util.*

class MemoListDetailViewModel : BaseViewModel(){
class MemoListDetailViewModel : BaseViewModel() {
val memoData = DataTransferHolder.instance.getData<MemoData>()
val dbControlBase = DbControlBase(memoData.course.subjectId, memoData.course.coursePackId,
memoData.course.coursePackType, memoData.course.courseId,
memoData.course.courseType)
/**搜索框: 搜索关键字*/
val keyWordSearch = MutableLiveData<String>()
/**存储选中的日期 到天*/
val selectTime = MutableLiveData<String>("")
//所有的memo数据
val allMemoList = mutableListOf<MemoBean>()
//今天需复习数据
val allNeedReviewList = MutableLiveData<MutableList<LearnWord>>()
//日历所需map
val calenderMap = mutableMapOf<String, MutableList<MemoBean>>()
//当天显示的备忘本集合
var showMemoTodayList = mutableListOf<MemoBean>()
//用于显示的备忘本集合, 可能带搜索关键字后的结果
val showMemoListLiveData = MutableLiveData<MutableList<MemoBean>>()
/** 首次加载 */
fun loadMain() {
initCurrentErrorWord()
}
/**此方法只进入时调用一次*/
private fun initCurrentErrorWord() {
val allMemoWords = mutableListOf<MemoBean>()
val todayReviewWords = mutableListOf<LearnWord>()
val calendar = Calendar.getInstance()
val currentTime = System.currentTimeMillis()
memoData.memoList.forEachIndexed { index, error ->
val splitValue = error.split("_") //拆分为数组
val originReviewNumber = splitValue[6].toInt()
//生成LearnWord
val learnWord = LearnWord(splitValue[0].toInt(), splitValue[1].toLong(), splitValue[2].toLong(),
memoData.course.coursePackType, memoData.course.courseType, splitValue[3].toLong(),
splitValue[4].toLong(), splitValue[5].toLong(), true, 0).apply {
reviewNum = originReviewNumber
createTime = DateUtil.format(splitValue[7], DateUtil.FORMAT_1).time
}
//添加到备忘本集合
val currentMemoBean = MemoBean(learnWord)
allMemoWords.add(currentMemoBean)
//判断是否能够进入复习
val isNeedInReview = CourseManager.calculateIsNeedInReview(calendar, originReviewNumber, splitValue[7], currentTime)
if (isNeedInReview) {
// lessonType为非准确的赋值,需要在查询具体详情数据的时候,在对lessonType进行具体赋值
todayReviewWords.add(learnWord)
}
//针对天数进行分组 背完本分组
val day = DateUtil.format(learnWord.createTime, DateUtil.FORMAT_4)
calenderMap[day]?.add(currentMemoBean) ?: let {
calenderMap[day] = mutableListOf<MemoBean>().apply {
add(currentMemoBean)
}
}
}
//备忘本排序: 倒叙
allMemoList.sortByDescending {
it.learnWord.createTime
}
//赋值
allNeedReviewList.value = todayReviewWords
allMemoList.addAll(allMemoWords)
//数据库查询, 并对今天需要复习的数据,进行赋值 查询内容
Observable.fromCallable {
//查询了详细数据
DBCourseManager.queryMemoList(dbControlBase, allMemoList)
return@fromCallable true
}.compose(diskIo2Main()).subscribe({
getTimeForMemoList()
}, {
it.printStackTrace()
showToast(ToastEvent("数据查询失败,请检查数据库是否存在"))
}
)
}
/**
* 获取选中日期数据,同时备忘本显示内容需要去重
*/
fun getTimeForMemoList() {
//如果数据为空,直接返回,不处理了
if (calenderMap.isEmpty()) return
//选中时间
val value = selectTime.value
//选中时间的备忘本,去重
showMemoTodayList = (if (value.isNullOrEmpty()) allMemoList else calenderMap[value] ?: mutableListOf()).distinctBy {
it.learnWord.wordId
}.toMutableList()
//是否有关键字搜索?
val keyWordSearchValue = keyWordSearch.value
//更新列表
showMemoListLiveData.value = if (keyWordSearchValue.isNullOrEmpty()) {
showMemoTodayList
} else {
showMemoTodayList.filter {
when (memoData.course.courseType) {
AppConstants.COURSE_TYPE_ENGLISH_SPELL -> it.learnWord.basic_explanation?.contains(keyWordSearchValue)
?: false
else -> it.learnWord.word.contains(keyWordSearchValue)
}
}.toMutableList()
}
}
/**
*
* @param key String 时间 天
* @param count 标记数量
* @return com.haibin.calendarview.Calendar
*/
fun getSchemeCalendar(key : String, count: Int) : com.haibin.calendarview.Calendar {
val split = key.split("-")
return com.haibin.calendarview.Calendar().apply {
year = split[0].toInt()
month = split[1].toInt()
day = split[2].toInt()
schemeColor = 0xff5082e6.toInt() //标记颜色
scheme = if (count > 99) "99+" else "$count" //标记内容
//添加标记
// addScheme(com.haibin.calendarview.Calendar.Scheme())
}
}
}

+ 116
- 0
app/src/main/java/com/xkl/cdl/module/m_memo/MemoTestActivity.kt View File

@@ -0,0 +1,116 @@
package com.xkl.cdl.module.m_memo

import android.annotation.SuppressLint
import android.os.Bundle
import androidx.lifecycle.ViewModelProvider
import com.google.android.flexbox.FlexDirection
import com.google.android.flexbox.FlexWrap
import com.google.android.flexbox.FlexboxLayoutManager
import com.jeremyliao.liveeventbus.LiveEventBus
import com.suliang.common.base.activity.BaseActivityVM
import com.suliang.common.extension.click
import com.suliang.common.extension.setHtml
import com.xkl.cdl.R
import com.xkl.cdl.adapter.AdapterCourseLessonTestChoose
import com.xkl.cdl.data.DataTransferHolder
import com.xkl.cdl.databinding.ActivityMemoTestBinding
import com.xkl.cdl.module.learn.LearnExamActivity

class MemoTestActivity : BaseActivityVM<ActivityMemoTestBinding, MemoTestViewModel>() {
private lateinit var adapter : AdapterCourseLessonTestChoose
@SuppressLint("NotifyDataSetChanged")
override fun initActivity(savedInstanceState : Bundle?) {
//先默认设置为备忘本的测试
vm.recordTestType = 1
binding.titleBar.onBackClick = {
finish()
}
binding.tvCourse.setHtml("当前课程:<font color=\'#5082E6\'>${vm.memoData.course.courseTitle}</font>")
binding.recyclerView.apply {
layoutManager = FlexboxLayoutManager(this@MemoTestActivity, FlexDirection.ROW, FlexWrap.WRAP)
this@MemoTestActivity.adapter = AdapterCourseLessonTestChoose(vm)
this.adapter = this@MemoTestActivity.adapter
}
//全选按钮 更新列表
binding.cbAll.setOnClickListener {
when {
//选中
binding.cbAll.isChecked -> for (i in 0 until adapter.itemCount) {
vm.checkLessonArray.put(i, true)
}
//未选中
else -> vm.checkLessonArray.clear()
}
adapter.notifyDataSetChanged()
vm.isAllCheck.value = binding.cbAll.isChecked
}
/** 开始测试 */
binding.tvTest.click {
val count = when (binding.rgNumber.checkedRadioButtonId) {
R.id.rb_smaller -> 20
R.id.rb_normal -> 20
R.id.rb_more -> 100
else -> 0
}
if (vm.checkLessonArray.size() == 0){
showToast("请选择测试章节")
return@click
}
vm.toStartTest(count).observe(this){
DataTransferHolder.instance.putData(value = it)
LearnExamActivity.newInstance(this)
}
}
}
override fun initViewModel() : MemoTestViewModel {
return ViewModelProvider(this)[MemoTestViewModel::class.java]
}
override fun loadData() {
vm.queryMemoLesson()
//列表显示: 默认设置为全选
vm.showLessonListLivaData.observe(this) {
vm.checkLessonArray.clear()
when (it) {
//备忘本
1 -> {
for (i in 0 until vm.memoTestLessonList.size) {
vm.checkLessonArray.put(i, true)
}
adapter.setData(vm.memoTestLessonList)
}
//全部
2 -> {
for (i in 0 until vm.memoTestLessonList.size) {
vm.checkLessonArray.put(i, true)
}
adapter.setData(vm.allLessonList)
}
}
binding.cbAll.isChecked = true
}
//全选监听: 适配器中item全选中的操作
vm.isAllCheck.observe(this) {
if (binding.cbAll.isChecked != it) {
binding.cbAll.toggle()
}
}
//备忘本测试完成再测一次监听
LiveEventBus.get<Int>("memo_test_again").observe(this){
binding.tvTest.performClick()
}
}
}

+ 151
- 0
app/src/main/java/com/xkl/cdl/module/m_memo/MemoTestViewModel.kt View File

@@ -0,0 +1,151 @@
package com.xkl.cdl.module.m_memo

import android.util.SparseBooleanArray
import androidx.lifecycle.MutableLiveData
import com.suliang.common.base.activity.ToastEvent
import com.suliang.common.base.viewmodel.BaseViewModel
import com.suliang.common.extension.diskIo2Main
import com.xkl.cdl.data.AppConstants
import com.xkl.cdl.data.DataTransferHolder
import com.xkl.cdl.data.bean.course.CourseDetail
import com.xkl.cdl.data.bean.course.Lesson
import com.xkl.cdl.data.bean.intentdata.ExamData
import com.xkl.cdl.data.bean.intentdata.MemoData
import com.xkl.cdl.data.manager.db.DBCourseManager
import com.xkl.cdl.data.manager.db.DbControlBase
import com.xkl.cdl.data.repository.DataRepository
import io.reactivex.rxjava3.core.Observable
import java.lang.StringBuilder

/**
* author suliang
* create 2022/6/16 14:45
* Describe:
*/
class MemoTestViewModel : BaseViewModel() {
val memoData = DataTransferHolder.instance.getData<MemoData>()
val dbControlBase = DbControlBase(memoData.course.subjectId, memoData.course.coursePackId, memoData.course.coursePackType,
memoData.course.courseId, memoData.course.courseType)
//记录选择的是备忘本测试还是课程的所有章节测试 1:备忘本 2:课程章节
var recordTestType = 1
//该课程备忘本的课时数据
lateinit var memoTestLessonList : MutableList<Lesson>
//该课程所有的课时数据
lateinit var allLessonList : MutableList<Lesson>
//通知显示使用的备忘本测试还是课程的所有章节测试 1:备忘本 2:课程章节
val showLessonListLivaData = MutableLiveData<Int>()
/**选中item集合 key position value: Boolean*/
val checkLessonArray = SparseBooleanArray()
/** 是否是全选 */
var isAllCheck = MutableLiveData<Boolean>(true)
fun isMemeTestLessonListInit() : Boolean {
return this::memoTestLessonList.isInitialized
}
fun isAllLessonListInit() : Boolean {
return this::memoTestLessonList.isInitialized
}
/** 查询备忘本的测试 */
fun queryMemoLesson() {
DataRepository.queryMemoLesson(dbControlBase, memoData.memoList).compose(diskIo2Main()).subscribe({
memoTestLessonList = it.toMutableList()
showLessonListLivaData.value = 1
}, {
it.printStackTrace()
})
}
/** 查询课程的所有课时 */
fun queryAllLesson() {
DataRepository.getCourseAllLesson(dbControlBase, CourseDetail()).compose(diskIo2Main()).subscribe({
memoTestLessonList = it.toMutableList()
showLessonListLivaData.value = 2
}, {
it.printStackTrace()
})
}
/** 开始测试,获取数据
* @param count Int 数量
* @return MutableLiveData<ExamData>
*/
fun toStartTest(count : Int) : MutableLiveData<ExamData> {
val result = MutableLiveData<ExamData>()
Observable.fromCallable<ExamData>() {
return@fromCallable when(recordTestType) {
//备忘本测试
1 -> {
//查询的lesson
val queryLesson = mutableListOf<Lesson>()
//拼接的lesson名称
val lessonListName = when {
isAllCheck.value!! -> {
queryLesson.addAll(memoTestLessonList)
"全部"
}
else -> {
val builder = StringBuilder()
memoTestLessonList.forEachIndexed { index, lesson ->
if (checkLessonArray.get(index)) {
queryLesson.add(lesson)
if (isShowLessonName()) {
builder.append("${lesson.chapterName}.${lesson.lessonName}、")
} else {
builder.append("${lesson.chapterName}、")
}
}
}
//去除顿号
builder.substring(0, builder.length - 1)
}
}
//保存的题目
val saveTitle = "${memoData.course.courseTitle}@@${lessonListName}"
//查询测试数据
val testDataList = DBCourseManager.queryMemoTest(dbControlBase,queryLesson,count)
ExamData(memoData.course.subjectId, AppConstants.TEST_TYPE_MEMO, memoData.course.courseTitle,
saveTitle).apply {
coursePackId = memoData.course.coursePackId //课程包id, 测试错误上次数据需要
coursePackType = memoData.course.coursePackType //课程包类型
courseId = memoData.course.courseId //课程id
courseType = memoData.course.courseType //课程类型
testData = testDataList //测试题数据
}
}
//章节测试
else -> ExamData(memoData.course.subjectId, AppConstants.TEST_TYPE_MEMO, memoData.course.courseTitle,
"saveTitle").apply {
coursePackId = memoData.course.coursePackId //课程包id, 测试错误上次数据需要
coursePackType = memoData.course.coursePackType //课程包类型
courseId = memoData.course.courseId //课程id
courseType = memoData.course.courseType //课程类型
// testData : List<ExamBean>? = null //测试题数据
}
}
}.compose(diskIo2Main())
.subscribe({
result.value = it
},{
it.printStackTrace()
showToast(ToastEvent("测试数据获取异常"))
})
return result
}
/**显示章节名称 还是显示课时名称 true章节+课时 false 章节*/
fun isShowLessonName() : Boolean{
return memoData.course.courseType != AppConstants.COURSE_TYPE_CHINESE_COMPOSITION
}
}

+ 66
- 0
app/src/main/java/com/xkl/cdl/module/m_service_center/TestDetailActivity.kt View File

@@ -0,0 +1,66 @@
package com.xkl.cdl.module.m_service_center

import android.annotation.SuppressLint
import android.os.Bundle
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import com.suliang.common.base.activity.BaseActivityVM
import com.suliang.common.extension.setHtml
import com.suliang.common.util.DateUtil
import com.xkl.cdl.adapter.AdapterTestDetail
import com.xkl.cdl.data.AppConstants
import com.xkl.cdl.data.manager.CourseManager
import com.xkl.cdl.databinding.ActivityTestDetailBinding

/**
* author suliang
* create 2022/6/20 16:52
* Describe: 测试详情
*/
class TestDetailActivity : BaseActivityVM<ActivityTestDetailBinding,TestDetailViewModel>() {
override fun initViewModel() : TestDetailViewModel {
return ViewModelProvider(this)[TestDetailViewModel::class.java]
}
@SuppressLint("SetTextI18n")
override fun initActivity(savedInstanceState : Bundle?) {
// TODO: 2022/6/21 词汇量测试暂未考虑
binding.run {
titleBar.onBackClick = { v -> finish() }
tvCourseName.setHtml(initCourseName())
tvScore.setHtml(initScore())
tvType.text = CourseManager.getExamTypeName(vm.learnExam.type.toInt()) //测试类型
tvUseTime.text = DateUtil.formatGMT(vm.learnExam.duration,DateUtil.FORMAT_2) //用时
tvTestTime.text = vm.learnExam.created //创建时间
//总数
tvTotalCount.text = "共${vm.learnExam.totalNum}题"
tvCorrectCount.text = "正确:${vm.learnExam.correctNum}"
tvErrorCount.text = "错误:${vm.learnExam.errorNum}"
//适配器
rv.layoutManager = LinearLayoutManager(this@TestDetailActivity,LinearLayoutManager.VERTICAL,false)
rv.adapter = AdapterTestDetail(vm)
(rv.adapter as AdapterTestDetail).setData(vm.learnExam.recordList)
}
}
override fun loadData() {
}
private fun initCourseName() : String{
val split = vm.learnExam.title.split("@@")
return if (split.size > 1){
"${split[0]}<font color=\'#8A8A99\'>(${split[1]})</font>"
}else{
split[0]
}
}
private fun initScore():String{
return when(vm.courseType){
AppConstants.COURSE_TYPE_ENGLISH_SPOKEN -> "完成"
else -> "${vm.learnExam.score}<small><small><small>分</small></small></small>"
}
}
}

+ 36
- 0
app/src/main/java/com/xkl/cdl/module/m_service_center/TestDetailViewModel.kt View File

@@ -0,0 +1,36 @@
package com.xkl.cdl.module.m_service_center

import android.text.StaticLayout
import com.google.gson.Gson
import com.google.gson.JsonObject
import com.google.gson.JsonParser
import com.suliang.common.base.viewmodel.BaseViewModel
import com.xkl.cdl.data.AppConstants
import com.xkl.cdl.data.DataTransferHolder
import mqComsumerV1.Struct

/**
* author suliang
* create 2022/6/20 16:54
* Describe:
*/
class TestDetailViewModel: BaseViewModel() {
//试卷
val learnExam = DataTransferHolder.instance.getData<Struct.LearnExam>()
//课程类型
val courseType = when(learnExam.type.toInt()){
//如果是词汇量测试,直接返回 0 ,不需要知道课程类型
AppConstants.TEST_TYPE_NORMAL -> 0
//其他测试类型都与课程有关,需要解析ext,获取课程类型
else -> try {
JsonParser.parseString(learnExam.ext).asJsonObject.get("courseType").asInt
} catch (e : Exception) {
e.printStackTrace()
0
}
}
}

+ 30
- 0
app/src/main/java/com/xkl/cdl/widget/CustomCalendarConstraintLayout.kt View File

@@ -0,0 +1,30 @@
package com.xkl.cdl.widget

import android.content.Context
import android.util.AttributeSet
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.recyclerview.widget.RecyclerView
import com.haibin.calendarview.CalendarLayout
import com.xkl.cdl.R

/**
* author suliang
* create 2022/6/15 14:58
* Describe: CalendarLayout 中与CalendarView 如果嵌套各种View出现事件冲突,可以实现这个方法即可
* 本类主要实现判断 内部的子item的RecyclerView下拉是否到顶
*/
class CustomCalendarConstraintLayout @JvmOverloads constructor(context : Context, attr:AttributeSet? = null,def:Int = 0): ConstraintLayout(context,attr,def),CalendarLayout.CalendarScrollView {
/**
* 如果你想让下拉无效,return false
* @return isScrollToTop 是否滚动到顶部
*/
override fun isScrollToTop() : Boolean {
val recycelerView = findViewById<RecyclerView>(R.id.rv_memo)
return recycelerView?.let {
it.computeVerticalScrollOffset() == 0
}?: true
}
}

+ 231
- 0
app/src/main/java/com/xkl/cdl/widget/CustomMonthView.java View File

@@ -0,0 +1,231 @@
package com.xkl.cdl.widget;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;

import androidx.core.content.ContextCompat;
import androidx.core.graphics.ColorUtils;

import com.haibin.calendarview.Calendar;
import com.haibin.calendarview.MonthView;
import com.xkl.cdl.R;

/**
* 演示一个变态需求的月视图
* Created by huanghaibin on 2018/2/9.
*/

public class CustomMonthView extends MonthView {

private int mRadius;

/**
* 自定义魅族标记的文本画笔
*/
private Paint mTextPaint = new Paint();


/**
* 24节气画笔
*/
private Paint mSolarTermTextPaint = new Paint();

/**
* 背景圆点
*/
private Paint mPointPaint = new Paint();

/**
* 今天的背景色
*/
private Paint mCurrentDayPaint = new Paint();

/**
* 圆点半径
*/
private float mPointRadius;

private int mPadding;

private float mCircleRadius;
/**
* 自定义魅族标记的圆形背景
*/
private Paint mSchemeBasicPaint = new Paint();

private float mSchemeBaseLine;

int color = ContextCompat.getColor(getContext(), R.color.theme_color);

public CustomMonthView(Context context) {
super(context);
int colorSchemeBasicPaint = ColorUtils.setAlphaComponent(color, 50);

mTextPaint.setTextSize(dipToPx(context, 9));
mTextPaint.setColor(0xffffffff);
mTextPaint.setAntiAlias(true);
mTextPaint.setFakeBoldText(true);


// mSolarTermTextPaint.setColor(0xff489dff);
// mSolarTermTextPaint.setAntiAlias(true);
// mSolarTermTextPaint.setTextAlign(Paint.Align.CENTER);

mSchemeBasicPaint.setAntiAlias(true);
mSchemeBasicPaint.setStyle(Paint.Style.FILL);
mSchemeBasicPaint.setTextAlign(Paint.Align.CENTER);
mSchemeBasicPaint.setFakeBoldText(true);
mSchemeBasicPaint.setColor(colorSchemeBasicPaint);


mCurrentDayPaint.setAntiAlias(true);
mCurrentDayPaint.setStyle(Paint.Style.FILL);
mCurrentDayPaint.setColor(0x1A5082E6);


// mPointPaint.setAntiAlias(true);
// mPointPaint.setStyle(Paint.Style.FILL);
// mPointPaint.setTextAlign(Paint.Align.CENTER);
// mPointPaint.setColor(Color.RED);

mCircleRadius = dipToPx(getContext(), 10);

mPadding = dipToPx(getContext(), 3);

mPointRadius = dipToPx(context, 2);

Paint.FontMetrics metrics = mSchemeBasicPaint.getFontMetrics();
mSchemeBaseLine = mCircleRadius - metrics.descent + (metrics.bottom - metrics.top) / 2 + dipToPx(getContext(), 1);


}

@Override
protected void onPreviewHook() {
// mSolarTermTextPaint.setTextSize(mCurMonthLunarTextPaint.getTextSize());
mRadius = Math.min(mItemWidth, mItemHeight) / 11 * 4;
}


@Override
protected boolean onDrawSelected(Canvas canvas, Calendar calendar, int x, int y, boolean hasScheme) {
int cx = x + mItemWidth / 2 ;
int cy = y + mItemHeight / 2 - (mRadius/2);
mSelectedPaint.setColor(color);
canvas.drawCircle(cx, cy, mRadius * 3/4, mSelectedPaint);
return true;
}

@SuppressWarnings("IntegerDivisionInFloatingPointContext")
@Override
protected void onDrawScheme(Canvas canvas, Calendar calendar, int x, int y) {

boolean isSelected = isSelected(calendar);
// if (isSelected) {
// mPointPaint.setColor(Color.WHITE);
// } else {
// mPointPaint.setColor(Color.GRAY);
// }
//
// canvas.drawCircle(x + mItemWidth / 2, y + mItemHeight - 3 * mPadding, mPointRadius, mPointPaint);
}

@SuppressWarnings("IntegerDivisionInFloatingPointContext")
@Override
protected void onDrawText(Canvas canvas, Calendar calendar, int x, int y, boolean hasScheme, boolean isSelected) {
int cx = x + mItemWidth / 2;
int cy = y + mItemHeight / 2 - (mRadius/2);
int top = y - mItemHeight / 6;

if (calendar.isCurrentDay() && !isSelected) {
mCurrentDayPaint.setStrokeWidth(3);
mCurrentDayPaint.setColor(color);
mCurrentDayPaint.setStyle(Paint.Style.STROKE);
canvas.drawCircle(cx, cy, mRadius * 3/4, mCurrentDayPaint);
}



if (hasScheme) {
canvas.drawCircle(x + mItemWidth - mPadding - mCircleRadius / 2, y + mPadding + mCircleRadius, mCircleRadius * 3/4, mSchemeBasicPaint);
mTextPaint.setColor(color);
int textWidth = getTextWidth(mTextPaint, calendar.getScheme());
canvas.drawText(calendar.getScheme(), x + mItemWidth - mCircleRadius - textWidth/3, y + mPadding + mSchemeBaseLine, mTextPaint);
}



//当然可以换成其它对应的画笔就不麻烦,
// if (calendar.isWeekend() && calendar.isCurrentMonth()) {
// mCurMonthTextPaint.setColor(0xFF489dff);
//// mCurMonthLunarTextPaint.setColor(0xFF489dff);
// mSchemeTextPaint.setColor(0xFF489dff);
// mSchemeLunarTextPaint.setColor(0xFF489dff);
// mOtherMonthLunarTextPaint.setColor(0xFF489dff);
// mOtherMonthTextPaint.setColor(0xFF489dff);
// } else {
mCurMonthTextPaint.setColor(0xff333333);
// mCurMonthLunarTextPaint.setColor(0xffCFCFCF);
mSchemeTextPaint.setColor(0xff333333);
mSchemeLunarTextPaint.setColor(0xffCFCFCF);

mOtherMonthTextPaint.setColor(0xFFe1e1e1);


mOtherMonthLunarTextPaint.setColor(0xFFe1e1e1);
// }

if (isSelected) {
canvas.drawText(String.valueOf(calendar.getDay()), cx, mTextBaseLine + top, mSelectTextPaint);

// canvas.drawText(calendar.getLunar(), cx, mTextBaseLine + y + mItemHeight / 10, mSelectedLunarTextPaint);
} else if (hasScheme) {

canvas.drawText(String.valueOf(calendar.getDay()), cx, mTextBaseLine + top, calendar.isCurrentMonth() ? mSchemeTextPaint : mOtherMonthTextPaint);

// canvas.drawText(calendar.getLunar(), cx, mTextBaseLine + y + mItemHeight / 10,
// !TextUtils.isEmpty(calendar.getSolarTerm()) ? mSolarTermTextPaint : mSchemeLunarTextPaint);
} else {
if ((calendar.isCurrentDay() ? mCurDayTextPaint :calendar.isCurrentMonth() ? mCurMonthTextPaint: mOtherMonthTextPaint) == mCurMonthTextPaint){
if (hasScheme) {
canvas.drawText(String.valueOf(calendar.getDay()), cx, mTextBaseLine + top,
calendar.isCurrentDay() ? mCurDayTextPaint :calendar.isCurrentMonth() ? mCurMonthTextPaint: mOtherMonthTextPaint);
}else {
mCurMonthTextPaint.setColor(0xFFCCCCCC);
canvas.drawText(String.valueOf(calendar.getDay()), cx, mTextBaseLine + top,mCurMonthTextPaint);
}
}else {
canvas.drawText(String.valueOf(calendar.getDay()), cx, mTextBaseLine + top,
calendar.isCurrentDay() ? mCurDayTextPaint :calendar.isCurrentMonth() ? mCurMonthTextPaint: mOtherMonthTextPaint);
}
}
}

/**
* dp转px
*
* @param context context
* @param dpValue dp
* @return px
*/
private static int dipToPx(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}


public static int getTextWidth(Paint paint, String str) {
int iRet = 0;
if (str != null && str.length() > 0) {
int len = str.length();
float[] widths = new float[len];
paint.getTextWidths(str, widths);
for (int j = 0; j < len; j++) {
iRet += (int) Math.ceil(widths[j]);
}
}
return iRet;
}

}

+ 227
- 0
app/src/main/java/com/xkl/cdl/widget/CustomWeekView.java View File

@@ -0,0 +1,227 @@
package com.xkl.cdl.widget;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;

import androidx.core.content.ContextCompat;
import androidx.core.graphics.ColorUtils;

import com.haibin.calendarview.Calendar;
import com.haibin.calendarview.WeekView;
import com.xkl.cdl.R;


/**
* 演示一个变态需求的周视图
* Created by huanghaibin on 2018/2/9.
*/

public class CustomWeekView extends WeekView {


private int mRadius;

/**
* 自定义魅族标记的文本画笔
*/
private Paint mTextPaint = new Paint();


/**
* 24节气画笔
*/
private Paint mSolarTermTextPaint = new Paint();

/**
* 背景圆点
*/
private Paint mPointPaint = new Paint();

/**
* 今天的背景色
*/
private Paint mCurrentDayPaint = new Paint();


/**
* 圆点半径
*/
private float mPointRadius;

private int mPadding;

private float mCircleRadius;
/**
* 自定义魅族标记的圆形背景
*/
private Paint mSchemeBasicPaint = new Paint();

private float mSchemeBaseLine;

int color = ContextCompat.getColor(getContext(), R.color.theme_color);


public CustomWeekView(Context context) {
super(context);
int colorSchemeBasicPaint = ColorUtils.setAlphaComponent(color, 50);
mTextPaint.setTextSize(dipToPx(context, 9));
mTextPaint.setColor(0xffffffff);
mTextPaint.setAntiAlias(true);
mTextPaint.setFakeBoldText(true);


// mSolarTermTextPaint.setColor(0xff489dff);
// mSolarTermTextPaint.setAntiAlias(true);
// mSolarTermTextPaint.setTextAlign(Paint.Align.CENTER);

mSchemeBasicPaint.setAntiAlias(true);
mSchemeBasicPaint.setStyle(Paint.Style.FILL);
mSchemeBasicPaint.setTextAlign(Paint.Align.CENTER);
mSchemeBasicPaint.setFakeBoldText(true);
mSchemeBasicPaint.setColor(colorSchemeBasicPaint);

// mPointPaint.setAntiAlias(true);
// mPointPaint.setStyle(Paint.Style.FILL);
// mPointPaint.setTextAlign(Paint.Align.CENTER);
// mPointPaint.setColor(0x1A5082E6);


mCurrentDayPaint.setAntiAlias(true);
mCurrentDayPaint.setStyle(Paint.Style.FILL);
mCurrentDayPaint.setColor(0x1A5082E6);


mCircleRadius = dipToPx(getContext(), 10);

mPadding = dipToPx(getContext(), 3);

mPointRadius = dipToPx(context, 2);

Paint.FontMetrics metrics = mSchemeBasicPaint.getFontMetrics();
mSchemeBaseLine = mCircleRadius - metrics.descent + (metrics.bottom - metrics.top) / 2 + dipToPx(getContext(), 1);

}


@Override
protected void onPreviewHook() {
// mSolarTermTextPaint.setTextSize(mCurMonthLunarTextPaint.getTextSize());
mRadius = Math.min(mItemWidth, mItemHeight) / 11 * 4;
}


@Override
protected boolean onDrawSelected(Canvas canvas, Calendar calendar, int x, boolean hasScheme) {
int cx = x + mItemWidth / 2;
int cy = mItemHeight / 2 - (mRadius/2);
mSelectedPaint.setColor(color);
canvas.drawCircle(cx, cy, mRadius * 3/4, mSelectedPaint);
return true;
}


@Override
protected void onDrawScheme(Canvas canvas, Calendar calendar, int x) {

boolean isSelected = isSelected(calendar);
// if (isSelected) {
// mPointPaint.setColor(Color.WHITE);
// } else {
// mPointPaint.setColor(Color.GRAY);
// }

// canvas.drawCircle(x + mItemWidth / 2, mItemHeight - 3 * mPadding, mPointRadius, mPointPaint);
}

@SuppressWarnings("IntegerDivisionInFloatingPointContext")
@Override
protected void onDrawText(Canvas canvas, Calendar calendar, int x, boolean hasScheme, boolean isSelected) {
int cx = x + mItemWidth / 2;
int cy = mItemHeight / 2 - (mRadius/2);
int top = -mItemHeight / 6 ;

if (calendar.isCurrentDay() && !isSelected) {
mCurrentDayPaint.setStrokeWidth(3);
mCurrentDayPaint.setColor(color);
mCurrentDayPaint.setStyle(Paint.Style.STROKE);
canvas.drawCircle(cx, cy, mRadius * 3/4, mCurrentDayPaint);
}

if(hasScheme){
canvas.drawCircle(x + mItemWidth - mPadding - mCircleRadius / 2, mPadding + mCircleRadius, mCircleRadius * 3/4, mSchemeBasicPaint);

mTextPaint.setColor(color);
int textWidth = getTextWidth(mTextPaint, calendar.getScheme());
canvas.drawText(calendar.getScheme(), x + mItemWidth - textWidth /3 - mCircleRadius, mPadding + mSchemeBaseLine, mTextPaint);
}

// if (calendar.isWeekend() && calendar.isCurrentMonth()) {
// mCurMonthTextPaint.setColor(0xFF489dff);
// mCurMonthLunarTextPaint.setColor(0xFF489dff);
// mSchemeTextPaint.setColor(0xFF489dff);
// mSchemeLunarTextPaint.setColor(0xFF489dff);
// mOtherMonthLunarTextPaint.setColor(0xFF489dff);
// mOtherMonthTextPaint.setColor(0xFF489dff);
// } else {
mCurMonthTextPaint.setColor(0xff333333);
mCurMonthLunarTextPaint.setColor(0xffCFCFCF);
mSchemeTextPaint.setColor(0xff333333);
mSchemeLunarTextPaint.setColor(0xffCFCFCF);

mOtherMonthTextPaint.setColor(0xFFe1e1e1);
mOtherMonthLunarTextPaint.setColor(0xFFe1e1e1);
// }

if (isSelected) {
canvas.drawText(String.valueOf(calendar.getDay()), cx, mTextBaseLine + top, mSelectTextPaint);
// canvas.drawText(calendar.getLunar(), cx, mTextBaseLine + mItemHeight / 10, mSelectedLunarTextPaint);
} else if (hasScheme) {

canvas.drawText(String.valueOf(calendar.getDay()), cx, mTextBaseLine + top, calendar.isCurrentMonth() ? mSchemeTextPaint : mOtherMonthTextPaint);

// canvas.drawText(calendar.getLunar(), cx, mTextBaseLine + mItemHeight / 10,
// !TextUtils.isEmpty(calendar.getSolarTerm()) ? mSolarTermTextPaint : mSchemeLunarTextPaint);
} else {

if ((calendar.isCurrentDay() ? mCurDayTextPaint :calendar.isCurrentMonth() ? mCurMonthTextPaint: mOtherMonthTextPaint) == mCurMonthTextPaint){
if (hasScheme) {
canvas.drawText(String.valueOf(calendar.getDay()), cx, mTextBaseLine + top,
calendar.isCurrentDay() ? mCurDayTextPaint :calendar.isCurrentMonth() ? mCurMonthTextPaint: mOtherMonthTextPaint);
}else {
mCurMonthTextPaint.setColor(0xFFCCCCCC);
canvas.drawText(String.valueOf(calendar.getDay()), cx, mTextBaseLine + top,mCurMonthTextPaint);
}
}else {
canvas.drawText(String.valueOf(calendar.getDay()), cx, mTextBaseLine + top,
calendar.isCurrentDay() ? mCurDayTextPaint :calendar.isCurrentMonth() ? mCurMonthTextPaint: mOtherMonthTextPaint);
}

}
}

/**
* dp转px
*
* @param context context
* @param dpValue dp
* @return px
*/
private static int dipToPx(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}

public static int getTextWidth(Paint paint, String str) {
int iRet = 0;
if (str != null && str.length() > 0) {
int len = str.length();
float[] widths = new float[len];
paint.getTextWidths(str, widths);
for (int j = 0; j < len; j++) {
iRet += (int) Math.ceil(widths[j]);
}
}
return iRet;
}
}

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

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true" android:drawable="@drawable/ic_checked_2"/>
<item android:drawable="@drawable/ic_checked_normal"/>
</selector>

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

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true" android:drawable="@drawable/ic_checked_1"/>
<item android:drawable="@drawable/ic_checked_normal"/>
</selector>

+ 10
- 0
app/src/main/res/drawable/selector_memo_review_bg.xml View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="true" android:drawable="@drawable/shape_rounder_8_solid_green1"/>
<item android:state_enabled="false">
<shape android:shape="rectangle">
<solid android:color="@color/gray_1"/>
<corners android:radius="8dp"/>
</shape>
</item>
</selector>

+ 15
- 0
app/src/main/res/drawable/selector_memo_test_bg.xml View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="true" >
<shape android:shape="rectangle">
<solid android:color="@color/theme_color"/>
<corners android:radius="8dp"/>
</shape>
</item>
<item android:state_enabled="false">
<shape android:shape="rectangle">
<solid android:color="@color/gray_1"/>
<corners android:radius="8dp"/>
</shape>
</item>
</selector>

+ 7
- 0
app/src/main/res/drawable/shape_cicler_24_c3d69b.xml View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="#C3D69B"/>
<size android:width="24dp"
android:height="24dp"/>
</shape>

+ 7
- 0
app/src/main/res/drawable/shape_cicler_24_ffcc99.xml View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="#FFCC99"/>
<size android:width="24dp"
android:height="24dp"/>
</shape>

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

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

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

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

+ 6
- 0
app/src/main/res/drawable/shape_rounder_toplr_8_white_1.xml View File

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

+ 97
- 0
app/src/main/res/layout/_xpopup_ext_time_picker.xml View File

@@ -0,0 +1,97 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">

<LinearLayout
android:orientation="horizontal"
android:paddingTop="15dp"
android:paddingBottom="15dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">

<TextView
android:id="@+id/btnCancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:paddingLeft="15dp"
android:paddingRight="10dp"
android:text="@string/xpopup_cancel"
android:textAllCaps="false"
android:textColor="@color/main_text_color"
android:textSize="@dimen/normalSize" />


<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="请选择时间区间"
android:gravity="center"
android:textSize="@dimen/bigSize"
android:textColor="@color/main_text_color"
/>

<TextView
android:id="@+id/btnConfirm"
android:gravity="center"
android:paddingLeft="10dp"
android:paddingRight="15dp"
android:textColor="@color/main_text_color"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/xpopup_ok"
android:textAllCaps="false"
android:textSize="@dimen/normalSize" />
</LinearLayout>


<LinearLayout
android:id="@+id/timepicker"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:minHeight="150dp"
android:orientation="horizontal">

<com.contrarywind.view.WheelView
android:id="@+id/year"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />

<com.contrarywind.view.WheelView
android:id="@+id/month"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />

<com.contrarywind.view.WheelView
android:id="@+id/day"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />

<com.contrarywind.view.WheelView
android:id="@+id/hour"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />

<com.contrarywind.view.WheelView
android:id="@+id/min"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />

<com.contrarywind.view.WheelView
android:id="@+id/second"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
</LinearLayout>


</LinearLayout>

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

@@ -87,7 +87,7 @@
android:id="@+id/nav_serviceCenter"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/memo"
android:text="@string/serviceCenter"
app:drawableTopCompat="@drawable/ic_nav_memo"
android:layout_weight="1"
android:gravity="center"

+ 180
- 48
app/src/main/res/layout/activity_memo_list_detail.xml View File

@@ -4,87 +4,206 @@
xmlns:tools="http://schemas.android.com/tools">

<data>

<variable
name="vm"
type="com.xkl.cdl.module.m_memo.MemoListDetailViewModel" />
</data>

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

<com.suliang.common.widget.TitleBar
android:id="@+id/title_bar"
android:layout_width="match_parent"
android:layout_height="@dimen/title_bar_height"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
/>
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<TextView
android:id="@+id/tv_search_cache"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:text="@string/cancel"
android:background="@color/white"
android:gravity="center_vertical"
android:paddingStart="12dp"
android:paddingEnd="@dimen/global_spacing"
android:text="@string/cancel"
android:textColor="@color/gray_2"
android:textSize="@dimen/smallSize"
app:layout_constraintTop_toTopOf="@+id/title_bar"
app:layout_constraintBottom_toBottomOf="@+id/title_bar"
app:layout_constraintEnd_toEndOf="parent"
android:paddingEnd="@dimen/global_spacing"
android:paddingStart="12dp"
android:background="@color/white"
android:textStyle="bold"
android:visibility="gone"
tools:visibility="visible"/>
app:layout_constraintBottom_toBottomOf="@+id/title_bar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/title_bar"
tools:visibility="visible" />

<com.suliang.common.widget.InputSearchEditText
android:id="@+id/et_search"
android:layout_width="0dp"
android:layout_height="36dp"
android:layout_marginStart="@dimen/global_spacing"
android:background="@drawable/et_search_bg"
android:drawablePadding="4dp"
android:gravity="center_vertical"
android:hint="@string/search_hint_input_key_word"
android:maxLines="1"
android:singleLine="true"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:layout_marginStart="@dimen/global_spacing"
android:singleLine="true"
android:textColor="@color/main_text_color"
android:textSize="@dimen/normalSize"
app:layout_constraintTop_toTopOf="@id/title_bar"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="@+id/title_bar"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@+id/tv_search_cache"
android:visibility="gone"
/>
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/title_bar"
android:text="@={vm.keyWordSearch}"/>

<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/layout_calendar_control"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/global_spacing"
android:layout_marginTop="8dp"
android:layout_marginEnd="@dimen/global_spacing"
android:background="@drawable/shape_rounder_toplr_8_white_1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/title_bar">

<TextView
android:id="@+id/tv_show_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/global_spacing"
android:drawablePadding="4dp"
android:paddingTop="12dp"
android:paddingBottom="12dp"
android:textColor="@color/main_text_color"
android:textSize="@dimen/smallSize"
app:drawableEndCompat="@drawable/ic_down"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="某年某月某日" />

<TextView
android:id="@+id/tv_calendar_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/global_spacing"
android:textColor="@color/gray_2"
android:textSize="@dimen/smallerSize"
app:layout_constraintBottom_toBottomOf="@+id/tv_show_time"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="展开" />
</androidx.constraintlayout.widget.ConstraintLayout>

<com.haibin.calendarview.CalendarLayout
android:id="@+id/layout_calendar"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginStart="@dimen/global_spacing"
android:layout_marginEnd="@dimen/global_spacing"
android:orientation="vertical"
app:gesture_mode="disabled"
app:default_status="shrink"
app:calendar_content_view_id="@+id/layout_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/title_bar"
app:layout_constraintBottom_toTopOf="@+id/guideline"
>


<androidx.constraintlayout.widget.ConstraintLayout
app:layout_constraintBottom_toTopOf="@+id/guideline"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/layout_calendar_control">
<!--app:gesture_mode="disabled" 默认手势 -->
<!--calendar_content_view_id 关联内容,估计是用于收缩的时候进行遮挡计算-->


<com.haibin.calendarview.CalendarView
android:id="@+id/calendarView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:current_month_lunar_text_color="#fff5f5f5"
app:current_month_text_color="#323233"
app:calendar_padding="10dp"
app:current_day_text_color="#FFCCCCCC"
app:day_text_size="@dimen/smallSize"
android:background="@drawable/shape_rounder_bottomlr_8_solider_white_1"
app:month_view_show_mode="mode_fix"
app:other_month_lunar_text_color="#e1e1e1"
app:other_month_text_color="#e1e1e1"
app:scheme_text="假"
app:scheme_text_color="#323233"
app:scheme_theme_color="#128c4b"
app:selected_lunar_text_color="#fff"
app:selected_text_color="#fff"
app:selected_theme_color="#5082E6"
app:week_background="#F5F5F5"
app:week_start_with="sun"
app:select_mode="single_mode"
app:week_text_color="#323233"
app:year_view_day_text_color="#333333"
app:year_view_day_text_size="2sp"
app:year_view_month_text_color="#ff0000"
app:year_view_month_text_size="20sp"
app:year_view_scheme_color="#f17706"
app:year_view_select_text_color="#fff"
app:year_view_week_height="12dp"
app:year_view_week_text_color="#e1e1e1"
app:year_view_week_text_size="6sp"
app:month_view="com.xkl.cdl.widget.CustomMonthView"
app:week_view="com.xkl.cdl.widget.CustomWeekView"/>
<!--scheme 角标标记 -->

<com.xkl.cdl.widget.CustomCalendarConstraintLayout
android:id="@+id/layout_content"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">


</androidx.constraintlayout.widget.ConstraintLayout>



android:layout_weight="1"
android:background="@color/white">

<TextView
android:id="@+id/tv_today_memo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:textColor="@color/gray_2"
android:textSize="@dimen/smallerSize"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="全部时间,共123条" />

<TextView
android:id="@+id/tv_today_review"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:textColor="@color/red_1"
android:textSize="@dimen/smallerSize"
app:layout_constraintStart_toEndOf="@+id/tv_today_memo"
app:layout_constraintTop_toTopOf="@+id/tv_today_memo"
tools:text="今日需复习" />

<View
android:id="@+id/v_2"
android:layout_width="0dp"
android:layout_height="@dimen/line_height"
android:layout_marginTop="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_today_memo" />

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_memo"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/v_2" />

</com.xkl.cdl.widget.CustomCalendarConstraintLayout>

</com.haibin.calendarview.CalendarLayout>

@@ -94,30 +213,43 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_end="72dp"
/>
app:layout_constraintGuide_end="72dp" />

<com.suliang.common.widget.TextViewCenterDrawable
android:id="@+id/tv_review_memo"
android:layout_width="0dp"
android:layout_height="@dimen/common_button_height"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@+id/tv_test_review"
android:layout_marginStart="@dimen/global_spacing"
android:layout_marginEnd="12dp"
android:layout_marginBottom="@dimen/global_spacing"
android:background="@color/red_1"
android:layout_marginEnd="12dp"/>
android:background="@drawable/selector_memo_review_bg"
android:drawableLeft="@drawable/ic_memo_review"
android:drawablePadding="4dp"
android:gravity="center_vertical"
android:text="复习备忘本"
android:textColor="@color/white"
android:textSize="@dimen/normalSize"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/tv_test_memo"
app:layout_constraintStart_toStartOf="parent" />

<com.suliang.common.widget.TextViewCenterDrawable
android:id="@+id/tv_test_review"
android:id="@+id/tv_test_memo"
android:layout_width="0dp"
android:layout_height="@dimen/common_button_height"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/tv_review_memo"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginEnd="@dimen/global_spacing"
android:layout_marginBottom="@dimen/global_spacing"
android:background="@color/main_text_color"/>
android:background="@drawable/selector_memo_test_bg"
android:drawableStart="@drawable/ic_memo_test"
android:drawablePadding="4dp"
android:gravity="center_vertical"
android:text="测试备忘本"
android:textColor="@color/white"
android:textSize="@dimen/normalSize"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/tv_review_memo"
/>

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

+ 191
- 0
app/src/main/res/layout/activity_memo_test.xml View File

@@ -0,0 +1,191 @@
<?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.m_memo.MemoTestActivity"
android:background="@color/white">
<com.suliang.common.widget.TitleBar
android:id="@+id/title_bar"
android:layout_width="match_parent"
android:layout_height="@dimen/title_bar_height"
app:layout_constraintTop_toTopOf="parent"
app:titleTextValue="课程测试"
app:barBackground="@color/white"/>
<TextView
android:id="@+id/tv_course"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@+id/title_bar"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:textSize="@dimen/normalSize"
android:textColor="@color/main_text_color"
android:background="@color/white_1"
android:paddingStart="@dimen/global_spacing"
android:paddingEnd="@dimen/global_spacing"
android:paddingTop="12dp"
android:paddingBottom="12dp"
tools:text="当前课程:测试课程认读"/>

<TextView
android:id="@+id/tv_choose_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="请选择测题量"
android:textColor="@color/gray_2"
android:layout_marginTop="10dp"
android:layout_marginStart="@dimen/global_spacing"
android:textSize="@dimen/smallSize"
app:layout_constraintTop_toBottomOf="@+id/tv_course"
app:layout_constraintStart_toStartOf="parent"
/>
<RadioGroup
android:id="@+id/rg_number"
android:layout_width="match_parent"
android:layout_height="44dp"
android:layout_marginLeft="@dimen/global_spacing"
android:layout_marginRight="@dimen/global_spacing"
android:orientation="horizontal"
app:layout_constraintTop_toBottomOf="@+id/tv_choose_number"
>
<RadioButton
android:id="@+id/rb_smaller"
android:button="@null"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="较少"
android:textColor="@color/main_text_color"
android:background="@color/white"
android:textSize="16dp"
android:layout_weight="1"
android:drawablePadding="8dp"
android:checked="true"
android:drawableStart="@drawable/choose_single"
/>

<RadioButton
android:id="@+id/rb_normal"
android:button="@null"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="普通"
android:layout_weight="1"
android:textColor="@color/main_text_color"
android:background="@color/white"
android:textSize="16dp"
android:drawablePadding="8dp"
android:checked="false"
android:drawableStart="@drawable/choose_single"
/>


<RadioButton
android:id="@+id/rb_more"
android:button="@null"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="较多"
android:layout_weight="1"
android:textColor="@color/main_text_color"
android:background="@color/white"
android:textSize="16dp"
android:drawablePadding="8dp"
android:checked="false"
android:drawableStart="@drawable/choose_single"
/>
</RadioGroup>

<View
android:id="@+id/v"
android:layout_width="0dp"
android:layout_height="@dimen/line_height"
android:background="@color/gray_1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/rg_number"
android:layout_marginStart="@dimen/global_spacing"
android:layout_marginEnd="@dimen/global_spacing"/>



<androidx.core.widget.NestedScrollView
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/v"
app:layout_constraintBottom_toTopOf="@+id/guideline">

<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">

<TextView
android:id="@+id/tv_choose_chapter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="请选择测试章节(多选)"
android:textColor="@color/gray_2"
android:layout_marginTop="16dp"
android:layout_marginStart="@dimen/global_spacing"
android:textSize="@dimen/smallSize"
app:layout_constraintTop_toBottomOf="@+id/v"
app:layout_constraintStart_toStartOf="parent"
/>

<CheckBox
android:id="@+id/cb_all"
android:button="@null"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/global_spacing"
android:paddingTop="4dp"
android:paddingBottom="4dp"
android:textSize="@dimen/normalSize"
android:text="全选"
android:drawablePadding="8dp"
android:drawableStart="@drawable/choose_multiple"
/>

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="@dimen/global_spacing"
android:layout_marginRight="@dimen/global_spacing"
/>

</androidx.appcompat.widget.LinearLayoutCompat>

</androidx.core.widget.NestedScrollView>

<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_end="72dp" />


<com.google.android.material.button.MaterialButton
android:id="@+id/tv_test"
style="@style/common_button_style"
android:text="@string/start_test"
app:cornerRadius="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/guideline"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginTop="0dp"
/>





</androidx.constraintlayout.widget.ConstraintLayout>

+ 228
- 0
app/src/main/res/layout/activity_test_detail.xml View File

@@ -0,0 +1,228 @@
<?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_service_center.TestDetailActivity"
android:background="@color/white">

<com.suliang.common.widget.TitleBar
android:id="@+id/title_bar"
android:layout_width="0dp"
android:layout_height="@dimen/title_bar_height"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:titleTextValue="测试成绩详情" />

<View
android:layout_width="0dp"
android:layout_height="@dimen/line_height"
app:layout_constraintTop_toBottomOf="@+id/title_bar"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:background="@color/gray_1" />

<androidx.core.widget.NestedScrollView
android:id="@+id/layout_memo_test"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/line_height"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/title_bar"
app:layout_constraintBottom_toBottomOf="parent"
android:orientation="vertical"
app:layout_constraintVertical_bias="0">

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

<androidx.appcompat.widget.LinearLayoutCompat
android:id="@+id/layout_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginStart="@dimen/global_spacing"
android:layout_marginEnd="@dimen/global_spacing">

<TextView
android:id="@+id/tv_course_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ellipsize="end"
android:maxLines="2"
android:textColor="@color/main_text_color"
android:textSize="@dimen/bigSize"
tools:text="课程名称(章节内容详情)课程名称(章节内容详情)课程名称(章节内容详情)课程名称(章节内容详情)课程名称(章节内容详情)课程名称(章节内容详情)" />

<TextView
android:id="@+id/tv_score"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/red_1"
android:textSize="26dp"
tools:text="100分" />
</androidx.appcompat.widget.LinearLayoutCompat>

<TextView
android:id="@+id/tv_type_flag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/layout_title"
android:layout_marginStart="@dimen/global_spacing"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginTop="12dp"
android:text="@string/test_type_1"
android:textSize="@dimen/smallSize"
android:textColor="@color/gray_2" />

<TextView
android:id="@+id/tv_type"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="@+id/tv_type_flag"
app:layout_constraintBottom_toBottomOf="@+id/tv_type_flag"
app:layout_constraintStart_toEndOf="@+id/tv_type_flag"
tools:text="@string/test_type_1"
android:textSize="@dimen/smallSize"
android:textColor="@color/main_text_color" />

<TextView
android:id="@+id/tv_use_time_flag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/tv_type_flag"
android:layout_marginStart="@dimen/global_spacing"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginTop="8dp"
android:text="@string/test_use_time_1"
android:textSize="@dimen/smallSize"
android:textColor="@color/gray_2" />

<TextView
android:id="@+id/tv_use_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="@+id/tv_use_time_flag"
app:layout_constraintStart_toStartOf="@+id/tv_type"
tools:text="@string/test_type_1"
android:textSize="@dimen/smallSize"
android:textColor="@color/main_text_color" />

<TextView
android:id="@+id/tv_test_time_flag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/tv_use_time_flag"
android:layout_marginStart="@dimen/global_spacing"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginTop="8dp"
android:text="@string/test_time_1"
android:textSize="@dimen/smallSize"
android:textColor="@color/gray_2" />

<TextView
android:id="@+id/tv_test_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="@+id/tv_test_time_flag"
app:layout_constraintStart_toEndOf="@+id/tv_test_time_flag"
tools:text="@string/test_type_1"
android:textSize="@dimen/smallSize"
android:textColor="@color/main_text_color" />

<View
android:id="@+id/v_1"
android:layout_width="0dp"
android:layout_height="36dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_test_time_flag"
android:layout_marginTop="@dimen/global_spacing"
android:background="@color/white_1" />

<TextView
android:id="@+id/tv_total_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/smallSize"
android:textColor="@color/gray_2"
tools:text="共50题"
app:layout_constraintTop_toTopOf="@+id/v_1"
app:layout_constraintBottom_toBottomOf="@+id/v_1"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="@dimen/global_spacing" />

<View
android:id="@+id/v_2"
android:layout_width="@dimen/line_height"
android:layout_height="12dp"
app:layout_constraintTop_toTopOf="@+id/v_1"
app:layout_constraintBottom_toBottomOf="@+id/v_1"
app:layout_constraintStart_toEndOf="@+id/tv_total_count"
android:background="@color/gray_1"
android:layout_marginStart="8dp" />

<TextView
android:id="@+id/tv_correct_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/smallSize"
android:textColor="@color/green_1"
tools:text="正确:共50题"
app:layout_constraintTop_toTopOf="@+id/v_1"
app:layout_constraintBottom_toBottomOf="@+id/v_1"
app:layout_constraintStart_toEndOf="@+id/v_2"
android:layout_marginStart="8dp" />

<View
android:id="@+id/v_3"
android:layout_width="@dimen/line_height"
android:layout_height="12dp"
app:layout_constraintTop_toTopOf="@+id/v_1"
app:layout_constraintBottom_toBottomOf="@+id/v_1"
app:layout_constraintStart_toEndOf="@+id/tv_correct_count"
android:background="@color/gray_1"
android:layout_marginStart="8dp" />

<TextView
android:id="@+id/tv_error_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/smallSize"
android:textColor="@color/red_1"
tools:text="错误:共50题"
app:layout_constraintTop_toTopOf="@+id/v_1"
app:layout_constraintBottom_toBottomOf="@+id/v_1"
app:layout_constraintStart_toEndOf="@+id/v_3"
android:layout_marginStart="8dp" />

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv"
android:layout_width="0dp"
android:layout_height="match_parent"
app:layout_constraintTop_toBottomOf="@+id/v_1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintVertical_weight="1"
android:layout_marginTop="1dp"/>

</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>

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

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

@@ -308,7 +308,12 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="tv_title,tv_tip_1"/>-->

<!--备忘本测试结束-->
<!--<androidx.constraintlayout.widget.Group
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="tv_score,tv_tip,tv_title,tv_tip_1,inc_statistics_number,tv_left,tv_top"/>
-->

</androidx.constraintlayout.widget.ConstraintLayout>


+ 22
- 0
app/src/main/res/layout/item_checkbox.xml View File

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

<data>

</data>

<CheckBox
android:id="@+id/cb_item"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16dp"
android:text="全选"
android:button="@null"
android:drawablePadding="8dp"
android:paddingTop="4dp"
android:paddingBottom="4dp"
android:layout_marginRight="8dp"
android:drawableStart="@drawable/choose_multiple">
</CheckBox>

</layout>

+ 169
- 0
app/src/main/res/layout/item_memo_detail_list_english.xml View File

@@ -0,0 +1,169 @@
<?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:id="@+id/itemGroup"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingStart="@dimen/global_spacing"
android:paddingEnd="@dimen/global_spacing"
android:layout_marginTop="1dp">


<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/title_box"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="5dp"
android:paddingBottom="10dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="@+id/iv_course_flag"
android:layout_width="22dp"
android:layout_height="22dp"
android:layout_marginTop="7dp"
android:gravity="center"
android:padding="0dp"
android:src="@drawable/ic_course_discern"
android:text="字"
android:textColor="@color/white"
android:textSize="@dimen/normalSize"
app:layout_constraintEnd_toStartOf="@+id/tv_word"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/tv_word" />

<TextView
android:id="@+id/tv_word"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="6dp"
android:ellipsize="end"
android:maxLines="1"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:textColor="#ff323233"
android:textSize="@dimen/bigSize"
android:textStyle="bold"
app:layout_constraintEnd_toStartOf="@id/right_icon"
app:layout_constraintStart_toEndOf="@+id/iv_course_flag"
app:layout_constraintTop_toTopOf="parent"
tools:text="显示word ,拼写时为释义拼写时为释义拼写时为释义拼写时为释义"
app:layout_constraintHorizontal_bias="0" />

<ImageView
android:id="@+id/right_icon"
android:layout_width="30dp"
android:layout_height="20dp"
android:scaleType="centerInside"
android:src="@drawable/ic_down"
app:layout_constraintBottom_toBottomOf="@+id/iv_course_flag"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/iv_course_flag" />

<TextView
android:id="@+id/tv_word_1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="6dp"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:textColor="#ff323233"
android:textSize="@dimen/bigSize"
android:textStyle="bold"
app:layout_constraintEnd_toStartOf="@id/right_icon"
app:layout_constraintStart_toEndOf="@+id/iv_course_flag"
app:layout_constraintTop_toBottomOf="@+id/tv_word"
tools:text="平时隐藏,拼写时为word,拼音时为释义" />

<com.suliang.common.widget.TagLinearLayout
android:id="@+id/layout_phonetic"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:item_horizontal_space="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@+id/tv_word"
app:layout_constraintTop_toBottomOf="@+id/tv_word_1">

<TextView
android:id="@+id/tv_phonetic_uk"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableEnd="@drawable/ic_horuns"
android:gravity="center"
android:textColor="@color/gray_2"
android:textSize="@dimen/smallerSize"
app:layout_constraintTop_toBottomOf="@+id/inc_word"
tools:text="英 [gud:bai] " />

<TextView
android:id="@+id/tv_phonetic_us"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableEnd="@drawable/ic_horuns"
android:gravity="center"
android:textColor="@color/gray_2"
android:textSize="@dimen/smallerSize"
app:layout_constraintTop_toBottomOf="@+id/inc_word"
tools:text="美 [gud:bai] " />

</com.suliang.common.widget.TagLinearLayout>

<TextView
android:id="@+id/tv_explain"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:textColor="@color/main_text_color"
android:textSize="@dimen/smallSize"
app:layout_constraintTop_toBottomOf="@+id/layout_phonetic"
app:layout_constraintStart_toStartOf="@+id/tv_word"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constrainedWidth="true"
app:layout_constraintHorizontal_bias="0"
tools:text="基本释义,作文时为解释内容作文时为解释内容作文时为解释内容作文时为解释内容作文时为解释内容作文时为解释内容"
/>

<TextView
android:id="@+id/tv_extend_explain"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:textColor="@color/gray_2"
android:textSize="@dimen/smallerSize"
app:layout_constraintStart_toStartOf="@+id/tv_word"
app:layout_constraintTop_toBottomOf="@+id/tv_explain"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constrainedWidth="true"
app:layout_constraintHorizontal_bias="0"
tools:text="扩展释义" />



</androidx.constraintlayout.widget.ConstraintLayout>

<include
android:id="@+id/inc_word_detail"
layout="@layout/inc_word_detail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="8dp"
android:visibility="visible"
app:layout_constraintTop_toBottomOf="@+id/title_box" />

<View
android:layout_width="match_parent"
android:layout_height="@dimen/line_height"
android:background="#E6E6E6"
app:layout_constraintTop_toBottomOf="@+id/inc_word_detail" />

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

+ 138
- 0
app/src/main/res/layout/item_memo_detail_list_literacy.xml View File

@@ -0,0 +1,138 @@
<?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:id="@+id/itemGroup"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginTop="1dp">


<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/title_box"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="6dp"
android:paddingBottom="6dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<!--识字备忘本item标题内容-->

<TextView
android:id="@+id/tv_course_flag"
android:layout_width="22dp"
android:layout_height="22dp"
android:background="@drawable/shape_cicler_24_ffcc99"
android:gravity="center"
android:padding="0dp"
android:text="字"
android:textColor="@color/white"
android:textSize="@dimen/normalSize"
app:layout_constraintBottom_toBottomOf="@+id/tv_literacy"
app:layout_constraintEnd_toStartOf="@+id/tv_polyphone_flag"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/tv_literacy" />

<TextView
android:id="@+id/tv_polyphone_flag"
android:layout_width="22dp"
android:layout_height="22dp"
android:layout_marginStart="4dp"
android:background="@drawable/shape_cicler_24_c3d69b"
android:gravity="center"
android:text="多"
android:textColor="@color/white"
android:textSize="@dimen/normalSize"
app:layout_constraintBottom_toBottomOf="@+id/tv_literacy"
app:layout_constraintEnd_toStartOf="@+id/tv_literacy"
app:layout_constraintStart_toEndOf="@+id/tv_course_flag"
app:layout_constraintTop_toTopOf="@+id/tv_literacy"
app:layout_goneMarginStart="0dp" />

<TextView
android:id="@+id/tv_literacy"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="6dp"
android:drawablePadding="8dp"
android:ellipsize="end"
android:maxLines="1"
android:layout_marginTop="6dp"
android:textColor="#ff323233"
android:textSize="@dimen/bigSize"
android:textStyle="bold"
app:layout_constraintStart_toEndOf="@+id/tv_polyphone_flag"
app:layout_constraintEnd_toStartOf="@id/tv_explain_pnonetic"
app:layout_constraintTop_toTopOf="parent"
tools:text="诗kljf"
android:drawableEnd="@drawable/ic_horuns"/>

<TextView
android:id="@+id/tv_explain_pnonetic"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:drawablePadding="6dp"
tools:text="你看didgfasgasgsadgsagasgdidgfasgasgsadgsagasg"
android:textSize="@dimen/smallSize"
android:maxLines="1"
android:ellipsize="end"
android:paddingTop="2dp"
android:textColor="@color/main_text_color"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toEndOf="@+id/tv_literacy"
app:layout_constraintEnd_toStartOf="@+id/right_icon"
app:layout_constraintTop_toTopOf="@id/tv_literacy"/>

<ImageView
android:id="@+id/right_icon"
android:layout_width="30dp"
android:layout_height="20dp"
android:scaleType="centerInside"
android:src="@drawable/ic_down"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/tv_explain_pnonetic"
app:layout_constraintBottom_toBottomOf="@+id/tv_course_flag"
app:layout_constraintStart_toEndOf="@+id/tv_explain_pnonetic"/>

<TextView
android:id="@+id/tv_word"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:textColor="@color/main_text_color"
android:textSize="@dimen/smallSize"
app:layout_constraintStart_toStartOf="@+id/tv_literacy"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_explain_pnonetic"
app:layout_constrainedWidth="true"
app:layout_constraintHorizontal_bias="0"
tools:text="诗歌诗歌诗歌诗歌" />

</androidx.constraintlayout.widget.ConstraintLayout>

<include
android:id="@+id/inc_word_detail"
layout="@layout/inc_word_detail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="8dp"
android:visibility="visible"
app:layout_constraintTop_toBottomOf="@+id/title_box" />

<View
android:layout_width="match_parent"
android:layout_height="@dimen/line_height"
android:background="#E6E6E6"
app:layout_constraintTop_toBottomOf="@+id/inc_word_detail" />

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

+ 134
- 0
app/src/main/res/layout/item_memo_detail_list_pinyin.xml View File

@@ -0,0 +1,134 @@
<?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:id="@+id/itemGroup"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingStart="@dimen/global_spacing"
android:paddingEnd="@dimen/global_spacing"
android:layout_marginTop="1dp">


<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/title_box"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="5dp"
android:paddingBottom="10dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<!--拼音-->
<ImageView
android:id="@+id/iv_course_flag"
android:layout_width="22dp"
android:layout_height="22dp"
android:layout_marginTop="7dp"
android:gravity="center"
android:padding="0dp"
android:src="@drawable/ic_course_pinying"
android:text="字"
android:textColor="@color/white"
android:textSize="@dimen/normalSize"
app:layout_constraintEnd_toStartOf="@+id/tv_word"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/tv_word" />

<TextView
android:id="@+id/tv_word"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="6dp"
android:ellipsize="end"
android:maxLines="1"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:textColor="#ff323233"
android:textSize="@dimen/bigSize"
android:textStyle="bold"
app:layout_constraintEnd_toStartOf="@id/tv_sound_for_pinyin"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toEndOf="@+id/iv_course_flag"
app:layout_constraintTop_toTopOf="parent"
tools:text="显示word" />

<TextView
android:id="@+id/tv_sound_for_pinyin"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:drawableStart="@drawable/ic_horuns"
android:drawablePadding="4dp"
android:paddingStart="@dimen/global_spacing"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="@+id/iv_course_flag"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintTop_toTopOf="@+id/iv_course_flag"
app:layout_constraintStart_toEndOf="@+id/tv_word"
app:layout_constraintEnd_toStartOf="@+id/right_icon"
tools:text="拼音时的韵母内容" />

<ImageView
android:id="@+id/right_icon"
android:layout_width="30dp"
android:layout_height="20dp"
android:scaleType="centerInside"
android:src="@drawable/ic_down"
app:layout_constraintBottom_toBottomOf="@+id/iv_course_flag"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/iv_course_flag" />

<TextView
android:id="@+id/tv_explain"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:textColor="@color/main_text_color"
android:textSize="@dimen/smallSize"
app:layout_constraintStart_toStartOf="@+id/tv_word"
app:layout_constraintTop_toBottomOf="@+id/tv_word"
app:layout_constraintEnd_toEndOf="parent"
tools:text="基本释义,作文时为解释内容" />

<TextView
android:id="@+id/tv_extend_explain"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:textColor="@color/gray_2"
android:textSize="@dimen/smallerSize"
app:layout_constraintStart_toStartOf="@+id/tv_word"
app:layout_constraintTop_toBottomOf="@+id/tv_explain"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constrainedWidth="true"
app:layout_constraintHorizontal_bias="0"
tools:text="扩展释义" />



</androidx.constraintlayout.widget.ConstraintLayout>

<include
android:id="@+id/inc_word_detail"
layout="@layout/inc_word_detail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="8dp"
android:visibility="visible"
app:layout_constraintTop_toBottomOf="@+id/title_box" />

<View
android:layout_width="match_parent"
android:layout_height="@dimen/line_height"
android:background="#E6E6E6"
app:layout_constraintTop_toBottomOf="@+id/inc_word_detail" />

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

+ 69
- 0
app/src/main/res/layout/item_test_detail.xml View File

@@ -0,0 +1,69 @@
<?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"
android:paddingStart="@dimen/global_spacing"
android:paddingEnd="@dimen/global_spacing"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp">

<TextView
android:id="@+id/tv_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textColor="@color/main_text_color"
android:textSize="@dimen/normalSize"
android:textStyle="bold"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toEndOf="@+id/tv_mark_number"
app:layout_constraintEnd_toStartOf="@+id/tv_answer"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
tools:text="问题" />

<TextView
android:id="@+id/tv_mark_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/gray_2"
android:textSize="@dimen/normalSize"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBaseline_toBaselineOf="@+id/tv_title"
app:layout_constraintStart_toStartOf="parent"
tools:text="1" />

<TextView
android:id="@+id/tv_answer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/main_text_color"
android:textSize="@dimen/normalSize"
android:textStyle="bold"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBaseline_toBaselineOf="@+id/tv_title"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/tv_title"
tools:text="(A)" />

<LinearLayout
android:id="@+id/layout_option"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="@+id/tv_title"
app:layout_constraintEnd_toEndOf="@+id/tv_title"
app:layout_constraintTop_toBottomOf="@+id/tv_title"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:orientation="vertical" />


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

+ 12
- 0
app/src/main/res/layout/item_test_detail_option_1.xml View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="4dp"
android:paddingBottom="4dp"
android:textSize="@dimen/smallSize"
android:textColor="@color/gray_2"
xmlns:tools="http://schemas.android.com/tools"
tools:text="D:jkksjlkjdj">

</TextView>

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

@@ -24,6 +24,7 @@
<color name="gray_4">#666D80</color>
<color name="white">#FFFFFFFF</color>
<color name="white_1">#FFF5F5F5</color>
<color name="white_2">#FFFAFAFA</color>
<color name="blue_1">#52CC52</color>
<color name="green_1">#40A540</color>
<color name="red_1">#FFF26255</color>

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

@@ -89,5 +89,8 @@
<string name="start_see_memo">查看备忘本</string>
<string name="smart_reviewing">智能复习中</string>
<string name="search_hint_input_key_word">请输入搜索关键字…</string>
<string name="test_type_1">测试类型:</string>
<string name="test_use_time_1">用时:</string>
<string name="test_time_1">测试时间:</string>

</resources>

+ 12
- 0
app/svg/drawable/ic_checked_1.xml View File

@@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="14dp"
android:height="14dp"
android:viewportWidth="14"
android:viewportHeight="14">
<path
android:pathData="M7,0C10.866,0 14,3.134 14,7C14,10.866 10.866,14 7,14C3.134,14 0,10.866 0,7C0,3.134 3.134,0 7,0ZM7,0.8235C3.5888,0.8235 0.8235,3.5888 0.8235,7C0.8235,10.4112 3.5888,13.1765 7,13.1765C10.4112,13.1765 13.1765,10.4112 13.1765,7C13.1765,3.5888 10.4112,0.8235 7,0.8235ZM7,2.8824C9.2741,2.8824 11.1176,4.7259 11.1176,7C11.1176,9.2741 9.2741,11.1176 7,11.1176C4.7259,11.1176 2.8824,9.2741 2.8824,7C2.8824,4.7259 4.7259,2.8824 7,2.8824Z"
android:strokeWidth="1"
android:fillColor="#5082E6"
android:fillType="evenOdd"
android:strokeColor="#00000000"/>
</vector>

+ 12
- 0
app/svg/drawable/ic_checked_2.xml View File

@@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="14dp"
android:height="14dp"
android:viewportWidth="14"
android:viewportHeight="14">
<path
android:pathData="M7,0C3.1325,0 0,3.1325 0,7C0,10.8675 3.1325,14 7,14C10.8675,14 14,10.8675 14,7C14,3.1325 10.8675,0 7,0ZM11.4712,4.6462L6.2387,9.8787L5.9412,10.1763C5.6262,10.4913 5.1275,10.4913 4.8125,10.1763L4.515,9.8787L2.5025,7.8663C2.24,7.6038 2.2662,7.1663 2.5725,6.9475C2.8175,6.7725 3.1588,6.8075 3.3688,7.0262L5.3812,9.0125L10.6225,3.7713C10.885,3.5087 11.3225,3.535 11.5413,3.8412C11.725,4.095 11.69,4.4363 11.4712,4.6462Z"
android:strokeWidth="1"
android:fillColor="#5082E6"
android:fillType="evenOdd"
android:strokeColor="#00000000"/>
</vector>

+ 12
- 0
app/svg/drawable/ic_checked_normal.xml View File

@@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="14dp"
android:height="14dp"
android:viewportWidth="14"
android:viewportHeight="14">
<path
android:pathData="M7,0C3.134,0 0,3.134 0,7C0,10.866 3.134,14 7,14C10.866,14 14,10.866 14,7C14,3.134 10.866,0 7,0ZM7,0.8235C10.4112,0.8235 13.1765,3.5888 13.1765,7C13.1765,10.4112 10.4112,13.1765 7,13.1765C3.5888,13.1765 0.8235,10.4112 0.8235,7C0.8235,3.5888 3.5888,0.8235 7,0.8235Z"
android:strokeWidth="1"
android:fillColor="#8A8A99"
android:fillType="evenOdd"
android:strokeColor="#00000000"/>
</vector>

+ 12
- 0
app/svg/drawable/ic_down.xml View File

@@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="14dp"
android:height="14dp"
android:viewportWidth="14"
android:viewportHeight="14">
<path
android:pathData="M1.988,4.9806C1.8147,4.7899 1.8287,4.4947 2.0194,4.3214C2.1955,4.1613 2.4605,4.161 2.6366,4.3119L2.6786,4.3528L7,9.107L11.3214,4.3528C11.4814,4.1767 11.7452,4.1512 11.9348,4.2847L11.9806,4.3214C12.1566,4.4814 12.1821,4.7452 12.0487,4.9348L12.012,4.9806L7.3453,10.1139C7.1734,10.303 6.8849,10.3165 6.6963,10.1544L6.6547,10.1139L1.988,4.9806Z"
android:strokeWidth="1"
android:fillColor="#323233"
android:fillType="evenOdd"
android:strokeColor="#00000000"/>
</vector>

+ 20
- 0
app/svg/drawable/ic_horuns.xml View File

@@ -0,0 +1,20 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="20dp"
android:height="20dp"
android:viewportWidth="20"
android:viewportHeight="20">
<path
android:pathData="M0,0h20v20h-20z"
android:strokeAlpha="0"
android:strokeWidth="1"
android:fillColor="#000000"
android:fillType="nonZero"
android:strokeColor="#00000000"
android:fillAlpha="0"/>
<path
android:pathData="M13.252,6.7078C12.9127,6.3684 12.3625,6.3684 12.0232,6.7078C11.6839,7.0471 11.6839,7.5972 12.0232,7.9365C13.0412,8.9545 13.0412,10.6049 12.0232,11.6229C11.6839,11.9622 11.6839,12.5123 12.0232,12.8516C12.3625,13.191 12.9127,13.191 13.252,12.8516C14.9486,11.1551 14.9486,8.4043 13.252,6.7076L13.252,6.7078ZM9.183,3.5237L9.183,3.5237L5.4756,6.3043L3.1573,6.3043C2.5129,6.3043 2,6.8183 2,7.4522L2,12.1077C2,12.7331 2.5182,13.2555 3.1573,13.2555L5.4756,13.2555L9.183,16.0362C9.6985,16.4227 10.1097,16.2112 10.1097,15.5698L10.1097,3.9902C10.1097,3.3568 9.6948,3.14 9.183,3.5237L9.183,3.5237ZM15.7096,4.2503C15.3702,3.9109 14.8201,3.9109 14.4808,4.2503C14.1415,4.5896 14.1414,5.1397 14.4808,5.479C16.8561,7.8543 16.8561,11.7054 14.4808,14.0807C14.1414,14.42 14.1414,14.9702 14.4808,15.3095C14.8201,15.6488 15.3702,15.6488 15.7096,15.3095L15.7096,15.3095C18.7635,12.2555 18.7635,7.3042 15.7096,4.2502L15.7096,4.2503Z"
android:strokeWidth="1"
android:fillColor="#9A9EB3"
android:fillType="evenOdd"
android:strokeColor="#00000000"/>
</vector>

+ 12
- 0
app/svg/drawable/ic_memo_review.xml View File

@@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="19dp"
android:height="18dp"
android:viewportWidth="19"
android:viewportHeight="18">
<path
android:pathData="M14.2283,1.8C14.7253,1.8 15.1283,2.2029 15.1283,2.7L15.1283,15.3C15.1283,15.7971 14.7253,16.2 14.2283,16.2L3.4283,16.2C2.9312,16.2 2.5283,15.7971 2.5283,15.3L2.5283,2.7C2.5283,2.2029 2.9312,1.8 3.4283,1.8L14.2283,1.8ZM7.2533,11.25L5.0033,11.25C4.6305,11.25 4.3283,11.5522 4.3283,11.925C4.3283,12.2978 4.6305,12.6 5.0033,12.6L5.0033,12.6L7.2533,12.6C7.6261,12.6 7.9283,12.2978 7.9283,11.925C7.9283,11.5522 7.6261,11.25 7.2533,11.25L7.2533,11.25ZM9.9533,8.1L5.0033,8.1C4.6305,8.1 4.3283,8.4022 4.3283,8.775C4.3283,9.1478 4.6305,9.45 5.0033,9.45L5.0033,9.45L9.9533,9.45C10.3261,9.45 10.6283,9.1478 10.6283,8.775C10.6283,8.4022 10.3261,8.1 9.9533,8.1L9.9533,8.1ZM12.6533,4.95L5.0033,4.95C4.6305,4.95 4.3283,5.2522 4.3283,5.625C4.3283,5.9978 4.6305,6.3 5.0033,6.3L5.0033,6.3L12.6533,6.3C13.0261,6.3 13.3283,5.9978 13.3283,5.625C13.3283,5.2522 13.0261,4.95 12.6533,4.95L12.6533,4.95Z"
android:strokeWidth="1"
android:fillColor="#FFFFFF"
android:fillType="evenOdd"
android:strokeColor="#00000000"/>
</vector>

+ 12
- 0
app/svg/drawable/ic_memo_test.xml View File

@@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="19dp"
android:height="18dp"
android:viewportWidth="19"
android:viewportHeight="18">
<path
android:pathData="M16.0293,13.9729C16.3607,13.9729 16.6293,14.2415 16.6293,14.5729C16.6293,14.8806 16.3977,15.1342 16.0993,15.1688L16.0293,15.1729L4.0293,15.1729C3.6979,15.1729 3.4293,14.9042 3.4293,14.5729C3.4293,14.2652 3.6609,14.0116 3.9593,13.9769L4.0293,13.9729L16.0293,13.9729ZM10.8417,2.1638C11.5447,1.4609 12.6844,1.4609 13.3873,2.1638L13.3873,2.1638L14.6601,3.4366C15.363,4.1395 15.363,5.2792 14.6601,5.9822L14.6601,5.9822L8.5745,12.0678C8.3032,12.339 7.9524,12.5165 7.5732,12.5744L7.5732,12.5744L5.2645,12.9267C4.6093,13.0267 3.9972,12.5766 3.8972,11.9214C3.8789,11.8014 3.8789,11.6794 3.8972,11.5594L3.8972,11.5594L4.2495,9.2507C4.3074,8.8715 4.4849,8.5207 4.7561,8.2494L4.7561,8.2494Z"
android:strokeWidth="1"
android:fillColor="#FFFFFF"
android:fillType="evenOdd"
android:strokeColor="#00000000"/>
</vector>

+ 12
- 0
app/svg/drawable/ic_up.xml View File

@@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="14dp"
android:height="14dp"
android:viewportWidth="16"
android:viewportHeight="16">
<path
android:pathData="M2.0054,10.5746C1.8072,10.7925 1.8233,11.1298 2.0412,11.328C2.2424,11.5109 2.5453,11.5112 2.7466,11.3388L2.7946,11.2921L7.7333,5.8587L12.672,11.2921C12.8549,11.4933 13.1564,11.5224 13.3731,11.3699L13.4254,11.328C13.6266,11.1451 13.6558,10.8436 13.5032,10.6269L13.4613,10.5746L8.128,4.7079C7.9315,4.4918 7.6018,4.4763 7.3863,4.6616L7.3387,4.7079L2.0054,10.5746Z"
android:strokeWidth="1"
android:fillColor="#323233"
android:fillType="evenOdd"
android:strokeColor="#00000000"/>
</vector>

+ 6
- 2
build.gradle View File

@@ -105,8 +105,12 @@ ext {
// BigImageViewPager : "com.github.SherlockGougou:BigImageViewPager:androidx-7.0.0",
//XPopup https://github.com/li-xiaojun/XPopup
XPopup : "com.github.li-xiaojun:XPopup:2.8.0",
//精美日历 calendarview
CalendarView : "com.haibin:calendarview:3.7.1"
//XPopupExt XPopup扩展
XPopupExt:"com.github.li-xiaojun:XPopupExt:0.0.8",
//精美日历 calendarview https://github.com/huanghaibin-dev/CalendarView
CalendarView : "com.haibin:calendarview:3.7.1",
//google 流式布局 https://blog.csdn.net/ww897532167/article/details/85952498 https://github.com/google/flexbox-layout
FlexBoxLayoutManager : "com.google.android.flexbox:flexbox:3.0.0"
]



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

@@ -32,7 +32,7 @@ abstract class BaseRVAdapter<T> :
* 当前位置是否需要显示空布局,主要是为0的时候,这个判断才会有效
* @param position Int
*/
private fun enableEmptyPosition(position:Int): Boolean{
protected fun enableEmptyPosition(position:Int): Boolean{
return position == 0 && mData.isEmpty() && needShowEmptyView
}


+ 1
- 0
lib/common/src/main/java/com/suliang/common/util/DateUtil.kt View File

@@ -16,6 +16,7 @@ class DateUtil {
val FORMAT_1 = "yyyy-MM-dd HH:mm:ss"
val FORMAT_2 = "HH:mm:ss"
val FORMAT_3 = "HH时mm分ss"
val FORMAT_4 = "yyyy-MM-dd"
/**
* 设置时区从0开始的,正时,可格式化时分秒

Loading…
Cancel
Save