Browse Source

作文逻辑 课堂练习

master
suliang 2 years ago
parent
commit
c44f0e1082
26 changed files with 1073 additions and 116 deletions
  1. 5
    1
      .idea/misc.xml
  2. 57
    0
      app/src/main/java/com/xkl/cdl/adapter/AdapterBottomDialogSwitch.kt
  3. 21
    0
      app/src/main/java/com/xkl/cdl/data/bean/CompositionReadingBean.kt
  4. 65
    0
      app/src/main/java/com/xkl/cdl/data/bean/CompositionTaskBean.java
  5. 4
    0
      app/src/main/java/com/xkl/cdl/data/bean/intentdata/LearnData.kt
  6. 4
    1
      app/src/main/java/com/xkl/cdl/data/event/LearnEventData.kt
  7. 47
    3
      app/src/main/java/com/xkl/cdl/data/manager/db/DBCourseManager.kt
  8. 229
    4
      app/src/main/java/com/xkl/cdl/module/learn/LearnCReadingActivity.kt
  9. 193
    0
      app/src/main/java/com/xkl/cdl/module/learn/LearnCReadingViewModel.kt
  10. 22
    6
      app/src/main/java/com/xkl/cdl/module/learn/LearnCTaskActivity.kt
  11. 15
    0
      app/src/main/java/com/xkl/cdl/module/learn/LearnCTaskViewModel.kt
  12. 1
    1
      app/src/main/java/com/xkl/cdl/module/learn/LearnWordViewModel.kt
  13. 15
    4
      app/src/main/java/com/xkl/cdl/module/m_center_learn/coursechildren/CourseLessonFragment.kt
  14. 46
    28
      app/src/main/java/com/xkl/cdl/module/m_center_learn/coursechildren/CourseMainFragmentViewModel.kt
  15. 5
    0
      app/src/main/res/color/composition_note_cb.xml
  16. 136
    6
      app/src/main/res/layout/activity_learn_creading.xml
  17. 114
    6
      app/src/main/res/layout/activity_learn_ctask.xml
  18. 2
    0
      app/src/main/res/layout/activity_learn_word.xml
  19. 1
    3
      app/src/main/res/layout/inc_control_button.xml
  20. 5
    1
      app/src/main/res/layout/include_title_bar.xml
  21. 12
    0
      app/svg/drawable/ic_menu.xml
  22. 12
    0
      app/svg/drawable/ic_note.xml
  23. 0
    1
      lib/common/src/main/java/com/suliang/common/base/adapter/BaseAdapterViewHolder.kt
  24. 1
    0
      lib/common/src/main/java/com/suliang/common/base/adapter/BaseRVAdapter.kt
  25. 60
    51
      lib/common/src/main/java/com/suliang/common/widget/TitleBar.kt
  26. 1
    0
      lib/common/src/main/res/layout/public_title_bar.xml

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

<entry key="..\:/Work/XKL/XKL/XklLocal/app/drawable/svg/drawable/ic_discern.xml" value="0.3223958333333333" /> <entry key="..\:/Work/XKL/XKL/XklLocal/app/drawable/svg/drawable/ic_discern.xml" value="0.3223958333333333" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/drawable/svg/drawable/ic_nav_learn_center.xml" value="0.3223958333333333" /> <entry key="..\:/Work/XKL/XKL/XklLocal/app/drawable/svg/drawable/ic_nav_learn_center.xml" value="0.3223958333333333" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/drawable/svg/drawable/ic_nav_my.xml" value="0.3223958333333333" /> <entry key="..\:/Work/XKL/XKL/XklLocal/app/drawable/svg/drawable/ic_nav_my.xml" value="0.3223958333333333" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/composition_note_cb.xml" value="0.4953125" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/detail_example_flag.xml" value="0.4546296296296296" /> <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/detail_example_flag.xml" value="0.4546296296296296" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/detail_phrase_flag.xml" value="0.4546296296296296" /> <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/detail_phrase_flag.xml" value="0.4546296296296296" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/detail_reference_flag.xml" value="0.4546296296296296" /> <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/detail_reference_flag.xml" value="0.4546296296296296" />
<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_exam_learn_spell.xml" value="0.47690217391304346" /> <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/activity_exam_learn_spell.xml" value="0.47690217391304346" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/activity_learn_base.xml" value="0.4979166666666667" /> <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/activity_learn_base.xml" value="0.4979166666666667" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/activity_learn_creading.xml" value="0.5" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/activity_learn_ctask.xml" value="0.23353596757852077" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/activity_learn_exam.xml" value="0.25" /> <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/activity_learn_exam.xml" value="0.25" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/activity_learn_exam_word.xml" value="0.33" /> <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/activity_learn_exam_word.xml" value="0.33" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/activity_learn_spell.xml" value="0.47690217391304346" /> <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/activity_learn_spell.xml" value="0.47690217391304346" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/activity_learn_word.xml" value="0.6435024322446143" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/activity_learn_word.xml" value="0.5" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/activity_learn_word2.xml" value="0.4979166666666667" /> <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/activity_learn_word2.xml" value="0.4979166666666667" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/activity_main.xml" value="0.5" /> <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/activity_main.xml" value="0.5" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/activity_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/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_discern.xml" value="0.5061538461538462" /> <entry key="..\:/Work/XKL/XKL/XklLocal/app/svg/drawable/ic_discern.xml" value="0.5061538461538462" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/svg/drawable/ic_icon___.xml" value="0.287962962962963" /> <entry key="..\:/Work/XKL/XKL/XklLocal/app/svg/drawable/ic_icon___.xml" value="0.287962962962963" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/svg/drawable/ic_menu.xml" value="0.4036458333333333" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/svg/drawable/ic_nav_learn_center.xml" value="0.44166666666666665" /> <entry key="..\:/Work/XKL/XKL/XklLocal/app/svg/drawable/ic_nav_learn_center.xml" value="0.44166666666666665" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/svg/drawable/ic_nav_memo.xml" value="0.21574074074074073" /> <entry key="..\:/Work/XKL/XKL/XklLocal/app/svg/drawable/ic_nav_memo.xml" value="0.21574074074074073" />
<entry key="..\:/Work/XKL/XKL/XklLocal/app/svg/drawable/ic_nav_my.xml" value="0.44166666666666665" /> <entry key="..\:/Work/XKL/XKL/XklLocal/app/svg/drawable/ic_nav_my.xml" value="0.44166666666666665" />

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

package com.xkl.cdl.adapter

import android.graphics.Color
import android.view.View
import android.view.ViewGroup
import androidx.core.content.ContextCompat
import com.suliang.common.base.adapter.BaseAdapterViewHolder
import com.suliang.common.base.adapter.BaseRVAdapter
import com.suliang.common.extension.click
import com.xkl.cdl.R
import com.xkl.cdl.data.bean.CompositionReadingBean
import com.xkl.cdl.data.bean.CompositionTaskBean
import com.xkl.cdl.databinding.DialogItemSelectRepeatBinding

/**
* author suliang
* create 2021/4/6 16:47
* Describe: 底部弹窗选择适配器 */
class AdapterBottomDialogSwitch<T> : BaseRVAdapter<T>() {
var selectItemIndex = -1 //选中下标
set(value) {
field = value
notifyDataSetChanged()
}
override fun coverViewHolder(parent : ViewGroup, viewType : Int) : BaseAdapterViewHolder {
return BaseAdapterViewHolder(inflateBinding(parent, R.layout.dialog_item_select_repeat))
}
override fun onBindVH(holder : BaseAdapterViewHolder, position : Int) {
var name : String? = ""
val item = getItem(position)
if (item is CompositionReadingBean) {
name = item.title
} else if (item is CompositionTaskBean) {
name = item.title
}
val binding = holder.binding as DialogItemSelectRepeatBinding
binding.tvOption.text = name
if (position == selectItemIndex) {
//设置背景主色透明度 10%
binding.root.setBackgroundColor(Color.parseColor("#1A5082E6"))
binding.tvOption.setTextColor(ContextCompat.getColor(context, R.color.theme_color))
} else {
binding.root.setBackgroundColor(ContextCompat.getColor(context, R.color.white))
binding.tvOption.setTextColor(ContextCompat.getColor(context, R.color.main_text_color))
}
binding.root.click { view : View? ->
if (onItemClickIsInitialized() && position != selectItemIndex) {
selectItemIndex = position
notifyDataSetChanged()
onItemClick.invoke(view!!, position, item)
}
}
}
}

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

package com.xkl.cdl.data.bean

/**
* author suliang
* create 2022/5/18 11:41
* Describe: 作文课堂练习数据
* @property id reading id
* @property title 题目
* @property content 内容
* @property question 问题
* @property answer 答案
* @property isLast 是否是最后一条Reading
*/
data class CompositionReadingBean(val id : Long,
val title : String,
val content : String,
val question : String,
val answer : String) {
var collectId : Long = 0 //收藏id
var isLast : Boolean = false
}

+ 65
- 0
app/src/main/java/com/xkl/cdl/data/bean/CompositionTaskBean.java View File

package com.xkl.cdl.data.bean;

import java.io.Serializable;

/**
* author suliang
* create 2021/4/6 18:25
* Describe: 作文课外练习实体
*/
public class CompositionTaskBean {
private long taskId; //数据id
private int stage; //阶段
private int type; //类型
private String title; //标题
private String introduce; //介绍
private String photo; //图片

public long getTaskId() {
return taskId;
}

public void setTaskId(long taskId) {
this.taskId = taskId;
}

public int getStage() {
return stage;
}

public void setStage(int stage) {
this.stage = stage;
}

public int getType() {
return type;
}

public void setType(int type) {
this.type = type;
}

public String getTitle() {
return title;
}

public void setTitle(String title) {
this.title = title;
}

public String getIntroduce() {
return introduce;
}

public void setIntroduce(String introduce) {
this.introduce = introduce;
}

public String getPhoto() {
return photo;
}

public void setPhoto(String photo) {
this.photo = photo;
}
}

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

package com.xkl.cdl.data.bean.intentdata package com.xkl.cdl.data.bean.intentdata


import com.xkl.cdl.data.bean.CompositionReadingBean
import com.xkl.cdl.data.bean.LearnWord import com.xkl.cdl.data.bean.LearnWord
import com.xkl.cdl.data.bean.course.Lesson import com.xkl.cdl.data.bean.course.Lesson


//自动播放次数 //自动播放次数
var autoPlayTime = 0 var autoPlayTime = 0
//作文课堂练习数据
var readingList : List<CompositionReadingBean> = mutableListOf()
} }

+ 4
- 1
app/src/main/java/com/xkl/cdl/data/event/LearnEventData.kt View File

//学习结束 newErrorMap 保存为所有的错误,包含学前和课程前的测试,主要用与后面进行小游戏的数据加载 //学习结束 newErrorMap 保存为所有的错误,包含学前和课程前的测试,主要用与后面进行小游戏的数据加载
//视频播放结束,数据传递的播放时间点 //视频播放结束,数据传递的播放时间点
val videoPlayTime : String = ""
var videoPlayTime : String = ""
//作文使用,发送消息时,是否只更新进度点,而不需要重算进度,进行上传进度
var isOnlyUpdatePoint = false
} }

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

import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.widget.Toast import android.widget.Toast
import androidx.core.database.getBlobOrNull import androidx.core.database.getBlobOrNull
import androidx.core.database.getLongOrNull
import androidx.core.database.getStringOrNull
import com.google.common.base.Joiner import com.google.common.base.Joiner
import com.suliang.common.AppConfig import com.suliang.common.AppConfig
import com.suliang.common.util.AppGlobals import com.suliang.common.util.AppGlobals
import com.suliang.common.util.file.FileUtil import com.suliang.common.util.file.FileUtil
import com.suliang.common.util.thread.AppExecutors 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.CompositionReadingBean
import com.xkl.cdl.data.bean.CompositionTaskBean
import com.xkl.cdl.data.bean.LearnWord import com.xkl.cdl.data.bean.LearnWord
import com.xkl.cdl.data.bean.course.CourseDetail import com.xkl.cdl.data.bean.course.CourseDetail
import com.xkl.cdl.data.bean.course.ExamBean import com.xkl.cdl.data.bean.course.ExamBean
import io.reactivex.rxjava3.annotations.NonNull import io.reactivex.rxjava3.annotations.NonNull
import net.sqlcipher.database.SQLiteDatabase import net.sqlcipher.database.SQLiteDatabase
import java.io.File import java.io.File
import java.lang.StringBuilder


/** /**
* author suliang * author suliang
return result return result
} }
/**
* 作文查询课堂练习 reading
* @param entity Lesson 课堂练习课时
* @return List<CompositionReadingBean>?
*/
fun queryCompositionReading(dbcb : DbControlBase, entity : Lesson) : List<CompositionReadingBean> {
val result = mutableListOf<CompositionReadingBean>()
val sql = "SELECT * FROM reading WHERE reading_id in (${Joiner.on(",").join(entity.wordIds)}) AND chapter_id = 5272 ORDER by CASE " + entity.wordIds.let {
val sortedCase = StringBuilder()
it.forEachIndexed{ index,id ->
sortedCase.append(" WHEN reading_id = $id THEN $index")
}
sortedCase
} + " END"
open(dbcb)
mDataBase?.rawQuery(sql,null)?.run {
while (moveToNext()){
result.add(CompositionReadingBean(
getLong(2),
getString(3),
getString(4),
getString(7),
getString(6)).apply {
collectId = 0
})
}
close()
}
result.last().isLast = true
return result
}
/**
* 查询作文的课外练习数据
* @param dbcb DbControlBase
* @param entity Lesson
* @return List<CompositionTaskBean>
*/
fun queryCompositonTask(dbcb : DbControlBase,entity : Lesson) : List<CompositionTaskBean>{
val result = mutableListOf<CompositionTaskBean>()
return result
}
} }

+ 229
- 4
app/src/main/java/com/xkl/cdl/module/learn/LearnCReadingActivity.kt View File

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


import android.content.res.ColorStateList
import android.graphics.Color
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle import android.os.Bundle
import android.text.Spannable
import android.text.SpannableStringBuilder
import android.text.style.BackgroundColorSpan
import android.text.style.ForegroundColorSpan
import android.view.MotionEvent
import android.view.View
import android.widget.CheckBox
import androidx.core.content.ContextCompat
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.suliang.common.base.activity.BaseActivity
import com.suliang.common.base.activity.BaseActivityVM
import com.suliang.common.extension.click
import com.xkl.cdl.R import com.xkl.cdl.R
import com.xkl.cdl.adapter.AdapterAutoPlaySelectRepeat
import com.xkl.cdl.adapter.AdapterBottomDialogSwitch
import com.xkl.cdl.data.bean.CompositionReadingBean
import com.xkl.cdl.databinding.ActivityLearnCreadingBinding
import com.xkl.cdl.databinding.DialogBottomAutoPlaySelectBinding
import com.xkl.cdl.dialog.CommonDialog
import com.xkl.cdl.dialog.CommonDialogBean


class LearnCReadingActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_learn_creading)
/**
* author suliang
* create 2022/5/19 11:20
* Describe: 作文课堂练习
*/
class LearnCReadingActivity : BaseActivityVM<ActivityLearnCreadingBinding, LearnCReadingViewModel>() {
override fun initViewModel() : LearnCReadingViewModel {
return ViewModelProvider(this).get(LearnCReadingViewModel::class.java)
}
override fun initActivity(savedInstanceState : Bundle?) {
binding.titleBar.onBackClick = { v -> onBackPressed() }
binding.titleBar.onRightClick = { v -> showChangeReadingDialog() }
binding.rbNote.click {
//点击时已经改变了状态,这个需要手动修改
(it as CheckBox).run {
toggle()
when {
//显示加入笔记,此时未加入笔记,做加入操作
isChecked -> vm.addCollect().observe(this@LearnCReadingActivity) {
toggle()
text = "取消笔记"
}
//显示取消笔记,此时已加入笔记,做移除操作
else -> vm.removeCollect().observe(this@LearnCReadingActivity) {
toggle()
text = "加入笔记"
}
}
}
}
binding.incControlButton.run {
tvRight.text = "下一条"
tvCenter.text = "全部答案"
tvCenter.backgroundTintList = ColorStateList.valueOf(ContextCompat.getColor(this@LearnCReadingActivity,R.color.gray_2))
//提示点击
tvLeft.click {
if (vm.tipCount < vm.tipMaxForCurrent) {
val clickTime = System.currentTimeMillis()
if (vm.tipClickIntervel > clickTime - vm.tipClickTime) {
showToast("请再思考一下吧~")
return@click
}
vm.tipClickTime = clickTime
vm.tipCount++
binding.incControlButton.tvLeft.text = "提示 ${vm.tipCount}/${vm.tipMaxForCurrent}"
if (vm.tipCount == vm.tipMaxForCurrent) {
//全部答案
tvCenter.text = "隐藏答案"
tvLeft.isEnabled = false
}
showAnswer()
}
}
tvCenter.click {
when (vm.tipCount) {
// 隐藏 -》 全部答案
vm.tipMaxForCurrent -> {
tvCenter.text = "全部答案"
tvLeft.text = "提示"
vm.tipCount = 0
vm.tipClickTime = 0L
tvLeft.isEnabled =true
tvLeft.alpha = 1f
}
//全部答案 -> 隐藏答案
else -> {
tvCenter.text = "隐藏答案"
vm.tipCount = 5
tvLeft.isEnabled = false
tvLeft.alpha = 0.3f
}
}
showAnswer()
}
tvRight.click { vm.loadNext() }
}
}
override fun loadData() {
vm.loadNext()
//数据来到
vm.currentValue.observe(this) {
if (it == null) return@observe
//笔记
binding.rbNote.run {
if (it.collectId != 0L) {
text = "取消笔记"
isChecked = false
} else {
text = "加入笔记"
isChecked = true
}
}
//内容
binding.tvTitle.text = it.title
binding.tvContent.text = it.content
binding.tvQuestion.text = it.question
showAnswer()
//按钮初始
binding.incControlButton.run {
tvLeft.text = "提示"
tvLeft.isEnabled = true
tvLeft.alpha = 1f
tvCenter.text = "全部答案"
tvRight.visibility = View.INVISIBLE
}
}
//上传数据后关闭当前activity
vm.uploadDate.observe(this){
finish()
}
}
/** 显示答案 */
private fun showAnswer() {
vm.currentValue.value?.let {
val builder = SpannableStringBuilder(it.answer)
if (vm.tipCount < vm.tipMaxForCurrent) {
val hideStart = vm.tipStepCount * vm.tipCount
builder.setSpan(ForegroundColorSpan(Color.parseColor("#F5F5F5")), hideStart, it.answer.length,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
builder.setSpan(BackgroundColorSpan(Color.parseColor("#F5F5F5")), hideStart, it.answer.length,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
}
binding.tvAnswer.text = builder
//如果显示答案为最后一条,且完全显示,则判断为本课时学习完成
if ( !vm.lastIsLearned && it.isLast && vm.tipCount == vm.tipMaxForCurrent){
vm.lastIsLearned = true
}
//右侧按钮
binding.incControlButton.tvRight.visibility = if (vm.tipCount == vm.tipMaxForCurrent){
binding.incControlButton.tvLeft.isEnabled = false
binding.incControlButton.tvLeft.alpha = 0.3f
View.VISIBLE
} else View.INVISIBLE
}
}
private var changeReadingDialog: BottomSheetDialog? = null
/** 切换item的dialog */
private fun showChangeReadingDialog() {
if (vm.learnData.readingList.size <= 1) return
if (changeReadingDialog == null) {
changeReadingDialog = BottomSheetDialog(this, R.style.dialog_style).apply {
val autoPlayBinding = DataBindingUtil.inflate<DialogBottomAutoPlaySelectBinding>(layoutInflater,
R.layout.dialog_bottom_auto_play_select,
null, false)
setContentView(autoPlayBinding.root)
autoPlayBinding.tvTitle.text = "请选择课堂练习查看详情"
autoPlayBinding.ivCancel.click { v -> dismiss() }
autoPlayBinding.rvRepeat.run {
layoutManager = LinearLayoutManager(this@LearnCReadingActivity,LinearLayoutManager.VERTICAL,false)
adapter = AdapterBottomDialogSwitch<CompositionReadingBean>().apply {
onItemClick = { _, position, _ ->
dismiss()
vm.currentLearnIndex = position - 1
vm.loadNext()
}
setData(vm.learnData.readingList.toMutableList())
}
}
//显示时,定位到当前item的位置
setOnShowListener{
(autoPlayBinding.rvRepeat.adapter as AdapterBottomDialogSwitch<*>).selectItemIndex = vm.currentLearnIndex
autoPlayBinding.rvRepeat.scrollToPosition(vm.currentLearnIndex)
}
}
}
changeReadingDialog?.show()
}
override fun dispatchTouchEvent(ev : MotionEvent?) : Boolean {
vm.executeLearnValidTime()
return super.dispatchTouchEvent(ev)
}
override fun onBackPressed() {
//如果学习完成,不弹窗提示,直接上传数据
if (vm.lastIsLearned){
vm.saveData()
return
}
vm.showOrDismissBackDialogForTime(true)
CommonDialog.newInstance(
CommonDialogBean(titleText = R.string.quit_learn_title, contentText = R.string.quit_learn_content, leftText = R.string.quit, rightText = R.string.cancel)).apply {
onCommonDialogButtonClickListener = { dialog, isRightClick ->
dialog.dismissAllowingStateLoss()
when {
isRightClick -> vm.showOrDismissBackDialogForTime(false)
else -> vm.saveData()
}
}
}.show(supportFragmentManager, "learn_back_dialog")
} }
} }

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

package com.xkl.cdl.module.learn

import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.MutableLiveData
import com.jeremyliao.liveeventbus.LiveEventBus
import com.suliang.common.base.activity.ToastEvent
import com.suliang.common.extension.diskIo2Main
import com.suliang.common.util.DateUtil
import com.xkl.cdl.data.AppConstants
import com.xkl.cdl.data.DataTransferHolder
import com.xkl.cdl.data.bean.CompositionReadingBean
import com.xkl.cdl.data.bean.intentdata.LearnData
import com.xkl.cdl.data.event.LearnEventData
import com.xkl.cdl.data.repository.DataRepository
import io.reactivex.rxjava3.core.Observable
import mqComsumerV1.Struct

class LearnCReadingViewModel : LearnBaseViewModel() {
/* 操作数据 */
val learnData = DataTransferHolder.instance.getData<LearnData>()
//当前学习下标
var currentLearnIndex = learnData.lesson.learnedIndex
//记录最后一条的item是否进行了学习, 初始标记直接为课时学习是否完成的标记就好了
var lastIsLearned = learnData.lesson.learnIsOver
//当前学习Bean
val currentValue = MutableLiveData<CompositionReadingBean>()
// 提示次数
var tipCount = 0
//当前答案最大提示数
var tipMaxForCurrent = 0
// 显示答案拆分,每一份的大小
var tipStepCount = 0
//提示点击的时间
var tipClickTime = 0L
//提示点击间隔时间
val tipClickIntervel = 5000
//上传数据监听
val uploadDate = MutableLiveData<Boolean>()
fun loadNext() {
currentLearnIndex++
when {
currentLearnIndex < learnData.readingList.size -> {
val readingBean = learnData.readingList[currentLearnIndex]
//恢复提示次数
tipCount = 0
tipClickTime = 0
//计算提示
when {
readingBean.answer.isEmpty() -> {
tipMaxForCurrent = 0
tipStepCount = 0
}
else -> {
tipMaxForCurrent = Math.min(readingBean.answer.length, 5)
tipStepCount = readingBean.answer.length / 5
}
}
//设置
currentValue.value = readingBean
}
else -> { //没有下一条
currentLearnIndex--
showToast(ToastEvent("查看完毕"))
}
}
}
/**
* 添加到收藏
* @return MutableLiveData<Long>
*/
fun addCollect() : MutableLiveData<Long> {
val result = MutableLiveData<Long>()
// TODO: 2022/5/19 实现收藏操作
Observable.create<Long> {
currentValue.value?.collectId = 1
result.postValue(1)
}.compose(diskIo2Main()).subscribe()
return result
}
/**
* 添加到收藏
* @return MutableLiveData<Long>
*/
fun removeCollect() : MutableLiveData<Long> {
val result = MutableLiveData<Long>()
// TODO: 2022/5/19 实现取消收藏操作
Observable.create<Long> {
currentValue.value?.collectId = 0
result.postValue(0)
}.compose(diskIo2Main()).subscribe()
return result
}
//是否显示返回弹窗
private var isShowBackDialog = false
override fun onResume(owner : LifecycleOwner) {
super.onResume(owner)
if (!isAllOver) {
if (!isShowBackDialog) {
executeLearnValidTime()
}
startTotalCounting()
}
}
override fun onPause(owner : LifecycleOwner) {
super.onPause(owner)
stopTotalCountTing()
}
/**
* 显示或关闭的返回弹窗: 不影响总计时,只影响当前的下一题计时或者倒计时
* 显示返回弹窗的时机,只会在测试当种,则是结束后则不会再显示此弹窗
* @param isShow Boolean
*/
fun showOrDismissBackDialogForTime(isShow : Boolean) {
isShowBackDialog = isShow
isRunValidTime = !isShowBackDialog //显示返回弹窗 总计时不停,停止有效计时 //关闭返回弹窗 恢复有效计时
}
fun saveData() {
// TODO: 2022/5/20 保存记录点 如果学习完成,则设置进度点和修改为学习完成
Observable.create<Boolean> { emitter ->
val record = Struct.Record.newBuilder().apply {
addEntity(Struct.LearnEntity.newBuilder().apply {
learnData.lesson.let {
projectId = it.subjectId.toLong()
packId = it.coursePackId
courseId = it.courseId
chapterId = it.chapterId
lessonId = it.lessonId
entityId = currentValue.value!!.id
}
isCompExercise = true
tag = "android"
created = getCurrentDateWithString()
})
addDuration(Struct.LearnDuration.newBuilder().apply {
learnData.lesson.let {
projectId = it.subjectId.toLong()
packId = it.coursePackId
courseId = it.courseId
categoryId = it.coursePackType.toLong()
}
tag = "android"
created = getCurrentDateWithString()
timeFrame = DateUtil.getTimeFrame(System.currentTimeMillis())
isReview = false
duration = validTime.value!!
totalDuration = totalUseTime.value!!
})
}
emitter.onNext(DataRepository.saveRecord(record))
emitter.onComplete()
}.compose(diskIo2Main()).subscribe {
learnData.lesson.learnedIndex = currentLearnIndex - 1
val temp = learnData.lesson.learnIsOver == lastIsLearned
//发送信息,更改进度点
if (!temp){
//以前是未完成的,才进行发送操作
learnData.lesson.learnIsOver = true
}
//发送数据事件
LiveEventBus.get<LearnEventData>(AppConstants.EVENT_LESSON_DATA)
.post(LearnEventData(learnData.lesson.subjectId, learnData.lesson.courseId,
AppConstants.DATA_LESSON_LEARN_OVER).apply {
this.leesonPositionIndex = learnData.lesson.lessonPositionInList
isOnlyUpdatePoint = temp
})
uploadDate.value = true
}
}
private fun getCurrentDateWithString() = DateUtil.format(System.currentTimeMillis(), DateUtil.FORMAT_1)
}

+ 22
- 6
app/src/main/java/com/xkl/cdl/module/learn/LearnCTaskActivity.kt View File

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


import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle import android.os.Bundle
import com.xkl.cdl.R
import androidx.lifecycle.ViewModelProvider
import com.suliang.common.base.activity.BaseActivityVM
import com.xkl.cdl.databinding.ActivityLearnCtaskBinding


class LearnCTaskActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_learn_ctask)
/**
* author suliang
* create 2022/5/20 17:49
* Describe: 课外练习
*/
class LearnCTaskActivity : BaseActivityVM<ActivityLearnCtaskBinding,LearnCTaskViewModel>() {
override fun initViewModel() : LearnCTaskViewModel {
return ViewModelProvider(this)[LearnCTaskViewModel::class.java]
} }
override fun initActivity(savedInstanceState : Bundle?) {
}
override fun loadData() {
}

} }

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

package com.xkl.cdl.module.learn

import com.suliang.common.base.viewmodel.BaseViewModel
import com.xkl.cdl.data.DataTransferHolder
import com.xkl.cdl.data.bean.course.Lesson

class LearnCTaskViewModel : BaseViewModel() {
val lesson = DataTransferHolder.instance.getData<Lesson>()
fun queryData(){
}
}

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

/** /**
* 保存当前的单词学习时长 * 保存当前的单词学习时长
*/ */
fun saveCurrentLearnDuration() : LearnDuration.Builder? {
private fun saveCurrentLearnDuration() : LearnDuration.Builder? {
return LearnDuration.newBuilder() return LearnDuration.newBuilder()
.setProjectId(learnData.lesson.subjectId.toLong()) .setProjectId(learnData.lesson.subjectId.toLong())
.setPackId(learnData.lesson.coursePackId) .setPackId(learnData.lesson.coursePackId)

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

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.module.learn.LearnCReadingActivity
import com.xkl.cdl.module.learn.LearnCTaskActivity
import com.xkl.cdl.module.learn.LearnWordActivity import com.xkl.cdl.module.learn.LearnWordActivity


/** /**
} }
//课堂练习 //课堂练习
AppConstants.LESSON_TYPE_COMPOSITION_READING -> vm.courseDetail.run { AppConstants.LESSON_TYPE_COMPOSITION_READING -> vm.courseDetail.run {
lesson_learn_point[key] = it.wordIds[it.learnedIndex] //更新课时学习点
course_learn_point = "${key}_${it.wordIds[it.learnedIndex]}" //更新课程学习点
val point = if (it.learnedIndex == -1) -1 else it.wordIds[it.learnedIndex]
lesson_learn_point[key] = point //更新课时学习点
course_learn_point = "${key}_$point" //更新课程学习点
if (learnEventData.isOnlyUpdatePoint){
return@observe
}
} }
//课外练习 不操作,不计算 //课外练习 不操作,不计算
AppConstants.LESSON_TYPE_COMPOSITION_TASK -> { } AppConstants.LESSON_TYPE_COMPOSITION_TASK -> { }
else -> {} else -> {}
} }
} }
LogUtil.e("是否在when中被 return @Observe 打断,有输出,未被打断,没有输出,则被打断 ")
//课程进度 //课程进度
val courseProgress = when (vm.course.coursePackType) { val courseProgress = when (vm.course.coursePackType) {
AppConstants.COURSEPACK_TYPE_CHINESE_COMPOSITION -> CourseManager.calculateCompositionCourseProgress( AppConstants.COURSEPACK_TYPE_CHINESE_COMPOSITION -> CourseManager.calculateCompositionCourseProgress(
} }
//课堂练习 //课堂练习
AppConstants.LESSON_TYPE_COMPOSITION_READING -> { AppConstants.LESSON_TYPE_COMPOSITION_READING -> {
vm.queryCompositionReadingData(entity).observe(this){
DataTransferHolder.instance.putData(value = it)
startActivity(LearnCReadingActivity::class.java)
}
} }
//课外练习 //课外练习
AppConstants.LESSON_TYPE_COMPOSITION_TASK -> { AppConstants.LESSON_TYPE_COMPOSITION_TASK -> {
DataTransferHolder.instance.putData(value = entity)
startActivity(LearnCTaskActivity::class.java)
} }
} }

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

import com.suliang.common.util.file.FileUtil import com.suliang.common.util.file.FileUtil
import com.suliang.common.util.thread.AppExecutors 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.CompositionReadingBean
import com.xkl.cdl.data.bean.LearnWord import com.xkl.cdl.data.bean.LearnWord
import com.xkl.cdl.data.bean.course.Course import com.xkl.cdl.data.bean.course.Course
import com.xkl.cdl.data.bean.course.CourseDetail import com.xkl.cdl.data.bean.course.CourseDetail
/** 课程包主页上的更多按钮点击是否有效 */ /** 课程包主页上的更多按钮点击是否有效 */
fun showMoreIsEnable() : Boolean { fun showMoreIsEnable() : Boolean {
return when(course.courseType){
return when (course.courseType) {
AppConstants.COURSE_TYPE_CHINESE_COMPOSITION -> courseDetail.courseLearnProgress > 0 AppConstants.COURSE_TYPE_CHINESE_COMPOSITION -> courseDetail.courseLearnProgress > 0
else -> courseDetail.st_before != AppConstants.NOT_DOING else -> courseDetail.st_before != AppConstants.NOT_DOING
} }
it.onNext(DBCourseManager.queryLearnData(dbControlBase, lesson)) it.onNext(DBCourseManager.queryLearnData(dbControlBase, lesson))
it.onComplete() it.onComplete()
}.compose(diskIo2Main()).subscribe { }.compose(diskIo2Main()).subscribe {
result.value = LearnData(lesson).apply {
learnWordList = it
examErrorMap = courseDetail.exam_w_r_list
}
}
result.value = LearnData(lesson).apply {
learnWordList = it
examErrorMap = courseDetail.exam_w_r_list
}
}
return result return result
} }
//学后总测试完成,默认无选中 //学后总测试完成,默认无选中
courseDetail.st_after != AppConstants.NOT_DOING -> temposition = -1 courseDetail.st_after != AppConstants.NOT_DOING -> temposition = -1
//进度100 //进度100
courseDetail.courseLearnProgress == AppConstants.DOING_OVER -> temposition = -1
courseDetail.courseLearnProgress == AppConstants.DOING_OVER -> temposition = -1
//有学习点 //有学习点
courseDetail.course_learn_point.isNotEmpty() -> { courseDetail.course_learn_point.isNotEmpty() -> {
run m@{ run m@{
fun relearnLesson(lessonPositionIndex : Int) : MutableLiveData<Boolean> { fun relearnLesson(lessonPositionIndex : Int) : MutableLiveData<Boolean> {
val result = MutableLiveData<Boolean>() val result = MutableLiveData<Boolean>()
//重学课时后课程的进度 //重学课时后课程的进度
val courseProgress = when(course.subjectId){
val courseProgress = when (course.subjectId) {
AppConstants.SUBJECT_ENGLISH -> CourseManager.calculateEnglishCourseProgress(allLesson, true, lessonPositionIndex) AppConstants.SUBJECT_ENGLISH -> CourseManager.calculateEnglishCourseProgress(allLesson, true, lessonPositionIndex)
//作文的重学虚拟进度 //作文的重学虚拟进度
else -> CourseManager.calculateCompositionCourseProgress(allLesson,true,lessonPositionIndex)
else -> CourseManager.calculateCompositionCourseProgress(allLesson, true, lessonPositionIndex)
} }
//重学课时后项目的总进度 //重学课时后项目的总进度
val subjectProgress = CourseManager.calculateSubjectProgressWithCourseLessonRelearn(course.subjectId, course.coursePackId, val subjectProgress = CourseManager.calculateSubjectProgressWithCourseLessonRelearn(course.subjectId, course.coursePackId,
file.delete() file.delete()
} }
}.compose(diskIo2DiskIo()).subscribe { }.compose(diskIo2DiskIo()).subscribe {
courseDetail.run {
courseLearnProgress = 0.0
st_before = AppConstants.NOT_DOING
st_after = AppConstants.NOT_DOING
before.clear()
after.clear()
right.clear()
wrong.clear()
lesson_learn_point.clear()
exam_w_r_list.clear()
course_learn_point = ""
rl += 1
temporary_words.clear()
vp.clear()
exercise_schedule.clear()
}
result.postValue(true)
}
courseDetail.run {
courseLearnProgress = 0.0
st_before = AppConstants.NOT_DOING
st_after = AppConstants.NOT_DOING
before.clear()
after.clear()
right.clear()
wrong.clear()
lesson_learn_point.clear()
exam_w_r_list.clear()
course_learn_point = ""
rl += 1
temporary_words.clear()
vp.clear()
exercise_schedule.clear()
}
result.postValue(true)
}
return result return result
} }
LogUtil.e("${javaClass} 保存文件异常失败") LogUtil.e("${javaClass} 保存文件异常失败")
} }
} }
super.onDestroy(owner) super.onDestroy(owner)
} }
return result return result
} }
/**
* 查询作文课堂练习数据
* @param entity Lesson 学习课时
* @return MutableLiveData<List<CompositionReadingBean>>
*/
fun queryCompositionReadingData(entity : Lesson) : MutableLiveData<LearnData> {
val result = MutableLiveData<LearnData>()
// TODO: 2022/5/19 查询课堂练习的收藏数据 需要给 CompositionReadingBean设置收藏id
Observable.create<List<CompositionReadingBean>> {
result.postValue(LearnData(entity).apply {
readingList = DBCourseManager.queryCompositionReading(dbControlBase,entity)
})
it.onComplete()
}.compose(diskIo2Main()).subscribe()
return result
}
} }

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

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#F7847F" android:state_checked="true"/>
<item android:color="@color/gray_2" android:state_checked="false"/>
</selector>

+ 136
- 6
app/src/main/res/layout/activity_learn_creading.xml View File

<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".module.learn.LearnCReadingActivity">
xmlns:tools="http://schemas.android.com/tools">


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

<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".module.learn.LearnCReadingActivity"
android:background="@color/white">

<com.suliang.common.widget.TitleBar
android:id="@+id/title_bar"
android:layout_width="match_parent"
android:layout_height="@dimen/title_bar_height"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:titleTextValue='@{"课堂练习"}'
app:rightSrc='@{@drawable/ic_menu}'
/>

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

<!--取消笔记、加入笔记,默认选中-->
<CheckBox
android:id="@+id/rb_note"
android:layout_width="wrap_content"
android:layout_height="36dp"
android:layout_marginEnd="@dimen/global_spacing"
android:button="@null"
android:drawableStart="@drawable/ic_note"
android:drawableTint="@color/composition_note_cb"
android:textColor="@color/composition_note_cb"
android:checked="true"
android:drawablePadding="4dp"
android:gravity="center_vertical"
android:insetTop="0dp"
android:insetBottom="0dp"
android:textSize="@dimen/smallSize"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/line_top" />


<androidx.core.widget.NestedScrollView
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="@+id/rb_note"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:paddingStart="@dimen/global_spacing"
android:paddingEnd="@dimen/global_spacing">

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

<TextView
android:id="@+id/tv_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
tools:text="fasfasfsdfsfdsfdfdfd"
android:gravity="center"
android:textColor="@color/main_text_color"
android:textSize="@dimen/normalSize"
android:textStyle="bold"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />


<TextView
android:id="@+id/tv_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:lineSpacingExtra="5dp"
tools:text="显示内容"
android:textColor="@color/gray_4"
android:textSize="@dimen/smallSize"
app:layout_constraintTop_toBottomOf="@+id/tv_title"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />


<TextView
android:id="@+id/tv_question"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:layout_marginBottom="@dimen/global_spacing"
tools:text="fdsfdsafsdfsdfsdgfsdgsagasgddsgg"
android:textColor="@color/red_1"
android:textSize="@dimen/biggerSize"
android:textStyle="bold"
app:layout_constraintTop_toBottomOf="@+id/tv_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />

<include
android:id="@+id/inc_control_button"
layout="@layout/inc_control_button"
android:layout_width="0dp"
android:layout_height="56dp"
app:layout_constraintTop_toBottomOf="@+id/tv_question"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
/>

<TextView
android:id="@+id/tv_answer"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:lineSpacingExtra="5dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginTop="@dimen/global_spacing"
app:layout_constraintTop_toBottomOf="@+id/inc_control_button"
tools:text="答案"/>


</androidx.constraintlayout.widget.ConstraintLayout>

</androidx.core.widget.NestedScrollView>

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

+ 114
- 6
app/src/main/res/layout/activity_learn_ctask.xml View File

<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".module.learn.LearnCTaskActivity">
xmlns:tools="http://schemas.android.com/tools">


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

</data>

<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".module.learn.LearnCTaskActivity"
android:background="@color/white">

<com.suliang.common.widget.TitleBar
android:id="@+id/title_bar"
android:layout_width="0dp"
android:layout_height="@dimen/title_bar_height"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:rightSrc="@drawable/ic_menu"
tools:title_text="第一章 小学...什么 " />

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

<TextView
android:id="@+id/topic_flag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="作文题目:"
android:textColor="@color/gray_2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/line_top"
android:layout_marginTop="@dimen/global_spacing"
android:layout_marginStart="@dimen/global_spacing"
android:textSize="@dimen/smallSize" />

<TextView
android:id="@+id/topic_value"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textColor="@color/main_text_color"
android:textSize="@dimen/smallSize"
android:layout_marginEnd="@dimen/global_spacing"
app:layout_constraintStart_toEndOf="@+id/topic_flag"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/topic_flag" />

<TextView
android:id="@+id/require_flag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="作文要求:"
android:textColor="@color/gray_2"
android:layout_marginTop="8dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/topic_value"
android:layout_marginStart="@dimen/global_spacing"
android:textSize="@dimen/smallSize" />

<TextView
android:id="@+id/require_value"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textColor="@color/main_text_color"
android:lineSpacingExtra="5dp"
app:layout_constraintStart_toEndOf="@+id/require_flag"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/require_flag"
android:layout_marginEnd="@dimen/global_spacing"
android:textSize="@dimen/smallSize" />

<TextView
android:id="@+id/source_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="作文来源:"
android:textColor="@color/gray_2"
android:layout_marginTop="8dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/require_value"
android:layout_marginStart="@dimen/global_spacing"
android:textSize="@dimen/smallSize" />

<TextView
android:id="@+id/source_value"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textColor="@color/main_text_color"
app:layout_constraintStart_toEndOf="@+id/source_name"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/source_name"
android:layout_marginEnd="@dimen/global_spacing"
android:textSize="@dimen/smallSize" />

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="@id/source_value"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginStart="14dp"
android:layout_marginEnd="14dp"
android:layout_marginTop="5dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

+ 2
- 0
app/src/main/res/layout/activity_learn_word.xml View File

layout="@layout/inc_control_button" layout="@layout/inc_control_button"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="56dp" android:layout_height="56dp"
android:layout_marginStart="@dimen/global_spacing"
android:layout_marginEnd="@dimen/global_spacing"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/container_layout" /> app:layout_constraintTop_toBottomOf="@id/container_layout" />

+ 1
- 3
app/src/main/res/layout/inc_control_button.xml View File

xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="@dimen/global_spacing"
android:paddingEnd="@dimen/global_spacing">
android:layout_height="wrap_content">


<Button <Button
android:id="@+id/tv_left" android:id="@+id/tv_left"

+ 5
- 1
app/src/main/res/layout/include_title_bar.xml View File

<data> <data>
<variable <variable
name="titleValue" name="titleValue"
type="java.lang.String" />
type="String" />
<variable <variable
name="titleColor" name="titleColor"
type="Integer" /> type="Integer" />
<variable
name="rightSrcD"
type="Integer" />
</data> </data>


<com.suliang.common.widget.TitleBar <com.suliang.common.widget.TitleBar
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:titleTextValue="@{titleValue}" app:titleTextValue="@{titleValue}"
app:titleTextColor="@{titleColor??@color/main_text_color}" app:titleTextColor="@{titleColor??@color/main_text_color}"
app:rightSrc="@{rightSrcD}"
/> />


</layout> </layout>

+ 12
- 0
app/svg/drawable/ic_menu.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="M4,16C4.8837,16 5.6,16.7163 5.6,17.6C5.6,18.4837 4.8837,19.2 4,19.2C3.1163,19.2 2.4,18.4837 2.4,17.6C2.4,16.7163 3.1163,16 4,16ZM20,16C20.8837,16 21.6,16.7163 21.6,17.6C21.6,18.4837 20.8837,19.2 20,19.2L8.8,19.2C7.9163,19.2 7.2,18.4837 7.2,17.6C7.2,16.7163 7.9163,16 8.8,16L20,16ZM4,10.4C4.8837,10.4 5.6,11.1163 5.6,12C5.6,12.8837 4.8837,13.6 4,13.6C3.1163,13.6 2.4,12.8837 2.4,12C2.4,11.1163 3.1163,10.4 4,10.4ZM20,10.4C20.8837,10.4 21.6,11.1163 21.6,12C21.6,12.8837 20.8837,13.6 20,13.6L8.8,13.6C7.9163,13.6 7.2,12.8837 7.2,12C7.2,11.1163 7.9163,10.4 8.8,10.4L20,10.4ZM4,4.8C4.8837,4.8 5.6,5.5163 5.6,6.4C5.6,7.2837 4.8837,8 4,8C3.1163,8 2.4,7.2837 2.4,6.4C2.4,5.5163 3.1163,4.8 4,4.8ZM20,4.8C20.8837,4.8 21.6,5.5163 21.6,6.4C21.6,7.2837 20.8837,8 20,8L8.8,8C7.9163,8 7.2,7.2837 7.2,6.4C7.2,5.5163 7.9163,4.8 8.8,4.8L20,4.8Z"
android:strokeWidth="1"
android:fillColor="#323232"
android:fillType="evenOdd"
android:strokeColor="#00000000"/>
</vector>

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

<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="20dp"
android:height="20dp"
android:viewportWidth="20"
android:viewportHeight="20">
<path
android:pathData="M10,1.8694C11.587,1.8694 13.0661,2.3315 14.31,3.1284L9.4836,7.955L12.152,10.6233L16.9208,5.854C17.607,7.0341 18,8.4059 18,9.8694C18,14.2876 14.4183,17.8694 10,17.8694C5.5817,17.8694 2,14.2876 2,9.8694C2,5.4511 5.5817,1.8694 10,1.8694ZM9.1323,8.3063L7.7981,12.3088L11.8006,10.9746L9.1323,8.3063Z"
android:strokeWidth="1"
android:fillColor="#F7874F"
android:fillType="evenOdd"
android:strokeColor="#00000000"/>
</vector>

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

package com.suliang.common.base.adapter package com.suliang.common.base.adapter


import androidx.databinding.ViewDataBinding
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.viewbinding.ViewBinding import androidx.viewbinding.ViewBinding



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

} }
// item 点击事件 // item 点击事件
lateinit var onItemClick : (v: View, position: Int, item:T) -> Unit lateinit var onItemClick : (v: View, position: Int, item:T) -> Unit
fun onItemClickIsInitialized() = this::onItemClick.isInitialized


//数据源 //数据源
private var mData: MutableList<T> = mutableListOf() private var mData: MutableList<T> = mutableListOf()

+ 60
- 51
lib/common/src/main/java/com/suliang/common/widget/TitleBar.kt View File



import android.content.Context import android.content.Context
import android.graphics.Color import android.graphics.Color
import android.graphics.drawable.Drawable
import android.util.AttributeSet import android.util.AttributeSet
import android.util.TypedValue import android.util.TypedValue
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View
import android.widget.TextView import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout import androidx.constraintlayout.widget.ConstraintLayout
import com.suliang.common.R import com.suliang.common.R
* Describe: 自定义标题栏 * Describe: 自定义标题栏
* 与databinding 结合时,自定义属性需要有set方法,否则编译不通过,所以,属性没有定义为private * 与databinding 结合时,自定义属性需要有set方法,否则编译不通过,所以,属性没有定义为private
*/ */
class TitleBar @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) :
class TitleBar @JvmOverloads constructor(context : Context, attrs : AttributeSet? = null, defStyleAttr : Int = 0) :
ConstraintLayout(context, attrs, defStyleAttr) { ConstraintLayout(context, attrs, defStyleAttr) {
lateinit var onBackClick: (view: TextView) -> Unit
lateinit var onRightClick: (view: TextView) -> Unit
lateinit var textViewBackView: TextView
lateinit var onBackClick : (view : TextView) -> Unit
lateinit var onRightClick : (view : TextView) -> Unit
lateinit var textViewBackView : TextView
private set private set
lateinit var textViewTitle: TextView
lateinit var textViewTitle : TextView
private set private set
lateinit var textViewRight: TextView
lateinit var textViewRight : TextView
private set private set
init { init {
initAttrs(attrs) initAttrs(attrs)
} }
private fun initAttrs(attrs: AttributeSet?) {
private fun initAttrs(attrs : AttributeSet?) {
context.obtainStyledAttributes(attrs, R.styleable.TitleBar).run { context.obtainStyledAttributes(attrs, R.styleable.TitleBar).run {
val barBackground = getColor(R.styleable.TitleBar_barBackground, 0) val barBackground = getColor(R.styleable.TitleBar_barBackground, 0)
val titleTextValue = getString(R.styleable.TitleBar_titleTextValue) val titleTextValue = getString(R.styleable.TitleBar_titleTextValue)
val backTextSize = getDimension(R.styleable.TitleBar_backTextSize, 0f) val backTextSize = getDimension(R.styleable.TitleBar_backTextSize, 0f)
val backTextColor = getColor(R.styleable.TitleBar_backTextColor, 0) val backTextColor = getColor(R.styleable.TitleBar_backTextColor, 0)
val backTextValue = getString(R.styleable.TitleBar_backTextValue) val backTextValue = getString(R.styleable.TitleBar_backTextValue)
val backSrc : Int = getResourceId(R.styleable.TitleBar_backSrc, R.drawable.ic_back)
val backSrc : Int = getResourceId(R.styleable.TitleBar_backSrc, R.drawable.ic_back)
val drawPadding = getDimension(R.styleable.TitleBar_drawPadding, 0f).toInt() val drawPadding = getDimension(R.styleable.TitleBar_drawPadding, 0f).toInt()
recycle() recycle()
initView() initView()
} }
textViewBackView.apply { textViewBackView.apply {
text = backTextValue text = backTextValue
setTextColor(titleTextColor)
setTextSize(TypedValue.COMPLEX_UNIT_PX, titleTextSize)
setTextColor(backTextColor)
setTextSize(TypedValue.COMPLEX_UNIT_PX, backTextSize)
if (backSrc != 0) { if (backSrc != 0) {
setCompoundDrawablesWithIntrinsicBounds(backSrc, 0, 0, 0) setCompoundDrawablesWithIntrinsicBounds(backSrc, 0, 0, 0)
} }
} }
textViewRight.apply { textViewRight.apply {
text = rightTextValue text = rightTextValue
setTextColor(titleTextColor)
setTextSize(TypedValue.COMPLEX_UNIT_PX, titleTextSize)
setTextColor(rightTextColor)
setTextSize(TypedValue.COMPLEX_UNIT_PX, rightTextSize)
if (rightSrc != 0) { if (rightSrc != 0) {
setCompoundDrawablesWithIntrinsicBounds(rightSrc, 0, 0, 0) setCompoundDrawablesWithIntrinsicBounds(rightSrc, 0, 0, 0)
if (drawPadding != 0) { if (drawPadding != 0) {
} }
} }
} }
if (!textViewRight.text.isNullOrEmpty() || rightSrc != 0) {
textViewRight.visibility = View.VISIBLE
}
//事件 //事件
textViewBackView.click { textViewBackView.click {
if (this@TitleBar::onBackClick.isInitialized)
onBackClick.invoke(it as TextView)
if (this@TitleBar::onBackClick.isInitialized) onBackClick.invoke(it as TextView)
} }
textViewRight.click { textViewRight.click {
if (this@TitleBar::onRightClick.isInitialized)
onRightClick.invoke(it as TextView)
if (this@TitleBar::onRightClick.isInitialized) onRightClick.invoke(it as TextView)
} }
} }
} }
private fun initView() { private fun initView() {
LayoutInflater.from(context).inflate(R.layout.public_title_bar, this, true) LayoutInflater.from(context).inflate(R.layout.public_title_bar, this, true)
textViewTitle = findViewById(R.id.title_bar_title) textViewTitle = findViewById(R.id.title_bar_title)
textViewBackView = findViewById(R.id.title_bar_back) textViewBackView = findViewById(R.id.title_bar_back)
textViewRight = findViewById(R.id.title_bar_right) textViewRight = findViewById(R.id.title_bar_right)
} }
//单独添加set属性,用于binding传值后的设置,否则传值无效,不会进行设置 //单独添加set属性,用于binding传值后的设置,否则传值无效,不会进行设置
fun setBarBackground(value: Int) {
setBackgroundColor(value)
fun setBarBackground(value : Int) {
setBackgroundColor(value)
} }
fun setTitleTextValue(value: String) { //标题文字-->
fun setTitleTextValue(value : String) { //标题文字-->
textViewTitle.text = value textViewTitle.text = value
} }
fun setTitleTextSize(value: Float) { //标题大小-->
fun setTitleTextSize(value : Float) { //标题大小-->
textViewTitle.setTextSize(TypedValue.COMPLEX_UNIT_PX, value) textViewTitle.setTextSize(TypedValue.COMPLEX_UNIT_PX, value)
} }
fun setTitleTextColor(value: Int) { //标题颜色-->
fun setTitleTextColor(value : Int) { //标题颜色-->
textViewTitle.setTextColor(value) textViewTitle.setTextColor(value)
} }
fun setRightTextValue(value: String) { //右侧文字
fun setRightTextValue(value : String) { //右侧文字
textViewRight.text = value textViewRight.text = value
} }
fun setRightTextSize(value: Float) { //右侧大小-->
fun setRightTextSize(value : Float) { //右侧大小-->
textViewRight.setTextSize(TypedValue.COMPLEX_UNIT_PX, value) textViewRight.setTextSize(TypedValue.COMPLEX_UNIT_PX, value)
} }
fun setRightTextColor(value : Int){ //右侧颜色-->
fun setRightTextColor(value : Int) { //右侧颜色-->
textViewRight.setTextColor(value) textViewRight.setTextColor(value)
} }
fun setRightSrc(value : Int) { //右侧图片--> fun setRightSrc(value : Int) { //右侧图片-->
textViewRight.setCompoundDrawablesWithIntrinsicBounds(0, 0, value, 0) textViewRight.setCompoundDrawablesWithIntrinsicBounds(0, 0, value, 0)
} }
fun setBackTextValue(value: String){ //左侧文字-->
fun setRightSrc(value : Drawable) { //右侧图片-->
textViewRight.visibility = View.VISIBLE
textViewRight.setCompoundDrawablesWithIntrinsicBounds(null, null, value, null)
}
fun setBackTextValue(value : String) { //左侧文字-->
textViewBackView.text = value textViewBackView.text = value
} }

fun setBackTextSize(value:Float) { //左侧文字大小-->
fun setBackTextSize(value : Float) { //左侧文字大小-->
textViewBackView.setTextSize(TypedValue.COMPLEX_UNIT_PX, value) textViewBackView.setTextSize(TypedValue.COMPLEX_UNIT_PX, value)
} }
fun setBackTextColor(value: Int){ //左侧颜色
fun setBackTextColor(value : Int) { //左侧颜色
textViewBackView.setTextColor(value) textViewBackView.setTextColor(value)
} }
fun setBackSrc(value: Int) { //左侧图片
fun setBackSrc(value : Int) { //左侧图片
textViewBackView.setCompoundDrawablesWithIntrinsicBounds(value, 0, 0, 0) textViewBackView.setCompoundDrawablesWithIntrinsicBounds(value, 0, 0, 0)
} }
fun setDrawPadding(value:Int){ //图片drawPadding-->
fun setDrawPadding(value : Int) { //图片drawPadding-->
textViewRight.compoundDrawablePadding = value textViewRight.compoundDrawablePadding = value
textViewBackView.compoundDrawablePadding = value textViewBackView.compoundDrawablePadding = value
} }
} }

+ 1
- 0
lib/common/src/main/res/layout/public_title_bar.xml View File

app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
tools:drawableStart="@android:drawable/ic_menu" tools:drawableStart="@android:drawable/ic_menu"
android:paddingRight="16dp"
tools:text="更多" /> tools:text="更多" />


</merge> </merge>

Loading…
Cancel
Save