| @@ -20,6 +20,5 @@ | |||
| <option name="resolveModulePerSourceSet" value="false" /> | |||
| </GradleProjectSettings> | |||
| </option> | |||
| <option name="offlineMode" value="true" /> | |||
| </component> | |||
| </project> | |||
| @@ -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" /> | |||
| @@ -76,6 +76,9 @@ Material Design Components 组件使用 https://www.jianshu.com/p/bc71b4179cb2 | |||
| 实现口语收藏、作文笔记收藏 | |||
| CourseMainFragmentViewModel.loadmain() | |||
| 测试的时候注意一下,如果课程包的数据库进行误删不存在的情况下,如何进行规避! | |||
| 日历控件使用研究 | |||
| 计算当前词汇量,课程完成/重学的时候调用一下;重学直接程序帮忙调用 | |||
| public native long calcCurrentVocabulary(long projectID) throws Exception; | |||
| @@ -113,7 +113,12 @@ dependencies { | |||
| implementation customDependencies.grpc_stub | |||
| //XPopup | |||
| implementation customDependencies.XPopup | |||
| implementation customDependencies.XPopupExt | |||
| //精美日历 calendarview | |||
| implementation customDependencies.CalendarView | |||
| // FlexBoxLayoutManager | |||
| implementation customDependencies.FlexBoxLayoutManager | |||
| } | |||
| @@ -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" /> | |||
| @@ -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 | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -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> <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) | |||
| } | |||
| } | |||
| @@ -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() | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -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 | |||
| } | |||
| @@ -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 | |||
| @@ -43,7 +43,7 @@ class LearnDialogBean(val dialogType:Int) :Parcelable { | |||
| /**章节课时名称: 第一章 第二课时 */ | |||
| var chapter_lesson_name = "" | |||
| /** 题数与时间 */ | |||
| /** 题数与时间 : 备忘本测试时用于显示课程的题目 */ | |||
| var showTimeCount = "" | |||
| constructor(parcel : Parcel) : this(parcel.readInt()) { | |||
| @@ -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 | |||
| } | |||
| @@ -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>) | |||
| @@ -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 | |||
| } | |||
| } | |||
| @@ -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() | |||
| } | |||
| } | |||
| } | |||
| @@ -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) } | |||
| } | |||
| } | |||
| @@ -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) | |||
| @@ -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 | |||
| } | |||
| @@ -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 | |||
| @@ -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)) | |||
| } | |||
| @@ -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() | |||
| //日历 | |||
| @@ -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() | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -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() | |||
| @@ -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() | |||
| } | |||
| } | |||
| @@ -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()) | |||
| } | |||
| } | |||
| } | |||
| @@ -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() | |||
| } | |||
| } | |||
| } | |||
| @@ -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 | |||
| } | |||
| } | |||
| @@ -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>" | |||
| } | |||
| } | |||
| } | |||
| @@ -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 | |||
| } | |||
| } | |||
| } | |||
| @@ -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 | |||
| } | |||
| } | |||
| @@ -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; | |||
| } | |||
| } | |||
| @@ -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; | |||
| } | |||
| } | |||
| @@ -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> | |||
| @@ -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> | |||
| @@ -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> | |||
| @@ -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> | |||
| @@ -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> | |||
| @@ -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> | |||
| @@ -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> | |||
| @@ -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> | |||
| @@ -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> | |||
| @@ -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> | |||
| @@ -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" | |||
| @@ -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> | |||
| @@ -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> | |||
| @@ -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> | |||
| @@ -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> | |||
| @@ -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> | |||
| @@ -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> | |||
| @@ -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> | |||
| @@ -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> | |||
| @@ -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> | |||
| @@ -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> | |||
| @@ -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> | |||
| @@ -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> | |||
| @@ -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> | |||
| @@ -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> | |||
| @@ -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> | |||
| @@ -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> | |||
| @@ -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> | |||
| @@ -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> | |||
| @@ -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> | |||
| @@ -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> | |||
| @@ -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" | |||
| ] | |||
| @@ -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 | |||
| } | |||
| @@ -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开始的,正时,可格式化时分秒 | |||