| @@ -29,6 +29,7 @@ | |||
| <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/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_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" /> | |||
| @@ -55,6 +56,7 @@ | |||
| <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_splash.xml" value="0.4921875" /> | |||
| <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/content_learn_base.xml" value="0.4979166666666667" /> | |||
| <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/dialog_bottom_auto_play_select.xml" value="0.4979166666666667" /> | |||
| @@ -86,13 +88,13 @@ | |||
| <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/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.67" /> | |||
| <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_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.478125" /> | |||
| <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_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_video_adapter.xml" value="0.67" /> | |||
| @@ -73,6 +73,9 @@ dependencies { | |||
| // implementation 'androidx.legacy:legacy-support-v4:1.0.0' | |||
| implementation project(path: ':lib:common') | |||
| implementation project(path: ':videoplayer') | |||
| implementation 'androidx.appcompat:appcompat:1.2.0' | |||
| implementation 'com.google.android.material:material:1.3.0' | |||
| implementation 'androidx.constraintlayout:constraintlayout:2.0.4' | |||
| // implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.1' | |||
| // implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1' | |||
| // implementation 'androidx.appcompat:appcompat:1.2.0' | |||
| @@ -110,5 +113,7 @@ dependencies { | |||
| implementation customDependencies.grpc_stub | |||
| //XPopup | |||
| implementation customDependencies.XPopup | |||
| //精美日历 calendarview | |||
| implementation customDependencies.CalendarView | |||
| } | |||
| @@ -12,6 +12,9 @@ | |||
| android:supportsRtl="true" | |||
| android:theme="@style/Theme.XklLocal" | |||
| tools:ignore="LockedOrientationActivity"> | |||
| <activity | |||
| android:name=".module.m_memo.MemoListDetailActivity" | |||
| android:exported="true" /> | |||
| <activity | |||
| android:name=".module.learn.LearnCTaskActivity" | |||
| android:exported="true" /> | |||
| @@ -20,11 +23,11 @@ | |||
| android:exported="true" /> | |||
| <activity | |||
| android:name=".module.learn.LearnCVideoActivity" | |||
| android:exported="true" | |||
| android:theme="@style/Theme.videoTheme" | |||
| android:configChanges="orientation|keyboardHidden|screenSize|locale" | |||
| android:exported="true" | |||
| android:screenOrientation="portrait" | |||
| android:windowSoftInputMode="adjustPan|stateHidden"/> | |||
| android:theme="@style/Theme.videoTheme" | |||
| android:windowSoftInputMode="adjustPan|stateHidden" /> | |||
| <activity | |||
| android:name=".module.learn.LearnExamActivity" | |||
| android:exported="true" /> | |||
| @@ -61,18 +61,19 @@ class AdapterCoursePackWithLearCenter(vm: CoursePackFragmentViewModel) : | |||
| when(it.courseType){ | |||
| AppConstants.COURSE_TYPE_ENGLISH_DISCERN -> imageViewTypeDiscern.visibility = View.VISIBLE | |||
| AppConstants.COURSE_TYPE_ENGLISH_SPELL -> imageViewTypeSpell.visibility = View.VISIBLE | |||
| AppConstants.COURSE_TYPE_ENGLISH_VOICE -> { | |||
| imageViewTypeVoice.run { | |||
| visibility = View.VISIBLE | |||
| setImageResource(R.drawable.ic_course_voice) | |||
| } | |||
| } | |||
| AppConstants.COURSE_TYPE_ENGLISH_VOICE -> imageViewTypeVoice.visibility = View.VISIBLE | |||
| AppConstants.COURSE_TYPE_ENGLISH_SPOKEN -> { | |||
| imageViewTypeVoice.run{ | |||
| visibility = View.VISIBLE | |||
| setImageResource(R.drawable.ic_course_spoken) | |||
| } | |||
| } | |||
| AppConstants.COURSE_TYPE_ENGLISH_SOUNDMARK -> { | |||
| imageViewTypeVoice.run { | |||
| visibility = View.VISIBLE | |||
| setImageResource(R.drawable.ic_course_soundmark) | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -83,6 +84,12 @@ class AdapterCoursePackWithLearCenter(vm: CoursePackFragmentViewModel) : | |||
| binding.apply { | |||
| //进度 | |||
| myRankingView.visibility = View.VISIBLE | |||
| //复习数量判断是否可见 | |||
| if (coursePack.reviewNumber > 0 ){ | |||
| tvReview.visibility = View.VISIBLE | |||
| }else{ | |||
| tvReview.visibility = View.GONE | |||
| } | |||
| } | |||
| } | |||
| @@ -6,6 +6,7 @@ import android.graphics.Color | |||
| import android.view.View | |||
| import android.view.ViewGroup | |||
| import android.view.ViewTreeObserver | |||
| import android.widget.TextView | |||
| import androidx.core.content.ContextCompat | |||
| import com.google.android.material.badge.BadgeDrawable | |||
| import com.google.android.material.badge.BadgeUtils | |||
| @@ -13,6 +14,8 @@ import com.google.android.material.imageview.ShapeableImageView | |||
| 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.util.os.ScreenUtil | |||
| import com.xkl.cdl.R | |||
| import com.xkl.cdl.data.AppConstants | |||
| import com.xkl.cdl.data.bean.MemoCoursePack | |||
| @@ -29,14 +32,16 @@ import com.xkl.cdl.module.m_memo.MemoFragmentViewModel | |||
| class AdapterCoursePackWithMemo(viewModel : MemoFragmentViewModel) : | |||
| BaseRVAdapterVM<MemoCoursePack, MemoFragmentViewModel>(viewModel) { | |||
| private val badgeDrawable : BadgeDrawable by lazy { | |||
| BadgeDrawable.create(context).apply { | |||
| badgeGravity = BadgeDrawable.TOP_END | |||
| maxCharacterCount = 3 | |||
| backgroundColor = ContextCompat.getColor(context, R.color.red_1) | |||
| badgeTextColor = ContextCompat.getColor(context, R.color.white) | |||
| } | |||
| } | |||
| // private val badgeDrawable : BadgeDrawable by lazy { | |||
| // BadgeDrawable.create(context).apply { | |||
| // badgeGravity = BadgeDrawable.TOP_END | |||
| // maxCharacterCount = 3 | |||
| // backgroundColor = ContextCompat.getColor(context, R.color.red_1) | |||
| // badgeTextColor = ContextCompat.getColor(context, R.color.white) | |||
| // horizontalOffset = -ScreenUtil.dp2px(6f).toInt() | |||
| // verticalOffset = ScreenUtil.dp2px(6f).toInt() | |||
| // } | |||
| // } | |||
| override fun onBindEmptyViewHolder(holder : BaseAdapterViewHolder) { | |||
| (holder.binding as ItemEmptyBinding).run { | |||
| @@ -67,19 +72,22 @@ class AdapterCoursePackWithMemo(viewModel : MemoFragmentViewModel) : | |||
| //图标与角标文字 | |||
| item.coursePack.childrenCourses.forEachIndexed { index : Int, course : Course -> | |||
| when (course.courseType) { | |||
| AppConstants.COURSE_TYPE_ENGLISH_DISCERN -> setImageIcon(imgCourseIcon1,course.courseType,item.coursePackChildrenReviewNumber[index].size) | |||
| AppConstants.COURSE_TYPE_ENGLISH_SPELL -> setImageIcon(imgCourseIcon2,course.courseType,item.coursePackChildrenReviewNumber[index].size) | |||
| AppConstants.COURSE_TYPE_ENGLISH_VOICE -> setImageIcon(imgCourseIcon3,course.courseType,item.coursePackChildrenReviewNumber[index].size) | |||
| AppConstants.COURSE_TYPE_ENGLISH_DISCERN -> setImageIcon(imgCourseIcon1,tvReviewNumber1,course.courseType,item.coursePackChildrenReview.getOrDefault(course.courseId,0)) | |||
| AppConstants.COURSE_TYPE_ENGLISH_SPELL -> setImageIcon(imgCourseIcon2,tvReviewNumber2,course.courseType,item.coursePackChildrenReview.getOrDefault(course.courseId,0)) | |||
| AppConstants.COURSE_TYPE_ENGLISH_VOICE -> setImageIcon(imgCourseIcon3,tvReviewNumber3,course.courseType,item.coursePackChildrenReview.getOrDefault(course.courseId,0)) | |||
| //其他只有一个课程类型 | |||
| else -> { | |||
| setImageIcon(imgCourseIcon1,course.courseType,item.coursePackChildrenReviewNumber[index].size) | |||
| setImageIcon(imgCourseIcon1,tvReviewNumber1,course.courseType,item.coursePackChildrenReview.getOrDefault(course.courseId,0)) | |||
| imgCourseIcon2.visibility = View.INVISIBLE | |||
| tvReviewNumber2.visibility = View.GONE | |||
| imgCourseIcon3.visibility = View.INVISIBLE | |||
| tvReviewNumber3.visibility = View.GONE | |||
| imgCourseIcon1.visibility = View.VISIBLE | |||
| } | |||
| } | |||
| } | |||
| root.click { onItemClick.invoke(holder.itemView,position,item) } | |||
| } | |||
| } | |||
| } | |||
| @@ -91,11 +99,9 @@ class AdapterCoursePackWithMemo(viewModel : MemoFragmentViewModel) : | |||
| * @param reviewNumber Int 复习数量 | |||
| */ | |||
| @SuppressLint("UnsafeOptInUsageError") | |||
| private fun setImageIcon(imageView : ShapeableImageView, courseType : Int, reviewNumber : Int) { | |||
| private fun setImageIcon(imageView : ShapeableImageView, tvReviewNumber: TextView, courseType : Int, reviewNumber : Int) { | |||
| imageView.visibility = View.VISIBLE | |||
| var color : Int = Color.parseColor("#00000000") | |||
| //取消角标 | |||
| BadgeUtils.detachBadgeDrawable(badgeDrawable,imageView) | |||
| when (reviewNumber) { | |||
| //没有数据 | |||
| 0 -> { | |||
| @@ -103,6 +109,7 @@ class AdapterCoursePackWithMemo(viewModel : MemoFragmentViewModel) : | |||
| //设置图标: 灰色,没有背景 | |||
| imageView.setImageResource(getCourseIcon(courseType)) | |||
| imageView.imageTintList = ColorStateList.valueOf(Color.parseColor("#9A9EB3")) | |||
| tvReviewNumber.visibility = View.GONE | |||
| } | |||
| //有复习数据 | |||
| else -> { | |||
| @@ -120,21 +127,8 @@ class AdapterCoursePackWithMemo(viewModel : MemoFragmentViewModel) : | |||
| //设置图标:原图颜色 | |||
| imageView.setImageResource(getCourseIcon(courseType)) | |||
| //添加角标 | |||
| imageView.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener { | |||
| @SuppressLint("UnsafeOptInUsageError") | |||
| override fun onGlobalLayout() { | |||
| BadgeDrawable.create(context).apply { | |||
| badgeGravity = BadgeDrawable.TOP_END | |||
| number = reviewNumber | |||
| maxCharacterCount = 3 | |||
| backgroundColor = ContextCompat.getColor(context, R.color.red_1) | |||
| badgeTextColor = ContextCompat.getColor(context, R.color.white) | |||
| BadgeUtils.attachBadgeDrawable(this, imageView) | |||
| } | |||
| imageView.viewTreeObserver.removeOnGlobalLayoutListener(this) | |||
| } | |||
| }) | |||
| tvReviewNumber.text = if (reviewNumber > 99 ) "99+" else "$reviewNumber" | |||
| tvReviewNumber.visibility = View.VISIBLE | |||
| } | |||
| } | |||
| } | |||
| @@ -8,9 +8,9 @@ import com.xkl.cdl.data.bean.course.CoursePack | |||
| * Describe: 课程包备忘本实体 | |||
| */ | |||
| class MemoCoursePack(val coursePack: CoursePack){ | |||
| //对应课程的备忘本数据 | |||
| var coursePackChildrenMemoNumber = mutableListOf<MutableList<String>>() | |||
| //对应需要复习的数据 | |||
| var coursePackChildrenReviewNumber = mutableListOf<MutableList<String>>() | |||
| //对应课程的备忘本数据 key: courseId value: MutableList<String> | |||
| var coursePackChildrenMemo = mutableMapOf<Long,MutableList<String>>() | |||
| //对应需要复习的数量 key : courseId value 数量 | |||
| var coursePackChildrenReview = mutableMapOf<Long,Int>() | |||
| } | |||
| @@ -29,7 +29,4 @@ data class Course( | |||
| ) { | |||
| var courseLearnProgress : Double = 0.0 //课程学习进度 | |||
| var courseReviewNumber : Int = 0 //课程复习数 | |||
| } | |||
| @@ -37,7 +37,13 @@ data class CoursePack( | |||
| field = value | |||
| notifyPropertyChanged(BR.learnProgress) | |||
| } | |||
| //复习数量,主要为课程包下的第一个课程的复习数量,主要用于在作文学习中心,对复习数的显示 | |||
| @get:Bindable | |||
| var reviewNumber : Int = 0 | |||
| set(value){ | |||
| field = value | |||
| notifyPropertyChanged(BR.reviewNumber) | |||
| } | |||
| override fun equals(other : Any?) : Boolean { | |||
| if (this === other) return true | |||
| if (javaClass != other?.javaClass) return false | |||
| @@ -0,0 +1,10 @@ | |||
| package com.xkl.cdl.data.bean.intentdata | |||
| import com.xkl.cdl.data.bean.course.Course | |||
| /** | |||
| * author suliang | |||
| * create 2022/6/9 16:35 | |||
| * Describe: 备忘本进入内容详情时,传递数据 MemoListDetailActivity | |||
| */ | |||
| data class MemoData(val course : Course, val memoList: MutableList<String>) | |||
| @@ -409,7 +409,7 @@ object CourseManager { | |||
| // TODO: 2022/6/2 时间需改为day 开发期间用于调式,故意设此值 | |||
| //间隔时间单位 | |||
| private val reviewIntervalUnit = "day" | |||
| private val reviewIntervalUnit = "hour" | |||
| //间隔单位时间 | |||
| private val reviewTime = IntArray(7){ | |||
| when(it){ | |||
| @@ -245,8 +245,20 @@ object DBCourseManager { | |||
| lessonId = lesson.lessonId | |||
| }) | |||
| } | |||
| AppConstants.COURSE_TYPE_ENGLISH_DISCERN, AppConstants.COURSE_TYPE_ENGLISH_VOICE, AppConstants.COURSE_TYPE_CHINESE_LITERACY, AppConstants.COURSE_TYPE_CHINESE_PINYIN -> while (moveToNext()) { | |||
| 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) | |||
| @@ -260,6 +272,20 @@ object DBCourseManager { | |||
| 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) | |||
| @@ -274,19 +300,6 @@ object DBCourseManager { | |||
| lessonId = getLong(12) | |||
| }) | |||
| } | |||
| 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_SPOKEN -> { | |||
| when (testType) { | |||
| AppConstants.TEST_TYPE_BEFORE_TOTAL, AppConstants.TEST_TYPE_AFTER_TOTAL -> { | |||
| @@ -4,6 +4,7 @@ import appApi.AppApi | |||
| import com.google.protobuf.ProtocolStringList | |||
| import com.googlecode.protobuf.format.JsonFormat | |||
| import com.suliang.common.extension.io2Io | |||
| import com.suliang.common.util.LogUtil | |||
| import com.suliang.common.util.file.FileUtil | |||
| import com.xkl.cdl.data.AppConstants | |||
| import com.xkl.cdl.data.bean.course.CourseDetail | |||
| @@ -52,10 +53,10 @@ object DataRepository { | |||
| } | |||
| val courseDetail = CourseDetail().apply { | |||
| courseLearnProgress = pbCourseDetail.s //课程学习进度 | |||
| st_before = pbCourseDetail.stBefore //学前总成绩 : -1代表没有进行学前总测试 | |||
| st_after = pbCourseDetail.stAfter //学后总成绩 : -1代表没有进行学后总测试 | |||
| before = HashMap(pbCourseDetail.beforeMap) //章节学前测试成绩,key=>{chapter_id}_{lesson_id} value=>成绩 | |||
| after = HashMap(pbCourseDetail.afterMap) //章节学后测试成绩,key=>{chapter_id}_{lesson_id} value=>成绩 | |||
| st_before = pbCourseDetail.strlBefore //学前总成绩 : -1代表没有进行学前总测试 | |||
| st_after = pbCourseDetail.strlAfter //学后总成绩 : -1代表没有进行学后总测试 | |||
| before = HashMap(pbCourseDetail.rlBeforeMap) //章节学前测试成绩,key=>{chapter_id}_{lesson_id} value=>成绩 | |||
| after = HashMap(pbCourseDetail.rlAfterMap) //章节学后测试成绩,key=>{chapter_id}_{lesson_id} value=>成绩 | |||
| right = HashMap(pbCourseDetail.rightMap) //正确条目数,key=>{chapter_id}_{lesson_id} value=>条目数量 | |||
| wrong = HashMap(pbCourseDetail.wrongMap) //错误条目数,key=>{chapter_id}_{lesson_id} value=>条目数量 | |||
| lesson_learn_point = HashMap( | |||
| @@ -133,13 +134,13 @@ object DataRepository { | |||
| } | |||
| } | |||
| } | |||
| if (subjectId != 0L ){ | |||
| //计算词汇量和学习效率 | |||
| calcCourseVocabularyAndEfficiency(subjectId,coursePackId,courseId) | |||
| } | |||
| LogUtil.e("保存数据 -> \n ${JsonFormat.printToString(record.build())}") | |||
| try { | |||
| XKLApplication.mobileCache.parseData(record.build().toByteArray()) | |||
| if (subjectId != 0L ){ | |||
| //计算词汇量和学习效率 | |||
| calcCourseVocabularyAndEfficiency(subjectId,coursePackId,courseId) | |||
| } | |||
| } catch (e : Exception) { | |||
| e.printStackTrace() | |||
| return false | |||
| @@ -902,7 +902,7 @@ class LearnWordActivity : BaseActivityVM<ActivityLearnWordBinding, LearnWordView | |||
| * 自动播放完成弹窗 | |||
| */ | |||
| private fun showAutoPlayOverDialog() { | |||
| val drawable = DrawableUti.changeSvgSizeAndColor(resources, R.drawable.ic_right, R.color.theme_color, 3) | |||
| val drawable = DrawableUti.changeSvgSizeAndColor(resources, R.drawable.ic_right, R.color.theme_color, 3f) | |||
| CommonDialog.newInstance(CommonDialogBean(titleText = R.string.quit_auto_play_title_over, rightText = R.string.sure), | |||
| drawable).apply { | |||
| onCommonDialogButtonClickListener = { dialog, _ -> | |||
| @@ -4,9 +4,8 @@ import android.content.Context | |||
| import android.content.Intent | |||
| import android.graphics.Color | |||
| import android.os.Bundle | |||
| import android.text.Html | |||
| import android.text.method.ScrollingMovementMethod | |||
| import android.view.View | |||
| import android.widget.TextView | |||
| import androidx.core.content.ContextCompat | |||
| import androidx.core.content.res.ResourcesCompat | |||
| import androidx.databinding.DataBindingUtil | |||
| @@ -14,12 +13,10 @@ import androidx.fragment.app.Fragment | |||
| import androidx.lifecycle.ViewModel | |||
| import androidx.lifecycle.ViewModelProvider | |||
| import androidx.viewpager2.widget.ViewPager2 | |||
| import com.google.android.material.bottomsheet.BottomSheetBehavior | |||
| import com.google.android.material.bottomsheet.BottomSheetDialog | |||
| import com.suliang.common.AppConfig | |||
| import com.suliang.common.base.activity.BaseActivityVM | |||
| import com.suliang.common.extension.click | |||
| import com.suliang.common.extension.setHtml | |||
| import com.suliang.common.util.os.ScreenUtil | |||
| import com.xkl.cdl.R | |||
| import com.xkl.cdl.adapter.AdapterAutoPlaySelectRepeat | |||
| @@ -27,6 +24,7 @@ import com.xkl.cdl.adapter.ViewPagerAdapter | |||
| 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.MemoCoursePack | |||
| import com.xkl.cdl.data.bean.course.Course | |||
| import com.xkl.cdl.data.bean.course.Lesson | |||
| import com.xkl.cdl.data.bean.intentdata.LearnData | |||
| @@ -46,6 +44,7 @@ import com.zackratos.ultimatebarx.ultimatebarx.statusBarOnly | |||
| class CoursePackMainActivity : BaseActivityVM<ActivityCourseMainBinding, CoursePackMainActivityViewModel>() { | |||
| companion object { | |||
| /** 学习中心跳转 */ | |||
| @JvmStatic | |||
| fun newInstance(context : Context, subjectId : Int, coursePackInPosition : Int) { | |||
| context.startActivity(Intent(context, CoursePackMainActivity::class.java).apply { | |||
| @@ -53,6 +52,17 @@ class CoursePackMainActivity : BaseActivityVM<ActivityCourseMainBinding, CourseP | |||
| putExtra(AppConfig.INTENT_2, coursePackInPosition) | |||
| }) | |||
| } | |||
| /** 备忘本跳转 */ | |||
| @JvmStatic | |||
| fun newInstance(context : Context, memoCoursePack : MemoCoursePack) { | |||
| DataTransferHolder.instance.putData(value = memoCoursePack) | |||
| context.startActivity(Intent(context, CoursePackMainActivity::class.java).apply { | |||
| putExtra(AppConfig.INTENT_1, memoCoursePack.coursePack.subjectId) | |||
| putExtra(AppConfig.INTENT_2, memoCoursePack.coursePack.inCoursePackPosition) | |||
| putExtra(AppConfig.INTENT_3, true) | |||
| }) | |||
| } | |||
| } | |||
| //子课程对应的Fragment | |||
| @@ -64,8 +74,10 @@ class CoursePackMainActivity : BaseActivityVM<ActivityCourseMainBinding, CourseP | |||
| override fun initViewModel() : CoursePackMainActivityViewModel { | |||
| val subjectId = intent.getIntExtra(AppConfig.INTENT_1, 0) | |||
| val coursePackInListPosition = intent.getIntExtra(AppConfig.INTENT_2, 0) | |||
| return ViewModelProvider(this, ViewModelFactory(subjectId, | |||
| coursePackInListPosition))[CoursePackMainActivityViewModel::class.java] | |||
| val isMemoSource = intent.getBooleanExtra(AppConfig.INTENT_3, false) | |||
| return ViewModelProvider(this, ViewModelFactory(subjectId, coursePackInListPosition, | |||
| isMemoSource))[CoursePackMainActivityViewModel::class.java] | |||
| } | |||
| override fun initStatusBar() { | |||
| @@ -91,14 +103,19 @@ class CoursePackMainActivity : BaseActivityVM<ActivityCourseMainBinding, CourseP | |||
| binding.tvIntroduction.click { | |||
| showIntroductionDialog() | |||
| } | |||
| //返回事件 | |||
| binding.includeTitleBar.titleBar.run { | |||
| //标题栏 | |||
| binding.titleBar.run { | |||
| textViewTitle.setText(if (vm.isMemoSource) R.string.course_detail else R.string.course_detail) | |||
| onBackClick = { _ -> finish() } | |||
| } | |||
| //更多按钮点击 | |||
| binding.includeCourseProgress.ivMore.click { | |||
| if ((childFragments[binding.viewPager2.currentItem] as CourseMainFragment).vm.showMoreIsEnable()) showMoreDialog() | |||
| else showToast("请先进行学习") | |||
| when { | |||
| vm.isMemoSource -> binding.includeCourseProgress.root.visibility = View.GONE | |||
| //更多按钮点击 | |||
| else -> binding.includeCourseProgress.ivMore.click { | |||
| if ((childFragments[binding.viewPager2.currentItem] as CourseMainFragment).vm.showMoreIsEnable()) showMoreDialog() | |||
| else showToast("请先进行学习") | |||
| } | |||
| } | |||
| //初始化tab和viewPager | |||
| @@ -172,6 +189,11 @@ class CoursePackMainActivity : BaseActivityVM<ActivityCourseMainBinding, CourseP | |||
| tabSpell.click { binding.viewPager2.currentItem = 1 } | |||
| tabVoice.click { binding.viewPager2.currentItem = 2 } | |||
| } | |||
| } | |||
| override fun loadData() { | |||
| //监听进度,设置进度 进度为百分制,已经乘了100了 | |||
| vm.currentCourseProgress.observe(this) { | |||
| binding.includeCourseProgress.apply { | |||
| @@ -190,42 +212,60 @@ class CoursePackMainActivity : BaseActivityVM<ActivityCourseMainBinding, CourseP | |||
| } | |||
| } | |||
| } | |||
| //监听复习数量,只有备忘本进入才进行监听,用于修改复习数据标记 | |||
| if (vm.isMemoSource) { | |||
| vm.reviewNumber1.observe(this) { | |||
| initMemoBadgeDrawable(binding.includeCourseTypeTab.tvReviewNumber1,it) | |||
| } | |||
| vm.reviewNumber2.observe(this) { | |||
| initMemoBadgeDrawable(binding.includeCourseTypeTab.tvReviewNumber2,it) | |||
| } | |||
| vm.reviewNumber3.observe(this) { | |||
| initMemoBadgeDrawable(binding.includeCourseTypeTab.tvReviewNumber3,it) | |||
| } | |||
| } | |||
| } | |||
| override fun loadData() { | |||
| /** 备忘本初始话小红点 */ | |||
| private fun initMemoBadgeDrawable(view : TextView, reviewNumber : Int) { | |||
| if (reviewNumber > 0) { | |||
| view.visibility = View.VISIBLE | |||
| view.text = if (reviewNumber > 99) "99+" else "$reviewNumber" | |||
| } else { | |||
| view.visibility = View.GONE | |||
| } | |||
| } | |||
| /** 简介弹窗 */ | |||
| private fun showIntroductionDialog() { | |||
| CoursePackIntroductionBottomSheetDialog.newInstance(vm.coursePack.coursePackName,vm.coursePack.summary).show(supportFragmentManager,"introducation") | |||
| CoursePackIntroductionBottomSheetDialog.newInstance(vm.coursePack.coursePackName, vm.coursePack.summary) | |||
| .show(supportFragmentManager, "introducation") | |||
| } | |||
| /** 点击显示更多的弹窗 */ | |||
| private fun showMoreDialog() { | |||
| BottomSheetDialog(this, R.style.dialog_style).apply { | |||
| val moreBinding = DataBindingUtil.inflate<DialogBottomCourseMoreBinding>(layoutInflater, | |||
| R.layout.dialog_bottom_course_more, null, | |||
| false) | |||
| setContentView(moreBinding.root) | |||
| //体验账号、拼些、口语课程、作文课程不显示自动播放 | |||
| when (vm.coursePack.childrenCourses[binding.viewPager2.currentItem].courseType) { | |||
| AppConstants.COURSE_TYPE_ENGLISH_SPELL, AppConstants.COURSE_TYPE_ENGLISH_SPOKEN, AppConstants.COURSE_TYPE_CHINESE_COMPOSITION -> moreBinding.tvAutoPlay.visibility = View.GONE | |||
| else -> moreBinding.tvAutoPlay.visibility = View.VISIBLE | |||
| } | |||
| moreBinding.ivCancel.click { | |||
| dismiss() | |||
| } | |||
| moreBinding.tvAutoPlay.click { | |||
| dismiss() | |||
| showAutoPlaySelectDialog() | |||
| } | |||
| moreBinding.tvClearLearnRecord.click { | |||
| dismiss() | |||
| showCourseRelearnDialog() | |||
| } | |||
| }.show() | |||
| val moreBinding = DataBindingUtil.inflate<DialogBottomCourseMoreBinding>(layoutInflater, | |||
| R.layout.dialog_bottom_course_more, null, | |||
| false) | |||
| setContentView(moreBinding.root) | |||
| //体验账号、拼些、口语课程、作文课程不显示自动播放 | |||
| when (vm.coursePack.childrenCourses[binding.viewPager2.currentItem].courseType) { | |||
| AppConstants.COURSE_TYPE_ENGLISH_SPELL, AppConstants.COURSE_TYPE_ENGLISH_SPOKEN, AppConstants.COURSE_TYPE_CHINESE_COMPOSITION -> moreBinding.tvAutoPlay.visibility = View.GONE | |||
| else -> moreBinding.tvAutoPlay.visibility = View.VISIBLE | |||
| } | |||
| moreBinding.ivCancel.click { | |||
| dismiss() | |||
| } | |||
| moreBinding.tvAutoPlay.click { | |||
| dismiss() | |||
| showAutoPlaySelectDialog() | |||
| } | |||
| moreBinding.tvClearLearnRecord.click { | |||
| dismiss() | |||
| showCourseRelearnDialog() | |||
| } | |||
| }.show() | |||
| } | |||
| /** 课程重学弹窗提示 */ | |||
| @@ -278,8 +318,8 @@ class CoursePackMainActivity : BaseActivityVM<ActivityCourseMainBinding, CourseP | |||
| (childFragments[binding.viewPager2.currentItem] as CourseMainFragment).vm.let { | |||
| it.queryWordAutoPlayWord().observe(this) { value -> | |||
| value?.let { data -> | |||
| val lesson = Lesson(it.course.subjectId, it.course.coursePackId, it.course.coursePackType, | |||
| it.course.courseId, it.course.courseType, 0, "", 0, it.course.courseTitle) | |||
| val lesson = Lesson(it.course.subjectId, it.course.coursePackId, it.course.coursePackType, it.course.courseId, | |||
| it.course.courseType, 0, "", 0, it.course.courseTitle) | |||
| DataTransferHolder.instance.putData(value = LearnData(lesson).apply { | |||
| learnWordList = data | |||
| @@ -299,10 +339,10 @@ class CoursePackMainActivity : BaseActivityVM<ActivityCourseMainBinding, CourseP | |||
| * @param course Course | |||
| * @param reviewData MutableList<LearnWord> | |||
| */ | |||
| fun startReview(course: Course, reviewData: MutableList<LearnWord>){ | |||
| val lesson = Lesson(course.subjectId, course.coursePackId, course.coursePackType, | |||
| course.courseId, course.courseType, 0, "", 0, course.courseTitle) | |||
| fun startReview(course : Course, reviewData : MutableList<LearnWord>) { | |||
| val lesson = Lesson(course.subjectId, course.coursePackId, course.coursePackType, course.courseId, course.courseType, 0, | |||
| "", 0, course.courseTitle) | |||
| DataTransferHolder.instance.putData(value = LearnData(lesson).apply { | |||
| learnWordList = reviewData | |||
| isReview = true | |||
| @@ -311,10 +351,11 @@ class CoursePackMainActivity : BaseActivityVM<ActivityCourseMainBinding, CourseP | |||
| } | |||
| /** ViewModel Factory工厂 */ | |||
| inner class ViewModelFactory(private val subjectId : Int, private val coursePackInPosition : Int) : | |||
| ViewModelProvider.Factory { | |||
| inner class ViewModelFactory(private val subjectId : Int, | |||
| private val coursePackInPosition : Int, | |||
| private val isMemoSource : Boolean) : ViewModelProvider.Factory { | |||
| override fun <T : ViewModel?> create(modelClass : Class<T>) : T { | |||
| return CoursePackMainActivityViewModel(subjectId, coursePackInPosition) as T | |||
| return CoursePackMainActivityViewModel(subjectId, coursePackInPosition, isMemoSource) as T | |||
| } | |||
| } | |||
| @@ -4,6 +4,8 @@ import androidx.lifecycle.LifecycleOwner | |||
| import androidx.lifecycle.MutableLiveData | |||
| import com.suliang.common.base.viewmodel.BaseViewModel | |||
| import com.xkl.cdl.data.AppConstants | |||
| import com.xkl.cdl.data.DataTransferHolder | |||
| import com.xkl.cdl.data.bean.MemoCoursePack | |||
| import com.xkl.cdl.data.manager.CourseManager | |||
| /** | |||
| @@ -11,10 +13,30 @@ import com.xkl.cdl.data.manager.CourseManager | |||
| * create 2022/3/24 17:42 | |||
| * Describe: 课程主页 | |||
| */ | |||
| class CoursePackMainActivityViewModel(subjectId: Int , coursePackInPosition : Int) : BaseViewModel() { | |||
| class CoursePackMainActivityViewModel(subjectId: Int , coursePackInPosition : Int,val isMemoSource:Boolean) : BaseViewModel() { | |||
| //操作的课程包 | |||
| val coursePack = CourseManager.subjectWithCoursePackMap[subjectId]!![coursePackInPosition] | |||
| //对应课程的备忘本数据 key: courseId value: MutableList<String> | |||
| var coursePackChildrenMemo = mutableMapOf<Long,MutableList<String>>() | |||
| //复习数 : 分别对应三个课程 ,当只有一个课程时,只使用了reviewNumber1,有改变时必须通知 | |||
| val reviewNumber1 = MutableLiveData<Int>() | |||
| val reviewNumber2 = MutableLiveData<Int>() | |||
| val reviewNumber3 = MutableLiveData<Int>() | |||
| init { | |||
| if (isMemoSource){ | |||
| DataTransferHolder.instance.getData<MemoCoursePack>().let { | |||
| coursePackChildrenMemo = it.coursePackChildrenMemo | |||
| it.coursePack.childrenCourses.forEach { c -> | |||
| updateReviewNumber(c.courseType,it.coursePackChildrenReview.getOrDefault(c.courseId,0)) | |||
| } | |||
| } | |||
| } | |||
| } | |||
| //设置显示当前课程的进度值和显示内容 | |||
| val currentCourseProgress = MutableLiveData<Double>() | |||
| @@ -26,4 +48,12 @@ class CoursePackMainActivityViewModel(subjectId: Int , coursePackInPosition : In | |||
| coursePack.learnProgress = coursePack.childrenCourses[0].courseLearnProgress | |||
| } | |||
| } | |||
| /** 更新复习数据 根据课程类型更新复习数量 */ | |||
| fun updateReviewNumber(courseType : Int, reviewNumber : Int) { | |||
| when(courseType){ | |||
| AppConstants.COURSE_TYPE_ENGLISH_SPELL -> reviewNumber2.value = reviewNumber | |||
| AppConstants.COURSE_TYPE_ENGLISH_VOICE -> reviewNumber3.value = reviewNumber | |||
| else -> reviewNumber1.value = reviewNumber } | |||
| } | |||
| } | |||
| @@ -102,6 +102,12 @@ class CourseMainFragment : BaseFragmentVM<FragmentCourseMainBinding, CourseMainF | |||
| override fun loadData() { | |||
| vm.loadMain().observe(this) { | |||
| //备忘本加载为复习界面,没有其他界面进行加载 | |||
| if (vm.coursePackMainActivityVM.isMemoSource){ | |||
| currentFragment = CourseReviewFragment.newInstance() | |||
| replaceFragment(R.id.layout_root,currentFragment) | |||
| return@observe | |||
| } | |||
| changeChildren() | |||
| } | |||
| } | |||
| @@ -120,7 +126,7 @@ class CourseMainFragment : BaseFragmentVM<FragmentCourseMainBinding, CourseMainF | |||
| private fun changeChildrenFragmentForWord() { | |||
| currentFragment = vm.courseDetail.let { | |||
| when{ | |||
| vm.reviewDataList.size > 0 -> CourseReviewFragment.newInstanceFromLearningCenter() //有复习 | |||
| vm.reviewDataList.size > 0 -> CourseReviewFragment.newInstance() //有复习 | |||
| it.st_before == AppConstants.NOT_DOING -> CourseTotalTestFragment.newInstance(AppConstants.TEST_TYPE_BEFORE_TOTAL) //学前总测未做 | |||
| it.courseLearnProgress != AppConstants.DOING_OVER -> CourseLessonFragment.newInstance() //学习未完成 | |||
| else -> CourseTotalTestFragment.newInstance(AppConstants.TEST_TYPE_AFTER_TOTAL) //学习完成,学后总测试界面 | |||
| @@ -134,7 +140,7 @@ class CourseMainFragment : BaseFragmentVM<FragmentCourseMainBinding, CourseMainF | |||
| */ | |||
| private fun changeChildrenFragmentForComposition() { | |||
| currentFragment = when { | |||
| vm.reviewDataList.size > 0 -> CourseReviewFragment.newInstanceFromLearningCenter() //复习 | |||
| vm.reviewDataList.size > 0 -> CourseReviewFragment.newInstance() //复习 | |||
| else -> CourseLessonFragment.newInstance() //目录 | |||
| } | |||
| replaceFragment(R.id.layout_root, currentFragment) | |||
| @@ -90,6 +90,9 @@ class CourseMainFragmentViewModel(val courseIndex : Int) : BaseViewModel() { | |||
| initReviewData(t2) | |||
| true | |||
| }).compose(diskIo2Main()).subscribe { | |||
| //如果是备忘本,更新复习数量,避免进入时,数据进行了改变,此时用于修改角标 | |||
| coursePackMainActivityVM.updateReviewNumber(course.courseType,reviewDataList.size) | |||
| mutableLiveData.value = it | |||
| } | |||
| return mutableLiveData | |||
| @@ -1,92 +1,72 @@ | |||
| package com.xkl.cdl.module.m_center_learn.coursechildren | |||
| import android.os.Bundle | |||
| import android.view.View | |||
| import androidx.lifecycle.ViewModelProvider | |||
| import com.jeremyliao.liveeventbus.LiveEventBus | |||
| import com.suliang.common.AppConfig | |||
| import com.suliang.common.base.fragment.BaseFragmentVM | |||
| import com.suliang.common.extension.click | |||
| import com.xkl.cdl.R | |||
| 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.bean.intentdata.MemoData | |||
| import com.xkl.cdl.data.event.LearnEventData | |||
| import com.xkl.cdl.data.repository.DataRepository | |||
| import com.xkl.cdl.databinding.FragmentCourseReviewBinding | |||
| import com.xkl.cdl.module.learn.LearnWordActivity | |||
| import com.xkl.cdl.module.m_center_learn.CoursePackMainActivity | |||
| import com.xkl.cdl.module.m_memo.MemoListDetailActivity | |||
| /** | |||
| * 复习界面 | |||
| * 加载此界面,需要传参 从备忘本进入的主页加载此界面,还是从学习中心进入的主页加载此界面,其显示将不同 | |||
| * 加载此界面,根据vm的isMemoSource结果,其显示将不同 | |||
| */ | |||
| class CourseReviewFragment : BaseFragmentVM<FragmentCourseReviewBinding, CourseMainFragmentViewModel>() { | |||
| companion object { | |||
| /** | |||
| * 新建实例 | |||
| * @param pageSource Int 页面来源,默认为0,从学习中心加载, 1为从备忘本加载 | |||
| * @return CourseReviewFragment | |||
| */ | |||
| @JvmStatic | |||
| fun newInstanceFromLearningCenter() : CourseReviewFragment { | |||
| fun newInstance() : CourseReviewFragment { | |||
| return CourseReviewFragment() | |||
| } | |||
| /** | |||
| * 新建实例 | |||
| * @param pageSource Int 页面来源,默认为0,从学习中心加载, 1为从备忘本加载 | |||
| * @return CourseReviewFragment | |||
| */ | |||
| @JvmStatic | |||
| fun newInstanceFromMemo() : CourseReviewFragment { | |||
| val args = Bundle() | |||
| args.putInt(AppConfig.INTENT_1, 1) | |||
| val fragment = CourseReviewFragment() | |||
| fragment.arguments = args | |||
| return fragment | |||
| } | |||
| } | |||
| override fun initFragment() { | |||
| //获取页面来源 0 : 学习中心进入的加载复习界面 其他为备忘本进入加载的复习数据界面 | |||
| val pageSource : Int = arguments?.getInt(AppConfig.INTENT_1) ?: 0 | |||
| when (vm.reviewDataList.size) { | |||
| 0 -> if (pageSource != 0) { | |||
| //备忘本无复习数据加载 | |||
| initMemoData() | |||
| binding.tvStartReview.visibility = View.GONE | |||
| binding.tvSeeMemo.visibility = View.VISIBLE | |||
| when{ | |||
| //备忘本 | |||
| vm.coursePackMainActivityVM.isMemoSource -> when{ | |||
| vm.reviewDataList.size > 0 -> { | |||
| initReviewData() | |||
| binding.tvStartReview.visibility = View.VISIBLE | |||
| binding.tvSeeMemo.visibility = View.VISIBLE | |||
| } | |||
| else -> initMemoData() | |||
| } | |||
| else -> { //有复习数据加载 | |||
| //学习中心 | |||
| else -> { | |||
| initReviewData() | |||
| when (pageSource) { | |||
| 0 -> { | |||
| binding.tvSeeMemo.visibility = View.GONE | |||
| binding.tvStartReview.visibility = View.VISIBLE | |||
| } | |||
| else -> { | |||
| binding.tvStartReview.visibility = View.VISIBLE | |||
| binding.tvSeeMemo.visibility = View.VISIBLE | |||
| } | |||
| } | |||
| binding.tvStartReview.visibility = View.VISIBLE | |||
| binding.tvSeeMemo.visibility = View.GONE | |||
| } | |||
| } | |||
| //开始复习 | |||
| binding.tvStartReview.click { | |||
| if (vm.isAssignmentReviewData){ //已经赋值,直接赋值跳转 | |||
| (requireActivity() as CoursePackMainActivity).startReview(vm.course,vm.reviewDataList) | |||
| }else{ //没有赋值,需要进行 | |||
| }else{ //没有赋值,需要进行查询 | |||
| vm.queryReviewForDb().observe(this){ | |||
| vm.isAssignmentReviewData = true | |||
| if (it){ | |||
| (requireActivity() as CoursePackMainActivity).startReview(vm.course,vm.reviewDataList) | |||
| }else{ | |||
| showToast("复习数据查询失败") | |||
| //如果是学习中心跳转过来,直接进行状态页 | |||
| if (pageSource == 0 ){ | |||
| //如果是学习中心跳转过来,没有查询出复习数据,需要进行状态也切换 | |||
| if (vm.coursePackMainActivityVM.isMemoSource ){ | |||
| initMemoData() | |||
| }else{ | |||
| (requireParentFragment() as CourseMainFragment).changeChildren() | |||
| } | |||
| } | |||
| @@ -95,7 +75,8 @@ class CourseReviewFragment : BaseFragmentVM<FragmentCourseReviewBinding, CourseM | |||
| } | |||
| //查看备忘本 | |||
| binding.tvSeeMemo.click { | |||
| showToast("查看备忘本") | |||
| DataTransferHolder.instance.putData(value = MemoData(vm.course, vm.coursePackMainActivityVM.coursePackChildrenMemo[vm.course.courseId] ?: mutableListOf())) | |||
| startActivity(MemoListDetailActivity::class.java) | |||
| } | |||
| } | |||
| @@ -111,16 +92,30 @@ class CourseReviewFragment : BaseFragmentVM<FragmentCourseReviewBinding, CourseM | |||
| } | |||
| private fun initMemoData() { | |||
| binding.tvTips.text = when (vm.course.courseType) { | |||
| AppConstants.COURSE_TYPE_ENGLISH_DISCERN -> "[认读] 课程加入备忘本数据共123条" | |||
| AppConstants.COURSE_TYPE_ENGLISH_VOICE -> "[辨音] 课程加入备忘本数据共123条" | |||
| AppConstants.COURSE_TYPE_ENGLISH_SPELL -> "[拼写] 课程加入备忘本数据共123条" | |||
| else -> "课程加入备忘本数据共123条" | |||
| val count = vm.coursePackMainActivityVM.coursePackChildrenMemo[vm.course.courseId]?.size ?: 0 | |||
| when{ | |||
| count > 0 -> { | |||
| binding.tvTips.text = when (vm.course.courseType) { | |||
| AppConstants.COURSE_TYPE_ENGLISH_DISCERN -> "[认读] 课程加入备忘本数据共${count}条" | |||
| AppConstants.COURSE_TYPE_ENGLISH_VOICE -> "[辨音] 课程加入备忘本数据共${count}条" | |||
| AppConstants.COURSE_TYPE_ENGLISH_SPELL -> "[拼写] 课程加入备忘本数据共${count}条" | |||
| else -> "课程加入备忘本数据共${count}条" | |||
| } | |||
| binding.tvSeeMemo.visibility = View.VISIBLE | |||
| binding.tvStartReview.visibility = View.GONE | |||
| } | |||
| else -> { | |||
| binding.ivIcon.setImageResource(R.mipmap.empty_nothing) | |||
| binding.tvTips.text = "暂无数据,快去学习吧!" | |||
| binding.tvSeeMemo.visibility = View.GONE | |||
| binding.tvStartReview.visibility = View.GONE | |||
| } | |||
| } | |||
| binding.tvReviewCount.visibility = View.GONE | |||
| } | |||
| override fun loadData() { | |||
| //监听复习回调 : 此处复习回调,主要用于更新界面剩余数显示,或者是复习完成,进行数据切换 | |||
| LiveEventBus.get<LearnEventData>(AppConstants.EVENT_REVIEW_DATA).observe(this){ | |||
| if (it.subjectId != vm.course.subjectId || it.courseId != vm.course.courseId) return@observe | |||
| when(it.actionFlag){ | |||
| @@ -129,18 +124,18 @@ class CourseReviewFragment : BaseFragmentVM<FragmentCourseReviewBinding, CourseM | |||
| if (it.leesonPositionIndex == vm.reviewDataList.size - 1){ | |||
| //清空 | |||
| vm.reviewDataList.clear() | |||
| //切换界面 | |||
| val pageSource = arguments?.getInt(AppConfig.INTENT_1) ?: 0 | |||
| if ( pageSource == 0 ){ | |||
| //非学习中心需要切换界面 | |||
| if ( !vm.coursePackMainActivityVM.isMemoSource){ | |||
| (requireParentFragment() as CourseMainFragment).changeChildren() | |||
| }else{ // TODO: 2022/6/6 备忘本需隐藏复习按钮,修改文字 | |||
| }else{ | |||
| initMemoData() | |||
| binding.tvStartReview.visibility = View.GONE | |||
| } | |||
| }else { // 复习未完成 todo 需要验证一下 sublist().clear() | |||
| vm.reviewDataList.subList(0, it.leesonPositionIndex + 1).clear() | |||
| initReviewData() | |||
| } | |||
| //更新复习数 | |||
| vm.coursePackMainActivityVM.updateReviewNumber(vm.course.courseType,vm.reviewDataList.size) | |||
| } | |||
| } | |||
| } | |||
| @@ -1,9 +1,12 @@ | |||
| package com.xkl.cdl.module.m_memo | |||
| import androidx.lifecycle.ViewModelProvider | |||
| import androidx.recyclerview.widget.LinearLayoutManager | |||
| import androidx.recyclerview.widget.StaggeredGridLayoutManager | |||
| import com.suliang.common.base.fragment.BaseFragmentVM | |||
| import com.xkl.cdl.data.bean.MemoCoursePack | |||
| import com.xkl.cdl.databinding.FragmentMemoBinding | |||
| import com.xkl.cdl.module.m_center_learn.CoursePackMainActivity | |||
| import com.xkl.cdl.module.main.MainActivityViewModel | |||
| /** | |||
| @@ -27,17 +30,29 @@ class MemoFragment : BaseFragmentVM<FragmentMemoBinding, MemoFragmentViewModel> | |||
| override fun initFragment() { | |||
| binding.rv.run { | |||
| layoutManager = StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL) | |||
| adapter = vm.adapter | |||
| binding.vm = vm | |||
| binding.rv.adapter = vm.adapter.apply { | |||
| onItemClick = { view, position, item -> | |||
| CoursePackMainActivity.newInstance(requireContext(),item) | |||
| } | |||
| } | |||
| } | |||
| override fun loadData() { | |||
| /** 搜索内容变化监听 */ | |||
| vm.etSearchLiveData.observe(this){ | |||
| val resources = if (it.isEmpty()) vm.memoCoursePackList else vm.memoCoursePackList.filter { memoCoursePack -> | |||
| memoCoursePack.coursePack.coursePackName.contains(it) | |||
| }.toMutableList() | |||
| //布局 | |||
| when{ | |||
| resources.size > 0 -> binding.rv.layoutManager = StaggeredGridLayoutManager(2, | |||
| StaggeredGridLayoutManager.VERTICAL).apply { | |||
| gapStrategy = StaggeredGridLayoutManager.GAP_HANDLING_NONE | |||
| } | |||
| else -> binding.rv.layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.VERTICAL, false) | |||
| } | |||
| vm.adapter.setData(resources) | |||
| } | |||
| } | |||
| @@ -2,16 +2,17 @@ package com.xkl.cdl.module.m_memo | |||
| import androidx.lifecycle.MutableLiveData | |||
| import appApi.AppApi | |||
| import com.googlecode.protobuf.format.JsonFormat | |||
| import com.suliang.common.base.viewmodel.BaseViewModel | |||
| import com.suliang.common.extension.diskIo2DiskIo | |||
| import com.suliang.common.util.LogUtil | |||
| import com.suliang.common.extension.diskIo2Main | |||
| import com.xkl.cdl.adapter.AdapterCoursePackWithMemo | |||
| import com.xkl.cdl.data.AppConstants | |||
| import com.xkl.cdl.data.bean.MemoCoursePack | |||
| import com.xkl.cdl.data.manager.CourseManager | |||
| import com.xkl.cdl.module.XKLApplication | |||
| import com.xkl.cdl.module.main.MainActivity | |||
| import com.xkl.cdl.module.main.MainActivityViewModel | |||
| import io.reactivex.rxjava3.core.Observable | |||
| import java.util.* | |||
| /** | |||
| * author suliang | |||
| @@ -35,21 +36,59 @@ class MemoFragmentViewModel : BaseViewModel() { | |||
| * 查询课程的错误数据结果 | |||
| */ | |||
| fun queryData() { | |||
| Observable.create<ByteArray> { | |||
| Observable.fromCallable<Boolean> { | |||
| //参数: 科目 课程包id 课程id category 1 获取正确的,2获取错误的,3正确错误都获取 | |||
| val wordList = XKLApplication.mobileCache.getWordList(0, 0, 0, 2) | |||
| it.onNext(wordList) | |||
| it.onComplete() | |||
| }.compose(diskIo2DiskIo()).subscribe({ | |||
| AppApi.GetWordListResponse.parseFrom(it).wrongList?.forEach { wrong -> | |||
| //组合所有绑定的课程 | |||
| val resultMemoCoursePack = mutableListOf<MemoCoursePack>() | |||
| //添加到集合的位置 key: coursePackId value:在result中的下标 | |||
| val coursePackInResultIndex = mutableMapOf<Long, Int>() | |||
| val calendar = Calendar.getInstance() | |||
| val currentTimeMillis = System.currentTimeMillis() | |||
| AppApi.GetWordListResponse.parseFrom(wordList).wrongList?.forEach { item -> | |||
| item.split("_").let { splitValue -> | |||
| val projectId = splitValue[0].toInt() | |||
| val coursePackId = splitValue[1].toLong() | |||
| val courseId = splitValue[2].toLong() | |||
| //生成 MemoCoursePack | |||
| var memoCoursePack : MemoCoursePack? = null | |||
| coursePackInResultIndex[coursePackId]?.let { index -> | |||
| memoCoursePack = resultMemoCoursePack[index] | |||
| } ?: let { | |||
| CourseManager.getCoursePackWithCoursePackId(projectId, coursePackId)?.let { coursePack -> | |||
| memoCoursePack = MemoCoursePack(coursePack).apply { | |||
| resultMemoCoursePack.add(this) | |||
| coursePackInResultIndex[coursePackId] = resultMemoCoursePack.lastIndex | |||
| } | |||
| } | |||
| } | |||
| memoCoursePack?.let { | |||
| it.coursePackChildrenMemo[courseId]?.add(item) ?: let { vm -> | |||
| val memoList = mutableListOf<String>() | |||
| memoList.add(item) | |||
| it.coursePackChildrenMemo[courseId] = memoList | |||
| } | |||
| //复习数量 | |||
| if (CourseManager.calculateIsNeedInReview(calendar, splitValue[6].toInt(), splitValue[7], | |||
| currentTimeMillis)) { | |||
| it.coursePackChildrenReview[courseId]?.let { valueNumber -> | |||
| it.coursePackChildrenReview[courseId] = valueNumber + 1 | |||
| } ?: let { vm -> | |||
| it.coursePackChildrenReview[courseId] = 1 | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| //赋值集合 | |||
| //列表刷新 | |||
| }, { | |||
| it.printStackTrace() | |||
| }) | |||
| memoCoursePackList.clear() | |||
| memoCoursePackList.addAll(resultMemoCoursePack) | |||
| return@fromCallable true | |||
| }.compose(diskIo2Main()).subscribe({ | |||
| etSearchLiveData.value = etSearchLiveData.value ?: "" | |||
| }, { | |||
| it.printStackTrace() | |||
| }) | |||
| } | |||
| } | |||
| @@ -0,0 +1,53 @@ | |||
| package com.xkl.cdl.module.m_memo | |||
| import android.os.Bundle | |||
| import android.view.View | |||
| import androidx.lifecycle.ViewModelProvider | |||
| import com.suliang.common.base.activity.BaseActivityVM | |||
| import com.suliang.common.extension.click | |||
| import com.suliang.common.util.DrawableUti | |||
| import com.xkl.cdl.R | |||
| import com.xkl.cdl.databinding.ActivityMemoListDetailBinding | |||
| /** | |||
| * author suliang | |||
| * create 2022/6/9 15:51 | |||
| * Describe: 备忘本课程详情列表 | |||
| */ | |||
| class MemoListDetailActivity : BaseActivityVM<ActivityMemoListDetailBinding, MemoListDetailViewModel>() { | |||
| override fun initViewModel() : MemoListDetailViewModel { | |||
| return ViewModelProvider(this)[MemoListDetailViewModel::class.java] | |||
| } | |||
| override fun initActivity(savedInstanceState : Bundle?) { | |||
| //标题 | |||
| binding.titleBar.run { | |||
| textViewTitle.text = vm.memoData.course.courseTitle | |||
| setRightSrc(DrawableUti.changeSvgSizeAndColor(resources,R.drawable.ic_search,R.color.main_text_color,1.33f)) | |||
| onBackClick = { | |||
| finish() | |||
| } | |||
| //显示搜索 | |||
| onRightClick = { | |||
| binding.tvSearchCache.visibility = View.VISIBLE | |||
| binding.etSearch.visibility = View.VISIBLE | |||
| } | |||
| } | |||
| //搜索取消 | |||
| binding.tvSearchCache.click { | |||
| binding.tvSearchCache.visibility = View.VISIBLE | |||
| binding.etSearch.visibility = View.VISIBLE | |||
| binding.etSearch.setText("") | |||
| } | |||
| } | |||
| override fun loadData() { | |||
| } | |||
| } | |||
| @@ -0,0 +1,11 @@ | |||
| package com.xkl.cdl.module.m_memo | |||
| import com.suliang.common.base.viewmodel.BaseViewModel | |||
| import com.xkl.cdl.data.DataTransferHolder | |||
| import com.xkl.cdl.data.bean.intentdata.MemoData | |||
| class MemoListDetailViewModel : BaseViewModel(){ | |||
| val memoData = DataTransferHolder.instance.getData<MemoData>() | |||
| } | |||
| @@ -0,0 +1,6 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | |||
| <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> | |||
| <solid android:color="@color/red_1"/> | |||
| <corners android:radius="6dp"/> | |||
| <padding android:left="6dp" android:right="6dp" android:top="0dp" android:bottom="0dp"/> | |||
| </shape> | |||
| @@ -42,14 +42,15 @@ | |||
| app:layout_constraintStart_toStartOf="parent" | |||
| app:layout_constraintTop_toTopOf="parent" /> | |||
| <include | |||
| android:id="@+id/include_title_bar" | |||
| <com.suliang.common.widget.TitleBar | |||
| android:id="@+id/title_bar" | |||
| android:layout_width="match_parent" | |||
| android:layout_height="@dimen/title_bar_height" | |||
| layout="@layout/include_title_bar" | |||
| app:layout_constraintTop_toBottomOf="@+id/status_bar_view" | |||
| bind:titleValue="@{@string/course_detail}" /> | |||
| app:layout_constraintStart_toStartOf="parent" | |||
| app:layout_constraintEnd_toEndOf="parent" | |||
| /> | |||
| <View | |||
| android:id="@+id/view_placeholder_1" | |||
| android:layout_width="wrap_content" | |||
| @@ -57,7 +58,7 @@ | |||
| android:layout_marginTop="124dp" | |||
| app:layout_constraintEnd_toEndOf="parent" | |||
| app:layout_constraintStart_toStartOf="parent" | |||
| app:layout_constraintTop_toBottomOf="@+id/include_title_bar" /> | |||
| app:layout_constraintTop_toBottomOf="@+id/title_bar" /> | |||
| <!--全显图--> | |||
| <com.google.android.material.imageview.ShapeableImageView | |||
| @@ -69,7 +70,7 @@ | |||
| app:imageByteArray="@{coursePack.cover}" | |||
| app:layout_constraintBottom_toTopOf="@+id/view_placeholder_1" | |||
| app:layout_constraintStart_toStartOf="parent" | |||
| app:layout_constraintTop_toBottomOf="@id/include_title_bar" | |||
| app:layout_constraintTop_toBottomOf="@id/title_bar" | |||
| app:shapeAppearance="@style/roundedCornerStyle" | |||
| tools:background="@color/theme_color" /> | |||
| @@ -0,0 +1,123 @@ | |||
| <?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_memo.MemoListDetailActivity" | |||
| 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:layout_constraintStart_toStartOf="parent" | |||
| app:layout_constraintEnd_toEndOf="parent" | |||
| /> | |||
| <TextView | |||
| android:id="@+id/tv_search_cache" | |||
| android:layout_width="wrap_content" | |||
| android:layout_height="0dp" | |||
| android:text="@string/cancel" | |||
| android:gravity="center_vertical" | |||
| 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"/> | |||
| <com.suliang.common.widget.InputSearchEditText | |||
| android:id="@+id/et_search" | |||
| android:layout_width="0dp" | |||
| android:layout_height="36dp" | |||
| 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:textColor="@color/main_text_color" | |||
| android:textSize="@dimen/normalSize" | |||
| app:layout_constraintTop_toTopOf="@id/title_bar" | |||
| app:layout_constraintBottom_toBottomOf="@+id/title_bar" | |||
| app:layout_constraintStart_toStartOf="parent" | |||
| app:layout_constraintEnd_toStartOf="@+id/tv_search_cache" | |||
| android:visibility="gone" | |||
| /> | |||
| <com.haibin.calendarview.CalendarLayout | |||
| android:layout_width="match_parent" | |||
| android:layout_height="0dp" | |||
| 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 | |||
| android:id="@+id/layout_content" | |||
| android:layout_width="match_parent" | |||
| android:layout_height="0dp" | |||
| android:layout_weight="1"> | |||
| </androidx.constraintlayout.widget.ConstraintLayout> | |||
| </com.haibin.calendarview.CalendarLayout> | |||
| <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.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_marginBottom="@dimen/global_spacing" | |||
| android:background="@color/red_1" | |||
| android:layout_marginEnd="12dp"/> | |||
| <com.suliang.common.widget.TextViewCenterDrawable | |||
| android:id="@+id/tv_test_review" | |||
| 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"/> | |||
| </androidx.constraintlayout.widget.ConstraintLayout> | |||
| </layout> | |||
| @@ -64,6 +64,9 @@ | |||
| app:layout_constraintBottom_toBottomOf="parent" | |||
| app:layout_constraintStart_toStartOf="parent" | |||
| app:layout_constraintEnd_toEndOf="parent" | |||
| android:paddingStart="10dp" | |||
| android:paddingEnd="10dp" | |||
| android:paddingTop="10dp" | |||
| android:background="@color/white_1" | |||
| android:overScrollMode="never" | |||
| android:scrollbars="none" /> | |||
| @@ -31,6 +31,24 @@ | |||
| android:visibility="gone" | |||
| tools:visibility="visible"/> | |||
| <TextView | |||
| android:id="@+id/tv_review_number_1" | |||
| android:layout_width="wrap_content" | |||
| android:layout_height="wrap_content" | |||
| android:background="@drawable/shape_red_badge" | |||
| android:textColor="@color/white" | |||
| android:gravity="center" | |||
| android:textSize="@dimen/smallerSize" | |||
| android:layout_marginEnd="1dp" | |||
| tools:text="99+" | |||
| android:includeFontPadding="false" | |||
| app:layout_constraintStart_toEndOf="@+id/tab_discern" | |||
| app:layout_constraintTop_toTopOf="parent" | |||
| android:layout_marginTop="6dp" | |||
| android:visibility="gone" | |||
| tools:visibility="visible" | |||
| /> | |||
| <ImageView | |||
| android:id="@+id/iv_arrow_1" | |||
| app:layout_constraintBottom_toBottomOf="parent" | |||
| @@ -60,6 +78,23 @@ | |||
| android:drawablePadding="4dp" | |||
| android:visibility="gone" | |||
| tools:visibility="visible"/> | |||
| <TextView | |||
| android:id="@+id/tv_review_number_2" | |||
| android:layout_width="wrap_content" | |||
| android:layout_height="wrap_content" | |||
| android:background="@drawable/shape_red_badge" | |||
| android:textColor="@color/white" | |||
| android:gravity="center" | |||
| android:textSize="@dimen/smallerSize" | |||
| android:layout_marginEnd="1dp" | |||
| tools:text="99+" | |||
| android:includeFontPadding="false" | |||
| app:layout_constraintStart_toEndOf="@+id/tab_spell" | |||
| app:layout_constraintTop_toTopOf="parent" | |||
| android:layout_marginTop="6dp" | |||
| android:visibility="gone" | |||
| tools:visibility="visible" | |||
| /> | |||
| <ImageView | |||
| android:id="@+id/iv_arrow_2" | |||
| @@ -89,6 +124,23 @@ | |||
| android:drawablePadding="4dp" | |||
| android:visibility="gone" | |||
| tools:visibility="visible"/> | |||
| <TextView | |||
| android:id="@+id/tv_review_number_3" | |||
| android:layout_width="wrap_content" | |||
| android:layout_height="wrap_content" | |||
| android:background="@drawable/shape_red_badge" | |||
| android:textColor="@color/white" | |||
| android:gravity="center" | |||
| android:textSize="@dimen/smallerSize" | |||
| android:layout_marginEnd="1dp" | |||
| tools:text="99+" | |||
| android:includeFontPadding="false" | |||
| app:layout_constraintStart_toEndOf="@+id/tab_voice" | |||
| app:layout_constraintTop_toTopOf="parent" | |||
| android:layout_marginTop="6dp" | |||
| android:visibility="gone" | |||
| tools:visibility="visible" | |||
| /> | |||
| </androidx.constraintlayout.widget.ConstraintLayout> | |||
| </layout> | |||
| @@ -1,74 +1,133 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | |||
| <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" | |||
| <layout xmlns:android="http://schemas.android.com/apk/res/android" | |||
| xmlns:app="http://schemas.android.com/apk/res-auto" | |||
| android:layout_width="match_parent" | |||
| android:layout_height="match_parent" | |||
| android:layout_margin="5dp" | |||
| android:background="@drawable/shape_rounder_12_white" | |||
| android:padding="8dp" | |||
| android:paddingBottom="12dp"> | |||
| xmlns:tools="http://schemas.android.com/tools"> | |||
| <com.google.android.material.imageview.ShapeableImageView | |||
| android:id="@+id/img_course_pack_cover" | |||
| style="@style/roundedCornerStyle" | |||
| android:layout_width="0dp" | |||
| android:layout_height="0dp" | |||
| app:layout_constraintHeight_min="128dp" | |||
| android:layout_marginEnd="8dp" | |||
| android:scaleType="centerCrop" | |||
| app:layout_constraintDimensionRatio="h,102:136" | |||
| app:layout_constraintEnd_toStartOf="@+id/barrier" | |||
| app:layout_constraintStart_toStartOf="parent" | |||
| app:layout_constraintTop_toTopOf="parent" /> | |||
| <data> | |||
| <androidx.constraintlayout.widget.Barrier | |||
| android:id="@+id/barrier" | |||
| android:layout_width="1dp" | |||
| </data> | |||
| <androidx.constraintlayout.widget.ConstraintLayout | |||
| android:layout_width="wrap_content" | |||
| android:layout_height="wrap_content" | |||
| app:barrierDirection="right" | |||
| app:constraint_referenced_ids="img_course_pack_cover" /> | |||
| android:background="@drawable/shape_rounder_12_white" | |||
| android:padding="8dp" | |||
| android:paddingBottom="12dp" | |||
| android:layout_margin="6dp"> | |||
| <com.google.android.material.imageview.ShapeableImageView | |||
| android:id="@+id/img_course_icon_1" | |||
| android:layout_width="40dp" | |||
| android:layout_height="40dp" | |||
| app:layout_constraintEnd_toEndOf="parent" | |||
| app:layout_constraintStart_toEndOf="@+id/barrier" | |||
| app:layout_constraintTop_toTopOf="parent" | |||
| app:layout_constraintBottom_toTopOf="@+id/img_course_icon_2" | |||
| app:strokeWidth="10dp" | |||
| style="@style/roundedCornerStyle"/> | |||
| <com.google.android.material.imageview.ShapeableImageView | |||
| android:id="@+id/img_course_pack_cover" | |||
| style="@style/roundedCornerStyle" | |||
| android:layout_width="0dp" | |||
| android:layout_height="0dp" | |||
| app:layout_constraintHeight_min="128dp" | |||
| android:layout_marginEnd="8dp" | |||
| android:scaleType="centerCrop" | |||
| app:layout_constraintDimensionRatio="h,102:136" | |||
| app:layout_constraintEnd_toStartOf="@+id/barrier" | |||
| app:layout_constraintStart_toStartOf="parent" | |||
| app:layout_constraintTop_toTopOf="parent" /> | |||
| <com.google.android.material.imageview.ShapeableImageView | |||
| android:id="@+id/img_course_icon_2" | |||
| android:layout_width="40dp" | |||
| android:layout_height="40dp" | |||
| app:layout_constraintEnd_toEndOf="parent" | |||
| app:layout_constraintStart_toEndOf="@+id/barrier" | |||
| app:layout_constraintTop_toBottomOf="@+id/img_course_icon_1" | |||
| app:layout_constraintBottom_toTopOf="@+id/img_course_icon_3" | |||
| app:strokeWidth="10dp" | |||
| android:visibility="invisible" | |||
| style="@style/roundedCornerStyle"/> | |||
| <androidx.constraintlayout.widget.Barrier | |||
| android:id="@+id/barrier" | |||
| android:layout_width="1dp" | |||
| android:layout_height="wrap_content" | |||
| app:barrierDirection="right" | |||
| app:constraint_referenced_ids="img_course_pack_cover" /> | |||
| <com.google.android.material.imageview.ShapeableImageView | |||
| android:id="@+id/img_course_icon_3" | |||
| android:layout_width="40dp" | |||
| android:layout_height="40dp" | |||
| app:layout_constraintEnd_toEndOf="parent" | |||
| app:layout_constraintStart_toEndOf="@+id/barrier" | |||
| app:layout_constraintTop_toBottomOf="@+id/img_course_icon_2" | |||
| app:layout_constraintBottom_toBottomOf="@+id/img_course_pack_cover" | |||
| app:strokeWidth="10dp" | |||
| android:visibility="invisible" | |||
| style="@style/roundedCornerStyle" | |||
| /> | |||
| <com.google.android.material.imageview.ShapeableImageView | |||
| android:id="@+id/img_course_icon_1" | |||
| android:layout_width="40dp" | |||
| android:layout_height="40dp" | |||
| app:layout_constraintEnd_toEndOf="parent" | |||
| app:layout_constraintStart_toEndOf="@+id/barrier" | |||
| app:layout_constraintTop_toTopOf="parent" | |||
| app:layout_constraintBottom_toTopOf="@+id/img_course_icon_2" | |||
| android:padding="6dp" | |||
| app:strokeWidth="10dp" | |||
| style="@style/roundedCornerStyle" /> | |||
| <TextView | |||
| android:id="@+id/tv_course_pack_name" | |||
| android:layout_width="match_parent" | |||
| android:layout_height="wrap_content" | |||
| app:layout_constraintTop_toBottomOf="@+id/img_course_pack_cover" /> | |||
| <TextView | |||
| android:id="@+id/tv_review_number_1" | |||
| android:layout_width="wrap_content" | |||
| android:layout_height="14dp" | |||
| android:background="@drawable/shape_red_badge" | |||
| android:textColor="@color/white" | |||
| android:gravity="center" | |||
| android:textSize="@dimen/smallerSize" | |||
| android:layout_marginEnd="1dp" | |||
| tools:text="1" | |||
| android:includeFontPadding="false" | |||
| app:layout_constraintEnd_toEndOf="@+id/img_course_icon_1" | |||
| app:layout_constraintTop_toTopOf="@+id/img_course_icon_1" | |||
| /> | |||
| <com.google.android.material.imageview.ShapeableImageView | |||
| android:id="@+id/img_course_icon_2" | |||
| android:layout_width="40dp" | |||
| android:layout_height="40dp" | |||
| app:layout_constraintEnd_toEndOf="parent" | |||
| app:layout_constraintStart_toEndOf="@+id/barrier" | |||
| app:layout_constraintTop_toBottomOf="@+id/img_course_icon_1" | |||
| app:layout_constraintBottom_toTopOf="@+id/img_course_icon_3" | |||
| android:padding="6dp" | |||
| app:strokeWidth="10dp" | |||
| style="@style/roundedCornerStyle" | |||
| android:visibility="invisible" | |||
| tools:visibility="visible" | |||
| /> | |||
| <TextView | |||
| android:id="@+id/tv_review_number_2" | |||
| android:layout_width="wrap_content" | |||
| android:layout_height="wrap_content" | |||
| android:background="@drawable/shape_red_badge" | |||
| android:textColor="@color/white" | |||
| android:gravity="center" | |||
| android:textSize="@dimen/smallerSize" | |||
| android:layout_marginEnd="1dp" | |||
| tools:text="1" | |||
| android:includeFontPadding="false" | |||
| app:layout_constraintEnd_toEndOf="@+id/img_course_icon_2" | |||
| app:layout_constraintTop_toTopOf="@+id/img_course_icon_2" | |||
| /> | |||
| <com.google.android.material.imageview.ShapeableImageView | |||
| android:id="@+id/img_course_icon_3" | |||
| android:layout_width="40dp" | |||
| android:layout_height="40dp" | |||
| app:layout_constraintEnd_toEndOf="parent" | |||
| app:layout_constraintStart_toEndOf="@+id/barrier" | |||
| app:layout_constraintTop_toBottomOf="@+id/img_course_icon_2" | |||
| app:layout_constraintBottom_toBottomOf="@+id/img_course_pack_cover" | |||
| app:strokeWidth="10dp" | |||
| style="@style/roundedCornerStyle" | |||
| android:visibility="invisible" | |||
| android:padding="6dp" | |||
| tools:visibility="visible"/> | |||
| <TextView | |||
| android:id="@+id/tv_review_number_3" | |||
| android:layout_width="wrap_content" | |||
| android:layout_height="wrap_content" | |||
| android:background="@drawable/shape_red_badge" | |||
| android:textColor="@color/white" | |||
| android:gravity="center" | |||
| android:textSize="@dimen/smallerSize" | |||
| android:layout_marginEnd="1dp" | |||
| tools:text="111" | |||
| android:includeFontPadding="false" | |||
| app:layout_constraintEnd_toEndOf="@+id/img_course_icon_3" | |||
| app:layout_constraintTop_toTopOf="@+id/img_course_icon_3" | |||
| /> | |||
| <TextView | |||
| android:id="@+id/tv_course_pack_name" | |||
| android:layout_width="match_parent" | |||
| android:layout_height="wrap_content" | |||
| app:layout_constraintTop_toBottomOf="@+id/img_course_pack_cover" | |||
| android:textSize="@dimen/normalSize" | |||
| android:textColor="@color/main_text_color" | |||
| android:layout_marginTop="12dp"/> | |||
| </androidx.constraintlayout.widget.ConstraintLayout> | |||
| </androidx.constraintlayout.widget.ConstraintLayout> | |||
| </layout> | |||
| @@ -4,7 +4,6 @@ | |||
| xmlns:tools="http://schemas.android.com/tools"> | |||
| <data> | |||
| <variable | |||
| name="coursePack" | |||
| type="com.xkl.cdl.data.bean.course.CoursePack" /> | |||
| @@ -132,6 +131,18 @@ | |||
| app:coursePackLearnProgressFormat="@{coursePack.learnProgress}"/> | |||
| </com.xkl.cdl.widget.MyRankingView> | |||
| <TextView | |||
| android:id="@+id/tv_review" | |||
| android:layout_width="wrap_content" | |||
| android:layout_height="wrap_content" | |||
| app:layout_constraintStart_toStartOf="@+id/textview_coursePack" | |||
| app:layout_constraintTop_toBottomOf="@+id/textview_coursePack" | |||
| android:layout_marginTop="10dp" | |||
| android:text='@{"智能复习数:" + coursePack.reviewNumber}' | |||
| android:textSize="@dimen/smallSize" | |||
| android:textColor="@color/red_1" | |||
| android:visibility="gone" | |||
| tools:visibility="visible" /> | |||
| </androidx.constraintlayout.widget.ConstraintLayout> | |||
| @@ -18,6 +18,7 @@ | |||
| <string name="empty_nothing">没有任何内容</string> | |||
| <string name="empty_nothing_search">没有搜索到任何内容</string> | |||
| <string name="course_detail">课程详情</string> | |||
| <string name="course_memo_detail">备忘本课程详情</string> | |||
| <string name="introduction">简介</string> | |||
| <string name="start_review">开始复习</string> | |||
| <string name="please_select_the_operation_you_want_to_do">请选择你要进行的操作</string> | |||
| @@ -87,5 +88,6 @@ | |||
| <string name="course_introduction">课程简介</string> | |||
| <string name="start_see_memo">查看备忘本</string> | |||
| <string name="smart_reviewing">智能复习中</string> | |||
| <string name="search_hint_input_key_word">请输入搜索关键字…</string> | |||
| </resources> | |||
| @@ -104,7 +104,9 @@ ext { | |||
| //BigImageViewPager | |||
| // 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" | |||
| XPopup : "com.github.li-xiaojun:XPopup:2.8.0", | |||
| //精美日历 calendarview | |||
| CalendarView : "com.haibin:calendarview:3.7.1" | |||
| ] | |||
| @@ -3,13 +3,13 @@ | |||
| xmlns:tools="http://schemas.android.com/tools" | |||
| package="com.suliang.common"> | |||
| <!--网络权限--> | |||
| <uses-permission android:name="android.permission.INTERNET"/> | |||
| <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> | |||
| <!--本地外置存储权限--> | |||
| <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> | |||
| <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" | |||
| tools:ignore="ScopedStorage" /> | |||
| <!-- <!–网络权限–>--> | |||
| <!-- <uses-permission android:name="android.permission.INTERNET"/>--> | |||
| <!-- <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>--> | |||
| <!-- <!–本地外置存储权限–>--> | |||
| <!-- <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>--> | |||
| <!-- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"--> | |||
| <!-- tools:ignore="ScopedStorage" />--> | |||
| <!--networkSecurityConfig,usesCleartextTraffic 二选一都可以9.0-P以上高版本的http连接,否则连接失败 | |||
| @@ -95,12 +95,21 @@ class DrawableUti { | |||
| fun byteArrayToBitmap(byteArray : ByteArray):Bitmap{ | |||
| return BitmapFactory.decodeByteArray(byteArray,0,byteArray.size) | |||
| } | |||
| fun changeSvgSizeAndColor(resource:Resources,svgId : Int,changeColor : Int,scale:Int):Drawable{ | |||
| /** | |||
| * | |||
| * @param resource Resources | |||
| * @param svgId Int | |||
| * @param changeColor Int R.color.xxx | |||
| * @param scale Int 放大缩小比例 | |||
| * @return Drawable | |||
| */ | |||
| fun changeSvgSizeAndColor(resource:Resources,svgId : Int,changeColor : Int,scale:Float):Drawable{ | |||
| val vectorDrawableCompat = VectorDrawableCompat.create(resource, svgId, null)!! | |||
| vectorDrawableCompat.setTint(ResourcesCompat.getColor(resource, changeColor, null)) | |||
| val oldBitmap = vectorDrawableCompat.toBitmap(scale*vectorDrawableCompat.intrinsicWidth,scale*vectorDrawableCompat.intrinsicHeight,Bitmap.Config.ARGB_8888) | |||
| val oldBitmap = vectorDrawableCompat.toBitmap((scale * vectorDrawableCompat.intrinsicWidth).toInt(), | |||
| (scale * vectorDrawableCompat.intrinsicHeight).toInt(), Bitmap.Config.ARGB_8888) | |||
| return BitmapDrawable(resource,oldBitmap) | |||
| // val newBitmap = Bitmap.createScaledBitmap(oldBitmap,scale*oldBitmap.width,scale*oldBitmap.height,true) | |||
| } | |||
| @@ -14,7 +14,8 @@ | |||
| android:layout_height="wrap_content" | |||
| android:layout_marginStart="60dp" | |||
| android:layout_marginEnd="60dp" | |||
| android:ellipsize="end" | |||
| android:ellipsize="middle" | |||
| android:singleLine="true" | |||
| android:gravity="center" | |||
| android:textColor="#323233" | |||
| android:textSize="18dp" | |||
| @@ -24,7 +25,7 @@ | |||
| app:layout_constraintEnd_toEndOf="parent" | |||
| app:layout_constraintStart_toStartOf="parent" | |||
| app:layout_constraintTop_toTopOf="parent" | |||
| tools:text="标题标题标题标题标题标" /> | |||
| tools:text="标题标题标题标题标题标标题标题标题标题标题标标题标题标题标题标题标标题标题标题标题标题标标题标题标题标题标题标标题标题标题标题标题标" /> | |||
| <TextView | |||
| @@ -1,6 +1,6 @@ | |||
| <manifest xmlns:android="http://schemas.android.com/apk/res/android" | |||
| package="com.xkl.videoplayer" > | |||
| <uses-permission android:name="android.permission.WRITE_SETTINGS" /> | |||
| <!-- <uses-permission android:name="android.permission.WRITE_SETTINGS" />--> | |||
| <application | |||
| android:allowBackup="true" | |||
| android:label="@string/app_name" | |||