Browse Source

memo main

master
suliang 2 years ago
parent
commit
4ec3ba29be
36 changed files with 785 additions and 285 deletions
  1. 4
    2
      .idea/misc.xml
  2. 5
    0
      app/build.gradle
  3. BIN
      app/libs/mobile_cache.aar
  4. 6
    3
      app/src/main/AndroidManifest.xml
  5. 13
    6
      app/src/main/java/com/xkl/cdl/adapter/AdapterCoursePackWithLearCenter.kt
  6. 25
    31
      app/src/main/java/com/xkl/cdl/adapter/AdapterCoursePackWithMemo.kt
  7. 4
    4
      app/src/main/java/com/xkl/cdl/data/bean/MemoCoursePack.kt
  8. 0
    3
      app/src/main/java/com/xkl/cdl/data/bean/course/Course.kt
  9. 7
    1
      app/src/main/java/com/xkl/cdl/data/bean/course/CoursePack.kt
  10. 10
    0
      app/src/main/java/com/xkl/cdl/data/bean/intentdata/MemoData.kt
  11. 1
    1
      app/src/main/java/com/xkl/cdl/data/manager/CourseManager.kt
  12. 28
    15
      app/src/main/java/com/xkl/cdl/data/manager/db/DBCourseManager.kt
  13. 10
    9
      app/src/main/java/com/xkl/cdl/data/repository/DataRepository.kt
  14. 1
    1
      app/src/main/java/com/xkl/cdl/module/learn/LearnWordActivity.kt
  15. 87
    46
      app/src/main/java/com/xkl/cdl/module/m_center_learn/CoursePackMainActivity.kt
  16. 31
    1
      app/src/main/java/com/xkl/cdl/module/m_center_learn/CoursePackMainActivityViewModel.kt
  17. 8
    2
      app/src/main/java/com/xkl/cdl/module/m_center_learn/coursechildren/CourseMainFragment.kt
  18. 3
    0
      app/src/main/java/com/xkl/cdl/module/m_center_learn/coursechildren/CourseMainFragmentViewModel.kt
  19. 50
    55
      app/src/main/java/com/xkl/cdl/module/m_center_learn/coursechildren/CourseReviewFragment.kt
  20. 20
    5
      app/src/main/java/com/xkl/cdl/module/m_memo/MemoFragment.kt
  21. 54
    15
      app/src/main/java/com/xkl/cdl/module/m_memo/MemoFragmentViewModel.kt
  22. 53
    0
      app/src/main/java/com/xkl/cdl/module/m_memo/MemoListDetailActivity.kt
  23. 11
    0
      app/src/main/java/com/xkl/cdl/module/m_memo/MemoListDetailViewModel.kt
  24. 6
    0
      app/src/main/res/drawable/shape_red_badge.xml
  25. 8
    7
      app/src/main/res/layout/activity_course_main.xml
  26. 123
    0
      app/src/main/res/layout/activity_memo_list_detail.xml
  27. 3
    0
      app/src/main/res/layout/fragment_memo.xml
  28. 52
    0
      app/src/main/res/layout/include_main_learn_center_course_type_title.xml
  29. 122
    63
      app/src/main/res/layout/item_memo.xml
  30. 12
    1
      app/src/main/res/layout/main_item_coursepack.xml
  31. 2
    0
      app/src/main/res/values/strings.xml
  32. 3
    1
      build.gradle
  33. 7
    7
      lib/common/src/main/AndroidManifest.xml
  34. 12
    3
      lib/common/src/main/java/com/suliang/common/util/DrawableUti.kt
  35. 3
    2
      lib/common/src/main/res/layout/public_title_bar.xml
  36. 1
    1
      videoplayer/src/main/AndroidManifest.xml

+ 4
- 2
.idea/misc.xml View File

<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_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/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/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_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_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_gray2.xml" value="0.48055555555555557" />
<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_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_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_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/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/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_auto_play_select.xml" value="0.4979166666666667" />
<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.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/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_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_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/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_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_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_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_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_task_image.xml" value="0.23353596757852077" />
<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/item_video_adapter.xml" value="0.67" />

+ 5
- 0
app/build.gradle View File

// implementation 'androidx.legacy:legacy-support-v4:1.0.0' // implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation project(path: ':lib:common') implementation project(path: ':lib:common')
implementation project(path: ':videoplayer') 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-livedata-ktx:2.3.1'
// implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1' // implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1'
// implementation 'androidx.appcompat:appcompat:1.2.0' // implementation 'androidx.appcompat:appcompat:1.2.0'
implementation customDependencies.grpc_stub implementation customDependencies.grpc_stub
//XPopup //XPopup
implementation customDependencies.XPopup implementation customDependencies.XPopup
//精美日历 calendarview
implementation customDependencies.CalendarView


} }

BIN
app/libs/mobile_cache.aar View File


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

android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/Theme.XklLocal" android:theme="@style/Theme.XklLocal"
tools:ignore="LockedOrientationActivity"> tools:ignore="LockedOrientationActivity">
<activity
android:name=".module.m_memo.MemoListDetailActivity"
android:exported="true" />
<activity <activity
android:name=".module.learn.LearnCTaskActivity" android:name=".module.learn.LearnCTaskActivity"
android:exported="true" /> android:exported="true" />
android:exported="true" /> android:exported="true" />
<activity <activity
android:name=".module.learn.LearnCVideoActivity" android:name=".module.learn.LearnCVideoActivity"
android:exported="true"
android:theme="@style/Theme.videoTheme"
android:configChanges="orientation|keyboardHidden|screenSize|locale" android:configChanges="orientation|keyboardHidden|screenSize|locale"
android:exported="true"
android:screenOrientation="portrait" android:screenOrientation="portrait"
android:windowSoftInputMode="adjustPan|stateHidden"/>
android:theme="@style/Theme.videoTheme"
android:windowSoftInputMode="adjustPan|stateHidden" />
<activity <activity
android:name=".module.learn.LearnExamActivity" android:name=".module.learn.LearnExamActivity"
android:exported="true" /> android:exported="true" />

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

when(it.courseType){ when(it.courseType){
AppConstants.COURSE_TYPE_ENGLISH_DISCERN -> imageViewTypeDiscern.visibility = View.VISIBLE AppConstants.COURSE_TYPE_ENGLISH_DISCERN -> imageViewTypeDiscern.visibility = View.VISIBLE
AppConstants.COURSE_TYPE_ENGLISH_SPELL -> imageViewTypeSpell.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 -> { AppConstants.COURSE_TYPE_ENGLISH_SPOKEN -> {
imageViewTypeVoice.run{ imageViewTypeVoice.run{
visibility = View.VISIBLE visibility = View.VISIBLE
setImageResource(R.drawable.ic_course_spoken) setImageResource(R.drawable.ic_course_spoken)
} }
} }
AppConstants.COURSE_TYPE_ENGLISH_SOUNDMARK -> {
imageViewTypeVoice.run {
visibility = View.VISIBLE
setImageResource(R.drawable.ic_course_soundmark)
}
}
} }
} }
} }
binding.apply { binding.apply {
//进度 //进度
myRankingView.visibility = View.VISIBLE myRankingView.visibility = View.VISIBLE
//复习数量判断是否可见
if (coursePack.reviewNumber > 0 ){
tvReview.visibility = View.VISIBLE
}else{
tvReview.visibility = View.GONE
}
} }
} }



+ 25
- 31
app/src/main/java/com/xkl/cdl/adapter/AdapterCoursePackWithMemo.kt View File

import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.view.ViewTreeObserver import android.view.ViewTreeObserver
import android.widget.TextView
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import com.google.android.material.badge.BadgeDrawable import com.google.android.material.badge.BadgeDrawable
import com.google.android.material.badge.BadgeUtils import com.google.android.material.badge.BadgeUtils
import com.suliang.common.base.adapter.BaseAdapterViewHolder import com.suliang.common.base.adapter.BaseAdapterViewHolder
import com.suliang.common.base.adapter.BaseRVAdapterVM import com.suliang.common.base.adapter.BaseRVAdapterVM
import com.suliang.common.databinding.ItemEmptyBinding 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.R
import com.xkl.cdl.data.AppConstants import com.xkl.cdl.data.AppConstants
import com.xkl.cdl.data.bean.MemoCoursePack import com.xkl.cdl.data.bean.MemoCoursePack
class AdapterCoursePackWithMemo(viewModel : MemoFragmentViewModel) : class AdapterCoursePackWithMemo(viewModel : MemoFragmentViewModel) :
BaseRVAdapterVM<MemoCoursePack, MemoFragmentViewModel>(viewModel) { 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) { override fun onBindEmptyViewHolder(holder : BaseAdapterViewHolder) {
(holder.binding as ItemEmptyBinding).run { (holder.binding as ItemEmptyBinding).run {
//图标与角标文字 //图标与角标文字
item.coursePack.childrenCourses.forEachIndexed { index : Int, course : Course -> item.coursePack.childrenCourses.forEachIndexed { index : Int, course : Course ->
when (course.courseType) { 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 -> { else -> {
setImageIcon(imgCourseIcon1,course.courseType,item.coursePackChildrenReviewNumber[index].size)
setImageIcon(imgCourseIcon1,tvReviewNumber1,course.courseType,item.coursePackChildrenReview.getOrDefault(course.courseId,0))
imgCourseIcon2.visibility = View.INVISIBLE imgCourseIcon2.visibility = View.INVISIBLE
tvReviewNumber2.visibility = View.GONE
imgCourseIcon3.visibility = View.INVISIBLE imgCourseIcon3.visibility = View.INVISIBLE
tvReviewNumber3.visibility = View.GONE
imgCourseIcon1.visibility = View.VISIBLE imgCourseIcon1.visibility = View.VISIBLE
} }
} }
} }
root.click { onItemClick.invoke(holder.itemView,position,item) }
} }
} }
} }
* @param reviewNumber Int 复习数量 * @param reviewNumber Int 复习数量
*/ */
@SuppressLint("UnsafeOptInUsageError") @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") var color : Int = Color.parseColor("#00000000")
//取消角标
BadgeUtils.detachBadgeDrawable(badgeDrawable,imageView)
when (reviewNumber) { when (reviewNumber) {
//没有数据 //没有数据
0 -> { 0 -> {
//设置图标: 灰色,没有背景 //设置图标: 灰色,没有背景
imageView.setImageResource(getCourseIcon(courseType)) imageView.setImageResource(getCourseIcon(courseType))
imageView.imageTintList = ColorStateList.valueOf(Color.parseColor("#9A9EB3")) imageView.imageTintList = ColorStateList.valueOf(Color.parseColor("#9A9EB3"))
tvReviewNumber.visibility = View.GONE
} }
//有复习数据 //有复习数据
else -> { else -> {
//设置图标:原图颜色 //设置图标:原图颜色
imageView.setImageResource(getCourseIcon(courseType)) 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
} }
} }
} }

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

* Describe: 课程包备忘本实体 * Describe: 课程包备忘本实体
*/ */
class MemoCoursePack(val coursePack: CoursePack){ 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>()
} }

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

) { ) {


var courseLearnProgress : Double = 0.0 //课程学习进度 var courseLearnProgress : Double = 0.0 //课程学习进度
var courseReviewNumber : Int = 0 //课程复习数


} }

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

field = value field = value
notifyPropertyChanged(BR.learnProgress) notifyPropertyChanged(BR.learnProgress)
} }
//复习数量,主要为课程包下的第一个课程的复习数量,主要用于在作文学习中心,对复习数的显示
@get:Bindable
var reviewNumber : Int = 0
set(value){
field = value
notifyPropertyChanged(BR.reviewNumber)
}
override fun equals(other : Any?) : Boolean { override fun equals(other : Any?) : Boolean {
if (this === other) return true if (this === other) return true
if (javaClass != other?.javaClass) return false if (javaClass != other?.javaClass) return false

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

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>)

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

// TODO: 2022/6/2 时间需改为day 开发期间用于调式,故意设此值 // TODO: 2022/6/2 时间需改为day 开发期间用于调式,故意设此值
//间隔时间单位 //间隔时间单位
private val reviewIntervalUnit = "day"
private val reviewIntervalUnit = "hour"
//间隔单位时间 //间隔单位时间
private val reviewTime = IntArray(7){ private val reviewTime = IntArray(7){
when(it){ when(it){

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

lessonId = lesson.lessonId 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 { result.add(ExamBean().apply {
id = getLong(0) id = getLong(0)
word_id = getLong(1) word_id = getLong(1)
lessonId = getLong(9) 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()) { AppConstants.COURSE_TYPE_ENGLISH_SOUNDMARK -> while (moveToNext()) {
result.add(ExamBean().apply { result.add(ExamBean().apply {
id = getLong(0) id = getLong(0)
lessonId = getLong(12) 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 -> { AppConstants.COURSE_TYPE_ENGLISH_SPOKEN -> {
when (testType) { when (testType) {
AppConstants.TEST_TYPE_BEFORE_TOTAL, AppConstants.TEST_TYPE_AFTER_TOTAL -> { AppConstants.TEST_TYPE_BEFORE_TOTAL, AppConstants.TEST_TYPE_AFTER_TOTAL -> {

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

import com.google.protobuf.ProtocolStringList import com.google.protobuf.ProtocolStringList
import com.googlecode.protobuf.format.JsonFormat import com.googlecode.protobuf.format.JsonFormat
import com.suliang.common.extension.io2Io import com.suliang.common.extension.io2Io
import com.suliang.common.util.LogUtil
import com.suliang.common.util.file.FileUtil import com.suliang.common.util.file.FileUtil
import com.xkl.cdl.data.AppConstants import com.xkl.cdl.data.AppConstants
import com.xkl.cdl.data.bean.course.CourseDetail import com.xkl.cdl.data.bean.course.CourseDetail
} }
val courseDetail = CourseDetail().apply { val courseDetail = CourseDetail().apply {
courseLearnProgress = pbCourseDetail.s //课程学习进度 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=>条目数量 right = HashMap(pbCourseDetail.rightMap) //正确条目数,key=>{chapter_id}_{lesson_id} value=>条目数量
wrong = HashMap(pbCourseDetail.wrongMap) //错误条目数,key=>{chapter_id}_{lesson_id} value=>条目数量 wrong = HashMap(pbCourseDetail.wrongMap) //错误条目数,key=>{chapter_id}_{lesson_id} value=>条目数量
lesson_learn_point = HashMap( lesson_learn_point = HashMap(
} }
} }
} }
if (subjectId != 0L ){
//计算词汇量和学习效率
calcCourseVocabularyAndEfficiency(subjectId,coursePackId,courseId)
}
LogUtil.e("保存数据 -> \n ${JsonFormat.printToString(record.build())}")
try { try {
XKLApplication.mobileCache.parseData(record.build().toByteArray()) XKLApplication.mobileCache.parseData(record.build().toByteArray())
if (subjectId != 0L ){
//计算词汇量和学习效率
calcCourseVocabularyAndEfficiency(subjectId,coursePackId,courseId)
}
} catch (e : Exception) { } catch (e : Exception) {
e.printStackTrace() e.printStackTrace()
return false return false

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

* 自动播放完成弹窗 * 自动播放完成弹窗
*/ */
private fun showAutoPlayOverDialog() { 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), CommonDialog.newInstance(CommonDialogBean(titleText = R.string.quit_auto_play_title_over, rightText = R.string.sure),
drawable).apply { drawable).apply {
onCommonDialogButtonClickListener = { dialog, _ -> onCommonDialogButtonClickListener = { dialog, _ ->

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

import android.content.Intent import android.content.Intent
import android.graphics.Color import android.graphics.Color
import android.os.Bundle import android.os.Bundle
import android.text.Html
import android.text.method.ScrollingMovementMethod
import android.view.View import android.view.View
import android.widget.TextView
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.content.res.ResourcesCompat import androidx.core.content.res.ResourcesCompat
import androidx.databinding.DataBindingUtil import androidx.databinding.DataBindingUtil
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.viewpager2.widget.ViewPager2 import androidx.viewpager2.widget.ViewPager2
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog import com.google.android.material.bottomsheet.BottomSheetDialog
import com.suliang.common.AppConfig import com.suliang.common.AppConfig
import com.suliang.common.base.activity.BaseActivityVM import com.suliang.common.base.activity.BaseActivityVM
import com.suliang.common.extension.click import com.suliang.common.extension.click
import com.suliang.common.extension.setHtml
import com.suliang.common.util.os.ScreenUtil import com.suliang.common.util.os.ScreenUtil
import com.xkl.cdl.R import com.xkl.cdl.R
import com.xkl.cdl.adapter.AdapterAutoPlaySelectRepeat import com.xkl.cdl.adapter.AdapterAutoPlaySelectRepeat
import com.xkl.cdl.data.AppConstants import com.xkl.cdl.data.AppConstants
import com.xkl.cdl.data.DataTransferHolder import com.xkl.cdl.data.DataTransferHolder
import com.xkl.cdl.data.bean.LearnWord 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.Course
import com.xkl.cdl.data.bean.course.Lesson import com.xkl.cdl.data.bean.course.Lesson
import com.xkl.cdl.data.bean.intentdata.LearnData import com.xkl.cdl.data.bean.intentdata.LearnData
class CoursePackMainActivity : BaseActivityVM<ActivityCourseMainBinding, CoursePackMainActivityViewModel>() { class CoursePackMainActivity : BaseActivityVM<ActivityCourseMainBinding, CoursePackMainActivityViewModel>() {
companion object { companion object {
/** 学习中心跳转 */
@JvmStatic @JvmStatic
fun newInstance(context : Context, subjectId : Int, coursePackInPosition : Int) { fun newInstance(context : Context, subjectId : Int, coursePackInPosition : Int) {
context.startActivity(Intent(context, CoursePackMainActivity::class.java).apply { context.startActivity(Intent(context, CoursePackMainActivity::class.java).apply {
putExtra(AppConfig.INTENT_2, coursePackInPosition) 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 //子课程对应的Fragment
override fun initViewModel() : CoursePackMainActivityViewModel { override fun initViewModel() : CoursePackMainActivityViewModel {
val subjectId = intent.getIntExtra(AppConfig.INTENT_1, 0) val subjectId = intent.getIntExtra(AppConfig.INTENT_1, 0)
val coursePackInListPosition = intent.getIntExtra(AppConfig.INTENT_2, 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() { override fun initStatusBar() {
binding.tvIntroduction.click { binding.tvIntroduction.click {
showIntroductionDialog() showIntroductionDialog()
} }
//返回事件
binding.includeTitleBar.titleBar.run {
//标题栏
binding.titleBar.run {
textViewTitle.setText(if (vm.isMemoSource) R.string.course_detail else R.string.course_detail)
onBackClick = { _ -> finish() } 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 //初始化tab和viewPager
tabSpell.click { binding.viewPager2.currentItem = 1 } tabSpell.click { binding.viewPager2.currentItem = 1 }
tabVoice.click { binding.viewPager2.currentItem = 2 } tabVoice.click { binding.viewPager2.currentItem = 2 }
} }
}
override fun loadData() {
//监听进度,设置进度 进度为百分制,已经乘了100了 //监听进度,设置进度 进度为百分制,已经乘了100了
vm.currentCourseProgress.observe(this) { vm.currentCourseProgress.observe(this) {
binding.includeCourseProgress.apply { binding.includeCourseProgress.apply {
} }
} }
} }
//监听复习数量,只有备忘本进入才进行监听,用于修改复习数据标记
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() { 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() { private fun showMoreDialog() {
BottomSheetDialog(this, R.style.dialog_style).apply { 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()
} }
/** 课程重学弹窗提示 */ /** 课程重学弹窗提示 */
(childFragments[binding.viewPager2.currentItem] as CourseMainFragment).vm.let { (childFragments[binding.viewPager2.currentItem] as CourseMainFragment).vm.let {
it.queryWordAutoPlayWord().observe(this) { value -> it.queryWordAutoPlayWord().observe(this) { value ->
value?.let { data -> 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 { DataTransferHolder.instance.putData(value = LearnData(lesson).apply {
learnWordList = data learnWordList = data
* @param course Course * @param course Course
* @param reviewData MutableList<LearnWord> * @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 { DataTransferHolder.instance.putData(value = LearnData(lesson).apply {
learnWordList = reviewData learnWordList = reviewData
isReview = true isReview = true
} }
/** ViewModel Factory工厂 */ /** 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 { override fun <T : ViewModel?> create(modelClass : Class<T>) : T {
return CoursePackMainActivityViewModel(subjectId, coursePackInPosition) as T
return CoursePackMainActivityViewModel(subjectId, coursePackInPosition, isMemoSource) as T
} }
} }

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

import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import com.suliang.common.base.viewmodel.BaseViewModel import com.suliang.common.base.viewmodel.BaseViewModel
import com.xkl.cdl.data.AppConstants 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 import com.xkl.cdl.data.manager.CourseManager


/** /**
* create 2022/3/24 17:42 * create 2022/3/24 17:42
* Describe: 课程主页 * Describe: 课程主页
*/ */
class CoursePackMainActivityViewModel(subjectId: Int , coursePackInPosition : Int) : BaseViewModel() {
class CoursePackMainActivityViewModel(subjectId: Int , coursePackInPosition : Int,val isMemoSource:Boolean) : BaseViewModel() {
//操作的课程包 //操作的课程包
val coursePack = CourseManager.subjectWithCoursePackMap[subjectId]!![coursePackInPosition] 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>() val currentCourseProgress = MutableLiveData<Double>()
coursePack.learnProgress = coursePack.childrenCourses[0].courseLearnProgress 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 }
}
} }

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

override fun loadData() { override fun loadData() {
vm.loadMain().observe(this) { vm.loadMain().observe(this) {
//备忘本加载为复习界面,没有其他界面进行加载
if (vm.coursePackMainActivityVM.isMemoSource){
currentFragment = CourseReviewFragment.newInstance()
replaceFragment(R.id.layout_root,currentFragment)
return@observe
}
changeChildren() changeChildren()
} }
} }
private fun changeChildrenFragmentForWord() { private fun changeChildrenFragmentForWord() {
currentFragment = vm.courseDetail.let { currentFragment = vm.courseDetail.let {
when{ 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.st_before == AppConstants.NOT_DOING -> CourseTotalTestFragment.newInstance(AppConstants.TEST_TYPE_BEFORE_TOTAL) //学前总测未做
it.courseLearnProgress != AppConstants.DOING_OVER -> CourseLessonFragment.newInstance() //学习未完成 it.courseLearnProgress != AppConstants.DOING_OVER -> CourseLessonFragment.newInstance() //学习未完成
else -> CourseTotalTestFragment.newInstance(AppConstants.TEST_TYPE_AFTER_TOTAL) //学习完成,学后总测试界面 else -> CourseTotalTestFragment.newInstance(AppConstants.TEST_TYPE_AFTER_TOTAL) //学习完成,学后总测试界面
*/ */
private fun changeChildrenFragmentForComposition() { private fun changeChildrenFragmentForComposition() {
currentFragment = when { currentFragment = when {
vm.reviewDataList.size > 0 -> CourseReviewFragment.newInstanceFromLearningCenter() //复习
vm.reviewDataList.size > 0 -> CourseReviewFragment.newInstance() //复习
else -> CourseLessonFragment.newInstance() //目录 else -> CourseLessonFragment.newInstance() //目录
} }
replaceFragment(R.id.layout_root, currentFragment) replaceFragment(R.id.layout_root, currentFragment)

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

initReviewData(t2) initReviewData(t2)
true true
}).compose(diskIo2Main()).subscribe { }).compose(diskIo2Main()).subscribe {
//如果是备忘本,更新复习数量,避免进入时,数据进行了改变,此时用于修改角标
coursePackMainActivityVM.updateReviewNumber(course.courseType,reviewDataList.size)
mutableLiveData.value = it mutableLiveData.value = it
} }
return mutableLiveData return mutableLiveData

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

package com.xkl.cdl.module.m_center_learn.coursechildren package com.xkl.cdl.module.m_center_learn.coursechildren


import android.os.Bundle
import android.view.View import android.view.View
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import com.jeremyliao.liveeventbus.LiveEventBus import com.jeremyliao.liveeventbus.LiveEventBus
import com.suliang.common.AppConfig import com.suliang.common.AppConfig
import com.suliang.common.base.fragment.BaseFragmentVM import com.suliang.common.base.fragment.BaseFragmentVM
import com.suliang.common.extension.click import com.suliang.common.extension.click
import com.xkl.cdl.R
import com.xkl.cdl.data.AppConstants import com.xkl.cdl.data.AppConstants
import com.xkl.cdl.data.DataTransferHolder 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.event.LearnEventData
import com.xkl.cdl.data.repository.DataRepository import com.xkl.cdl.data.repository.DataRepository
import com.xkl.cdl.databinding.FragmentCourseReviewBinding 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_center_learn.CoursePackMainActivity
import com.xkl.cdl.module.m_memo.MemoListDetailActivity


/** /**
* 复习界面 * 复习界面
* 加载此界面,需要传参 从备忘本进入的主页加载此界面,还是从学习中心进入的主页加载此界面,其显示将不同
* 加载此界面,根据vm的isMemoSource结果,其显示将不同
*/ */
class CourseReviewFragment : BaseFragmentVM<FragmentCourseReviewBinding, CourseMainFragmentViewModel>() { class CourseReviewFragment : BaseFragmentVM<FragmentCourseReviewBinding, CourseMainFragmentViewModel>() {
companion object { companion object {
/** /**
* 新建实例 * 新建实例
* @param pageSource Int 页面来源,默认为0,从学习中心加载, 1为从备忘本加载
* @return CourseReviewFragment * @return CourseReviewFragment
*/ */
@JvmStatic @JvmStatic
fun newInstanceFromLearningCenter() : CourseReviewFragment {
fun newInstance() : CourseReviewFragment {
return 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() { 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() 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 { binding.tvStartReview.click {
if (vm.isAssignmentReviewData){ //已经赋值,直接赋值跳转 if (vm.isAssignmentReviewData){ //已经赋值,直接赋值跳转
(requireActivity() as CoursePackMainActivity).startReview(vm.course,vm.reviewDataList) (requireActivity() as CoursePackMainActivity).startReview(vm.course,vm.reviewDataList)
}else{ //没有赋值,需要进行
}else{ //没有赋值,需要进行查询
vm.queryReviewForDb().observe(this){ vm.queryReviewForDb().observe(this){
vm.isAssignmentReviewData = true vm.isAssignmentReviewData = true
if (it){ if (it){
(requireActivity() as CoursePackMainActivity).startReview(vm.course,vm.reviewDataList) (requireActivity() as CoursePackMainActivity).startReview(vm.course,vm.reviewDataList)
}else{ }else{
showToast("复习数据查询失败") showToast("复习数据查询失败")
//如果是学习中心跳转过来,直接进行状态页
if (pageSource == 0 ){
//如果是学习中心跳转过来,没有查询出复习数据,需要进行状态也切换
if (vm.coursePackMainActivityVM.isMemoSource ){
initMemoData()
}else{
(requireParentFragment() as CourseMainFragment).changeChildren() (requireParentFragment() as CourseMainFragment).changeChildren()
} }
} }
} }
//查看备忘本 //查看备忘本
binding.tvSeeMemo.click { binding.tvSeeMemo.click {
showToast("查看备忘本")
DataTransferHolder.instance.putData(value = MemoData(vm.course, vm.coursePackMainActivityVM.coursePackChildrenMemo[vm.course.courseId] ?: mutableListOf()))
startActivity(MemoListDetailActivity::class.java)
} }
} }
} }
private fun initMemoData() { 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 binding.tvReviewCount.visibility = View.GONE
} }
override fun loadData() { override fun loadData() {
//监听复习回调 : 此处复习回调,主要用于更新界面剩余数显示,或者是复习完成,进行数据切换
LiveEventBus.get<LearnEventData>(AppConstants.EVENT_REVIEW_DATA).observe(this){ LiveEventBus.get<LearnEventData>(AppConstants.EVENT_REVIEW_DATA).observe(this){
if (it.subjectId != vm.course.subjectId || it.courseId != vm.course.courseId) return@observe if (it.subjectId != vm.course.subjectId || it.courseId != vm.course.courseId) return@observe
when(it.actionFlag){ when(it.actionFlag){
if (it.leesonPositionIndex == vm.reviewDataList.size - 1){ if (it.leesonPositionIndex == vm.reviewDataList.size - 1){
//清空 //清空
vm.reviewDataList.clear() vm.reviewDataList.clear()
//切换界面
val pageSource = arguments?.getInt(AppConfig.INTENT_1) ?: 0
if ( pageSource == 0 ){
//非学习中心需要切换界面
if ( !vm.coursePackMainActivityVM.isMemoSource){
(requireParentFragment() as CourseMainFragment).changeChildren() (requireParentFragment() as CourseMainFragment).changeChildren()
}else{ // TODO: 2022/6/6 备忘本需隐藏复习按钮,修改文字
}else{
initMemoData() initMemoData()
binding.tvStartReview.visibility = View.GONE
} }
}else { // 复习未完成 todo 需要验证一下 sublist().clear() }else { // 复习未完成 todo 需要验证一下 sublist().clear()
vm.reviewDataList.subList(0, it.leesonPositionIndex + 1).clear() vm.reviewDataList.subList(0, it.leesonPositionIndex + 1).clear()
initReviewData() initReviewData()
} }
//更新复习数
vm.coursePackMainActivityVM.updateReviewNumber(vm.course.courseType,vm.reviewDataList.size)
} }
} }
} }

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

package com.xkl.cdl.module.m_memo package com.xkl.cdl.module.m_memo


import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.StaggeredGridLayoutManager import androidx.recyclerview.widget.StaggeredGridLayoutManager
import com.suliang.common.base.fragment.BaseFragmentVM import com.suliang.common.base.fragment.BaseFragmentVM
import com.xkl.cdl.data.bean.MemoCoursePack
import com.xkl.cdl.databinding.FragmentMemoBinding import com.xkl.cdl.databinding.FragmentMemoBinding
import com.xkl.cdl.module.m_center_learn.CoursePackMainActivity
import com.xkl.cdl.module.main.MainActivityViewModel import com.xkl.cdl.module.main.MainActivityViewModel


/** /**
override fun initFragment() { 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() { override fun loadData() {
/** 搜索内容变化监听 */ /** 搜索内容变化监听 */
vm.etSearchLiveData.observe(this){ 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)
} }
} }

+ 54
- 15
app/src/main/java/com/xkl/cdl/module/m_memo/MemoFragmentViewModel.kt View File



import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import appApi.AppApi import appApi.AppApi
import com.googlecode.protobuf.format.JsonFormat
import com.suliang.common.base.viewmodel.BaseViewModel import com.suliang.common.base.viewmodel.BaseViewModel
import com.suliang.common.extension.diskIo2DiskIo 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.adapter.AdapterCoursePackWithMemo
import com.xkl.cdl.data.AppConstants
import com.xkl.cdl.data.bean.MemoCoursePack 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.XKLApplication
import com.xkl.cdl.module.main.MainActivity
import com.xkl.cdl.module.main.MainActivityViewModel import com.xkl.cdl.module.main.MainActivityViewModel
import io.reactivex.rxjava3.core.Observable import io.reactivex.rxjava3.core.Observable
import java.util.*


/** /**
* author suliang * author suliang
* 查询课程的错误数据结果 * 查询课程的错误数据结果
*/ */
fun queryData() { fun queryData() {
Observable.create<ByteArray> {
Observable.fromCallable<Boolean> {
//参数: 科目 课程包id 课程id category 1 获取正确的,2获取错误的,3正确错误都获取 //参数: 科目 课程包id 课程id category 1 获取正确的,2获取错误的,3正确错误都获取
val wordList = XKLApplication.mobileCache.getWordList(0, 0, 0, 2) 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()
})
} }
} }

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

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() {
}
}

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

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>()
}

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

<?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>

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

app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="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_width="match_parent"
android:layout_height="@dimen/title_bar_height" android:layout_height="@dimen/title_bar_height"
layout="@layout/include_title_bar"
app:layout_constraintTop_toBottomOf="@+id/status_bar_view" app:layout_constraintTop_toBottomOf="@+id/status_bar_view"
bind:titleValue="@{@string/course_detail}" />

app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
/>
<View <View
android:id="@+id/view_placeholder_1" android:id="@+id/view_placeholder_1"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_marginTop="124dp" android:layout_marginTop="124dp"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="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 <com.google.android.material.imageview.ShapeableImageView
app:imageByteArray="@{coursePack.cover}" app:imageByteArray="@{coursePack.cover}"
app:layout_constraintBottom_toTopOf="@+id/view_placeholder_1" app:layout_constraintBottom_toTopOf="@+id/view_placeholder_1"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/include_title_bar"
app:layout_constraintTop_toBottomOf="@id/title_bar"
app:shapeAppearance="@style/roundedCornerStyle" app:shapeAppearance="@style/roundedCornerStyle"
tools:background="@color/theme_color" /> tools:background="@color/theme_color" />



+ 123
- 0
app/src/main/res/layout/activity_memo_list_detail.xml View File

<?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>

+ 3
- 0
app/src/main/res/layout/fragment_memo.xml View File

app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:paddingTop="10dp"
android:background="@color/white_1" android:background="@color/white_1"
android:overScrollMode="never" android:overScrollMode="never"
android:scrollbars="none" /> android:scrollbars="none" />

+ 52
- 0
app/src/main/res/layout/include_main_learn_center_course_type_title.xml View File

android:visibility="gone" android:visibility="gone"
tools:visibility="visible"/> 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 <ImageView
android:id="@+id/iv_arrow_1" android:id="@+id/iv_arrow_1"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
android:drawablePadding="4dp" android:drawablePadding="4dp"
android:visibility="gone" android:visibility="gone"
tools:visibility="visible"/> 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 <ImageView
android:id="@+id/iv_arrow_2" android:id="@+id/iv_arrow_2"
android:drawablePadding="4dp" android:drawablePadding="4dp"
android:visibility="gone" android:visibility="gone"
tools:visibility="visible"/> 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> </androidx.constraintlayout.widget.ConstraintLayout>
</layout> </layout>

+ 122
- 63
app/src/main/res/layout/item_memo.xml View File

<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns: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" 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>

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

xmlns:tools="http://schemas.android.com/tools"> xmlns:tools="http://schemas.android.com/tools">


<data> <data>

<variable <variable
name="coursePack" name="coursePack"
type="com.xkl.cdl.data.bean.course.CoursePack" /> type="com.xkl.cdl.data.bean.course.CoursePack" />
app:coursePackLearnProgressFormat="@{coursePack.learnProgress}"/> app:coursePackLearnProgressFormat="@{coursePack.learnProgress}"/>
</com.xkl.cdl.widget.MyRankingView> </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> </androidx.constraintlayout.widget.ConstraintLayout>



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

<string name="empty_nothing">没有任何内容</string> <string name="empty_nothing">没有任何内容</string>
<string name="empty_nothing_search">没有搜索到任何内容</string> <string name="empty_nothing_search">没有搜索到任何内容</string>
<string name="course_detail">课程详情</string> <string name="course_detail">课程详情</string>
<string name="course_memo_detail">备忘本课程详情</string>
<string name="introduction">简介</string> <string name="introduction">简介</string>
<string name="start_review">开始复习</string> <string name="start_review">开始复习</string>
<string name="please_select_the_operation_you_want_to_do">请选择你要进行的操作</string> <string name="please_select_the_operation_you_want_to_do">请选择你要进行的操作</string>
<string name="course_introduction">课程简介</string> <string name="course_introduction">课程简介</string>
<string name="start_see_memo">查看备忘本</string> <string name="start_see_memo">查看备忘本</string>
<string name="smart_reviewing">智能复习中</string> <string name="smart_reviewing">智能复习中</string>
<string name="search_hint_input_key_word">请输入搜索关键字…</string>


</resources> </resources>

+ 3
- 1
build.gradle View File

//BigImageViewPager //BigImageViewPager
// BigImageViewPager : "com.github.SherlockGougou:BigImageViewPager:androidx-7.0.0", // BigImageViewPager : "com.github.SherlockGougou:BigImageViewPager:androidx-7.0.0",
//XPopup https://github.com/li-xiaojun/XPopup //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"
] ]





+ 7
- 7
lib/common/src/main/AndroidManifest.xml View File

xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
package="com.suliang.common"> 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" />
<!-- &lt;!&ndash;网络权限&ndash;&gt;-->
<!-- <uses-permission android:name="android.permission.INTERNET"/>-->
<!-- <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>-->
<!-- &lt;!&ndash;本地外置存储权限&ndash;&gt;-->
<!-- <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连接,否则连接失败 <!--networkSecurityConfig,usesCleartextTraffic 二选一都可以9.0-P以上高版本的http连接,否则连接失败

+ 12
- 3
lib/common/src/main/java/com/suliang/common/util/DrawableUti.kt View File

fun byteArrayToBitmap(byteArray : ByteArray):Bitmap{ fun byteArrayToBitmap(byteArray : ByteArray):Bitmap{
return BitmapFactory.decodeByteArray(byteArray,0,byteArray.size) 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)!! val vectorDrawableCompat = VectorDrawableCompat.create(resource, svgId, null)!!
vectorDrawableCompat.setTint(ResourcesCompat.getColor(resource, changeColor, 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) return BitmapDrawable(resource,oldBitmap)
// val newBitmap = Bitmap.createScaledBitmap(oldBitmap,scale*oldBitmap.width,scale*oldBitmap.height,true) // val newBitmap = Bitmap.createScaledBitmap(oldBitmap,scale*oldBitmap.width,scale*oldBitmap.height,true)
} }

+ 3
- 2
lib/common/src/main/res/layout/public_title_bar.xml View File

android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="60dp" android:layout_marginStart="60dp"
android:layout_marginEnd="60dp" android:layout_marginEnd="60dp"
android:ellipsize="end"
android:ellipsize="middle"
android:singleLine="true"
android:gravity="center" android:gravity="center"
android:textColor="#323233" android:textColor="#323233"
android:textSize="18dp" android:textSize="18dp"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
tools:text="标题标题标题标题标题标" />
tools:text="标题标题标题标题标题标标题标题标题标题标题标标题标题标题标题标题标标题标题标题标题标题标标题标题标题标题标题标标题标题标题标题标题标" />




<TextView <TextView

+ 1
- 1
videoplayer/src/main/AndroidManifest.xml View File

<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.xkl.videoplayer" > package="com.xkl.videoplayer" >
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<!-- <uses-permission android:name="android.permission.WRITE_SETTINGS" />-->
<application <application
android:allowBackup="true" android:allowBackup="true"
android:label="@string/app_name" android:label="@string/app_name"

Loading…
Cancel
Save