Browse Source

我的功能完成

master
suliang 2 years ago
parent
commit
f415da6692
42 changed files with 1208 additions and 144 deletions
  1. 7
    2
      .idea/misc.xml
  2. 6
    0
      README.md
  3. 1
    0
      app/build.gradle
  4. 19
    0
      app/src/main/AndroidManifest.xml
  5. 33
    1
      app/src/main/java/com/xkl/cdl/data/manager/UserInfoManager.kt
  6. 4
    0
      app/src/main/java/com/xkl/cdl/data/repository/AudioCache.kt
  7. 11
    49
      app/src/main/java/com/xkl/cdl/data/repository/DataRepository.kt
  8. 1
    1
      app/src/main/java/com/xkl/cdl/data/repository/PhotoCache.kt
  9. 0
    1
      app/src/main/java/com/xkl/cdl/dialog/LearnDialog.kt
  10. 0
    7
      app/src/main/java/com/xkl/cdl/module/learn/LearnCVideoViewModel.kt
  11. 10
    0
      app/src/main/java/com/xkl/cdl/module/learn/LearnExamActivity.kt
  12. 1
    2
      app/src/main/java/com/xkl/cdl/module/learn/LearnExamViewModel.kt
  13. 6
    1
      app/src/main/java/com/xkl/cdl/module/m_center_learn/coursechildren/CourseLessonFragment.kt
  14. 1
    2
      app/src/main/java/com/xkl/cdl/module/m_memo/MemoFragment.kt
  15. 5
    0
      app/src/main/java/com/xkl/cdl/module/m_memo/MemoFragmentViewModel.kt
  16. 25
    0
      app/src/main/java/com/xkl/cdl/module/m_my/AboutUsActivity.kt
  17. 57
    0
      app/src/main/java/com/xkl/cdl/module/m_my/CacheClearActivity.kt
  18. 76
    0
      app/src/main/java/com/xkl/cdl/module/m_my/CacheClearViewModel.kt
  19. 158
    57
      app/src/main/java/com/xkl/cdl/module/m_my/MyFragment.kt
  20. 22
    0
      app/src/main/java/com/xkl/cdl/module/m_my/MyViewModel.kt
  21. 36
    0
      app/src/main/java/com/xkl/cdl/module/m_my/SettingActivity.kt
  22. 2
    7
      app/src/main/java/com/xkl/cdl/module/m_service_center/ServiceCenterFragment.kt
  23. 3
    3
      app/src/main/java/com/xkl/cdl/module/m_statics/StatisticsTimeTopFragmentViewModel.kt
  24. 14
    0
      app/src/main/java/com/xkl/cdl/module/main/MainActivity.kt
  25. 50
    0
      app/src/main/java/com/xkl/cdl/util/EasyPhotoEngine.kt
  26. 99
    0
      app/src/main/res/layout/activity_about_us.xml
  27. 152
    0
      app/src/main/res/layout/activity_cache_clear.xml
  28. 79
    0
      app/src/main/res/layout/activity_setting.xml
  29. 223
    8
      app/src/main/res/layout/fragment_my.xml
  30. 37
    0
      app/src/main/res/layout/item_my_setting.xml
  31. BIN
      app/src/main/res/mipmap-xxxhdpi/head_portrait_default.png
  32. BIN
      app/src/main/res/mipmap-xxxhdpi/logo_1.png
  33. BIN
      app/src/main/res/mipmap-xxxhdpi/my_bg_img.png
  34. 6
    0
      app/src/main/res/values/strings.xml
  35. 8
    0
      app/src/main/res/xml/file_paths_public.xml
  36. 20
    0
      app/svg/drawable/ic_about_we.xml
  37. 1
    1
      app/svg/drawable/ic_checked_1.xml
  38. 12
    0
      app/svg/drawable/ic_palette.xml
  39. 12
    0
      app/svg/drawable/ic_setting.xml
  40. 1
    1
      build.gradle
  41. 1
    1
      lib/common/build.gradle
  42. 9
    0
      lib/common/src/main/java/com/suliang/common/util/file/FileUtil.kt

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

<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/video_tab_bg.xml" value="0.26851851851851855" /> <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/video_tab_bg.xml" value="0.26851851851851855" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout-v23/include_main_learn_center_course_type_title.xml" value="0.4963768115942029" /> <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout-v23/include_main_learn_center_course_type_title.xml" value="0.4963768115942029" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/_xpopup_ext_time_picker.xml" value="0.23632218844984804" /> <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/_xpopup_ext_time_picker.xml" value="0.23632218844984804" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/activity_about_us.xml" value="0.2373353596757852" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/activity_cache_clear.xml" value="0.2373353596757852" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/activity_course_main.xml" value="0.33" /> <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/activity_course_main.xml" value="0.33" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/activity_course_statistics_detail.xml" value="0.33" /> <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/activity_course_statistics_detail.xml" value="0.33" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/activity_course_test.xml" value="0.31567028985507245" /> <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/activity_course_test.xml" value="0.31567028985507245" />
<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.3621621621621622" /> <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/activity_memo_list_detail.xml" value="0.3621621621621622" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/activity_memo_test.xml" value="0.25" /> <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/activity_memo_test.xml" value="0.25" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/activity_setting.xml" value="0.22847011144883486" />
<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/activity_subject_statistics.xml" value="0.23454913880445796" /> <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/activity_subject_statistics.xml" value="0.23454913880445796" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/activity_test_detail.xml" value="0.3348694316436252" /> <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/activity_test_detail.xml" value="0.3348694316436252" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/fragment_first.xml" value="0.4979166666666667" /> <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/fragment_first.xml" value="0.4979166666666667" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/fragment_learn_center.xml" value="0.25" /> <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/fragment_learn_center.xml" value="0.25" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/fragment_memo.xml" value="0.25" /> <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/fragment_memo.xml" value="0.25" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/fragment_my.xml" value="0.28229166666666666" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/fragment_my.xml" value="0.38450899031811897" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/fragment_statics.xml" value="0.33" /> <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/fragment_statics.xml" value="0.33" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/fragment_statistics_time_top.xml" value="0.10833333333333334" /> <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/fragment_statistics_time_top.xml" value="0.10833333333333334" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/inc_control_button.xml" value="0.46467391304347827" /> <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/inc_control_button.xml" value="0.46467391304347827" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/item_memo_detail_list_for_literacy.xml" value="0.67" /> <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/item_memo_detail_list_for_literacy.xml" value="0.67" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/item_memo_detail_list_literacy.xml" value="0.5" /> <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/item_memo_detail_list_literacy.xml" value="0.5" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/item_memo_detail_list_pinyin.xml" value="0.67" /> <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/item_memo_detail_list_pinyin.xml" value="0.67" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/item_my_setting.xml" value="0.24094202898550723" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/item_service_center_item.xml" value="0.6604774535809018" /> <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/item_service_center_item.xml" value="0.6604774535809018" />
<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_statics_for_time.xml" value="0.27717391304347827" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/item_statics_for_time.xml" value="0.5" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/item_statistics_bottom_course_change.xml" value="0.30842391304347827" /> <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/item_statistics_bottom_course_change.xml" value="0.30842391304347827" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/item_statistics_course.xml" value="0.33" /> <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/item_statistics_course.xml" value="0.33" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/item_statistics_course_chapter_info.xml" value="0.5" /> <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/item_statistics_course_chapter_info.xml" value="0.5" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/textview_only.xml" value="0.49773550724637683" /> <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/textview_only.xml" value="0.49773550724637683" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/statedrawable/drawable/ic_nav_learn_center.xml" value="0.44166666666666665" /> <entry key="..\:/Work/XKL/XKL/XklLocal/app/statedrawable/drawable/ic_nav_learn_center.xml" value="0.44166666666666665" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/svg/drawable/ic_arrow_right.xml" value="0.29814814814814816" /> <entry key="..\:/Work/XKL/XKL/XklLocal/app/svg/drawable/ic_arrow_right.xml" value="0.29814814814814816" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/svg/drawable/ic_checked_1.xml" value="0.49538461538461537" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/svg/drawable/ic_course_composition.xml" value="0.30092592592592593" /> <entry key="..\:/Work/XKL/XKL/XklLocal/app/svg/drawable/ic_course_composition.xml" value="0.30092592592592593" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/svg/drawable/ic_course_discern.xml" value="0.30092592592592593" /> <entry key="..\:/Work/XKL/XKL/XklLocal/app/svg/drawable/ic_course_discern.xml" value="0.30092592592592593" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/svg/drawable/ic_course_literacy.xml" value="0.2972222222222222" /> <entry key="..\:/Work/XKL/XKL/XklLocal/app/svg/drawable/ic_course_literacy.xml" value="0.2972222222222222" />

+ 6
- 0
README.md View File



Android Studio 配置:
Arctic Fox 2020.3.1
classpath "com.android.tools.build:gradle:7.0.1"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.20"
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip

gradle 版本管理 gradle 版本管理
ext.android : app版本信息 ext.android : app版本信息
ext.version : 依赖包版本信息 ext.version : 依赖包版本信息

+ 1
- 0
app/build.gradle View File

// } // }
// implementation "me.zhanghai.android.materialratingbar:library:1.4.0" // implementation "me.zhanghai.android.materialratingbar:library:1.4.0"
implementation 'com.xl.ratingbar:ratingbar:0.1.1' implementation 'com.xl.ratingbar:ratingbar:0.1.1'
implementation 'com.github.HuanTanSheng:EasyPhotos:3.1.5'


} }

+ 19
- 0
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_my.CacheClearActivity"
android:exported="true" />
<activity
android:name=".module.m_my.SettingActivity"
android:exported="true" />
<activity
android:name=".module.m_my.AboutUsActivity"
android:exported="true" />
<activity <activity
android:name=".module.m_service_center.DictionaryActivity" android:name=".module.m_service_center.DictionaryActivity"
android:exported="true" /> android:exported="true" />
android:screenOrientation="portrait" android:screenOrientation="portrait"
android:windowSoftInputMode="adjustPan|adjustResize|stateHidden" /> android:windowSoftInputMode="adjustPan|adjustResize|stateHidden" />
<activity android:name=".module.m_service_center.CourseTestActivity" /> <activity android:name=".module.m_service_center.CourseTestActivity" />

<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.xkl.cdl.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths_public" />
</provider>
</application> </application>


</manifest> </manifest>

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

package com.xkl.cdl.data.manager package com.xkl.cdl.data.manager


import com.suliang.common.util.SpUtils import com.suliang.common.util.SpUtils
import com.suliang.common.util.file.FileUtil
import com.suliang.common.util.thread.AppExecutors
import com.xkl.cdl.data.AppConstants import com.xkl.cdl.data.AppConstants
import java.io.File


/** /**
* author suliang * author suliang
fun putDefaultSoundWay(soundWay : Int){ fun putDefaultSoundWay(soundWay : Int){
SpUtils.instance.encode("defaultSoundWay",soundWay) SpUtils.instance.encode("defaultSoundWay",soundWay)
} }

/** 存放用户头像 */
fun putUserHeadPortrait(readFile : File){
AppExecutors.io.run {
val file = File(FileUtil.getSaveDirFile("user"),"head")
FileUtil.copyFile(readFile,file,false)
SpUtils.instance.encode("head_portrait",file.path)
}
}
/** 获取用户头像 */
fun getUserHeadPortrait(): File? {
return SpUtils.instance.decode("head_portrait",String::class.java,"").let {
if (it.isEmpty()){
return null
}else
File(it);
}
}
/** 获取昵称 */
fun getNickname() : String {
return SpUtils.instance.decode("nickname",String::class.java,"")
}
/** 存储昵称 */
fun putNickname(nickname:String) {
SpUtils.instance.encode("nickname",nickname)
}
} }

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

return audioLiveData return audioLiveData
} }
fun clear(){
lruCache.evictAll()
}
/** /**
* 获取对应音频 * 获取对应音频
* 1缓存 2文件 3数据库 * 1缓存 2文件 3数据库

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

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.LogUtil
import com.suliang.common.util.file.FileUtil
import com.suliang.common.util.thread.AppExecutors
import com.xkl.cdl.data.AppConstants import com.xkl.cdl.data.AppConstants
import com.xkl.cdl.data.bean.course.CourseDetail import com.xkl.cdl.data.bean.course.CourseDetail
import com.xkl.cdl.data.bean.course.Lesson import com.xkl.cdl.data.bean.course.Lesson
import com.xkl.cdl.data.manager.db.DBCourseManager import com.xkl.cdl.data.manager.db.DBCourseManager
import com.xkl.cdl.data.manager.db.DbControlBase import com.xkl.cdl.data.manager.db.DbControlBase
import com.xkl.cdl.module.XKLApplication import com.xkl.cdl.module.XKLApplication
import io.reactivex.rxjava3.annotations.NonNull
import io.reactivex.rxjava3.core.Observable import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.schedulers.Schedulers
import mqComsumerV1.Struct import mqComsumerV1.Struct
import java.io.File
import java.io.FileOutputStream
import kotlin.math.sign


/** /**
* author suliang * author suliang
*/ */
object DataRepository { object DataRepository {
// TODO: 2022/6/1 需自己实现获取课程收藏数据,同时需自己处理保存数据
// TODO: 2022/6/1 需自己实现获取课程收藏数据,同时需自己处理保存数据, 主要用于保存口语的收藏数据,现在没有集成口语,暂时不管
/** 获取课程的收藏本 */ /** 获取课程的收藏本 */
fun getCourseCollect() : Observable<HashMap<String, Long>> { fun getCourseCollect() : Observable<HashMap<String, Long>> {
return Observable.create { return Observable.create {
AppDatabase.instance.examMiddleDao().insert(AppDatabase.instance,examWithDetail) AppDatabase.instance.examMiddleDao().insert(AppDatabase.instance,examWithDetail)
} }
if (subjectId != 0L) {
if (subjectId != 0L && record.entityCount > 0) {
//计算词汇量和学习效率 //计算词汇量和学习效率
calcCourseVocabularyAndEfficiency(subjectId, coursePackId, courseId) calcCourseVocabularyAndEfficiency(subjectId, coursePackId, courseId)
} }
e.printStackTrace() e.printStackTrace()
return false return false
} }
/*var fileName = ""
//写入文件
if (record.examCount > 0 ){ //当前为测试
val s = when (record.getExam(0).type.toInt()) { //测试类型
AppConstants.TEST_TYPE_BEFORE_TOTAL -> "学前总测试"
AppConstants.TEST_TYPE_BEFORE -> "章节学前测试"
AppConstants.TEST_TYPE_AFTER -> "章节学后测试"
AppConstants.TEST_TYPE_AFTER_TOTAL -> "学后总测试"
AppConstants.TEST_TYPE_COMPOSITION -> "作文知识点测试"
else -> ""
}
fileName = "${record.getExam(0).projectId}_${record.getExam(0).packId}_${record.getExam(0).courseId}_${record.getExam(0).chapterId}_${record.getExam(0).lessonId}_$s"
}else if (record.entityCount > 0 ){ //没有测试,则为学习
fileName = "${record.getEntity(0).projectId}_${record.getEntity(0).packId}_${record.getEntity(0).courseId}_${record.getEntity(0).chapterId}_${record.getEntity(0).lessonId}_课时学习"
}else if (record.scheduleCount > 0 ) { //进度更新
fileName = "${record.getSchedule(0).projectId}_${record.getSchedule(0).packId}_${record.getSchedule(0).courseId}_进度更新"
}else { // 时长更新
fileName = "${record.getDuration(0).projectId}_${record.getDuration(0).packId}_${record.getDuration(0).courseId}_时长更新"
}
FileUtil.getSaveDirFile("saveData").let {
if (!it.exists()){
it.mkdirs()
}
//序列化输出
val string = JsonFormat.printToString(record.build())
val saveArray = record.build().toByteArray()

val saveStringName = "${fileName}_jsonString.txt"
FileUtil.writeBytesToFile(it,saveStringName,string.toByteArray())

val saveByteArrayName = "${fileName}_byteArray.txt"
FileUtil.writeBytesToFile(it,saveByteArrayName,saveArray)
}*/
return true return true
} }
// TODO: 2022/6/1 计算词汇量和效率可以在需要的时候进行计算后再获取
/** /**
* 计算当前词汇量 与 学习效率 * 计算当前词汇量 与 学习效率
*/ */
} }
} }
/**设置课程已学数*/
fun setLearnedCourseID(subjectId : Long, coursePackId : Long, courseId : Long) {
Observable.fromCallable{
XKLApplication.mobileCache.setLearnedCourseID(subjectId,coursePackId,courseId)
}.subscribeOn(Schedulers.from(AppExecutors.io))
.subscribe()
}
} }

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

} }
/** /**
* 获取对应图片 * 获取对应图片
* 1缓存 2文件 3数据库
* 1缓存 2数据库
* @return String 文件路径 * @return String 文件路径
*/ */
fun get(dbControlBase : DbControlBase, wordId : Long) { fun get(dbControlBase : DbControlBase, wordId : Long) {

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

tvLeft.text = "再测一次" tvLeft.text = "再测一次"
tvRight.text = "下一课时" tvRight.text = "下一课时"
// TODO: 2022/4/21 小游戏练习先搁置
// tvTop1.visibility = View.VISIBLE // tvTop1.visibility = View.VISIBLE
// tvTop.text = "小游戏练习" // tvTop.text = "小游戏练习"
} }

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

package com.xkl.cdl.module.learn package com.xkl.cdl.module.learn


import android.provider.SyncStateContract
import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import appApi.AppApi
import com.jeremyliao.liveeventbus.LiveEventBus import com.jeremyliao.liveeventbus.LiveEventBus
import com.suliang.common.extension.diskIo2Main import com.suliang.common.extension.diskIo2Main
import com.suliang.common.util.DateUtil import com.suliang.common.util.DateUtil
import com.suliang.common.util.LogUtil import com.suliang.common.util.LogUtil
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.VideoBean import com.xkl.cdl.data.bean.VideoBean
import com.xkl.cdl.data.bean.course.Lesson import com.xkl.cdl.data.bean.course.Lesson
import com.xkl.cdl.data.event.LearnEventData import com.xkl.cdl.data.event.LearnEventData
import com.xkl.cdl.data.manager.UserInfoManager
import com.xkl.cdl.data.manager.db.DBCourseManager import com.xkl.cdl.data.manager.db.DBCourseManager
import com.xkl.cdl.data.manager.db.DbControlBase import com.xkl.cdl.data.manager.db.DbControlBase
import com.xkl.cdl.data.repository.DataRepository import com.xkl.cdl.data.repository.DataRepository
import com.xkl.cdl.module.XKLApplication import com.xkl.cdl.module.XKLApplication
import com.xkl.videoplayer.bean.PineMediaPlayerBean import com.xkl.videoplayer.bean.PineMediaPlayerBean
import io.reactivex.rxjava3.core.Observable import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.functions.BiFunction
import mqComsumerV1.Struct import mqComsumerV1.Struct
import java.util.* import java.util.*
import kotlin.Comparator
import kotlin.collections.ArrayList




class LearnCVideoViewModel : LearnBaseViewModel() { class LearnCVideoViewModel : LearnBaseViewModel() {

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

import com.xkl.cdl.data.manager.CourseManager import com.xkl.cdl.data.manager.CourseManager
import com.xkl.cdl.data.manager.UserInfoManager import com.xkl.cdl.data.manager.UserInfoManager
import com.xkl.cdl.data.repository.AudioCache import com.xkl.cdl.data.repository.AudioCache
import com.xkl.cdl.data.repository.DataRepository
import com.xkl.cdl.databinding.* import com.xkl.cdl.databinding.*
import com.xkl.cdl.dialog.CommonDialog import com.xkl.cdl.dialog.CommonDialog
import com.xkl.cdl.dialog.CommonDialogBean import com.xkl.cdl.dialog.CommonDialogBean
import com.xkl.cdl.dialog.LearnDialog import com.xkl.cdl.dialog.LearnDialog
import com.xkl.cdl.dialog.VocabularyDialog import com.xkl.cdl.dialog.VocabularyDialog
import com.xkl.cdl.module.XKLApplication
import com.xkl.cdl.module.m_service_center.TestDetailActivity import com.xkl.cdl.module.m_service_center.TestDetailActivity


/** /**
} }
} }
}.show(supportFragmentManager, javaClass.name) }.show(supportFragmentManager, javaClass.name)
//如果是学前总测试完成,则标记本课程为已学课程
if (vm.intentData.examType == AppConstants.TEST_TYPE_BEFORE_TOTAL){
vm.intentData.let {
DataRepository.setLearnedCourseID(it.subjectId.toLong(), it.coursePackId, it.courseId)
}
}
} }
} }

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

ext = "{\"courseType\": ${intentData.courseType} }" ext = "{\"courseType\": ${intentData.courseType} }"
//词汇量测试: 覆盖率、阶段 //词汇量测试: 覆盖率、阶段
if (examType == AppConstants.TEST_TYPE_NORMAL) { if (examType == AppConstants.TEST_TYPE_NORMAL) {
// TODO: 2022/4/14 设置词汇量测试的范围题目和覆盖率
stage = "小学"
stage = intentData.vocabularyItem?.level ?:""
coverRate = vocabularyCoverange.toFloat() coverRate = vocabularyCoverange.toFloat()
} }
//添加测试题 词汇量测试不添加测试题 //添加测试题 词汇量测试不添加测试题

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

import com.xkl.cdl.data.bean.intentdata.ExamData import com.xkl.cdl.data.bean.intentdata.ExamData
import com.xkl.cdl.data.event.LearnEventData import com.xkl.cdl.data.event.LearnEventData
import com.xkl.cdl.data.manager.CourseManager import com.xkl.cdl.data.manager.CourseManager
import com.xkl.cdl.data.repository.DataRepository
import com.xkl.cdl.databinding.FragmentCourseLessonBinding import com.xkl.cdl.databinding.FragmentCourseLessonBinding
import com.xkl.cdl.dialog.CommonDialog import com.xkl.cdl.dialog.CommonDialog
import com.xkl.cdl.dialog.CommonDialogBean import com.xkl.cdl.dialog.CommonDialogBean
if (learnEventData.isOnlyUpdatePoint){ if (learnEventData.isOnlyUpdatePoint){
return@observe return@observe
} }
DataRepository.setLearnedCourseID(it.subjectId.toLong(),it.coursePackId,it.courseId)
} }
//知识点 //知识点
AppConstants.LESSON_TYPE_COMPOSITION_KNOWLEDGE -> vm.courseDetail.run { AppConstants.LESSON_TYPE_COMPOSITION_KNOWLEDGE -> vm.courseDetail.run {
right[key] = it.correctNumber.toLong() //更新正确数 right[key] = it.correctNumber.toLong() //更新正确数
lesson_learn_point[key] = it.wordIds[it.learnedIndex] //更新课时学习点 lesson_learn_point[key] = it.wordIds[it.learnedIndex] //更新课时学习点
course_learn_point = "${key}_${it.wordIds[it.learnedIndex]}" //更新课程学习点 course_learn_point = "${key}_${it.wordIds[it.learnedIndex]}" //更新课程学习点
DataRepository.setLearnedCourseID(it.subjectId.toLong(),it.coursePackId,it.courseId)
} }
//测试 //测试
AppConstants.LESSON_TYPE_COMPOSITION_EXAM -> vm.courseDetail.run { AppConstants.LESSON_TYPE_COMPOSITION_EXAM -> vm.courseDetail.run {
if (learnEventData.isOnlyUpdatePoint) { if (learnEventData.isOnlyUpdatePoint) {
return@observe return@observe
} }
DataRepository.setLearnedCourseID(it.subjectId.toLong(),it.coursePackId,it.courseId)
} }
//课堂练习 //课堂练习
AppConstants.LESSON_TYPE_COMPOSITION_READING -> vm.courseDetail.run { AppConstants.LESSON_TYPE_COMPOSITION_READING -> vm.courseDetail.run {
if (learnEventData.isOnlyUpdatePoint){ if (learnEventData.isOnlyUpdatePoint){
return@observe return@observe
} }
DataRepository.setLearnedCourseID(it.subjectId.toLong(),it.coursePackId,it.courseId)
} }
//课外练习 不操作,不计算 //课外练习 不操作,不计算
AppConstants.LESSON_TYPE_COMPOSITION_TASK -> { } AppConstants.LESSON_TYPE_COMPOSITION_TASK -> { }
dialog.dismissAllowingStateLoss() dialog.dismissAllowingStateLoss()
when (action) { when (action) {
AppConstants.DIALOG_START_LEARN -> { //跳过测试 继续学习 AppConstants.DIALOG_START_LEARN -> { //跳过测试 继续学习
// TODO: 2022/4/21 进入学习界面 ,不能跳过测试,必须学习
// 进入学习界面 ,不能跳过测试,必须学习
} }
// 开始测试 // 开始测试
AppConstants.DIALOG_START_TEST -> startLessonTest(lesson, AppConstants.TEST_TYPE_BEFORE, it) AppConstants.DIALOG_START_TEST -> startLessonTest(lesson, AppConstants.TEST_TYPE_BEFORE, it)

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

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

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

} }
} }
memoCoursePackList.clear() memoCoursePackList.clear()
//排序,根据课程id固定排序
resultMemoCoursePack.sortBy {
it.coursePack.coursePackId
}
memoCoursePackList.addAll(resultMemoCoursePack) memoCoursePackList.addAll(resultMemoCoursePack)
return@fromCallable true return@fromCallable true
}.compose(diskIo2Main()).subscribe({ }.compose(diskIo2Main()).subscribe({

+ 25
- 0
app/src/main/java/com/xkl/cdl/module/m_my/AboutUsActivity.kt View File

package com.xkl.cdl.module.m_my

import android.content.Intent
import android.net.Uri
import android.os.Bundle
import com.suliang.common.base.activity.BaseActivity
import com.suliang.common.extension.click
import com.xkl.cdl.databinding.ActivityAboutUsBinding

class AboutUsActivity : BaseActivity<ActivityAboutUsBinding>() {
override fun initActivity(savedInstanceState : Bundle?) {
binding.titleBar.onBackClick = { finish() }
binding.tvWebsite.click {
val uri = Uri.parse(binding.tvWebsite.text.toString())
startActivity(Intent(Intent.ACTION_VIEW,uri))
}
}
override fun loadData() {
}
}

+ 57
- 0
app/src/main/java/com/xkl/cdl/module/m_my/CacheClearActivity.kt View File

package com.xkl.cdl.module.m_my

import android.annotation.SuppressLint
import android.os.Bundle
import androidx.lifecycle.ViewModelProvider
import com.suliang.common.base.activity.BaseActivityVM
import com.suliang.common.extension.click
import com.xkl.cdl.databinding.ActivityCacheClearBinding

class CacheClearActivity : BaseActivityVM<ActivityCacheClearBinding,CacheClearViewModel>() {
@SuppressLint("SetTextI18n")
override fun initActivity(savedInstanceState : Bundle?) {
binding.titleBar.onBackClick = {finish()}
binding.rbAudioCache.setOnCheckedChangeListener { _, isChecked ->
vm.audioChecked = isChecked
binding.tvClear.isEnabled = vm.audioChecked || vm.photoChecked
}
binding.rbPhotoCache.setOnCheckedChangeListener { _, isChecked ->
vm.photoChecked = isChecked
binding.tvClear.isEnabled = vm.audioChecked || vm.photoChecked
}
binding.tvClear.click {
vm.clearCache()
}
binding.llAudio.click {
binding.rbAudioCache.isChecked = !vm.audioChecked
}
binding.llPhoto.click {
binding.rbPhotoCache.isChecked = !vm.photoChecked
}
vm.cacheChangeLiveData.observe(this){
binding.tvTotalCache.text = vm.getFormatSize(vm.totalCache)
binding.rbAudioCache.text = "本地音频文件(${vm.getFormatSize(vm.audioCache)})"
binding.rbPhotoCache.text = "本地图片文件(${vm.getFormatSize(vm.photoCache)})"
if (vm.photoCache == 0L){
binding.rbAudioCache.isChecked = false
}
if (vm.photoCache == 0L){
binding.rbPhotoCache.isChecked = false
}
}
}
override fun loadData() {
vm.getTotalCache()
}
override fun initViewModel() : CacheClearViewModel {
return ViewModelProvider(this)[CacheClearViewModel::class.java]
}
}

+ 76
- 0
app/src/main/java/com/xkl/cdl/module/m_my/CacheClearViewModel.kt View File

package com.xkl.cdl.module.m_my

import androidx.lifecycle.MutableLiveData
import com.suliang.common.base.viewmodel.BaseViewModel
import com.suliang.common.util.file.FileUtil
import com.suliang.common.util.thread.AppExecutors
import com.xkl.cdl.data.manager.FilePathManager
import com.xkl.cdl.data.repository.AudioCache
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.schedulers.Schedulers
import java.io.File

class CacheClearViewModel : BaseViewModel() {
var totalCache : Long = 0
var audioCache : Long = 0
var photoCache : Long = 0
val cacheChangeLiveData = MutableLiveData<Boolean>()
//选中状态
var audioChecked : Boolean = false
var photoChecked : Boolean = false
fun getTotalCache() {
Observable.fromCallable {
totalCache = getAudioCache1() + getPhotoCache1()
cacheChangeLiveData.postValue(true)
}.subscribeOn(Schedulers.from(AppExecutors.io)).subscribe()
}
private fun getAudioCache1() : Long {
audioCache = getCache(FilePathManager.getVoiceParent())
return audioCache
}
private fun getPhotoCache1() : Long {
photoCache = getCache(FileUtil.getSaveDirFile("glide"))
return photoCache
}
fun clearCache() {
if (totalCache == 0L){
cacheChangeLiveData.postValue(true)
return
}
Observable.fromCallable {
if (audioChecked && photoChecked) {
FileUtil.deleteFile(FilePathManager.getVoiceParent())
AudioCache.clear()
FileUtil.deleteFile(FileUtil.getSaveDirFile("glide"))
totalCache = 0
}else if (photoChecked){
FileUtil.deleteFile(FileUtil.getSaveDirFile("glide"))
totalCache = audioCache
photoCache = 0
}else if(audioChecked){
FileUtil.deleteFile(FilePathManager.getVoiceParent())
AudioCache.clear()
totalCache = photoCache
audioCache = 0
}
cacheChangeLiveData.postValue(true)
}.subscribeOn(Schedulers.from(AppExecutors.io)).subscribe()
}
private fun getCache(file : File) : Long {
return FileUtil.getFileSize(file)
}
fun getFormatSize(size : Long) : String {
return FileUtil.sizeFormat(size)
}
}

+ 158
- 57
app/src/main/java/com/xkl/cdl/module/m_my/MyFragment.kt View File

package com.xkl.cdl.module.m_my package com.xkl.cdl.module.m_my


import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.TextView
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import com.suliang.common.base.activity.BaseActivityVM
import androidx.recyclerview.widget.LinearLayoutManager
import com.huantansheng.easyphotos.EasyPhotos
import com.huantansheng.easyphotos.callback.SelectCallback
import com.huantansheng.easyphotos.models.album.entity.Photo
import com.lxj.xpopup.XPopup
import com.suliang.common.base.adapter.BaseAdapterViewHolder
import com.suliang.common.base.adapter.BaseRVAdapter
import com.suliang.common.base.fragment.BaseFragmentVM import com.suliang.common.base.fragment.BaseFragmentVM
import com.suliang.common.extension.click
import com.suliang.common.util.LogUtil
import com.suliang.common.util.SpUtils
import com.suliang.common.util.image.ImageLoader
import com.suliang.common.util.image.ImageLoaderOption
import com.xkl.cdl.R import com.xkl.cdl.R
import com.xkl.cdl.data.bean.TimeStatisticItem
import com.xkl.cdl.data.manager.UserInfoManager
import com.xkl.cdl.databinding.FragmentMyBinding import com.xkl.cdl.databinding.FragmentMyBinding
import com.xkl.cdl.module.main.MainActivityViewModel
import com.xkl.cdl.databinding.ItemMySettingBinding
import com.xkl.cdl.module.main.MainActivity
import com.xkl.cdl.util.EasyPhotoEngine
import java.io.File
import java.util.ArrayList


// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private const val ARG_PARAM1 = "param1"
private const val ARG_PARAM2 = "param2"

/**
* A simple [Fragment] subclass.
* Use the [MyFragment.newInstance] factory method to
* create an instance of this fragment.
*/
class MyFragment : BaseFragmentVM<FragmentMyBinding,MainActivityViewModel>() {
// TODO: Rename and change types of parameters
private var param1: String? = null
private var param2: String? = null

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
param1 = it.getString(ARG_PARAM1)
param2 = it.getString(ARG_PARAM2)
}
}

override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_my, container, false)
}


class MyFragment : BaseFragmentVM<FragmentMyBinding, MyViewModel>() {
companion object { companion object {
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* @param param1 Parameter 1.
* @param param2 Parameter 2.
* @return A new instance of fragment MyFragment.
*/
// TODO: Rename and change types and number of parameters
@JvmStatic @JvmStatic
fun newInstance() = MyFragment() fun newInstance() = MyFragment()
// .apply {
// arguments = Bundle().apply {
// putString(ARG_PARAM1, param1)
// putString(ARG_PARAM2, param2)
// }
// }
} }

private val rvData = mutableListOf<MyFragment.Item>(
// Item("个性化", R.drawable.ic_palette,0),
Item("设置", R.drawable.ic_setting,1),
Item("关于我们", R.drawable.ic_about_we,2))
override fun initViewModel() : MyViewModel {
return ViewModelProvider(this)[MyViewModel::class.java]
}
override fun initFragment() { override fun initFragment() {

//加载头像
UserInfoManager.getUserHeadPortrait()?.let {
ImageLoader.loadImage(ImageLoaderOption().apply {
targetView = binding.headPortrait
placeholderResId = R.mipmap.img_default
errorResId = R.mipmap.img_default
file = it
})
}
//图片选择
binding.headPortrait.click {
EasyPhotos.createAlbum(this, true, false, EasyPhotoEngine.instance)
.setFileProviderAuthority("com.xkl.cdl.fileprovider")
.setCount(1)
.start(object : SelectCallback() {
override fun onResult(photos : ArrayList<Photo>?, isOriginal : Boolean) {
photos?.let {
if (it.size > 0) {
UserInfoManager.putUserHeadPortrait(File(it[0].path))
ImageLoader.loadImage(binding.headPortrait, it[0].uri)
}
}
}
override fun onCancel() {
}
})
}
//昵称
UserInfoManager.getNickname().let {
if (it.isEmpty()) binding.tvNickname.hint = "点击可设置昵称"
else binding.tvNickname.text = it
}
binding.tvNickname.click {
XPopup.Builder(context)
.hasStatusBarShadow(false)
.isDestroyOnDismiss(true)
.autoOpenSoftInput(true)
.isDarkTheme(false)
.isViewMode(true)
.asInputConfirm("修改昵称", null, binding.tvNickname.text.toString(), "限制为1-12个字符") {
//修改确认
if (it.isNotEmpty() && it.length <= 12) {
UserInfoManager.putNickname(it)
binding.tvNickname.text = it
} else {
showToast("输入格式错误")
}
}
.show()
}
//rv
binding.rv.apply {
layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
setHasFixedSize(true)
adapter = object : BaseRVAdapter<Item>(rvData) {
override fun coverViewHolder(parent : ViewGroup, viewType : Int) : BaseAdapterViewHolder {
return BaseAdapterViewHolder(inflateBinding(parent, R.layout.item_my_setting))
}
override fun onBindVH(holder : BaseAdapterViewHolder, position : Int) {
(holder.binding as ItemMySettingBinding).run {
getItem(position).let {
tvName.text = it.name
tvName.setCompoundDrawablesWithIntrinsicBounds(it.icon, 0, 0, 0)
ivArrowRight.visibility = if (it.isShowArrow) View.VISIBLE else View.GONE
}
root.click {
when(getItem(position).itemFlag){
0 -> "" //个性化
1 -> startActivity(SettingActivity::class.java) //设置
2 -> startActivity(AboutUsActivity::class.java) //关于我们
}
}
}
}
}
}
} }

override fun loadData() { override fun loadData() {

} }

override fun initViewModel(): MainActivityViewModel {
return ViewModelProvider(requireActivity())[MainActivityViewModel::class.java]
override fun onHiddenChanged(hidden : Boolean) {
super.onHiddenChanged(hidden)
activity?.let {
(it as MainActivity).setStatusBar(!hidden)
}
}
override fun onResume() {
super.onResume()
LogUtil.e("个人中心,获取统计信息")
//获取统计
vm.getStatistics().observe(this) {
if (it && vm.totalResult.isNotEmpty()) {
vm.totalResult[0].let {
setStatistics(it, binding.tvLearnTime, binding.tvLearnTimeUnit)
}
vm.totalResult[1].let {
setStatistics(it, binding.tvLearnEfficiency, binding.tvLearnEfficiencyUnit)
}
vm.totalResult[2].let {
setStatistics(it, binding.tvLearnedCourse, binding.tvLearnedCourseUnit)
}
}
}
}
/**
* 赋值
* @param item TimeStatisticItem
* @param tvValue TextView 显示的值
* @param tvUnit TextView 显示的单位
*/
private fun setStatistics(item : TimeStatisticItem, tvValue : TextView, tvUnit : TextView) {
tvValue.text = item.time
tvUnit.text = item.unit
} }
data class Item(val name : String, val icon : Int,val itemFlag : Int , var isShowArrow : Boolean = true)
} }

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

package com.xkl.cdl.module.m_my

import appApi.AppApi
import com.xkl.cdl.R
import com.xkl.cdl.data.bean.TimeStatisticItem
import com.xkl.cdl.module.m_statics.StatisticsTimeTopFragmentViewModel

/**
* author suliang
* create 2022/8/15 15:00
* Describe:
*/
class MyViewModel: StatisticsTimeTopFragmentViewModel() {
var totalResult : MutableList<TimeStatisticItem> = mutableListOf()

override fun initTimeStatic(statisticsResponse : AppApi.StatisticsCenterResponse) {
totalResult = initTimeStaticItem(statisticsResponse.total)
}
}

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

package com.xkl.cdl.module.m_my

import android.os.Bundle
import com.suliang.common.base.activity.BaseActivity
import com.suliang.common.extension.click
import com.suliang.common.util.DrawableUti
import com.xkl.cdl.R
import com.xkl.cdl.data.manager.UserInfoManager
import com.xkl.cdl.databinding.ActivitySettingBinding

class SettingActivity : BaseActivity<ActivitySettingBinding>() {
override fun initActivity(savedInstanceState : Bundle?) {
binding.titleBar.onBackClick = {finish()}
//默认发音方式
binding.voiceSwitch.setSoundWay(UserInfoManager.getDefaultSoundWay())
//清理缓存图标
val arrowRightDrawable = DrawableUti.changeSvgSizeAndColor(resources, R.drawable.ic_arrow_right, R.color.gray_2, 0.667f)
binding.tvClearCache.setCompoundDrawablesWithIntrinsicBounds(null,null,arrowRightDrawable,null)
binding.voiceSwitch.soundWayChange.observe(this){
UserInfoManager.putDefaultSoundWay(it)
}
binding.tvClearCache.click {
startActivity(CacheClearActivity::class.java)
}
}
override fun loadData() {
}
}

+ 2
- 7
app/src/main/java/com/xkl/cdl/module/m_service_center/ServiceCenterFragment.kt View File

package com.xkl.cdl.module.m_service_center package com.xkl.cdl.module.m_service_center


import android.graphics.Color import android.graphics.Color
import androidx.lifecycle.ViewModelProvider
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import com.suliang.common.base.adapter.BaseAdapterViewHolder import com.suliang.common.base.adapter.BaseAdapterViewHolder
import com.suliang.common.base.adapter.BaseRVAdapter import com.suliang.common.base.adapter.BaseRVAdapter
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.R
import com.xkl.cdl.adapter.DictionaryAdapter
import com.xkl.cdl.databinding.FragmentMyBinding
import com.xkl.cdl.databinding.ItemServiceCenterItemBinding import com.xkl.cdl.databinding.ItemServiceCenterItemBinding
import com.xkl.cdl.databinding.ServiceCenterFragmentBinding import com.xkl.cdl.databinding.ServiceCenterFragmentBinding
import com.xkl.cdl.module.main.MainActivityViewModel import com.xkl.cdl.module.main.MainActivityViewModel
import com.zackratos.ultimatebarx.ultimatebarx.statusBarOnly


class ServiceCenterFragment : BaseFragmentVM<ServiceCenterFragmentBinding, MainActivityViewModel>() { class ServiceCenterFragment : BaseFragmentVM<ServiceCenterFragmentBinding, MainActivityViewModel>() {

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

import io.reactivex.rxjava3.core.Observable import io.reactivex.rxjava3.core.Observable
import kotlin.math.abs import kotlin.math.abs


class StatisticsTimeTopFragmentViewModel : BaseViewModel() {
open class StatisticsTimeTopFragmentViewModel : BaseViewModel() {
/**顶部统计信息*/ /**顶部统计信息*/
/** 时间统计选择位置 */ /** 时间统计选择位置 */
var projectId = 0 //默认全部 var projectId = 0 //默认全部
return result return result
} }
private fun initTimeStatic(statisticsResponse : AppApi.StatisticsCenterResponse) {
protected open fun initTimeStatic(statisticsResponse : AppApi.StatisticsCenterResponse) {
timeValuesList.clear() timeValuesList.clear()
timeValuesList.add(initTimeStaticItem(statisticsResponse.total)) timeValuesList.add(initTimeStaticItem(statisticsResponse.total))
timeValuesList.add(initTimeStaticItem(statisticsResponse.today)) timeValuesList.add(initTimeStaticItem(statisticsResponse.today))
} }
private fun initTimeStaticItem(statistics : AppApi.Statistics) : MutableList<TimeStatisticItem> {
protected fun initTimeStaticItem(statistics : AppApi.Statistics) : MutableList<TimeStatisticItem> {
val result = mutableListOf<TimeStatisticItem>() val result = mutableListOf<TimeStatisticItem>()
//有效学习时长 //有效学习时长
val timeStaticItem_1 = TimeStatisticItem().apply { val timeStaticItem_1 = TimeStatisticItem().apply {

+ 14
- 0
app/src/main/java/com/xkl/cdl/module/main/MainActivity.kt View File

package com.xkl.cdl.module.main package com.xkl.cdl.module.main


import android.graphics.Color
import android.os.Bundle import android.os.Bundle
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import com.suliang.common.base.activity.BaseActivityVM import com.suliang.common.base.activity.BaseActivityVM
import com.xkl.cdl.module.m_my.MyFragment import com.xkl.cdl.module.m_my.MyFragment
import com.xkl.cdl.module.m_service_center.ServiceCenterFragment import com.xkl.cdl.module.m_service_center.ServiceCenterFragment
import com.xkl.cdl.module.m_statics.StaticsFragment import com.xkl.cdl.module.m_statics.StaticsFragment
import com.zackratos.ultimatebarx.ultimatebarx.java.UltimateBarX
import com.zackratos.ultimatebarx.ultimatebarx.statusBarOnly


/** /**
* 主界面、控制切换子Fragment * 主界面、控制切换子Fragment
binding.layoutNavContainer.check(R.id.nav_learnCenter) binding.layoutNavContainer.check(R.id.nav_learnCenter)
} }


fun setStatusBar(isMyFragment : Boolean){
when{
isMyFragment -> statusBarOnly {
fitWindow = false //布局是否侵入状态栏
color = Color.TRANSPARENT //透明
light = true
}
else -> initStatusBar()
}
}
} }

+ 50
- 0
app/src/main/java/com/xkl/cdl/util/EasyPhotoEngine.kt View File

package com.xkl.cdl.util

import android.content.Context
import android.graphics.Bitmap
import android.net.Uri
import android.widget.ImageView
import com.bumptech.glide.Glide
import com.huantansheng.easyphotos.engine.ImageEngine
import com.suliang.common.util.image.ImageLoader
import com.suliang.common.util.image.ImageLoaderOption

/**
* author suliang
* create 2022/8/16 11:27
* Describe:
*/
class EasyPhotoEngine private constructor(): ImageEngine {
companion object{
val instance by lazy(LazyThreadSafetyMode.SYNCHRONIZED) {
EasyPhotoEngine()
}
}
override fun loadPhoto(context : Context, uri : Uri, imageView : ImageView) {
ImageLoader.loadImage(imageView,uri)
}
override fun loadGifAsBitmap(context : Context, gifUri : Uri, imageView : ImageView) {
ImageLoader.loadImage(ImageLoaderOption().apply {
this.context = context;
targetView = imageView
asBitmap = true
uri = gifUri
})
}
override fun loadGif(context : Context, gifUri : Uri, imageView : ImageView) {
ImageLoader.loadImage(ImageLoaderOption().apply {
this.context = context;
targetView = imageView
asGif = true
uri = gifUri
})
}
override fun getCacheBitmap(context : Context, uri : Uri, width : Int, height : Int) : Bitmap {
return Glide.with(context).asBitmap().load(uri).submit(width,height).get()
}
}

+ 99
- 0
app/src/main/res/layout/activity_about_us.xml View File

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
tools:context=".module.m_my.AboutUsActivity">


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

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

<ImageView
android:id="@+id/head_logo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@mipmap/logo_1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/title_bar"
android:layout_marginTop="56dp"/>

<TextView
android:id="@+id/version_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="@dimen/global_spacing"
android:text="当前版本:v 1.0.0"
android:textColor="#8A8A99"
android:textSize="@dimen/smallSize"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/head_logo" />


<TextView
android:id="@+id/tv_website_flag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="学考乐官网:"
android:textColor="@color/main_text_color"
android:textSize="@dimen/smallSize"
app:layout_constraintEnd_toStartOf="@+id/tv_website"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/version_name"
android:layout_marginTop="54dp"
app:layout_constraintHorizontal_chainStyle="packed"/>

<TextView
android:id="@+id/tv_website"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="www.xuekaole.com"
android:textColor="@color/theme_color"
android:textSize="@dimen/smallSize"
app:layout_constraintBaseline_toBaselineOf="@+id/tv_website_flag"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/tv_website_flag" />

<TextView
android:id="@+id/tv_bottom_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="20dp"
android:text="学考乐xuekaole.com版权所有"
android:textSize="@dimen/smallerSize"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />

<TextView
android:id="@+id/tv_bottom_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="Copyright© 2021-2030"
android:textSize="@dimen/smallerSize"
app:layout_constraintBottom_toTopOf="@+id/tv_bottom_1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginBottom="4dp"/>


</androidx.constraintlayout.widget.ConstraintLayout>

+ 152
- 0
app/src/main/res/layout/activity_cache_clear.xml View File

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
tools:context=".module.m_my.CacheClearActivity">

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

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

<TextView
android:id="@+id/tv_total_cache_flag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:text="学考乐已使用内存"
android:textColor="@color/main_text_color"
android:textSize="@dimen/normalSize"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/title_bar" />

<TextView
android:id="@+id/tv_total_cache"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/global_spacing"
android:textColor="@color/theme_color"
android:textSize="42dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_total_cache_flag"
tools:text="学考乐已使用内存" />

<View
android:id="@+id/v_1"
android:layout_width="match_parent"
android:layout_height="8dp"
android:layout_marginTop="32dp"
android:background="@color/gray_1"
app:layout_constraintTop_toBottomOf="@+id/tv_total_cache" />

<androidx.appcompat.widget.LinearLayoutCompat
android:id="@+id/ll_audio"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:minHeight="96dp"
android:padding="@dimen/global_spacing"
android:paddingBottom="12dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/v_1"
android:orientation="vertical">

<RadioButton
android:id="@+id/rb_audio_cache"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:button="@null"
android:drawableStart="@drawable/choose_single"
android:drawablePadding="8dp"
android:gravity="center_vertical"
android:text="本地音频文件()"
android:textColor="@color/main_text_color"
android:textSize="@dimen/normalSize"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/v_1"
android:clickable="false"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="清理本地缓存的所有音频缓存文件,清理后不会影响你的正常使用"
android:layout_marginStart="22dp"
android:textSize="@dimen/smallSize"
android:textColor="@color/gray_2"/>

</androidx.appcompat.widget.LinearLayoutCompat>

<View
android:id="@+id/v_2"
android:layout_width="match_parent"
android:layout_height="8dp"
android:background="@color/gray_1"
app:layout_constraintTop_toBottomOf="@+id/ll_audio" />

<androidx.appcompat.widget.LinearLayoutCompat
android:id="@+id/ll_photo"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:minHeight="96dp"
android:padding="@dimen/global_spacing"
android:paddingBottom="12dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/v_2"
android:orientation="vertical">

<RadioButton
android:id="@+id/rb_photo_cache"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:button="@null"
android:drawableStart="@drawable/choose_single"
android:drawablePadding="8dp"
android:gravity="center_vertical"
tools:text="本地图片文件()"
android:textColor="@color/main_text_color"
android:textSize="@dimen/normalSize"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/v_1"
android:clickable="false"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="清理本地缓存的所有图片缓存文件,清理后不会影响你的正常使用"
android:layout_marginStart="22dp"
android:textSize="@dimen/smallSize"
android:textColor="@color/gray_2"/>

</androidx.appcompat.widget.LinearLayoutCompat>

<View
android:id="@+id/v_3"
android:layout_width="match_parent"
android:layout_height="8dp"
android:background="@color/gray_1"
app:layout_constraintTop_toBottomOf="@+id/ll_photo" />

<com.google.android.material.button.MaterialButton
android:id="@+id/tv_clear"
style="@style/common_button_style"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginBottom="42dp"
android:text="@string/clear_cache"
android:backgroundTint="@color/com_btn_enable_selector"
android:enabled="false" />

</androidx.constraintlayout.widget.ConstraintLayout>

+ 79
- 0
app/src/main/res/layout/activity_setting.xml View File

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
tools:context=".module.m_my.SettingActivity">

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


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

<!--单词默认发音-->
<RelativeLayout
android:id="@+id/rl_sound"
android:layout_width="0dp"
android:layout_height="40dp"
android:clickable="true"
android:paddingLeft="@dimen/global_spacing"
android:paddingRight="@dimen/global_spacing"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/title_bar">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:text="@string/default_sound"
android:textColor="@color/main_text_color"
android:textSize="@dimen/normalSize" />

<com.xkl.cdl.widget.VoiceSwitch
android:id="@+id/voice_switch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true" />

</RelativeLayout>

<View
android:layout_width="match_parent"
android:layout_height="@dimen/line_height"
android:layout_marginStart="@dimen/global_spacing"
android:layout_marginEnd="@dimen/global_spacing"
android:background="@color/gray_1"
app:layout_constraintTop_toBottomOf="@+id/rl_sound" />

<!--清理缓存-->
<TextView
android:id="@+id/tv_clear_cache"
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_centerVertical="true"
android:text="清理缓存"
android:textColor="@color/main_text_color"
android:textSize="@dimen/normalSize"
app:layout_constraintTop_toBottomOf="@+id/rl_sound"
android:layout_marginTop="@dimen/line_height"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:paddingStart="@dimen/global_spacing"
android:paddingEnd="@dimen/global_spacing"
android:gravity="center_vertical"
tools:drawableEnd="@drawable/ic_arrow_right"/>

</androidx.constraintlayout.widget.ConstraintLayout>

+ 223
- 8
app/src/main/res/layout/fragment_my.xml View File

<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".module.m_my.MyFragment">
xmlns:app="http://schemas.android.com/apk/res-auto">


<!-- TODO: Update blank fragment layout -->
<TextView
<data>

</data>

<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:text="@string/hello_blank_fragment" />
tools:context=".module.m_my.MyFragment"
android:background="@color/white_1">

<ImageView
android:id="@+id/head_bg"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:background="@mipmap/my_bg_img"
android:backgroundTint="@color/theme_color"
android:backgroundTintMode="screen"
android:paddingStart="0dp"
android:paddingEnd="0dp" />


<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/layout_1"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/head_bg"
app:layout_constraintBottom_toBottomOf="@+id/head_bg"
android:layout_marginStart="@dimen/global_spacing"
android:layout_marginEnd="@dimen/global_spacing"
android:background="@drawable/shape_rounder_12_white">

<TextView
android:id="@+id/tv_nickname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="51dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:textStyle="bold"
android:textSize="@dimen/normalSize"
android:textColor="@color/main_text_color"
tools:text="Petter"
android:gravity="center"/>

<TextView
android:id="@+id/tv_learn_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="22dp"
android:textColor="@color/main_text_color"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="@+id/tv_learn_time_flag"
app:layout_constraintEnd_toStartOf="@+id/tv_learn_time_unit"
tools:text="12"
app:layout_constraintBottom_toTopOf="@+id/tv_learn_time_flag"
app:layout_constraintTop_toTopOf="@+id/v_1" />

<TextView
android:id="@+id/tv_learn_time_unit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/smallerSize"
android:textColor="@color/gray_2"
app:layout_constraintStart_toEndOf="@+id/tv_learn_time"
app:layout_constraintEnd_toEndOf="@+id/tv_learn_time_flag"
app:layout_constraintBaseline_toBaselineOf="@+id/tv_learn_time"
tools:text="小时"
android:layout_marginStart="4dp"/>

<TextView
android:id="@+id/tv_learn_time_flag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/smallerSize"
android:textColor="@color/gray_2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@+id/v_1"
android:text="@string/learn_duration"
app:layout_constraintTop_toBottomOf="@+id/tv_learn_time"
app:layout_constraintBottom_toBottomOf="@+id/v_1"
android:layout_marginTop="6dp" />

<View
android:id="@+id/v_1"
android:layout_width="1dp"
android:layout_height="32dp"
android:background="@color/gray_1"
app:layout_constraintStart_toEndOf="@+id/tv_learn_time_flag"
app:layout_constraintEnd_toStartOf="@+id/tv_learn_efficiency_flag"
app:layout_constraintTop_toBottomOf="@+id/tv_nickname"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginBottom="24dp"
android:layout_marginTop="24dp" />

<TextView
android:id="@+id/tv_learn_efficiency"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="22dp"
android:textColor="@color/main_text_color"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="@+id/tv_learn_efficiency_flag"
app:layout_constraintEnd_toStartOf="@+id/tv_learn_efficiency_unit"
tools:text="12"
app:layout_constraintBottom_toTopOf="@+id/tv_learn_efficiency_flag"
app:layout_constraintTop_toTopOf="@+id/v_1" />

<TextView
android:id="@+id/tv_learn_efficiency_unit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/smallerSize"
android:textColor="@color/gray_2"
app:layout_constraintStart_toEndOf="@+id/tv_learn_efficiency"
app:layout_constraintEnd_toEndOf="@+id/tv_learn_efficiency_flag"
android:text="%"
app:layout_constraintBaseline_toBaselineOf="@+id/tv_learn_efficiency"
android:layout_marginStart="4dp"/>


<TextView
android:id="@+id/tv_learn_efficiency_flag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/smallerSize"
android:textColor="@color/gray_2"
app:layout_constraintStart_toEndOf="@+id/v_1"
app:layout_constraintEnd_toStartOf="@+id/v_2"
app:layout_constraintTop_toBottomOf="@+id/tv_learn_efficiency"
app:layout_constraintBottom_toBottomOf="@+id/v_1"
android:text="@string/learn_efficiency"
android:layout_marginTop="6dp" />

<View
android:id="@+id/v_2"
android:layout_width="@dimen/line_height"
android:layout_height="32dp"
android:background="@color/gray_1"
app:layout_constraintStart_toEndOf="@+id/tv_learn_efficiency_flag"
app:layout_constraintEnd_toStartOf="@+id/tv_learned_course_flag"
app:layout_constraintTop_toTopOf="@+id/v_1"
app:layout_constraintBottom_toBottomOf="@+id/v_1" />

<TextView
android:id="@+id/tv_learned_course"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="22dp"
android:textColor="@color/main_text_color"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="@+id/tv_learned_course_flag"
app:layout_constraintEnd_toStartOf="@+id/tv_learned_course_unit"
tools:text="12"
app:layout_constraintBottom_toTopOf="@+id/tv_learned_course_flag"
app:layout_constraintTop_toTopOf="@+id/v_1" />

<TextView
android:id="@+id/tv_learned_course_unit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/smallerSize"
android:textColor="@color/gray_2"
app:layout_constraintStart_toEndOf="@+id/tv_learned_course"
app:layout_constraintEnd_toEndOf="@+id/tv_learned_course_flag"
tools:text="/12个"
app:layout_constraintBaseline_toBaselineOf="@+id/tv_learned_course"
android:layout_marginStart="4dp"/>


<TextView
android:id="@+id/tv_learned_course_flag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/smallerSize"
android:textColor="@color/gray_2"
app:layout_constraintStart_toEndOf="@+id/v_2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_learned_course"
app:layout_constraintBottom_toBottomOf="@+id/v_1"
android:text="@string/learned_course"
android:layout_marginTop="6dp" />


</androidx.constraintlayout.widget.ConstraintLayout>


<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/head_portrait"
android:layout_width="70dp"
android:layout_height="70dp"
app:shapeAppearanceOverlay="@style/CircleStyle"
app:layout_constraintTop_toTopOf="@+id/layout_1"
app:layout_constraintBottom_toTopOf="@+id/layout_1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:background="@color/white"
android:src="@mipmap/head_portrait_default" />


<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/layout_1"
app:layout_constraintBottom_toBottomOf="parent"
android:background="@drawable/shape_rounder_12_white"
android:layout_marginStart="@dimen/global_spacing"
android:layout_marginEnd="@dimen/global_spacing"
android:layout_marginTop="12dp"
android:layout_marginBottom="27dp"
android:paddingTop="@dimen/global_spacing"
android:paddingBottom="@dimen/global_spacing"/>

</androidx.constraintlayout.widget.ConstraintLayout>


</FrameLayout>
</layout>

+ 37
- 0
app/src/main/res/layout/item_my_setting.xml View File

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">

<data>

</data>

<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="40dp"
android:orientation="horizontal"
android:gravity="center_vertical"
android:layout_marginBottom="10dp">
<TextView
android:id="@+id/tv_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textColor="@color/main_text_color"
android:textSize="@dimen/normalSize"
android:layout_marginLeft="@dimen/global_spacing"
android:drawablePadding="8dp"
tools:text="设置"
tools:drawableStart="@drawable/ic_setting"/>

<ImageView
android:id="@+id/iv_arrow_right"
android:layout_width="16dp"
android:layout_height="16dp"
android:src="@drawable/ic_arrow_right"
android:layout_marginRight="@dimen/global_spacing"
android:layout_gravity="center_vertical"/>

</androidx.appcompat.widget.LinearLayoutCompat>

</layout>

BIN
app/src/main/res/mipmap-xxxhdpi/head_portrait_default.png View File


BIN
app/src/main/res/mipmap-xxxhdpi/logo_1.png View File


BIN
app/src/main/res/mipmap-xxxhdpi/my_bg_img.png View File


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

<string name="xkl_dictionary">学考乐英汉双向词典</string> <string name="xkl_dictionary">学考乐英汉双向词典</string>
<string name="dialog_delete_history">你确定要删除历史记录吗?</string> <string name="dialog_delete_history">你确定要删除历史记录吗?</string>
<string name="delete">删除</string> <string name="delete">删除</string>
<string name="learn_duration">学习时长</string>
<string name="learn_efficiency">学习效率</string>
<string name="learned_course">已学课程</string>
<string name="setting">设置</string>
<string name="default_sound">单词默认发音</string>
<string name="clear_cache">清除缓存</string>


</resources> </resources>

+ 8
- 0
app/src/main/res/xml/file_paths_public.xml View File

<?xml version="1.0" encoding="utf-8"?>
<resources>
<paths>
<root-path
name="camera_photos"
path="" />
</paths>
</resources>

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

<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M0,0h24v24h-24z"
android:strokeAlpha="0"
android:strokeWidth="1"
android:fillColor="#000000"
android:fillType="nonZero"
android:strokeColor="#00000000"
android:fillAlpha="0"/>
<path
android:pathData="M12,21.6C6.698,21.6 2.4,17.3019 2.4,12C2.4,6.6981 6.698,2.4 12,2.4C17.3019,2.4 21.6,6.6981 21.6,12C21.6,17.3019 17.3019,21.6 12,21.6ZM12,6.6147C11.3534,6.6147 10.8292,7.1388 10.8292,7.7854C10.8292,8.432 11.3534,8.9561 12,8.9561C12.6466,8.9561 13.1707,8.432 13.1707,7.7854C13.1707,7.1388 12.6466,6.6147 12,6.6147ZM13.1707,11.2976C13.1707,10.7803 12.7513,10.361 12.2341,10.361L11.7658,10.361C11.2486,10.361 10.8292,10.7803 10.8292,11.2976L10.8292,16.9171C10.8292,17.4343 11.2485,17.8537 11.7658,17.8537L12.2341,17.8537C12.7513,17.8537 13.1707,17.4343 13.1707,16.9171L13.1707,11.2976Z"
android:strokeWidth="1"
android:fillColor="#5082E6"
android:fillType="evenOdd"
android:strokeColor="#00000000"/>
</vector>

+ 1
- 1
app/svg/drawable/ic_checked_1.xml View File

<path <path
android:pathData="M7,0C10.866,0 14,3.134 14,7C14,10.866 10.866,14 7,14C3.134,14 0,10.866 0,7C0,3.134 3.134,0 7,0ZM7,0.8235C3.5888,0.8235 0.8235,3.5888 0.8235,7C0.8235,10.4112 3.5888,13.1765 7,13.1765C10.4112,13.1765 13.1765,10.4112 13.1765,7C13.1765,3.5888 10.4112,0.8235 7,0.8235ZM7,2.8824C9.2741,2.8824 11.1176,4.7259 11.1176,7C11.1176,9.2741 9.2741,11.1176 7,11.1176C4.7259,11.1176 2.8824,9.2741 2.8824,7C2.8824,4.7259 4.7259,2.8824 7,2.8824Z" android:pathData="M7,0C10.866,0 14,3.134 14,7C14,10.866 10.866,14 7,14C3.134,14 0,10.866 0,7C0,3.134 3.134,0 7,0ZM7,0.8235C3.5888,0.8235 0.8235,3.5888 0.8235,7C0.8235,10.4112 3.5888,13.1765 7,13.1765C10.4112,13.1765 13.1765,10.4112 13.1765,7C13.1765,3.5888 10.4112,0.8235 7,0.8235ZM7,2.8824C9.2741,2.8824 11.1176,4.7259 11.1176,7C11.1176,9.2741 9.2741,11.1176 7,11.1176C4.7259,11.1176 2.8824,9.2741 2.8824,7C2.8824,4.7259 4.7259,2.8824 7,2.8824Z"
android:strokeWidth="1" android:strokeWidth="1"
android:fillColor="#5082E6"
android:fillColor="@color/theme_color"
android:fillType="evenOdd" android:fillType="evenOdd"
android:strokeColor="#00000000"/> android:strokeColor="#00000000"/>
</vector> </vector>

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

<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M1.3345,13.9186C0.4165,7.2149 5.873,2.0931 13.1591,2.5086C18.8837,2.8351 25.0028,9.5396 22.7059,14.1658C21.8721,15.845 20.5376,16.3233 18.2458,16.332L18.2458,16.332L17.3044,16.329C16.2099,16.3341 15.7395,16.4078 15.3728,16.6426C15.043,16.8537 14.991,16.9885 15.1259,17.5943L15.1259,17.5943L15.2802,18.252C15.5163,19.4021 15.3112,20.2269 14.2989,20.9152C13.0322,21.7764 9.9962,21.6268 7.3202,20.6055C4.0473,19.3564 1.7651,17.0631 1.3345,13.9186ZM5.6,11.2C4.7163,11.2 4,11.9163 4,12.8C4,13.6837 4.7163,14.4 5.6,14.4C6.4837,14.4 7.2,13.6837 7.2,12.8C7.2,11.9163 6.4837,11.2 5.6,11.2ZM17.6,8.8C16.7163,8.8 16,9.5163 16,10.4C16,11.2837 16.7163,12 17.6,12C18.4837,12 19.2,11.2837 19.2,10.4C19.2,9.5163 18.4837,8.8 17.6,8.8ZM8,6.4C7.1163,6.4 6.4,7.1163 6.4,8C6.4,8.8837 7.1163,9.6 8,9.6C8.8837,9.6 9.6,8.8837 9.6,8C9.6,7.1163 8.8837,6.4 8,6.4ZM13.6,5.6C12.7163,5.6 12,6.3163 12,7.2C12,8.0837 12.7163,8.8 13.6,8.8C14.4837,8.8 15.2,8.0837 15.2,7.2C15.2,6.3163 14.4837,5.6 13.6,5.6Z"
android:strokeWidth="1"
android:fillColor="#F26255"
android:fillType="evenOdd"
android:strokeColor="#00000000"/>
</vector>

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

<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M12.5662,15.5359C11.4868,15.7143 10.388,15.3697 9.6145,14.6131C8.8411,13.8565 8.4917,12.777 8.6748,11.7216C8.9013,10.353 10.029,9.247 11.4265,9.0205C12.5084,8.8374 13.612,9.1819 14.3879,9.9409C15.1638,10.7024 15.5131,11.7843 15.3252,12.8421C15.0915,14.2131 13.9638,15.3143 12.5662,15.5359M20.4817,13.4059L22.072,12.4324C22.325,12.2782 22.4479,11.9843 22.3828,11.6999L21.6045,8.353C21.5395,8.0687 21.2961,7.8567 20.9997,7.8254L19.1323,7.623C18.9468,7.6037 18.7781,7.5121 18.6624,7.3699L18.3492,6.9844C18.2335,6.8423 18.1805,6.6591 18.2022,6.4784L18.4167,4.6544C18.4504,4.3652 18.2938,4.0857 18.0263,3.958L14.8698,2.4689C14.6023,2.3436 14.2819,2.3966 14.0698,2.6014L12.7446,3.9026C12.6144,4.0303 12.4361,4.105 12.2482,4.105L11.7494,4.105C11.5639,4.105 11.3856,4.0327 11.253,3.9026L9.9278,2.6014C9.7181,2.3942 9.3977,2.3412 9.1278,2.4689L5.9737,3.958C5.7062,4.0857 5.5496,4.3628 5.5833,4.6544L5.7978,6.4808C5.8195,6.6615 5.7665,6.8423 5.6508,6.9868L5.34,7.3675C5.2243,7.5097 5.0556,7.6013 4.8701,7.6205L3.0027,7.8254C2.7063,7.8567 2.4654,8.0687 2.3979,8.353L1.6172,11.6975C1.5521,11.9818 1.675,12.2758 1.928,12.43L3.5183,13.4059C3.675,13.5023 3.7882,13.6565 3.8292,13.8348L3.94,14.3143C3.981,14.4926 3.9497,14.6781 3.8509,14.8324L2.8485,16.3865C2.6895,16.6323 2.7087,16.9504 2.8943,17.1793L5.0797,19.8611C5.2653,20.09 5.5785,20.1768 5.858,20.0804L7.6291,19.4708C7.805,19.4105 7.9977,19.4202 8.164,19.4997L8.6146,19.7117C8.7832,19.7912 8.9109,19.931 8.9712,20.1045L9.588,21.8394C9.6868,22.114 9.9519,22.2996 10.2482,22.2996L13.7493,22.2996C14.0481,22.2996 14.3132,22.114 14.4096,21.8394L15.0264,20.1045C15.0866,19.9334 15.2168,19.7912 15.383,19.7117L15.8336,19.4997C15.9999,19.4202 16.1926,19.4105 16.3685,19.4708L18.1396,20.0804C18.4215,20.1768 18.7323,20.09 18.9178,19.8611L21.1033,17.1793C21.2889,16.9504 21.3057,16.6323 21.1491,16.3865L20.1467,14.8324C20.0479,14.6781 20.0142,14.4926 20.0552,14.3143L20.166,13.8372C20.2118,13.6565 20.3226,13.5023 20.4817,13.4059"
android:strokeWidth="1"
android:fillColor="#F7874F"
android:fillType="evenOdd"
android:strokeColor="#00000000"/>
</vector>

+ 1
- 1
build.gradle View File

] ]
//依赖项 //依赖项
dependencies_custom = [ dependencies_custom = [
//设置状态栏和导航栏的框架 https://github.com/Zackratos/UltimateBarX
//设置状态栏和导航栏的框架 https://github.com/Zackratos/UltimateBarX https://juejin.cn/post/6903165109485436935
UltimateBarX : "com.gitee.zackratos:UltimateBarX:0.8.0", UltimateBarX : "com.gitee.zackratos:UltimateBarX:0.8.0",
//Glide 依赖和配置 //Glide 依赖和配置
Glide : "com.github.bumptech.glide:glide:${versions.glide_version}", Glide : "com.github.bumptech.glide:glide:${versions.glide_version}",

+ 1
- 1
lib/common/build.gradle View File

} }
debug { debug {
buildConfigField("Boolean","LOG_ENABLE","true") buildConfigField("Boolean","LOG_ENABLE","true")
buildConfigField("Boolean","SHOW_LIFECYCLER_LOG","true")
buildConfigField("Boolean","SHOW_LIFECYCLER_LOG","false")
minifyEnabled false minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
} }

+ 9
- 0
lib/common/src/main/java/com/suliang/common/util/file/FileUtil.kt View File

else -> "too large" else -> "too large"
} }
} }
fun sizeFormat(size : Long): String{
return when{
size < 1024 -> DecimalFormat("0B").format(size)
size < 1048576 -> DecimalFormat("0KB").format(size/1024.0)
size < 1073741824 -> DecimalFormat("0.00MB").format(size/1048576.0)
else -> DecimalFormat("0.00GB").format(size/1073741824.0)
}
}




} }

Loading…
Cancel
Save