Browse Source

service center

master
suliang 2 years ago
parent
commit
22ab734912
51 changed files with 1799 additions and 113 deletions
  1. 9
    1
      .idea/misc.xml
  2. 18
    1
      app/build.gradle
  3. 9
    3
      app/src/main/AndroidManifest.xml
  4. BIN
      app/src/main/assets/dictionary.db
  5. BIN
      app/src/main/assets/vocabulary.db
  6. 43
    0
      app/src/main/java/com/xkl/cdl/adapter/AdapterTestFilter.kt
  7. 104
    0
      app/src/main/java/com/xkl/cdl/adapter/AdapterTestScore.kt
  8. 8
    0
      app/src/main/java/com/xkl/cdl/data/bean/VocabularyItem.kt
  9. 85
    0
      app/src/main/java/com/xkl/cdl/data/exam_record/AppDatabase.kt
  10. 33
    0
      app/src/main/java/com/xkl/cdl/data/exam_record/Exam.kt
  11. 126
    0
      app/src/main/java/com/xkl/cdl/data/exam_record/ExamDao.kt
  12. 21
    0
      app/src/main/java/com/xkl/cdl/data/exam_record/ExamItem.kt
  13. 18
    0
      app/src/main/java/com/xkl/cdl/data/exam_record/ExamItemDao.kt
  14. 35
    0
      app/src/main/java/com/xkl/cdl/data/exam_record/ExamMiddleDao.kt
  15. 13
    0
      app/src/main/java/com/xkl/cdl/data/exam_record/ExamWithDetail.kt
  16. 22
    0
      app/src/main/java/com/xkl/cdl/data/manager/CourseManager.kt
  17. 17
    0
      app/src/main/java/com/xkl/cdl/data/manager/FilePathManager.kt
  18. 48
    0
      app/src/main/java/com/xkl/cdl/data/manager/db/VocabularyManager.kt
  19. 49
    33
      app/src/main/java/com/xkl/cdl/data/repository/DataRepository.kt
  20. 4
    0
      app/src/main/java/com/xkl/cdl/module/XKLApplication.kt
  21. 1
    1
      app/src/main/java/com/xkl/cdl/module/m_memo/MemoTestActivity.kt
  22. 2
    2
      app/src/main/java/com/xkl/cdl/module/m_service_center/ServiceCenterFragment.kt
  23. 26
    2
      app/src/main/java/com/xkl/cdl/module/m_service_center/TestDetailActivity.kt
  24. 172
    0
      app/src/main/java/com/xkl/cdl/module/m_service_center/TestScoreActivity.kt
  25. 99
    0
      app/src/main/java/com/xkl/cdl/module/m_service_center/TestScoreViewModel.kt
  26. 54
    0
      app/src/main/java/com/xkl/cdl/module/m_service_center/TestVocabularyActivity.kt
  27. 47
    0
      app/src/main/java/com/xkl/cdl/module/m_service_center/TestVocabularyViewModle.kt
  28. 13
    2
      app/src/main/java/com/xkl/cdl/module/splash/SplashActivity.kt
  29. 28
    0
      app/src/main/java/com/xkl/cdl/widget/MyFlexboxLayoutManager.kt
  30. 5
    0
      app/src/main/res/color/rb_select_gray_white.xml
  31. 16
    0
      app/src/main/res/drawable/rb_select_white1_theme_bg.xml
  32. 237
    63
      app/src/main/res/layout/activity_test_detail.xml
  33. 142
    0
      app/src/main/res/layout/activity_test_score.xml
  34. 52
    0
      app/src/main/res/layout/activity_test_vocabulary.xml
  35. 32
    0
      app/src/main/res/layout/item_test_filter.xml
  36. 89
    0
      app/src/main/res/layout/item_test_score.xml
  37. 50
    0
      app/src/main/res/layout/item_vocabulary_level.xml
  38. BIN
      app/src/main/res/mipmap-xxhdpi/cry.png
  39. BIN
      app/src/main/res/mipmap-xxhdpi/ic_comprehensive_test.png
  40. BIN
      app/src/main/res/mipmap-xxhdpi/ic_high_school.png
  41. BIN
      app/src/main/res/mipmap-xxhdpi/ic_junior_school.png
  42. BIN
      app/src/main/res/mipmap-xxhdpi/ic_lelts.png
  43. BIN
      app/src/main/res/mipmap-xxhdpi/ic_primary_school.png
  44. BIN
      app/src/main/res/mipmap-xxhdpi/ic_toefl.png
  45. BIN
      app/src/main/res/mipmap-xxhdpi/ic_university_4.png
  46. BIN
      app/src/main/res/mipmap-xxhdpi/ic_university_6.png
  47. 5
    0
      app/src/main/res/values/strings.xml
  48. 24
    0
      app/svg/drawable/ic_star.xml
  49. 24
    0
      app/svg/drawable/ic_star_1.xml
  50. 14
    4
      build.gradle
  51. 5
    1
      lib/common/src/main/java/com/suliang/common/base/adapter/BaseRVAdapter.kt

+ 9
- 1
.idea/misc.xml View File

@@ -31,6 +31,7 @@
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/progress_center.xml" value="0.287962962962963" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/progress_statistics.xml" value="0.4425925925925926" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/progressbar_countdown_time.xml" value="0.45740740740740743" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/rb_select_white1_theme_bg.xml" value="0.34629629629629627" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/selector_memo_review_bg.xml" value="0.5010416666666667" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/selector_memo_test_bg.xml" value="0.5010416666666667" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/shadow_layer.xml" value="0.4876923076923077" />
@@ -82,7 +83,9 @@
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/activity_memo_test.xml" value="0.25" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/activity_splash.xml" value="0.4921875" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/activity_subject_statistics.xml" value="0.23454913880445796" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/activity_test_detail.xml" value="0.33" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/activity_test_detail.xml" value="0.3348694316436252" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/activity_test_score.xml" value="0.31521739130434784" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/activity_test_vocabulary.xml" value="0.18591691995947315" />
<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/custom_marker_view.xml" value="0.23353596757852077" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/dialog_bottom_auto_play_select.xml" value="0.4979166666666667" />
@@ -143,7 +146,10 @@
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/item_test_detail.xml" value="0.348731884057971" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/item_test_detail_option.xml" value="0.348731884057971" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/item_test_detail_option_2.xml" value="0.348731884057971" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/item_test_filter.xml" value="0.75" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/item_test_score.xml" value="0.33" />
<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_vocabulary_level.xml" value="0.23632218844984804" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/item_xpopup_statistics_choose_subject.xml" value="0.21965579710144928" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/main_item_course_progress.xml" value="0.25" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/main_item_coursepack.xml" value="0.43500866551126516" />
@@ -186,6 +192,8 @@
<entry key="..\:/Work/XKL/XKL/XklLocal/app/svg/drawable/ic_right.xml" value="0.4425925925925926" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/svg/drawable/ic_spell.xml" value="0.5061538461538462" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/svg/drawable/ic_spoken.xml" value="0.5061538461538462" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/svg/drawable/ic_star.xml" value="0.49538461538461537" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/svg/drawable/ic_star_1.xml" value="0.49538461538461537" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/svg/drawable/ic_up.xml" value="0.503125" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/svg/drawable/ic_voice.xml" value="0.5061538461538462" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/svg/drawable/ic_wrong.xml" value="0.4425925925925926" />

+ 18
- 1
app/build.gradle View File

@@ -16,6 +16,13 @@ android {
versionName androidConfig.version_name
multiDexEnabled true //解决64k 分包限制
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

javaCompileOptions {
annotationProcessorOptions {
arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]
}
}

}
/*构建类型: 定义Gradle在构建阶段和打包应用时使用的某些属性*/
buildTypes {
@@ -121,6 +128,16 @@ dependencies {
implementation customDependencies.FlexBoxLayoutManager
//图标
implementation customDependencies.Chart

//Room
implementation customDependencies.Room_Runtime
kapt customDependencies.Room_Compiler
//Paging
// implementation customDependencies.Paging
//Room_Paging
// implementation(customDependencies.Room_Paging){
// force = true
// }
// implementation "me.zhanghai.android.materialratingbar:library:1.4.0"
implementation 'com.xl.ratingbar:ratingbar:0.1.1'

}

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

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.xkl.cdl" >
package="com.xkl.cdl">

<application
android:name=".module.XKLApplication"
@@ -11,7 +11,13 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.XklLocal"
tools:ignore="LockedOrientationActivity" >
tools:ignore="LockedOrientationActivity">
<activity
android:name=".module.m_service_center.TestVocabularyActivity"
android:exported="true" />
<activity
android:name=".module.m_service_center.TestScoreActivity"
android:exported="true" />
<activity
android:name=".module.m_statics.CourseStatisticsDetailActivity"
android:exported="true" />
@@ -54,7 +60,7 @@
android:configChanges="orientation|keyboardHidden|screenSize"
android:exported="true"
android:screenOrientation="portrait"
android:theme="@style/Theme.Splash" >
android:theme="@style/Theme.Splash">
<intent-filter>
<action android:name="android.intent.action.MAIN" />


BIN
app/src/main/assets/dictionary.db View File


BIN
app/src/main/assets/vocabulary.db View File


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

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

import android.annotation.SuppressLint
import android.view.ViewGroup
import com.google.android.flexbox.FlexboxLayoutManager
import com.suliang.common.base.adapter.BaseAdapterViewHolder
import com.suliang.common.base.adapter.BaseRVAdapter
import com.suliang.common.base.adapter.BaseRVAdapterVM
import com.suliang.common.extension.click
import com.xkl.cdl.R
import com.xkl.cdl.databinding.ItemTestFilterBinding
import com.xkl.cdl.module.m_service_center.TestScoreViewModel

/**
* author suliang
* create 2022/7/8 14:44
* Describe: 测试成绩筛选适配器
*/
class AdapterTestFilter(vm:TestScoreViewModel) : BaseRVAdapterVM<String,TestScoreViewModel>(vm) {
override fun coverViewHolder(parent : ViewGroup, viewType : Int) : BaseAdapterViewHolder {
return BaseAdapterViewHolder(inflateBinding(parent, R.layout.item_test_filter))
}
@SuppressLint("NotifyDataSetChanged")
override fun onBindVH(holder : BaseAdapterViewHolder, position : Int) {
(holder.binding as ItemTestFilterBinding).rb.run {
text = getItem(position)
isChecked = vm.filterPosition.value == position
click {
if (vm.filterPosition.value != position){
vm.filterPosition.value = position
notifyDataSetChanged()
}
}
//加上这句话,保证主轴上的子view均分主轴剩余空间
// if (layoutParams is FlexboxLayoutManager.LayoutParams){
// (layoutParams as FlexboxLayoutManager.LayoutParams).flexGrow = 1f
// }
}
}
}

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

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

import android.annotation.SuppressLint
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import com.suliang.common.base.adapter.BaseAdapterViewHolder
import com.suliang.common.base.adapter.BaseRVAdapterVM
import com.suliang.common.databinding.ItemEmptyBinding
import com.suliang.common.extension.click
import com.suliang.common.extension.setHtml
import com.xkl.cdl.R
import com.xkl.cdl.data.AppConstants
import com.xkl.cdl.data.exam_record.Exam
import com.xkl.cdl.data.manager.CourseManager
import com.xkl.cdl.databinding.ItemTestScoreBinding
import com.xkl.cdl.module.m_service_center.TestScoreViewModel

/**
* author suliang
* create 2022/7/8 10:45
* Describe:
*/
class AdapterTestScore(vm : TestScoreViewModel) : BaseRVAdapterVM<Exam,TestScoreViewModel>(vm) {
override fun onBindEmptyViewHolder(holder : BaseAdapterViewHolder) {
(holder.binding as ItemEmptyBinding).apply {
val nullOrEmpty = vm.keyWordSearch.value.isNullOrEmpty()
imgEmpty.setImageResource(if (nullOrEmpty) R.mipmap.empty_nothing else R.mipmap.empty_nothing_search)
tvContent.setText(if (nullOrEmpty) R.string.empty_nothing else R.string.empty_nothing_search)
}
}
override fun coverViewHolder(parent : ViewGroup, viewType : Int) : BaseAdapterViewHolder {
return BaseAdapterViewHolder(DataBindingUtil.inflate(LayoutInflater.from(parent.context), R.layout.item_test_score,parent,false))
}
@SuppressLint("SetTextI18n")
override fun onBindVH(holder : BaseAdapterViewHolder, position : Int) {
(holder.binding as ItemTestScoreBinding).run {
tvMarkNumber.text = "${position + 1}"
getItem(position).let {
val split = it.title.split("@@")
if (split.size > 1){
tvTitle.setHtml("${split[0]}<font color = \'#8A8A99\'><small>(${split[1]})</small></font>")
}else{
tvTitle.text = it.title
}
tvExamType.text = if (CourseManager.isSpokenAfterDialogueTest(it.examType,it.ext)){
"口语练习"
}else CourseManager.getExamTypeName(it.examType)
tvCreateTime.text = it.createTime
tvScore.text = if (it.examType == AppConstants.TEST_TYPE_NORMAL){
if (it.score > 0) it.score.toInt().toString() else "较少"
}else if (CourseManager.isSpokenAfterDialogueTest(it.examType,it.ext)){
"完成"
}else it.score.toInt().toString()
}
root.click {
if (onItemClickIsInitialized()){
onItemClick.invoke(it,position,getItem(position))
}
}
}
}
}
/*
class AdapterTestScore(val vm : TestScoreViewModel) : PagingDataAdapter<Exam,BaseAdapterViewHolder>(diffCallback) {
companion object{
private val diffCallback = object : DiffUtil.ItemCallback<Exam>(){
override fun areItemsTheSame(oldItem : Exam, newItem : Exam) : Boolean = oldItem.id == newItem.id
override fun areContentsTheSame(oldItem : Exam, newItem : Exam) : Boolean = oldItem == newItem
}
}
@SuppressLint("SetTextI18n")
override fun onBindViewHolder(holder : BaseAdapterViewHolder, position : Int) {
(holder.binding as ItemTestScoreBinding).run {
tvMarkNumber.text = "${position + 1}"
getItem(position)?.let {
val split = it.title.split("@@")
if (split.size > 1){
tvTitle.setHtml("${split[0]}<font color = \'#8A8A99\'><small>(${split[1]})</small></font>")
}else{
tvTitle.text = it.title
}
tvExamType.text = if (CourseManager.isSpokenAfterDialogueTest(it.examType,it.ext)){
"口语练习"
}else CourseManager.getExamTypeName(it.examType)
tvCreateTime.text = it.createTime
tvScore.text = if (it.examType == AppConstants.TEST_TYPE_NORMAL){
if (it.score > 0) it.score.toInt().toString() else "较少"
}else if (CourseManager.isSpokenAfterDialogueTest(it.examType,it.ext)){
"完成"
}else it.score.toInt().toString()
}
}
}
override fun onCreateViewHolder(parent : ViewGroup, viewType : Int) : BaseAdapterViewHolder {
return BaseAdapterViewHolder(DataBindingUtil.inflate(LayoutInflater.from(parent.context), R.layout.item_test_score,parent,false))
}
}*/

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

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

/**
* author suliang
* create 2022/7/13 10:48
* Describe:
*/
class VocabularyItem(val icon: Int, val level: String,val level_e: String)

+ 85
- 0
app/src/main/java/com/xkl/cdl/data/exam_record/AppDatabase.kt View File

@@ -0,0 +1,85 @@
package com.xkl.cdl.data.exam_record

import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import com.suliang.common.util.file.FileUtil
import com.xkl.cdl.module.XKLApplication
import mqComsumerV1.Struct
import java.io.File

/**
* author suliang
* create 2022/7/7 16:50
* Describe:
*/
@Database(entities = [Exam::class,ExamItem::class],version = 1,exportSchema = true)
abstract class AppDatabase : RoomDatabase() {
abstract fun examDao() : ExamDao
abstract fun examItemDao(): ExamItemDao
abstract fun examMiddleDao(): ExamMiddleDao
companion object{
private var DATABASE_NAME :String = "${FileUtil.getSaveDirPath("db")}${File.separator}app.db"
val instance by lazy(LazyThreadSafetyMode.SYNCHRONIZED) {
Room.databaseBuilder(XKLApplication.instance(), AppDatabase::class.java, DATABASE_NAME).build()
}
@JvmStatic
fun examBuilderToExamWithDetail(learnExam : Struct.LearnExam) : ExamWithDetail {
val exam = learnExam.run {
Exam(projectId.toInt(), packId, courseId, chapterId, lessonId, title, type.toInt(), score, totalNum.toInt(),
correctNum.toInt(), errorNum.toInt(), unanswerNum.toInt(), typeId, duration, ext, created, coverRate.toInt(),
stage)
}
val examItemList = mutableListOf<ExamItem>().apply {
learnExam.recordList.forEach {
add(ExamItem(it.questionId, it.questionType.toInt(), it.question, it.userAnswer, it.answerStatus.toInt(),
it.duration))
}
}
return ExamWithDetail(exam, examItemList)
}
@JvmStatic
fun examWithDetailToExamBuild(examWithDetail : ExamWithDetail) : Struct.LearnExam {
val examRecordList = mutableListOf<Struct.ExamRecord>().apply {
examWithDetail.examItemList.forEach {
add(Struct.ExamRecord.newBuilder().apply {
questionId = it.questionId
questionType = it.questionType.toLong()
question = it.question
userAnswer = it.userAnswer
answerStatus = it.answerStatus.toLong()
duration = it.duration
}.build())
}
}
return Struct.LearnExam.newBuilder().apply {
examWithDetail.exam.let {
projectId = it.projectId.toLong()
packId = it.packId
courseId = it.courseId
chapterId = it.chapterId
lessonId = it.lessonId
title = it.title
type = it.examType.toLong()
score = it.score
totalNum = it.totalNum.toLong()
correctNum = it.correctNum.toLong()
errorNum = it.errorNum.toLong()
unanswerNum = it.unAnswerNum.toLong()
duration = it.duration
ext = it.ext
created = it.createTime
typeId = it.typeId
coverRate = it.coverRate.toFloat()
stage = it.stage
}
addAllRecord(examRecordList)
}.build()
}
}
}

+ 33
- 0
app/src/main/java/com/xkl/cdl/data/exam_record/Exam.kt View File

@@ -0,0 +1,33 @@
package com.xkl.cdl.data.exam_record

import androidx.room.Entity
import androidx.room.PrimaryKey

/**
* author suliang
* create 2022/7/7 15:27
* Describe: 测试试卷
*/
@Entity(tableName = "exam")
data class Exam(val projectId : Int,
val packId : Long,
val courseId : Long,
val chapterId : Long, //章节测试必传
val lessonId : Long, //课时id
val title : String, //测试试卷名称
val examType : Int,
val score : Float,
val totalNum : Int,
val correctNum : Int,
val errorNum : Int,
val unAnswerNum : Int,
val typeId : Long, //作文必传,课程类型
val duration : Long, //测试所用时间 毫秒
val ext : String, //扩展字段 json
val createTime : String, //创建时间
val coverRate : Int, // 覆盖率
//词汇量测试测试阶段)
val stage : String) {
@PrimaryKey(autoGenerate = true)
var id : Long = 0L
}

+ 126
- 0
app/src/main/java/com/xkl/cdl/data/exam_record/ExamDao.kt View File

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

import androidx.room.Dao
import androidx.room.Insert
import androidx.room.Query
import androidx.room.RawQuery
import androidx.sqlite.db.SimpleSQLiteQuery
import androidx.sqlite.db.SupportSQLiteQuery
import com.suliang.common.util.LogUtil

/**
* author suliang
* create 2022/7/7 16:04
* Describe:
*/
@Dao
interface ExamDao {
/**
* 插入
* @param exam Exam
* @return Long
*/
@Insert
fun insert(exam:Exam) : Long
@RawQuery
fun query(query : SupportSQLiteQuery) : List<Exam>
/**
* 查询,实现拼接查询功能
* @param isAll Boolean? 是否全部
* @param examType Long? 测试类型
* @param projectId Long? 项目查询
* @param keyWord String? 关键词查询
* @param lastId Long 最后一条的id,初始默认为0
* @param pageSize Int 页码查询
*/
fun queryS(isAll:Boolean = false , examType:Int? ,projectId:Int? , keyWord_ : String? , lastId: Long?, pageSize : Int = 50 ) : List<Exam>{
val keyWord = if (keyWord_.isNullOrBlank()) null else keyWord_
val sql = when{
isAll -> keyWord ?. let {
lastId?.let {
"SELECT * FROM exam WHERE id < $lastId AND title LIKE %$keyWord% ORDER BY id DESC LIMIT $pageSize"
}?:let {
"SELECT * FROM exam WHERE title LIKE %$keyWord% ORDER BY id DESC LIMIT $pageSize"
}
} ?:let {
lastId?.let {
"SELECT * FROM exam WHERE id < $lastId ORDER BY id DESC LIMIT $pageSize"
}?:let {
"SELECT * FROM exam ORDER BY id DESC LIMIT $pageSize"
}
}
//课程测试的英语测试和作文测试
examType != null && projectId != null -> keyWord ?. let {
lastId?.let {
"SELECT * FROM exam WHERE id < $lastId AND examType = $examType AND projectId = $projectId AND title LIKE %$keyWord% ORDER BY id DESC LIMIT $pageSize"
}?:let {
"SELECT * FROM exam WHERE examType = $examType AND projectId = $projectId AND title LIKE %$keyWord% ORDER BY id DESC LIMIT $pageSize"
}
} ?:let {
lastId?.let {
"SELECT * FROM exam WHERE id < $lastId AND examType = $examType AND projectId = $projectId ORDER BY id DESC LIMIT $pageSize"
}?:let {
"SELECT * FROM exam WHERE examType = $examType AND projectId = $projectId ORDER BY id DESC LIMIT $pageSize"
}
}
examType != null -> keyWord ?. let {
lastId?.let {
"SELECT * FROM exam WHERE id < $lastId AND examType = $examType AND title LIKE %$keyWord% ORDER BY id DESC LIMIT $pageSize"
}?:let {
"SELECT * FROM exam WHERE examType = $examType AND title LIKE %$keyWord% ORDER BY id DESC LIMIT $pageSize"
}
} ?:let {
lastId?.let {
"SELECT * FROM exam WHERE id < $lastId AND examType = $examType ORDER BY id DESC LIMIT $pageSize"
}?:let {
"SELECT * FROM exam WHERE examType = $examType ORDER BY id DESC LIMIT $pageSize"
}
}
else -> ""
}
LogUtil.e(sql)
return query(SimpleSQLiteQuery(sql))
}
/* *//**
* 查询所有
* @param examId Long
* @return List<Exam>
*//*
@Query("SELECT * FROM exam ORDER BY id DESC")
// fun queryAll(): PagingSource<Int,Exam> //分页加载
fun query(examId: Long): List<Exam>
*//**
* 根据项目id查询
* @param projectId Int
* @return List<Exam>
*//*
@Query("SELECT * FROM exam WHERE projectId = :projectId")
fun queryWithProjectId(projectId: Int) : List<Exam>
*//**
* 根据测试类型查询
* @param examType Int
* @return List<Exam>
*//*
@Query("SELECT * FROM exam WHERE examType = :examType")
fun queryWithExamType(examType:Int) : List<Exam>
*//** 关键字模糊查询
* @param keyWord String 关键字
* @return List<Exam>
*//*
@Query("SELECT * FROM exam WHERE title LIKE '%' || :keyWord || '%'")
fun queryWithKeyWord(keyWord: String) : List<Exam>
*/
}

+ 21
- 0
app/src/main/java/com/xkl/cdl/data/exam_record/ExamItem.kt View File

@@ -0,0 +1,21 @@
package com.xkl.cdl.data.exam_record

import androidx.room.Entity
import androidx.room.PrimaryKey

/**
* author suliang
* create 2022/7/7 15:38
* Describe: 测试记录的item
*/
@Entity(tableName = "exam_item")
data class ExamItem( val questionId : Long ,
val questionType : Int,
val question : String, //题目和选项答案信息,json
val userAnswer : String, //用户答案
val answerStatus : Int, //回答状态(1:正确 0:未答 -1:错误)
val duration : Long //用时
) {
@PrimaryKey(autoGenerate = true) var itemId : Long = 0
var examId : Long = 0 // 试卷Exam所属id
}

+ 18
- 0
app/src/main/java/com/xkl/cdl/data/exam_record/ExamItemDao.kt View File

@@ -0,0 +1,18 @@
package com.xkl.cdl.data.exam_record

import androidx.room.Dao
import androidx.room.Insert

/**
* author suliang
* create 2022/7/7 16:48
* Describe:
*/
@Dao
interface ExamItemDao {
@Insert
fun insertAll(vararg examItem: ExamItem)
}

+ 35
- 0
app/src/main/java/com/xkl/cdl/data/exam_record/ExamMiddleDao.kt View File

@@ -0,0 +1,35 @@
package com.xkl.cdl.data.exam_record

import androidx.room.Dao
import androidx.room.Insert
import androidx.room.Query
import androidx.room.Transaction
import com.xkl.cdl.data.AppConstants

/**
* author suliang
* create 2022/7/7 18:00
* Describe: 中间数据类
*/
@Dao
interface ExamMiddleDao {
@Insert
fun insert(db : AppDatabase,exam:ExamWithDetail){
val insertId = db.examDao().insert(exam.exam)
if (exam.exam.examType != AppConstants.TEST_TYPE_NORMAL) {
exam.examItemList.forEach {
it.examId = insertId
}
db.examItemDao().insertAll(*exam.examItemList.toTypedArray())
}
}
/**
* 查询试卷与内容详情
* @param examId Long exam 存储唯一键id
* @return Exam
*/
@Transaction
@Query("SELECT * FROM exam WHERE id = :examId")
fun queryDetail(examId : Long): ExamWithDetail
}

+ 13
- 0
app/src/main/java/com/xkl/cdl/data/exam_record/ExamWithDetail.kt View File

@@ -0,0 +1,13 @@
package com.xkl.cdl.data.exam_record

import androidx.room.Embedded
import androidx.room.Relation

/**
* author suliang
* create 2022/7/7 16:00
* Describe: 试卷与试卷题目关联
*/
data class ExamWithDetail(@Embedded val exam : Exam,
@Relation(parentColumn = "id", entityColumn = "examId")
val examItemList : List<ExamItem>)

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

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

import android.text.TextUtils
import appApi.AppApi
import com.suliang.common.util.AppGlobals
import com.suliang.common.util.DateUtil
@@ -8,6 +9,7 @@ import com.xkl.cdl.data.AppConstants
import com.xkl.cdl.data.bean.course.CoursePack
import com.xkl.cdl.data.bean.course.ExamBean
import com.xkl.cdl.data.bean.course.Lesson
import org.json.JSONObject
import java.io.*
import java.lang.Exception
import java.math.BigDecimal
@@ -498,4 +500,24 @@ object CourseManager {
return result
}
/**
* 是否是口语对话练习
* @param examType Int
* @param ext String
* @return Boolean
*/
fun isSpokenAfterDialogueTest(examType : Int, ext : String) : Boolean {
if (examType == AppConstants.TEST_TYPE_AFTER && !TextUtils.isEmpty(ext)){
try {
val jsonObject = JSONObject(ext)
val courseType = jsonObject.getInt("courseType")
val lessonType = if (jsonObject.has("lessonType")) jsonObject.getInt("lessonType") else -1
return courseType == AppConstants.COURSE_TYPE_ENGLISH_SPOKEN && lessonType == AppConstants.LESSON_TYPE_DIALOGUE
} catch (e : Exception) {
e.printStackTrace()
}
}
return false
}
}

+ 17
- 0
app/src/main/java/com/xkl/cdl/data/manager/FilePathManager.kt View File

@@ -12,6 +12,23 @@ import java.io.File
class FilePathManager {

companion object{
/**
* 获取测词汇量数据所在的地址
* @return File
*/
@JvmStatic
fun getVocabularyDbPath(): File{
return File(getDbRootPath(), "vocabulary.db")
}
/**
* 获取词典数据所在的地址
* @return File
*/
@JvmStatic
fun getDictionaryDbPath(): File{
return File(getDbRootPath(), "dictionary.db")
}
/**
* 获取课程包目录数据所在的地址
* @return File

+ 48
- 0
app/src/main/java/com/xkl/cdl/data/manager/db/VocabularyManager.kt View File

@@ -0,0 +1,48 @@
package com.xkl.cdl.data.manager.db

import android.widget.Toast
import appApi.AppApi
import com.suliang.common.util.AppGlobals
import com.suliang.common.util.thread.AppExecutors
import com.xkl.cdl.data.AppConstants
import com.xkl.cdl.data.bean.VocabularyItem
import com.xkl.cdl.data.bean.course.ExamBean
import com.xkl.cdl.data.manager.FilePathManager
import net.sqlcipher.database.SQLiteDatabase

/**
* author suliang
* create 2022/7/14 17:28
* Describe:
*/
object VocabularyManager {
private var mDataBase : SQLiteDatabase? = null
private fun open() {
synchronized(VocabularyManager) {
if (mDataBase == null) {
mDataBase = SQLiteDatabase.openDatabase(FilePathManager.getVocabularyDbPath().path, "", null, SQLiteDatabase.OPEN_READONLY)
}
if (mDataBase == null) {
AppExecutors.mainThread.run {
Toast.makeText(AppGlobals.application, "词汇量测试数据获取失败,请重启应用或联系业务员", Toast.LENGTH_LONG)
}
}
}
}
/**
* 查询词汇量测试数据
* @param level VocabularyItem
* @return List<ExamBean>
*/
fun queryVocabularyTestData(level : VocabularyItem) : List<ExamBean>{
open()
val result = mutableListOf<ExamBean>()
val sql = "SELECT * FROM "
}
}

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

@@ -9,6 +9,10 @@ import com.suliang.common.util.file.FileUtil
import com.xkl.cdl.data.AppConstants
import com.xkl.cdl.data.bean.course.CourseDetail
import com.xkl.cdl.data.bean.course.Lesson
import com.xkl.cdl.data.exam_record.AppDatabase
import com.xkl.cdl.data.exam_record.Exam
import com.xkl.cdl.data.exam_record.ExamItem
import com.xkl.cdl.data.exam_record.ExamWithDetail
import com.xkl.cdl.data.manager.db.DBCourseManager
import com.xkl.cdl.data.manager.db.DbControlBase
import com.xkl.cdl.module.XKLApplication
@@ -16,40 +20,41 @@ import io.reactivex.rxjava3.core.Observable
import mqComsumerV1.Struct
import java.io.File
import java.io.FileOutputStream
import kotlin.math.sign

/**
* author suliang
* create 2022/3/29 10:24
* Describe: 数据提供
*/
* author suliang
* create 2022/3/29 10:24
* Describe: 数据提供
*/
object DataRepository {
// TODO: 2022/6/1 需自己实现获取课程收藏数据,同时需自己处理保存数据
/** 获取课程的收藏本 */
fun getCourseCollect() : Observable<HashMap<String,Long>>{
return Observable.create{
fun getCourseCollect() : Observable<HashMap<String, Long>> {
return Observable.create {
it.onNext(hashMapOf())
it.onComplete()
}
}
/** 获取复习的内容 */
fun getReviewData(subjectId : Int,coursePackId : Long,courseId : Long) : Observable<ProtocolStringList> {
return Observable.create{
fun getReviewData(subjectId : Int, coursePackId : Long, courseId : Long) : Observable<ProtocolStringList> {
return Observable.create {
val wordList = XKLApplication.mobileCache.getWordList(subjectId.toLong(), coursePackId, courseId, 2)
val parseFrom = wordList?.let {
AppApi.GetWordListResponse.parseFrom(wordList)
}?: AppApi.GetWordListResponse.newBuilder().build()
} ?: AppApi.GetWordListResponse.newBuilder().build()
it.onNext(parseFrom.wrongList)
it.onComplete()
}
}
/** 获取课程的详情 */
fun getCourseDetails(subjectId:Int, coursePackId:Long, courseId:Long): Observable<CourseDetail>{
return Observable.create{
fun getCourseDetails(subjectId : Int, coursePackId : Long, courseId : Long) : Observable<CourseDetail> {
return Observable.create {
val pbCourseDetail = XKLApplication.mobileCache.courseDetail(subjectId.toLong(), coursePackId, courseId).let {
AppApi.CourseDetailResponse .parseFrom(it).detail
AppApi.CourseDetailResponse.parseFrom(it).detail
}
val courseDetail = CourseDetail().apply {
courseLearnProgress = pbCourseDetail.s //课程学习进度
@@ -64,7 +69,7 @@ object DataRepository {
exam_w_r_list = HashMap(
pbCourseDetail.examWRListMap) //课程/课时学前测试正确错误列表 key=> {chapter_id}_{lesson_id}_{entity_id} value=>正确 true;错误 false
course_learn_point = pbCourseDetail.lp //课程学习进度点 {chapter_id}_{lesson_id}_{entity_id}
vp = HashMap(pbCourseDetail.vpMap) //视频播放点,记录最新的就行 时间点 key=>video_id value=>{时间点}
ct = pbCourseDetail.ct //课程已学词汇量
e = pbCourseDetail.e //学习效率
@@ -80,7 +85,7 @@ object DataRepository {
// rl: Int = 0 //课程重学次数;有值表示是重新学,默认不是重新学习,对应数值表示第几次重学 用于辨音,拼写判断是否解锁,
// chapter_rl: HashMap<String, Long> = hashMapOf() //章节重学次数,key =>{chapter_id}_{lesson_id} value=> relearn times
}
it.onNext(courseDetail)
it.onComplete()
// T这里自己使用的缓存
@@ -90,14 +95,14 @@ object DataRepository {
// }else{
// CourseDetail()
// }
}
}
/** 获取课程课时 */
fun getCourseAllLesson(base: DbControlBase,courseDetail: CourseDetail):Observable<List<Lesson>>{
return Observable.create{
it.onNext(DBCourseManager.queryAllLesson(base,courseDetail))
fun getCourseAllLesson(base : DbControlBase, courseDetail : CourseDetail) : Observable<List<Lesson>> {
return Observable.create {
it.onNext(DBCourseManager.queryAllLesson(base, courseDetail))
it.onComplete()
}
}
@@ -107,11 +112,11 @@ object DataRepository {
* @param record Builder
* @return Boolean
*/
fun saveRecord(record : Struct.Record.Builder): Boolean {
fun saveRecord(record : Struct.Record.Builder) : Boolean {
var subjectId : Long = 0
var coursePackId : Long = 0
var courseId : Long = 0
when{
when {
record.entityCount > 0 -> {
record.getEntity(0).let {
subjectId = it.projectId
@@ -137,15 +142,23 @@ object DataRepository {
LogUtil.e("保存数据 -> \n ${JsonFormat.printToString(record.build())}")
try {
XKLApplication.mobileCache.parseData(record.build().toByteArray())
if (subjectId != 0L ){
//如果是测试数据,进行数据转换,并将数据进行保存
if (record.examCount > 0) {
val examWithDetail = AppDatabase.examBuilderToExamWithDetail(record.getExam(0))
AppDatabase.instance.examMiddleDao().insert(AppDatabase.instance,examWithDetail)
}
if (subjectId != 0L) {
//计算词汇量和学习效率
calcCourseVocabularyAndEfficiency(subjectId,coursePackId,courseId)
calcCourseVocabularyAndEfficiency(subjectId, coursePackId, courseId)
}
} catch (e : Exception) {
e.printStackTrace()
return false
}

/*var fileName = ""
//写入文件
if (record.examCount > 0 ){ //当前为测试
@@ -180,17 +193,19 @@ object DataRepository {
FileUtil.writeBytesToFile(it,saveByteArrayName,saveArray)
}*/
return true
return true
}
// TODO: 2022/6/1 计算词汇量和效率可以在需要的时候进行计算后再获取
/**
* 计算当前词汇量 与 学习效率
*/
private fun calcCourseVocabularyAndEfficiency( projectId:Long, packId:Long, courseId:Long) {
private fun calcCourseVocabularyAndEfficiency(projectId : Long, packId : Long, courseId : Long) {
Observable.create<Boolean> {
try {
XKLApplication.mobileCache.calcCurrentVocabulary(projectId) //词汇量
XKLApplication.mobileCache.calcEfficiency(projectId,packId,courseId) //效率
XKLApplication.mobileCache.calcEfficiency(projectId, packId, courseId) //效率
} catch (e : Exception) {
e.printStackTrace()
}
@@ -199,15 +214,15 @@ object DataRepository {
}
/** 获取备忘本可测试的课时 */
fun queryMemoLesson(base: DbControlBase,memoList: MutableList<String>):Observable<List<Lesson>>{
return Observable.create{
it.onNext(DBCourseManager.queryMemoLesson(base,memoList))
fun queryMemoLesson(base : DbControlBase, memoList : MutableList<String>) : Observable<List<Lesson>> {
return Observable.create {
it.onNext(DBCourseManager.queryMemoLesson(base, memoList))
it.onComplete()
}
}
/** 获取词条数统计 */
fun getStatisticsChartData(projectId:Int): Observable<AppApi.EntityCountListResponse> {
fun getStatisticsChartData(projectId : Int) : Observable<AppApi.EntityCountListResponse> {
return Observable.create {
//近90天词条数统计
val entityCountList = XKLApplication.mobileCache.entityCountList(projectId.toLong(), 0)
@@ -217,4 +232,5 @@ object DataRepository {
}
}
}

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

@@ -13,6 +13,7 @@ import net.sqlcipher.database.SQLiteDatabase
import java.io.File
import java.io.IOException
import java.util.*
import kotlin.properties.Delegates

/**
* author suliang
@@ -26,11 +27,14 @@ class XKLApplication : Application() {
val file : String = File(FileUtil.getSaveDirFile("db"), "mydb").absolutePath
Mobile_cache.new_(file)
}
private var instance : XKLApplication by Delegates.notNull()
fun instance() = instance
}
override fun onCreate() {
super.onCreate()
instance = this
SQLiteDatabase.loadLibs(this)
LogUtil.e(UUID.randomUUID().toString().replace("-",""))
//初始MMKV存储

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

@@ -84,10 +84,10 @@ class MemoTestActivity : BaseActivityVM<ActivityMemoTestBinding, MemoTestViewMod
1 -> { //备忘本
binding.tvCourse.setHtml("当前课程:<font color=\'#5082E6\'>${vm.memoData.course.courseTitle}</font>")
binding.rbMemo.isChecked = true
binding.tvCourse.visibility = View.VISIBLE
}
2 -> { //课程测试
binding.group1.visibility = View.VISIBLE
binding.tvCourse.visibility = View.GONE
binding.rbLesson.isChecked = true
}
}

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

@@ -57,8 +57,8 @@ class ServiceCenterFragment : BaseFragmentVM<ServiceCenterFragmentBinding, Main
private fun startTo(position : Int) {
when(position){
0 -> startActivity(CourseTestActivity::class.java)
1 -> ""
2 -> ""
1 -> startActivity(TestVocabularyActivity::class.java)
2 -> startActivity(TestScoreActivity::class.java)
3 -> ""
}
}

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

@@ -2,6 +2,7 @@ package com.xkl.cdl.module.m_service_center

import android.annotation.SuppressLint
import android.os.Bundle
import android.view.View
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import com.suliang.common.base.activity.BaseActivityVM
@@ -11,6 +12,7 @@ import com.xkl.cdl.adapter.AdapterTestDetail
import com.xkl.cdl.data.AppConstants
import com.xkl.cdl.data.manager.CourseManager
import com.xkl.cdl.databinding.ActivityTestDetailBinding
import mqComsumerV1.Struct

/**
* author suliang
@@ -25,8 +27,30 @@ class TestDetailActivity : BaseActivityVM<ActivityTestDetailBinding,TestDetailVi
@SuppressLint("SetTextI18n")
override fun initActivity(savedInstanceState : Bundle?) {
// TODO: 2022/6/21 词汇量测试暂未考虑
//词汇量测试
if (vm.learnExam.type == AppConstants.TEST_TYPE_NORMAL.toLong()){
binding.run {
layoutMemoTest.visibility = View.GONE
layoutVocabulary.visibility = View.VISIBLE
tvVocabularyTestTime.text = vm.learnExam.created
if (vm.learnExam.score > 0){
groupVocabularyLittle.visibility = View.GONE
groupVocabularyNormal.visibility = View.VISIBLE
tvVocabularyCount.text = "${vm.learnExam.score}"
ratingBar.setStar(vm.learnExam.score/20)
tvVocabularyCoverRateStage.setHtml("覆盖率<font color=\'#F7874F\'>${vm.learnExam.coverRate}%</font>\t\t(${vm.learnExam.stage})")
}else{
groupVocabularyLittle.visibility = View.VISIBLE
groupVocabularyNormal.visibility = View.GONE
tvVocabularyLevel.text = vm.learnExam.stage
}
}
return
}
//正常测试
binding.run {
layoutMemoTest.visibility = View.VISIBLE
layoutVocabulary.visibility = View.GONE
titleBar.onBackClick = { v -> finish() }
tvCourseName.setHtml(initCourseName())
tvScore.setHtml(initScore())
@@ -51,7 +75,7 @@ class TestDetailActivity : BaseActivityVM<ActivityTestDetailBinding,TestDetailVi
private fun initCourseName() : String{
val split = vm.learnExam.title.split("@@")
return if (split.size > 1){
"${split[0]}<font color=\'#8A8A99\'>(${split[1]})</font>"
"${split[0]}<font color=\'#8A8A99\'><small>(${split[1]})</small></font>"
}else{
split[0]
}

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

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

import android.os.Bundle
import android.view.View
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.flexbox.FlexDirection
import com.google.android.flexbox.FlexWrap
import com.google.android.flexbox.FlexboxLayoutManager
import com.scwang.smart.refresh.layout.api.RefreshLayout
import com.scwang.smart.refresh.layout.listener.OnRefreshLoadMoreListener
import com.suliang.common.base.activity.BaseActivityVM
import com.suliang.common.extension.click
import com.suliang.common.extension.diskIo2Main
import com.suliang.common.util.DrawableUti
import com.xkl.cdl.R
import com.xkl.cdl.adapter.AdapterTestFilter
import com.xkl.cdl.adapter.AdapterTestScore
import com.xkl.cdl.data.DataTransferHolder
import com.xkl.cdl.data.exam_record.AppDatabase
import com.xkl.cdl.databinding.ActivityTestScoreBinding
import com.xkl.cdl.widget.MyFlexboxLayoutManager
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.core.ObservableConverter

class TestScoreActivity : BaseActivityVM<ActivityTestScoreBinding, TestScoreViewModel>() {
override fun initViewModel() : TestScoreViewModel {
return ViewModelProvider(this)[TestScoreViewModel::class.java]
}
private lateinit var detailAdapter : AdapterTestScore
private lateinit var filterAdapter : AdapterTestFilter
override fun initActivity(savedInstanceState : Bundle?) {
binding.vm = vm
//标题
binding.titleBar.run {
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.GONE
binding.etSearch.visibility = View.GONE
binding.etSearch.setText("")
}
//关键字查询
vm.keyWordSearch.observe(this) {
binding.rvList.scrollToPosition(0)
binding.smartRefresh.autoRefresh()
}
//筛选rv
filterAdapter = AdapterTestFilter(vm)
binding.rvFilter.apply {
layoutManager = LinearLayoutManager(this@TestScoreActivity,
LinearLayoutManager.HORIZONTAL, false)
adapter = filterAdapter
}
filterAdapter.setData(vm.filterArray)
//筛选的下拉箭头
binding.ivExtend.click {
vm.downState.value = !vm.downState.value!!
}
binding.vMaskLayer.click {
vm.downState.value = !vm.downState.value!!
}
//列表rv
detailAdapter = AdapterTestScore(vm)
binding.rvList.apply {
layoutManager = LinearLayoutManager(this@TestScoreActivity, LinearLayoutManager.VERTICAL, false)
adapter = detailAdapter.apply {
onItemClick = {_, _, item ->
Observable.fromCallable {
val queryDetail = AppDatabase.instance.examMiddleDao().queryDetail(item.id)
AppDatabase.examWithDetailToExamBuild(queryDetail)
}.compose(diskIo2Main()).subscribe{
DataTransferHolder.instance.putData(value = it)
startActivity(TestDetailActivity::class.java)
}
}
}
}
binding.smartRefresh.setEnableLoadMore(true)
binding.smartRefresh.setOnRefreshLoadMoreListener(object : OnRefreshLoadMoreListener {
override fun onRefresh(refreshLayout : RefreshLayout) {
binding.smartRefresh.setNoMoreData(false)
vm.loadExam(false)
}
override fun onLoadMore(refreshLayout : RefreshLayout) {
vm.loadExam(true)
}
})
//筛选item改变
vm.filterPosition.observe(this) {
binding.smartRefresh.autoRefresh()
}
}
override fun loadData() {
// 设置筛选的item
/*lifecycleScope.launch{
@OptIn(ExperimentalCoroutinesApi::class)
vm.allExam.collectLatest {
detailAdapter.submitData(it)
}
}*/
binding.rvFilter.post {
vm.downState.observe(this) {
when {
//展开
it -> {
binding.ivExtend.setImageResource(R.drawable.ic_up)
binding.rvFilter.layoutManager = MyFlexboxLayoutManager(this, FlexDirection.ROW, FlexWrap.WRAP)
binding.vMaskLayer.visibility = View.VISIBLE
}
//收起
else -> {
binding.ivExtend.setImageResource(R.drawable.ic_down)
binding.rvFilter.layoutManager = LinearLayoutManager(this@TestScoreActivity,
LinearLayoutManager.HORIZONTAL, false)
binding.rvFilter.scrollToPosition(vm.filterPosition.value!!)
binding.vMaskLayer.visibility = View.GONE
}
}
}
}
/**数据更新*/
vm.dataLiveData.observe(this) {
when {
//加载更多
vm.isLoadMore -> {
detailAdapter.addData(it)
if (vm.isHaveNextPage) {
binding.smartRefresh.finishLoadMore()
} else {
binding.smartRefresh.finishLoadMoreWithNoMoreData()
}
}
//刷新
else -> {
binding.smartRefresh.finishRefresh()
if (it.isNullOrEmpty()){
detailAdapter.needShowEmptyView = true
}
detailAdapter.setData(it.toMutableList())
if (!vm.isHaveNextPage) {
binding.smartRefresh.setNoMoreData(true)
}
}
}
}
}
}

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

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

import androidx.lifecycle.MutableLiveData
import com.suliang.common.base.viewmodel.BaseViewModel
import com.suliang.common.extension.diskIo2Main
import com.xkl.cdl.data.AppConstants
import com.xkl.cdl.data.exam_record.AppDatabase
import com.xkl.cdl.data.exam_record.Exam
import io.reactivex.rxjava3.core.Observable

class TestScoreViewModel : BaseViewModel() {
/**搜索框: 搜索关键字*/
val keyWordSearch = MutableLiveData<String>()
/** 筛选数组 */
val filterArray = mutableListOf("全部", "学前总测试", "学后总测试", "课时学前测试", "课时学后测试", "词汇量测试", "课程测试", "知识点测试", "备忘本测试", "英语课程测试",
"作文课程测试")
//默认选中
val filterPosition = MutableLiveData(0)
//下拉状态 是否展开
val downState = MutableLiveData<Boolean>(false)
private val pageSize = 50 //分页数量
private var totalSize = 0 //总数
private var lastId : Long? = null //最后一条id
var isHaveNextPage : Boolean = false //是否还有下一页
//记录当前加载的isLoadMore状态
var isLoadMore = false
//通知数据有更新
val dataLiveData = MutableLiveData<List<Exam>>()
fun loadExam(isLoadMore : Boolean) {
this.isLoadMore = isLoadMore
//如果是刷新,lastId为null
if (!isLoadMore) {
isHaveNextPage = true
lastId = null
}
Observable.create<List<Exam>> {
val queryS = AppDatabase.instance.examDao()
.queryS(isAll = isFilterAll(), examType = getExamType(), projectId = getTestProjectId(),
keyWord_ = keyWordSearch.value, lastId, pageSize = pageSize)
it.onNext(queryS)
it.onComplete()
}.compose(diskIo2Main()).subscribe({
isHaveNextPage = it.size == pageSize
lastId = if (it.isNullOrEmpty()) null else it.last().id
dataLiveData.value = it
}, {
it.printStackTrace()
dataLiveData.value = mutableListOf()
})
}
/**筛选的是否是全部*/
private fun isFilterAll() : Boolean {
return filterPosition.value == 0
}
private fun getExamType() : Int? {
return when (filterPosition.value) {
1 -> AppConstants.TEST_TYPE_BEFORE_TOTAL
2 -> AppConstants.TEST_TYPE_AFTER_TOTAL
3 -> AppConstants.TEST_TYPE_BEFORE
4 -> AppConstants.TEST_TYPE_AFTER
5 -> AppConstants.TEST_TYPE_NORMAL
7 -> AppConstants.TEST_TYPE_COMPOSITION
8 -> AppConstants.TEST_TYPE_MEMO
6, 9, 10 -> AppConstants.TEST_TYPE_SERVICE_CENTER
else -> null
}
}
private fun getTestProjectId() : Int? {
return when (filterPosition.value) {
9 -> AppConstants.SUBJECT_CHINESE
10 -> AppConstants.SUBJECT_CHINESE
else -> null
}
}


// companion object{
// private const val PAGE_SIZE = 15
// private const val ENABLE_PLACEHOLDERS = false
// }
//
// val allExam = Pager(PagingConfig(PAGE_SIZE, enablePlaceholders = ENABLE_PLACEHOLDERS,maxSize = 100)){
// AppDatabase.instance.examDao().queryAll()
// }.flow
}

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

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

import android.os.Bundle
import android.view.ViewGroup
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import com.suliang.common.base.activity.BaseActivityVM
import com.suliang.common.base.adapter.BaseAdapterViewHolder
import com.suliang.common.base.adapter.BaseRVAdapter
import com.suliang.common.extension.click
import com.xkl.cdl.R
import com.xkl.cdl.data.bean.VocabularyItem
import com.xkl.cdl.databinding.ActivityTestVocabularyBinding
import com.xkl.cdl.databinding.ItemVocabularyLevelBinding

class TestVocabularyActivity : BaseActivityVM<ActivityTestVocabularyBinding, TestVocabularyViewModle>() {
override fun initViewModel() : TestVocabularyViewModle {
return ViewModelProvider(this)[TestVocabularyViewModle::class.java]
}
override fun initActivity(savedInstanceState : Bundle?) {
binding.titleBar.onBackClick = {_ -> finish()}
binding.rv.apply {
layoutManager = LinearLayoutManager(this@TestVocabularyActivity,LinearLayoutManager.VERTICAL,false)
setHasFixedSize(true)
adapter = object :BaseRVAdapter<VocabularyItem>(vm.data){
override fun coverViewHolder(parent : ViewGroup, viewType : Int) : BaseAdapterViewHolder {
return BaseAdapterViewHolder(inflateBinding(parent, R.layout.item_vocabulary_level))
}
override fun onBindVH(holder : BaseAdapterViewHolder, position : Int) {
getItem(position).let {
(holder.binding as ItemVocabularyLevelBinding).run {
iv.setImageResource(it.icon)
tvLevel.text = it.level
tvLevelE.text = it.level_e
root.click {
// vm.queryVocabulary(it)
}
}
}
}
}
}
}
override fun loadData() {
}
}

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

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

import androidx.lifecycle.MutableLiveData
import com.suliang.common.base.viewmodel.BaseViewModel
import com.suliang.common.extension.diskIo2Main
import com.xkl.cdl.R
import com.xkl.cdl.data.bean.VocabularyItem
import com.xkl.cdl.data.bean.course.ExamBean
import com.xkl.cdl.data.manager.db.DBCourseManager
import io.reactivex.rxjava3.core.Observable

/**
* author suliang
* create 2022/7/13 10:38
* Describe:
*/
class TestVocabularyViewModle : BaseViewModel() {
val data = mutableListOf(
VocabularyItem(R.mipmap.ic_comprehensive_test,"综合测试",""),
VocabularyItem(R.mipmap.ic_primary_school,"小学",""),
VocabularyItem(R.mipmap.ic_junior_school,"初中",""),
VocabularyItem(R.mipmap.ic_high_school,"高中",""),
VocabularyItem(R.mipmap.ic_university_4,"大学四级",""),
VocabularyItem(R.mipmap.ic_university_6,"大学六级",""),
VocabularyItem(R.mipmap.ic_lelts,"雅思",""),
VocabularyItem(R.mipmap.ic_toefl,"托福","") )
/**
* 查询测试数据
* @param item VocabularyItem
*/
fun queryVocabularyTestData(item : VocabularyItem) : MutableLiveData<List<ExamBean>> {
val result = MutableLiveData<List<ExamBean>>()
Observable.create<List<ExamBean>> {
it.onNext(DBCourseManager.queryLearnTest(dbControlBase, testType, lesson))
it.onComplete()
}.compose(diskIo2Main()).subscribe({
result.value = it
}, {
it.printStackTrace()
})
return result
}
}

+ 13
- 2
app/src/main/java/com/xkl/cdl/module/splash/SplashActivity.kt View File

@@ -6,14 +6,17 @@ import appApi.AppApi
import com.googlecode.protobuf.format.JsonFormat
import com.suliang.common.base.activity.BaseActivity
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.manager.CourseManager
import com.xkl.cdl.data.manager.FilePathManager
import com.xkl.cdl.data.manager.db.DbCoursePackManager
import com.xkl.cdl.databinding.ActivitySplashBinding
import com.xkl.cdl.module.XKLApplication
import com.xkl.cdl.module.main.MainActivity
import io.reactivex.rxjava3.core.Observable
import java.io.File
import java.util.*
import java.util.concurrent.TimeUnit

@@ -36,8 +39,6 @@ class SplashActivity : BaseActivity<ActivitySplashBinding>() {
showHideLoading(true)
AppExecutors.diskIO.execute {
//读取课程数据
//用户的sort信息
@@ -50,6 +51,16 @@ class SplashActivity : BaseActivity<ActivitySplashBinding>() {
val parseFrom = AppApi.CourseSortedResponse.parseFrom(value).toBuilder()
CourseManager.mSortInfoList.put(AppConstants.SUBJECT_CHINESE, parseFrom.listBuilderList)
}
//复制词典 和 词汇量测试
val dictionary = FilePathManager.getDictionaryDbPath()
if (!dictionary.exists()) {
val copyAssetResult = FileUtil.copyAsset("dictionary.db", dictionary)
}
val vocabulary = FilePathManager.getVocabularyDbPath()
if (!dictionary.exists()) {
val copyAssetResult = FileUtil.copyAsset("vocabulary.db", vocabulary)
}
// TODO: 2022/3/22 读取当前app绑定的课程数据,
DbCoursePackManager().queryBindingCoursePack("262,261,264,136,547,615,516,411")

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

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

import android.content.Context
import android.util.AttributeSet
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.google.android.flexbox.FlexboxLayoutManager

/**
* author suliang
* create 2022/7/12 10:56
* Describe:
*/
class MyFlexboxLayoutManager : FlexboxLayoutManager {
constructor(context : Context): super(context)
constructor(context : Context,flexDirection : Int): super(context,flexDirection)
constructor(context : Context,flexDirection : Int,flexWrap : Int): super(context,flexDirection,flexWrap)
constructor(context:Context, attrs : AttributeSet, defStyleAttr :Int,defStyleRes: Int) : super(context,attrs,defStyleAttr,defStyleRes)
/**
* 将LayoutParams转换成新的FlexboxLayoutManager.LayoutParams
*/
override fun generateLayoutParams(lp : ViewGroup.LayoutParams) : RecyclerView.LayoutParams {
return FlexboxLayoutManager.LayoutParams(lp)
}
}

+ 5
- 0
app/src/main/res/color/rb_select_gray_white.xml View File

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

+ 16
- 0
app/src/main/res/drawable/rb_select_white1_theme_bg.xml View File

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

</selector>

+ 237
- 63
app/src/main/res/layout/activity_test_detail.xml View File

@@ -10,52 +10,226 @@
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".module.m_service_center.TestDetailActivity"
android:background="@color/white">
android:background="@color/white"
tools:context=".module.m_service_center.TestDetailActivity">

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

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


<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/layout_vocabulary"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="@dimen/line_height"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:background="@color/gray_1" />
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/title_bar"
tools:visibility="visible"
>

<TextView
android:id="@+id/tv_vocabulary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/global_spacing"
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_toTopOf="parent" />

<TextView
android:id="@+id/tv_vocabulary_test_time_flag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="@string/test_time_1"
android:textColor="@color/gray_2"
android:textSize="@dimen/smallSize"
app:layout_constraintEnd_toStartOf="@+id/tv_vocabulary_test_time"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_vocabulary"
app:layout_constraintHorizontal_chainStyle="packed"/>

<TextView
android:id="@+id/tv_vocabulary_test_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/gray_2"
android:textSize="@dimen/smallSize"
app:layout_constraintBaseline_toBaselineOf="@+id/tv_vocabulary_test_time_flag"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/tv_vocabulary_test_time_flag"
tools:text="时间" />


<TextView
android:id="@+id/tv_vocabulary_count_flag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="@string/vocabulary"
android:textColor="@color/gray_2"
android:textSize="@dimen/smallSize"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_vocabulary_test_time_flag" />

<TextView
android:id="@+id/tv_vocabulary_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/red_1"
android:textSize="60dp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_vocabulary_count_flag"
tools:text="1000" />

<com.xl.ratingbar.MyRatingBar
android:id="@+id/rating_bar"
android:layout_width="wrap_content"
android:layout_height="24dp"
android:layout_marginTop="24dp"
android:clickable="false"
android:gravity="center"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_vocabulary_count"
app:starEmpty="@drawable/ic_star"
app:starFill="@drawable/ic_star_1"
app:starHalf="@drawable/ic_star_1"
app:starCount = "5"
tools:starNum = "2"
app:starImageWidth="24dp"
app:starImageHeight="24dp"/>


<TextView
android:id="@+id/tv_vocabulary_cover_rate_stage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
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/rating_bar"
tools:text="覆盖率67%(高中)" />


<!--少-->
<ImageView
android:id="@+id/iv_little"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="38dp"
android:src="@mipmap/cry"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_vocabulary_test_time" />

<TextView
android:id="@+id/tv_vocabulary_little"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="@string/little_vocabulary"
android:textColor="@color/main_text_color"
android:textSize="@dimen/normalSize"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/iv_little" />

<TextView
android:id="@+id/tv_vocabulary_test_level_flag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:text="@string/vocabulary_level"
android:textColor="@color/gray_2"
android:textSize="@dimen/smallSize"
app:layout_constraintEnd_toStartOf="@+id/tv_vocabulary_level"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_vocabulary_little" />

<TextView
android:id="@+id/tv_vocabulary_level"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/gray_2"
android:textSize="@dimen/smallSize"
app:layout_constraintBaseline_toBaselineOf="@+id/tv_vocabulary_test_level_flag"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/tv_vocabulary_test_level_flag"
tools:text="时间" />

<androidx.constraintlayout.widget.Group
android:id="@+id/group_vocabulary_little"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="iv_little,tv_vocabulary_little,tv_vocabulary_test_level_flag,tv_vocabulary_level"
tools:visibility="gone"/>

<androidx.constraintlayout.widget.Group
android:id="@+id/group_vocabulary_normal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="tv_vocabulary_count_flag,tv_vocabulary_count,rating_bar,tv_vocabulary_cover_rate_stage"
tools:visibility="visible"/>


</androidx.constraintlayout.widget.ConstraintLayout>


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

+ 142
- 0
app/src/main/res/layout/activity_test_score.xml View File

@@ -0,0 +1,142 @@
<?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>
<variable
name="vm"
type="com.xkl.cdl.module.m_service_center.TestScoreViewModel" />
</data>

<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".module.m_service_center.TestScoreActivity"
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_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:titleTextValue="@string/test_score" />

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

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

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_filter"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:minHeight="42dp"
app:layout_constraintTop_toBottomOf="@+id/title_bar"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@+id/iv_extend"
android:paddingStart="@dimen/global_spacing"
android:paddingBottom="8dp"
tools:itemCount="10"
tools:listitem="@layout/item_test_filter"
tools:layoutManager="com.google.android.flexbox.FlexboxLayoutManager"
tools:orientation="horizontal"/>

<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/iv_extend"
android:layout_width="30dp"
android:layout_height="30dp"
app:contentPadding="7dp"
android:src="@drawable/ic_down"
app:layout_constraintStart_toEndOf="@+id/rv_filter"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/rv_filter"
android:layout_marginRight="@dimen/global_spacing"
android:layout_marginTop="6dp"/>


<com.scwang.smart.refresh.layout.SmartRefreshLayout
android:id="@+id/smart_refresh"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="@+id/rv_filter"
app:layout_constraintBottom_toBottomOf="parent">

<com.xkl.cdl.widget.smartRefresh.XkLRefreshHeader
android:layout_width="match_parent"
android:layout_height="wrap_content"/>

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minHeight="42dp"/>

<com.scwang.smart.refresh.footer.ClassicsFooter
android:layout_width="match_parent"
android:layout_height="wrap_content"/>

</com.scwang.smart.refresh.layout.SmartRefreshLayout>



<View
android:id="@+id/v_mask_layer"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="@+id/rv_filter"
app:layout_constraintBottom_toBottomOf="parent"
android:clickable="true"
android:background="#4D000000"
android:visibility="gone"
tools:visibility="visible"/>





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

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

@@ -0,0 +1,52 @@
<?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.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".module.m_service_center.TestVocabularyActivity"
android:background="@color/white"
android:orientation="vertical">

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

<View
android:layout_width="match_parent"
android:layout_height="@dimen/line_height"
android:background="@color/gray_1"/>

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="请选择你的测试等级"
android:layout_margin="@dimen/global_spacing"
android:textColor="@color/gray_2"
android:textSize="@dimen/normalSize"
/>

<View
android:layout_width="match_parent"
android:layout_height="@dimen/line_height"
android:background="@color/gray_1"/>

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:overScrollMode="never"
android:layout_marginTop="12dp"
android:scrollbars="none"/>


</androidx.appcompat.widget.LinearLayoutCompat>
</layout>

+ 32
- 0
app/src/main/res/layout/item_test_filter.xml View File

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

<data>

</data>

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

<RadioButton
android:id="@+id/rb"
android:layout_width="wrap_content"
android:layout_height="26dp"
android:layout_marginStart="6dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="6dp"
android:background="@drawable/rb_select_white1_theme_bg"
android:button="@null"
android:checked="true"
android:gravity="center"
android:paddingStart="8dp"
android:paddingEnd="8dp"
android:textColor="@color/rb_select_gray_white"
android:textSize="@dimen/smallSize"
tools:text="全部"/>
</androidx.appcompat.widget.LinearLayoutCompat>

</layout>

+ 89
- 0
app/src/main/res/layout/item_test_score.xml View File

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

<data>

</data>

<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="12dp"
android:paddingBottom="12dp"
android:paddingStart="@dimen/global_spacing"
android:paddingEnd="@dimen/global_spacing">

<TextView
android:id="@+id/tv_mark_number"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:background="@drawable/shape_cicler_24_c3d69b"
android:backgroundTint="#1A5082E6"
android:gravity="center"
android:textColor="@color/theme_color"
android:textSize="@dimen/normalSize"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintHeight_min="24dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_min="24dp"
tools:text="91" />

<TextView
android:id="@+id/tv_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintStart_toEndOf="@+id/tv_mark_number"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@+id/tv_exam_type"
app:layout_constraintEnd_toStartOf="@+id/tv_score"
android:layout_marginStart="12dp"
android:layout_marginEnd="12dp"
android:maxLines="2"
android:ellipsize="end"
android:textSize="@dimen/normalSize"
android:textColor="@color/main_text_color"
tools:text="课程名称名称" />

<TextView
android:id="@+id/tv_exam_type"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@+id/tv_title"
app:layout_constraintStart_toStartOf="@+id/tv_title"
app:layout_constraintBottom_toBottomOf="parent"
android:textSize="@dimen/smallSize"
android:textColor="@color/theme_color"
android:layout_marginTop="4dp"
tools:text="测试类型" />

<TextView
android:id="@+id/tv_create_time"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintStart_toEndOf="@+id/tv_exam_type"
app:layout_constraintBaseline_toBaselineOf="@+id/tv_exam_type"
tools:text="12:12:12"
android:textSize="@dimen/smallSize"
android:textColor="@color/gray_2"
android:layout_marginStart="24dp" />

<TextView
android:id="@+id/tv_score"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/tv_title"
app:layout_constraintEnd_toEndOf="parent"
android:textSize="26dp"
android:textColor="@color/red_1"
android:textStyle="bold"
tools:text="100" />


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

+ 50
- 0
app/src/main/res/layout/item_vocabulary_level.xml View File

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

<data>

</data>

<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/shape_rounder_12_white"
android:padding="@dimen/global_spacing"
android:layout_marginBottom="12dp"
android:layout_marginStart="@dimen/global_spacing"
android:layout_marginEnd="@dimen/global_spacing">

<ImageView
android:id="@+id/iv"
android:layout_width="50dp"
android:layout_height="50dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />

<TextView
android:id="@+id/tv_level"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toEndOf="@+id/iv"
app:layout_constraintTop_toTopOf="@+id/iv"
android:layout_marginStart="@dimen/global_spacing"
android:textStyle="bold"
android:textColor="@color/main_text_color"
android:textSize="@dimen/normalSize"
tools:text="综合测试" />

<TextView
android:id="@+id/tv_level_e"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="@id/tv_level"
app:layout_constraintBottom_toBottomOf="@+id/iv"
android:textColor="@color/gray_2"
android:textSize="@dimen/smallSize"
tools:text="ckkdjkj" />

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

BIN
app/src/main/res/mipmap-xxhdpi/cry.png View File


BIN
app/src/main/res/mipmap-xxhdpi/ic_comprehensive_test.png View File


BIN
app/src/main/res/mipmap-xxhdpi/ic_high_school.png View File


BIN
app/src/main/res/mipmap-xxhdpi/ic_junior_school.png View File


BIN
app/src/main/res/mipmap-xxhdpi/ic_lelts.png View File


BIN
app/src/main/res/mipmap-xxhdpi/ic_primary_school.png View File


BIN
app/src/main/res/mipmap-xxhdpi/ic_toefl.png View File


BIN
app/src/main/res/mipmap-xxhdpi/ic_university_4.png View File


BIN
app/src/main/res/mipmap-xxhdpi/ic_university_6.png View File


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

@@ -94,5 +94,10 @@
<string name="test_time_1">测试时间:</string>
<string name="course_test">课程测试</string>
<string name="next_step">下一步</string>
<string name="test_score">测试成绩</string>
<string name="little_vocabulary">词汇量较少</string>
<string name="vocabulary_level">测试等级:</string>
<string name="vocabulary">词汇量</string>
<string name="test_vocabulary">测词汇量</string>

</resources>

+ 24
- 0
app/svg/drawable/ic_star.xml View File

@@ -0,0 +1,24 @@
<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="M-232,-268h375v812h-375z"
android:strokeWidth="1"
android:fillColor="#FFFFFF"
android:fillType="evenOdd"
android:strokeColor="#00000000"/>
<path
android:pathData="M11.7729,19.707L7.2406,21.3187C6.6748,21.5199 6.053,21.2243 5.8517,20.6585C5.8068,20.5321 5.7856,20.3984 5.7893,20.2643L5.9215,15.4557C5.9284,15.2057 5.8489,14.961 5.6964,14.7627L2.763,10.9503C2.3968,10.4743 2.4858,9.7916 2.9617,9.4254C3.0681,9.3435 3.1887,9.2821 3.3174,9.2442L7.9314,7.884C8.1713,7.8133 8.3795,7.662 8.5209,7.4557L11.2403,3.4878C11.5798,2.9924 12.2566,2.8661 12.752,3.2056C12.8627,3.2814 12.9584,3.3771 13.0342,3.4878L15.7536,7.4557C15.895,7.662 16.1032,7.8133 16.3431,7.884L20.9572,9.2442C21.5332,9.414 21.8625,10.0186 21.6927,10.5947C21.6548,10.7234 21.5933,10.8439 21.5115,10.9503L18.5781,14.7627C18.4256,14.961 18.3461,15.2057 18.353,15.4557L18.4852,20.2643C18.5017,20.8646 18.0285,21.3646 17.4281,21.3811C17.294,21.3848 17.1603,21.3637 17.0339,21.3187L12.5016,19.707C12.2659,19.6232 12.0086,19.6232 11.7729,19.707Z"
android:strokeWidth="1"
android:fillColor="#D9D9D9"
android:fillType="evenOdd"
android:strokeColor="#00000000"/>
<path
android:pathData="M11.7729,19.707L7.2406,21.3187C6.6748,21.5199 6.053,21.2243 5.8517,20.6585C5.8068,20.5321 5.7856,20.3984 5.7893,20.2643L5.9215,15.4557C5.9284,15.2057 5.8489,14.961 5.6964,14.7627L2.763,10.9503C2.3968,10.4743 2.4858,9.7916 2.9617,9.4254C3.0681,9.3435 3.1887,9.2821 3.3174,9.2442L7.9314,7.884C8.1713,7.8133 8.3795,7.662 8.5209,7.4557L11.2403,3.4878C11.5798,2.9924 12.2566,2.8661 12.752,3.2056C12.8627,3.2814 12.9584,3.3771 13.0342,3.4878L15.7536,7.4557C15.895,7.662 16.1032,7.8133 16.3431,7.884L20.9572,9.2442C21.5332,9.414 21.8625,10.0186 21.6927,10.5947C21.6548,10.7234 21.5933,10.8439 21.5115,10.9503L18.5781,14.7627C18.4256,14.961 18.3461,15.2057 18.353,15.4557L18.4852,20.2643C18.5017,20.8646 18.0285,21.3646 17.4281,21.3811C17.294,21.3848 17.1603,21.3637 17.0339,21.3187L12.5016,19.707C12.2659,19.6232 12.0086,19.6232 11.7729,19.707Z"
android:strokeWidth="1"
android:fillColor="#D9D9D9"
android:fillType="evenOdd"
android:strokeColor="#00000000"/>
</vector>

+ 24
- 0
app/svg/drawable/ic_star_1.xml View File

@@ -0,0 +1,24 @@
<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="M-232,-268h375v812h-375z"
android:strokeWidth="1"
android:fillColor="#FFFFFF"
android:fillType="evenOdd"
android:strokeColor="#00000000"/>
<path
android:pathData="M11.7729,19.707L7.2406,21.3187C6.6748,21.5199 6.053,21.2243 5.8517,20.6585C5.8068,20.5321 5.7856,20.3984 5.7893,20.2643L5.9215,15.4557C5.9284,15.2057 5.8489,14.961 5.6964,14.7627L2.763,10.9503C2.3968,10.4743 2.4858,9.7916 2.9617,9.4254C3.0681,9.3435 3.1887,9.2821 3.3174,9.2442L7.9314,7.884C8.1713,7.8133 8.3795,7.662 8.5209,7.4557L11.2403,3.4878C11.5798,2.9924 12.2566,2.8661 12.752,3.2056C12.8627,3.2814 12.9584,3.3771 13.0342,3.4878L15.7536,7.4557C15.895,7.662 16.1032,7.8133 16.3431,7.884L20.9572,9.2442C21.5332,9.414 21.8625,10.0186 21.6927,10.5947C21.6548,10.7234 21.5933,10.8439 21.5115,10.9503L18.5781,14.7627C18.4256,14.961 18.3461,15.2057 18.353,15.4557L18.4852,20.2643C18.5017,20.8646 18.0285,21.3646 17.4281,21.3811C17.294,21.3848 17.1603,21.3637 17.0339,21.3187L12.5016,19.707C12.2659,19.6232 12.0086,19.6232 11.7729,19.707Z"
android:strokeWidth="1"
android:fillColor="#F7874F"
android:fillType="evenOdd"
android:strokeColor="#00000000"/>
<path
android:pathData="M11.7729,19.707L7.2406,21.3187C6.6748,21.5199 6.053,21.2243 5.8517,20.6585C5.8068,20.5321 5.7856,20.3984 5.7893,20.2643L5.9215,15.4557C5.9284,15.2057 5.8489,14.961 5.6964,14.7627L2.763,10.9503C2.3968,10.4743 2.4858,9.7916 2.9617,9.4254C3.0681,9.3435 3.1887,9.2821 3.3174,9.2442L7.9314,7.884C8.1713,7.8133 8.3795,7.662 8.5209,7.4557L11.2403,3.4878C11.5798,2.9924 12.2566,2.8661 12.752,3.2056C12.8627,3.2814 12.9584,3.3771 13.0342,3.4878L15.7536,7.4557C15.895,7.662 16.1032,7.8133 16.3431,7.884L20.9572,9.2442C21.5332,9.414 21.8625,10.0186 21.6927,10.5947C21.6548,10.7234 21.5933,10.8439 21.5115,10.9503L18.5781,14.7627C18.4256,14.961 18.3461,15.2057 18.353,15.4557L18.4852,20.2643C18.5017,20.8646 18.0285,21.3646 17.4281,21.3811C17.294,21.3848 17.1603,21.3637 17.0339,21.3187L12.5016,19.707C12.2659,19.6232 12.0086,19.6232 11.7729,19.707Z"
android:strokeWidth="1"
android:fillColor="#F7874F"
android:fillType="evenOdd"
android:strokeColor="#00000000"/>
</vector>

+ 14
- 4
build.gradle View File

@@ -22,7 +22,7 @@ task clean(type: Delete) {
//在项目级别定义某些属性并在所有模块之间共享这些属性
ext {
android = [
compile_sdk_version: 31, //使用rootProject.ext.android.compile_sdk_version
compile_sdk_version: 32, //使用rootProject.ext.android.compile_sdk_version
build_tools_version: "30.0.2",
min_sdk_version : 21,
target_sdk_version : 31,
@@ -77,8 +77,9 @@ ext {
//Activity_ktx Activity扩展
Activity_ktx : "androidx.activity:activity-ktx:1.4.0",
//SqlCipher 需要在application 实现 : SQLiteDatabase.loadLibs(this)
SqlCipher : "net.zetetic:android-database-sqlcipher:4.5.0",
Sqlite : "androidx.sqlite:sqlite:2.0.1",
SqlCipher : "net.zetetic:android-database-sqlcipher:4.5.1",
Sqlite : "androidx.sqlite:sqlite:2.3.0-alpha03",
// Sqlite : "androidx.sqlite:sqlite:2.0.1",
//SmartRefreshLayout
SmartRefreshLayout: "io.github.scwang90:refresh-layout-kernel:2.0.5",
//Lottie
@@ -112,7 +113,16 @@ ext {
//google 流式布局 https://blog.csdn.net/ww897532167/article/details/85952498 https://github.com/google/flexbox-layout
FlexBoxLayoutManager : "com.google.android.flexbox:flexbox:3.0.0",
//图表
Chart: "com.github.PhilJay:MPAndroidChart:v3.1.0"
Chart: "com.github.PhilJay:MPAndroidChart:v3.1.0",
//数据库 Room
// Room_Runtime : "androidx.room:room-runtime:2.4.2",
// Room_Compiler : "androidx.room:room-compiler:2.4.2",
Room_Runtime : "androidx.room:room-runtime:2.3.0-alpha01",
Room_Compiler : "androidx.room:room-compiler:2.3.0-alpha01",
//Paging
Paging: "androidx.paging:paging-runtime:3.0.0-alpha08",
//room_paging
// Room_Paging : "androidx.room:room-paging:${versions.lifecycle_version}"
]



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

@@ -10,9 +10,13 @@ import androidx.recyclerview.widget.RecyclerView
import androidx.viewbinding.ViewBinding
import com.suliang.common.R

abstract class BaseRVAdapter<T> :
abstract class BaseRVAdapter<T> constructor() :
RecyclerView.Adapter<BaseAdapterViewHolder>() {

public constructor(data : MutableList<T>): this(){
this.mData = data
}
companion object{
const val TYPE_EMPTY = -1
}

Loading…
Cancel
Save