</formatting-settings> | </formatting-settings> | ||||
</DBN-SQL> | </DBN-SQL> | ||||
<JetCodeStyleSettings> | <JetCodeStyleSettings> | ||||
<option name="CONTINUATION_INDENT_IN_PARAMETER_LISTS" value="true" /> | |||||
<option name="CONTINUATION_INDENT_FOR_EXPRESSION_BODIES" value="true" /> | |||||
<option name="CONTINUATION_INDENT_IN_SUPERTYPE_LISTS" value="true" /> | |||||
<option name="WRAP_EXPRESSION_BODY_FUNCTIONS" value="0" /> | |||||
<option name="WRAP_ELVIS_EXPRESSIONS" value="0" /> | |||||
<option name="IF_RPAREN_ON_NEW_LINE" value="false" /> | |||||
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" /> | <option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" /> | ||||
</JetCodeStyleSettings> | </JetCodeStyleSettings> | ||||
<DBN-PSQL> | <DBN-PSQL> | ||||
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" /> | <option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" /> | ||||
<option name="RIGHT_MARGIN" value="120" /> | <option name="RIGHT_MARGIN" value="120" /> | ||||
<option name="KEEP_LINE_BREAKS" value="false" /> | <option name="KEEP_LINE_BREAKS" value="false" /> | ||||
<option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" /> | |||||
<option name="ALIGN_MULTILINE_METHOD_BRACKETS" value="true" /> | |||||
<option name="CALL_PARAMETERS_LPAREN_ON_NEXT_LINE" value="false" /> | |||||
<option name="CALL_PARAMETERS_RPAREN_ON_NEXT_LINE" value="false" /> | |||||
<option name="METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE" value="false" /> | |||||
<option name="METHOD_PARAMETERS_RPAREN_ON_NEXT_LINE" value="false" /> | |||||
<option name="EXTENDS_LIST_WRAP" value="0" /> | |||||
</codeStyleSettings> | </codeStyleSettings> | ||||
</code_scheme> | </code_scheme> | ||||
</component> | </component> |
<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/dialog_bottom_bg.xml" value="0.5140625" /> | |||||
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/et_search_bg.xml" value="0.175" /> | <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/et_search_bg.xml" value="0.175" /> | ||||
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/ic_delete.xml" value="0.30520833333333336" /> | <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/ic_delete.xml" value="0.30520833333333336" /> | ||||
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/ic_discern.xml" value="0.30520833333333336" /> | <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/ic_discern.xml" value="0.30520833333333336" /> | ||||
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/nav_service.xml" value="0.30520833333333336" /> | <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/nav_service.xml" value="0.30520833333333336" /> | ||||
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/nav_statistics.xml" value="0.1" /> | <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/nav_statistics.xml" value="0.1" /> | ||||
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/progress_center.xml" value="0.287962962962963" /> | <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/progress_center.xml" value="0.287962962962963" /> | ||||
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/shape_rounder_12_white.xml" value="0.5140625" /> | |||||
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/shape_rounder_toplr_24_white.xml" value="0.5061538461538462" /> | <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/shape_rounder_toplr_24_white.xml" value="0.5061538461538462" /> | ||||
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/spoken_autoplay_btn_text_color_.xml" value="0.5140625" /> | |||||
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/theme_splash_bg.xml" value="0.30520833333333336" /> | <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/drawable/theme_splash_bg.xml" value="0.30520833333333336" /> | ||||
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout-v23/include_main_learn_center_course_type_title.xml" value="0.4963768115942029" /> | <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout-v23/include_main_learn_center_course_type_title.xml" value="0.4963768115942029" /> | ||||
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/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_learn_base.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/src/main/res/layout/content_learn_base.xml" value="0.4979166666666667" /> | |||||
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/dialog_bottom_auto_play_select.xml" value="0.4979166666666667" /> | |||||
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/dialog_bottom_course_more.xml" value="0.33" /> | |||||
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/dialog_item_select_repeat.xml" value="0.4979166666666667" /> | |||||
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/dialog_lesson_learn.xml" value="0.4144927536231884" /> | |||||
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/fragment_course_lesson.xml" value="0.33" /> | |||||
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/fragment_course_main.xml" value="0.4979166666666667" /> | |||||
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/fragment_course_pack.xml" value="0.34427083333333336" /> | <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/fragment_course_pack.xml" value="0.34427083333333336" /> | ||||
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/fragment_course_review.xml" value="0.12802768166089964" /> | |||||
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/fragment_course_total_test.xml" value="0.33" /> | |||||
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/fragment_first.xml" value="0.4979166666666667" /> | |||||
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/fragment_learn_center.xml" value="0.25" /> | <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/fragment_learn_center.xml" value="0.25" /> | ||||
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/fragment_my.xml" value="0.28229166666666666" /> | <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/fragment_my.xml" value="0.28229166666666666" /> | ||||
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/inc_over_number.xml" value="0.4979166666666667" /> | |||||
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/include_main_learn_center_course_progress.xml" value="0.503125" /> | |||||
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/include_main_learn_center_course_type_title.xml" value="0.67" /> | <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/include_main_learn_center_course_type_title.xml" value="0.67" /> | ||||
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/include_recyclerview_smart_refresh_layout.xml" value="0.4979166666666667" /> | <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/include_recyclerview_smart_refresh_layout.xml" value="0.4979166666666667" /> | ||||
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/include_title_bar.xml" value="0.25052083333333336" /> | <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/include_title_bar.xml" value="0.25052083333333336" /> | ||||
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/item_course_lesson.xml" value="0.4785615491009682" /> | |||||
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/item_empty.xml" value="0.4979166666666667" /> | <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/item_empty.xml" value="0.4979166666666667" /> | ||||
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/main_item_course_progress.xml" value="0.25" /> | <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" /> | <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/main_item_coursepack.xml" value="0.43500866551126516" /> | ||||
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/textview.xml" value="0.49773550724637683" /> | <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/textview.xml" value="0.49773550724637683" /> | ||||
<entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/textview_only.xml" value="0.49773550724637683" /> | <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/textview_only.xml" value="0.49773550724637683" /> | ||||
<entry key="..\:/Work/XKL/XKL/XklLocal/app/statedrawable/drawable/ic_nav_learn_center.xml" value="0.44166666666666665" /> | <entry key="..\:/Work/XKL/XKL/XklLocal/app/statedrawable/drawable/ic_nav_learn_center.xml" value="0.44166666666666665" /> | ||||
<entry key="..\:/Work/XKL/XKL/XklLocal/app/svg/drawable/ic_arrow_right.xml" value="0.29814814814814816" /> | |||||
<entry key="..\:/Work/XKL/XKL/XklLocal/app/svg/drawable/ic_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_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/lib/common/src/main/res/drawable/ic_back.xml" value="0.4148148148148148" /> | <entry key="..\:/Work/XKL/XKL/XklLocal/lib/common/src/main/res/drawable/ic_back.xml" value="0.4148148148148148" /> | ||||
<entry key="..\:/Work/XKL/XKL/XklLocal/lib/common/src/main/res/drawable/ic_search.xml" value="0.19814814814814816" /> | <entry key="..\:/Work/XKL/XKL/XklLocal/lib/common/src/main/res/drawable/ic_search.xml" value="0.19814814814814816" /> | ||||
<entry key="..\:/Work/XKL/XKL/XklLocal/lib/common/src/main/res/drawable/loading_bg.xml" value="0.5061538461538462" /> | <entry key="..\:/Work/XKL/XKL/XklLocal/lib/common/src/main/res/drawable/loading_bg.xml" value="0.5061538461538462" /> | ||||
<entry key="..\:/Work/XKL/XKL/XklLocal/lib/common/src/main/res/layout/item_empty.xml" value="0.34427083333333336" /> | |||||
<entry key="..\:/Work/XKL/XKL/XklLocal/lib/common/src/main/res/layout/lib_dialog_loading.xml" value="0.4979166666666667" /> | <entry key="..\:/Work/XKL/XKL/XklLocal/lib/common/src/main/res/layout/lib_dialog_loading.xml" value="0.4979166666666667" /> | ||||
<entry key="..\:/Work/XKL/XKL/XklLocal/lib/common/src/main/res/layout/lib_layout_custom_title.xml" value="0.4979166666666667" /> | <entry key="..\:/Work/XKL/XKL/XklLocal/lib/common/src/main/res/layout/lib_layout_custom_title.xml" value="0.4979166666666667" /> | ||||
<entry key="..\:/Work/XKL/XKL/XklLocal/lib/common/src/main/res/layout/loadding_fragment.xml" value="0.4817708333333333" /> | <entry key="..\:/Work/XKL/XKL/XklLocal/lib/common/src/main/res/layout/loadding_fragment.xml" value="0.4817708333333333" /> |
3、尽一切可能针对防欺诈支付和电话以外的所有其他用例使用实例 ID 或私密存储的 GUID。对于绝大多数非广告用例,使用实例 ID 或 GUID 应已足够。 | 3、尽一切可能针对防欺诈支付和电话以外的所有其他用例使用实例 ID 或私密存储的 GUID。对于绝大多数非广告用例,使用实例 ID 或 GUID 应已足够。 | ||||
4、使用适合您的用例的 API 以尽量降低隐私权风险 | 4、使用适合您的用例的 API 以尽量降低隐私权风险 | ||||
如何实现防快速点击 aspectJ | |||||
如何实现防快速点击 aspectJ | |||||
饿汉式(直接获取实例)、懒汉式(一次判空获取实例)、双重校验锁 | 饿汉式(直接获取实例)、懒汉式(一次判空获取实例)、双重校验锁 | ||||
object 声明: 为饿汉式单例,即直接实例 | object 声明: 为饿汉式单例,即直接实例 | ||||
数字精度格式: https://www.jianshu.com/p/5286a44ed9b1 | 数字精度格式: https://www.jianshu.com/p/5286a44ed9b1 | ||||
Material Design Components 组件使用 https://www.jianshu.com/p/bc71b4179cb2 | |||||
// Android Gradle 插件 4.0,下述配置不再是必需的,并且会导致构建失败。外部原生 build 现在会自动打包这些库,因此使用 jniLibs 明确打包库会导致重复。 | |||||
// sourceSets { | |||||
// main { | |||||
// jniLibs.srcDirs = ['libs'] | |||||
// } | |||||
// } |
} | } | ||||
dependencies { | dependencies { | ||||
implementation fileTree(include: ['*.jar',"*.aar"], dir: 'libs') | |||||
implementation 'androidx.legacy:legacy-support-v4:1.0.0' | implementation 'androidx.legacy:legacy-support-v4:1.0.0' | ||||
implementation project(path: ':lib:common') | implementation project(path: ':lib:common') | ||||
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.1' | implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.1' | ||||
implementation 'androidx.appcompat:appcompat:1.2.0' | implementation 'androidx.appcompat:appcompat:1.2.0' | ||||
implementation 'com.google.android.material:material:1.3.0' | implementation 'com.google.android.material:material:1.3.0' | ||||
implementation 'androidx.constraintlayout:constraintlayout:2.0.4' | implementation 'androidx.constraintlayout:constraintlayout:2.0.4' | ||||
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.5' | |||||
implementation 'androidx.navigation:navigation-ui-ktx:2.3.5' | |||||
rootProject.ext.dependencies_required.each{ k, v -> implementation v} | rootProject.ext.dependencies_required.each{ k, v -> implementation v} | ||||
testImplementation rootProject.ext.dependencies_testImplementation.junit | testImplementation rootProject.ext.dependencies_testImplementation.junit | ||||
rootProject.ext.dependencies_androidTestImplementation.each{ k,v -> androidTestImplementation v} | rootProject.ext.dependencies_androidTestImplementation.each{ k,v -> androidTestImplementation v} |
android:theme="@style/Theme.XklLocal" | android:theme="@style/Theme.XklLocal" | ||||
tools:ignore="LockedOrientationActivity"> | tools:ignore="LockedOrientationActivity"> | ||||
<activity | <activity | ||||
android:name=".module.m_center_learn.CourseMainActivity" | |||||
android:name=".module.learn.LearnCTaskActivity" | |||||
android:exported="true" /> | |||||
<activity | |||||
android:name=".module.learn.LearnCReadingActivity" | |||||
android:exported="true" /> | |||||
<activity | |||||
android:name=".module.learn.LearnCVideoActivity" | |||||
android:exported="true" /> | |||||
<activity | |||||
android:name=".module.learn.LearnExamSpellActivity" | |||||
android:exported="true" /> | |||||
<activity | |||||
android:name=".module.learn.LearnExamWordActivity" | |||||
android:exported="true" /> | |||||
<activity | |||||
android:name=".module.learn.LearnSpellActivity" | |||||
android:exported="true" /> | |||||
<activity | |||||
android:name=".module.learn.LearnWordActivity" | |||||
android:exported="true" /> | |||||
<activity | |||||
android:name=".module.m_center_learn.CoursePackMainActivity" | |||||
android:exported="true" /> | android:exported="true" /> | ||||
<activity | <activity | ||||
android:name=".module.splash.SplashActivity" | android:name=".module.splash.SplashActivity" |
package com.xkl.cdl.adapter | |||||
import android.view.ViewGroup | |||||
import com.suliang.common.base.adapter.BaseAdapterViewHolder | |||||
import androidx.viewbinding.ViewBinding | |||||
import com.suliang.common.base.adapter.BaseAdapter | |||||
import com.suliang.common.extension.click | |||||
import com.xkl.cdl.R | |||||
import com.xkl.cdl.databinding.DialogItemSelectRepeatBinding | |||||
/** | |||||
* author suliang | |||||
* create 2020/6/29 13:44 | |||||
* Describe: 自动播放弹窗列表选择适配器 | |||||
*/ | |||||
class AdapterAutoPlaySelectRepeat : BaseAdapter<Void?>() { | |||||
override fun coverEmptyViewHolder(parent: ViewGroup): BaseAdapterViewHolder { | |||||
return BaseAdapterViewHolder(inflateBinding(parent, R.layout.item_empty)) | |||||
} | |||||
override fun onBindEmptyViewHolder(holder: BaseAdapterViewHolder) {} | |||||
override fun getItemCount(): Int { | |||||
return 5 | |||||
} | |||||
override fun coverViewHolder(parent: ViewGroup, viewType: Int): BaseAdapterViewHolder { | |||||
val binding = inflateBinding(parent, R.layout.dialog_item_select_repeat) | |||||
return BaseAdapterViewHolder(binding) | |||||
} | |||||
override fun onBindVH(holder: BaseAdapterViewHolder, position: Int) { | |||||
val binding = holder.binding as DialogItemSelectRepeatBinding | |||||
when (position) { | |||||
0 -> binding.tvOption.setText(R.string.auto_play_repeat_1) | |||||
1 -> binding.tvOption.setText(R.string.auto_play_repeat_2) | |||||
2 -> binding.tvOption.setText(R.string.auto_play_repeat_3) | |||||
3 -> binding.tvOption.setText(R.string.auto_play_repeat_4) | |||||
4 -> binding.tvOption.setText(R.string.auto_play_repeat_5) | |||||
} | |||||
binding.root.click { | |||||
onItemClick.invoke(it,position,null) | |||||
} | |||||
} | |||||
} |
package com.xkl.cdl.adapter | package com.xkl.cdl.adapter | ||||
import android.opengl.Visibility | |||||
import android.view.View | import android.view.View | ||||
import android.view.ViewGroup | import android.view.ViewGroup | ||||
import com.suliang.common.base.adapter.BaseAdapterVM | import com.suliang.common.base.adapter.BaseAdapterVM | ||||
import com.suliang.common.base.adapter.BaseAdapterViewHolder | import com.suliang.common.base.adapter.BaseAdapterViewHolder | ||||
import com.suliang.common.databinding.ItemEmptyBinding | |||||
import com.suliang.common.extension.click | import com.suliang.common.extension.click | ||||
import com.xkl.cdl.R | import com.xkl.cdl.R | ||||
import com.xkl.cdl.data.Constants | |||||
import com.xkl.cdl.data.course.CoursePack | |||||
import com.xkl.cdl.databinding.ItemEmptyBinding | |||||
import com.xkl.cdl.data.AppConstants | |||||
import com.xkl.cdl.data.bean.course.CoursePack | |||||
import com.xkl.cdl.databinding.MainItemCoursepackBinding | import com.xkl.cdl.databinding.MainItemCoursepackBinding | ||||
import com.xkl.cdl.module.m_center_learn.CoursePackFragmentViewModel | import com.xkl.cdl.module.m_center_learn.CoursePackFragmentViewModel | ||||
class AdapterCoursePackWithLearCenter(vm: CoursePackFragmentViewModel) : | class AdapterCoursePackWithLearCenter(vm: CoursePackFragmentViewModel) : | ||||
BaseAdapterVM<CoursePack, CoursePackFragmentViewModel>(vm) { | BaseAdapterVM<CoursePack, CoursePackFragmentViewModel>(vm) { | ||||
override fun coverEmptyViewHolder(parent: ViewGroup): BaseAdapterViewHolder { | |||||
return BaseAdapterViewHolder(inflateBinding(parent, R.layout.item_empty)) | |||||
} | |||||
override fun onBindEmptyViewHolder(holder: BaseAdapterViewHolder) { | override fun onBindEmptyViewHolder(holder: BaseAdapterViewHolder) { | ||||
(holder.binding as ItemEmptyBinding).apply { | (holder.binding as ItemEmptyBinding).apply { | ||||
val nullOrEmpty = vm.learnCenterFragmentViewModel.mCoursePackSearchValueMap[vm.projectId].isNullOrEmpty() | val nullOrEmpty = vm.learnCenterFragmentViewModel.mCoursePackSearchValueMap[vm.projectId].isNullOrEmpty() | ||||
imageViewTypeVoice.visibility = View.GONE | imageViewTypeVoice.visibility = View.GONE | ||||
coursePack = getItem(position).also { cp -> | coursePack = getItem(position).also { cp -> | ||||
when (vm.projectId) { | when (vm.projectId) { | ||||
Constants.SUBJECT_ENGLISH -> initEnglish(this, cp, position) | |||||
Constants.SUBJECT_CHINESE -> initChinese(this, cp, position) | |||||
AppConstants.SUBJECT_ENGLISH -> initEnglish(this, cp, position) | |||||
AppConstants.SUBJECT_CHINESE -> initChinese(this, cp, position) | |||||
} | } | ||||
root.click { | root.click { | ||||
onItemClick.invoke(it, position, cp) | onItemClick.invoke(it, position, cp) | ||||
//图标 | //图标 | ||||
coursePack.childrenCourses.forEach { | coursePack.childrenCourses.forEach { | ||||
when(it.courseType){ | when(it.courseType){ | ||||
Constants.COURSE_TYPE_ENGLISH_DISCERN -> imageViewTypeDiscern.visibility = View.VISIBLE | |||||
Constants.COURSE_TYPE_ENGLISH_SPELL -> imageViewTypeSpell.visibility = View.VISIBLE | |||||
Constants.COURSE_TYPE_ENGLISH_VOICE -> { | |||||
AppConstants.COURSE_TYPE_ENGLISH_DISCERN -> imageViewTypeDiscern.visibility = View.VISIBLE | |||||
AppConstants.COURSE_TYPE_ENGLISH_SPELL -> imageViewTypeSpell.visibility = View.VISIBLE | |||||
AppConstants.COURSE_TYPE_ENGLISH_VOICE -> { | |||||
imageViewTypeVoice.run { | imageViewTypeVoice.run { | ||||
visibility = View.VISIBLE | visibility = View.VISIBLE | ||||
setImageResource(R.drawable.ic_voice) | setImageResource(R.drawable.ic_voice) | ||||
} | } | ||||
} | } | ||||
Constants.COURSE_TYPE_ENGLISH_SPOKEN -> { | |||||
AppConstants.COURSE_TYPE_ENGLISH_SPOKEN -> { | |||||
imageViewTypeVoice.run{ | imageViewTypeVoice.run{ | ||||
visibility = View.VISIBLE | visibility = View.VISIBLE | ||||
setImageResource(R.drawable.ic_spoken) | setImageResource(R.drawable.ic_spoken) |
package com.xkl.cdl.adapter | |||||
import android.content.res.ColorStateList | |||||
import android.view.View | |||||
import android.view.ViewGroup | |||||
import androidx.core.content.ContextCompat | |||||
import com.suliang.common.base.adapter.BaseAdapterVM | |||||
import com.suliang.common.base.adapter.BaseAdapterViewHolder | |||||
import com.suliang.common.extension.click | |||||
import com.xkl.cdl.R | |||||
import com.xkl.cdl.data.AppConstants | |||||
import com.xkl.cdl.data.bean.course.Lesson | |||||
import com.xkl.cdl.databinding.ItemCourseLessonBinding | |||||
import com.xkl.cdl.module.m_center_learn.coursechildren.CourseMainFragmentViewModel | |||||
/** | |||||
* author suliang | |||||
* create 2022/3/29 16:43 | |||||
* Describe: 课程课时列表适配器 | |||||
*/ | |||||
class AdapterLesson(vm: CourseMainFragmentViewModel) : BaseAdapterVM<Lesson, CourseMainFragmentViewModel>(vm) { | |||||
/** 选中item的位置 */ | |||||
var selectPos = -1 | |||||
override fun coverViewHolder(parent: ViewGroup, viewType: Int): BaseAdapterViewHolder { | |||||
return BaseAdapterViewHolder(inflateBinding(parent, R.layout.item_course_lesson)) | |||||
} | |||||
override fun onBindVH(holder: BaseAdapterViewHolder, position: Int) { | |||||
val lesson = getItem(position) | |||||
(holder.binding as ItemCourseLessonBinding).run { | |||||
data = lesson | |||||
//章节名称是否显示 | |||||
if (position == 0 || lesson.chapterId != getItem(position - 1).chapterId) { //不为第一个个且与上一个章节id相同 | |||||
tvChapterName.visibility = View.VISIBLE | |||||
} else { | |||||
tvChapterName.visibility = View.GONE | |||||
} | |||||
//执行 | |||||
executePendingBindings() | |||||
initColor(position, lesson) | |||||
when(lesson.lessonType){ | |||||
AppConstants.LESSON_TYPE_COMPOSITION_VIDEO -> { // 作文视频 | |||||
} | |||||
AppConstants.LESSON_TYPE_COMPOSITION_EXAM -> { //作文章节测试 | |||||
} | |||||
AppConstants.LESSON_TYPE_COMPOSITION_READING -> { //作文课堂练习 | |||||
} | |||||
AppConstants.LESSON_TYPE_COMPOSITION_TASK -> { //作文课外练习 | |||||
} | |||||
AppConstants.LESSON_TYPE_DIALOGUE -> { //口语对话 | |||||
} | |||||
else -> { } // 其他课时类型为布局的正常显示 | |||||
} | |||||
//事件: 将章节名称的点击事件取消了 | |||||
layoutContent.click { | |||||
//选中项非当前项,则需要改变选中颜色,直接通知更新,调用对应位置的notfy | |||||
if (selectPos != position) { | |||||
notifyItemChanged(selectPos) | |||||
selectPos = position | |||||
notifyItemChanged(selectPos) | |||||
} | |||||
notifyItemChanged(position) | |||||
notifyItemChanged(position, null) | |||||
onItemClick.invoke(it, position, lesson) | |||||
} | |||||
} | |||||
} | |||||
/** | |||||
* 处理颜色 选中色 未选中色(学习完成/学习未完成) | |||||
* @receiver ItemCourseLessonBinding | |||||
* @param position Int | |||||
* @param lesson Lesson | |||||
*/ | |||||
private fun ItemCourseLessonBinding.initColor(position: Int, lesson: Lesson) { | |||||
val normalColorNotLearnOver = ContextCompat.getColor(context, R.color.gray_2) //学习未完成未选中时的颜色 | |||||
val normalColorLearnOver = ContextCompat.getColor(context, R.color.gray_1) //学习已完成未选中时的颜色 | |||||
val mainTextColor = ContextCompat.getColor(context, R.color.main_text_color) //选中颜色 | |||||
val translationColor = ContextCompat.getColor(context, R.color.translation) //透明颜色 | |||||
//item的背景和状态设置 | |||||
if (selectPos == position) { //选中,背景设置 | |||||
layoutContent.setBackgroundColor(ContextCompat.getColor(context, R.color.gray_3)) //选中背景 | |||||
tvLessonName.run { | |||||
setTextColor(mainTextColor) //课时名称颜色 | |||||
paint.isFakeBoldText = true//加粗 | |||||
} | |||||
tvLessonNumber.setTextColor(normalColorNotLearnOver) //数量颜色 | |||||
//箭头 | |||||
ivArrowRight.apply { | |||||
setBackgroundColor(ContextCompat.getColor(context, R.color.theme_color)) | |||||
imageTintList = ColorStateList.valueOf(ContextCompat.getColor(context, R.color.white)) | |||||
strokeColor = ColorStateList.valueOf(translationColor) | |||||
} | |||||
} else { //未选中:根据学习情况判断 | |||||
layoutContent.setBackgroundColor(translationColor) //未选中背景透明 | |||||
if (lesson.learnIsOver) { | |||||
tvLessonName.run { | |||||
setTextColor(normalColorLearnOver) //课时名称颜色 | |||||
paint.isFakeBoldText = false //加粗 | |||||
} | |||||
tvLessonNumber.setTextColor(normalColorLearnOver) //数量颜色 | |||||
ivArrowRight.run { | |||||
setBackgroundColor(translationColor) | |||||
imageTintList = ColorStateList.valueOf(ContextCompat.getColor(context, R.color.theme_color)) | |||||
strokeColor = ColorStateList.valueOf(ContextCompat.getColor(context, R.color.theme_color)) | |||||
} | |||||
} else { | |||||
tvLessonName.run { | |||||
setTextColor(normalColorNotLearnOver) //课时名称颜色 | |||||
paint.isFakeBoldText = false //加粗 | |||||
} | |||||
tvLessonNumber.setTextColor(normalColorNotLearnOver) //数量颜色 | |||||
ivArrowRight.run { | |||||
setBackgroundColor(translationColor) | |||||
imageTintList = ColorStateList.valueOf(normalColorNotLearnOver) | |||||
strokeColor = ColorStateList.valueOf(normalColorNotLearnOver) | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} |
* create 2022/3/18 9:34 | * create 2022/3/18 9:34 | ||||
* Describe: | * Describe: | ||||
*/ | */ | ||||
object Constants { | |||||
object AppConstants { | |||||
/** 项目: 英语 */ | /** 项目: 英语 */ | ||||
const val SUBJECT_ENGLISH = 3 | const val SUBJECT_ENGLISH = 3 | ||||
/** 项目: 语文*/ | /** 项目: 语文*/ | ||||
const val SUBJECT_CHINESE = 1 | const val SUBJECT_CHINESE = 1 | ||||
/**课程包类型: categoryId -> 英语单词课程 */ | /**课程包类型: categoryId -> 英语单词课程 */ | ||||
const val COURSEPACK_TYPE_ENGLISH_WORD = 1 | const val COURSEPACK_TYPE_ENGLISH_WORD = 1 | ||||
/**课程包类型: categoryId -> 英语音标课程 */ | /**课程包类型: categoryId -> 英语音标课程 */ | ||||
const val COURSEPACK_TYPE_ENGLISH_SOUNDMARK = 4 | const val COURSEPACK_TYPE_ENGLISH_SOUNDMARK = 4 | ||||
/**课程包类型: categoryId -> 英语口语 */ | /**课程包类型: categoryId -> 英语口语 */ | ||||
const val COURSEPACK_TYPE_ENGLISH_SPOKEN = 13 | const val COURSEPACK_TYPE_ENGLISH_SPOKEN = 13 | ||||
/**课程包类型: categoryId -> 语文作文 */ | /**课程包类型: categoryId -> 语文作文 */ | ||||
const val COURSEPACK_TYPE_CHINESE_COMPOSITION = 2 | const val COURSEPACK_TYPE_CHINESE_COMPOSITION = 2 | ||||
/**课程包类型: categoryId -> 语文识字 */ | /**课程包类型: categoryId -> 语文识字 */ | ||||
const val COURSEPACK_TYPE_CHINESE_LITERACY = 3 | const val COURSEPACK_TYPE_CHINESE_LITERACY = 3 | ||||
/**课程包类型: categoryId -> 语文拼音 */ | /**课程包类型: categoryId -> 语文拼音 */ | ||||
const val COURSEPACK_TYPE_CHINESE_PINYIN = 1 | const val COURSEPACK_TYPE_CHINESE_PINYIN = 1 | ||||
/**课程类型: typeId 英语认读*/ | /**课程类型: typeId 英语认读*/ | ||||
const val COURSE_TYPE_ENGLISH_DISCERN = 1 | const val COURSE_TYPE_ENGLISH_DISCERN = 1 | ||||
/**课程类型: typeId 英语辨音*/ | /**课程类型: typeId 英语辨音*/ | ||||
const val COURSE_TYPE_ENGLISH_VOICE = 2 | const val COURSE_TYPE_ENGLISH_VOICE = 2 | ||||
/**课程类型: typeId 英语拼写*/ | /**课程类型: typeId 英语拼写*/ | ||||
const val COURSE_TYPE_ENGLISH_SPELL = 3 | const val COURSE_TYPE_ENGLISH_SPELL = 3 | ||||
/**课程类型: typeId 英语音标*/ | /**课程类型: typeId 英语音标*/ | ||||
const val COURSE_TYPE_ENGLISH_SOUNDMARK = 6 | const val COURSE_TYPE_ENGLISH_SOUNDMARK = 6 | ||||
/**课程类型: typeId 英语口语*/ | /**课程类型: typeId 英语口语*/ | ||||
const val COURSE_TYPE_ENGLISH_SPOKEN = 8 | const val COURSE_TYPE_ENGLISH_SPOKEN = 8 | ||||
/**课程类型: typeId 语文作文*/ | /**课程类型: typeId 语文作文*/ | ||||
const val COURSE_TYPE_CHINESE_COMPOSITION = 4 | const val COURSE_TYPE_CHINESE_COMPOSITION = 4 | ||||
/**课程类型: typeId 语文识字*/ | /**课程类型: typeId 语文识字*/ | ||||
const val COURSE_TYPE_CHINESE_LITERACY = 5 | const val COURSE_TYPE_CHINESE_LITERACY = 5 | ||||
/**课程类型: typeId 语文拼音*/ | /**课程类型: typeId 语文拼音*/ | ||||
const val COURSE_TYPE_CHINESE_PINYIN = 7 | const val COURSE_TYPE_CHINESE_PINYIN = 7 | ||||
/**课时类型: 词汇, 口语词汇*/ | /**课时类型: 词汇, 口语词汇*/ | ||||
const val LESSON_TYPE_WORD = 1 | |||||
const val LESSON_TYPE_WORD = 6 | |||||
/**课时类型: 口语句型*/ | /**课时类型: 口语句型*/ | ||||
const val LESSON_TYPE_SENTENCE = 2 | |||||
const val LESSON_TYPE_SENTENCE = 7 | |||||
/**课时类型: 口语对话*/ | /**课时类型: 口语对话*/ | ||||
const val LESSON_TYPE_DIALOGUE = 3 | |||||
const val LESSON_TYPE_DIALOGUE = 8 | |||||
/**课时类型: 作文视频*/ | /**课时类型: 作文视频*/ | ||||
const val COMPOSITION_TYPE_VIDEO = 4 //视频 | |||||
const val LESSON_TYPE_COMPOSITION_VIDEO = 1 //视频 | |||||
/**课时类型: 作文知识点学习*/ | /**课时类型: 作文知识点学习*/ | ||||
const val COMPOSITION_TYPE_KNOWLEDGE = 5 //知识点学习 | |||||
const val LESSON_TYPE_COMPOSITION_KNOWLEDGE = 2 //知识点学习 | |||||
/**课时类型: 作文知识点测试*/ | /**课时类型: 作文知识点测试*/ | ||||
const val COMPOSITION_TYPE_EXAM = 6 //知识点测试 | |||||
const val LESSON_TYPE_COMPOSITION_EXAM = 3 //知识点测试 | |||||
/**课时类型: 作文课堂练习*/ | /**课时类型: 作文课堂练习*/ | ||||
const val COMPOSITION_TYPE_READING = 7 //课堂练习 | |||||
const val LESSON_TYPE_COMPOSITION_READING = 4 //课堂练习 | |||||
/**课时类型: 作文课外练习*/ | /**课时类型: 作文课外练习*/ | ||||
const val COMPOSITION_TYPE_TASK = 8 //课外练习 | |||||
const val LESSON_TYPE_COMPOSITION_TASK = 5 //课外练习 | |||||
// 分组(1:普通测试(词汇测试,不做redis统计关联) 2:章节学前测试 3:章节学后测试 4:学前总测试 5:学后总测试 6:备忘录测试(不做redis统计关联);7:作文知识点测试,8:服务中心的课程测试) | |||||
/**普通测试(词汇测试,不做redis统计关联)*/ | |||||
const val TEST_TYPE_NORMAL = 1 | |||||
/**学前测试*/ | |||||
const val TEST_TYPE_BEFORE = 2 | |||||
/**学后测试*/ | |||||
const val TEST_TYPE_AFTER = 3 | |||||
/**学前总测试*/ | |||||
const val TEST_TYPE_BEFORE_TOTAL = 4 | |||||
/**学后总测试*/ | |||||
const val TEST_TYPE_AFTER_TOTAL = 5 | |||||
/**备忘录测试*/ | |||||
const val TEST_TYPE_MEMO = 6 | |||||
/**作文知识点测试*/ | |||||
const val TEST_TYPE_COMPOSITION = 7 | |||||
/**服务中心的课程测试*/ | |||||
const val TEST_TYPE_SERVICE_CENTER = 8 | |||||
/** 未做测试,没有做等用-1表示的内容 */ | |||||
const val NOT_DOING = -1.0 | |||||
/** 测试通过:>80 < 90 继续加油 <80 悲伤 */ | |||||
const val TEST_SCORE_LEVEL_1 = 80 | |||||
/** 测试通过 >= 太棒了 */ | |||||
const val TEST_SCORE_LEVEL_2 = 90 | |||||
} | } |
package com.xkl.cdl.data | |||||
import com.suliang.common.AppConfig | |||||
/** | |||||
* author suliang | |||||
* create 2022/3/28 9:52 | |||||
* Describe: 用于数据传递 | |||||
*/ | |||||
class DataTransferHolder private constructor(){ | |||||
companion object{ | |||||
val instance by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { | |||||
DataTransferHolder() | |||||
} | |||||
} | |||||
private val dataMap = hashMapOf<String,Any>() | |||||
fun <T : Any> putData(t : T){ | |||||
dataMap.put(AppConfig.INTENT_1,t) | |||||
} | |||||
@Suppress("UNCHECKED_CAST") | |||||
fun <T> getData() : T{ | |||||
return dataMap.get(AppConfig.INTENT_1) as T | |||||
} | |||||
fun clear(){ | |||||
dataMap.clear() | |||||
} | |||||
} |
package com.xkl.cdl.data.bean | |||||
import com.xkl.cdl.R | |||||
/** | |||||
* 数据基类 | |||||
* @property subjectId Long 项目id | |||||
* @property coursePackId Long 课程包id | |||||
* @property courseId Long 课程id | |||||
* @property coursePackType Int 课程包类型 | |||||
* @property courseType Int 课程类型 | |||||
* @property chapterId Long 章节id | |||||
* @property lessonId Long 课时id | |||||
* @property wordId Long 内容id | |||||
* @property first Boolean 是否第一次出现 | |||||
* @property reviewNum Int 大七次次数 | |||||
* @property reviewTime Long 复习时间 | |||||
* @property createTime Long 创建时间 | |||||
* @property repeatNum Int 小七次次数 | |||||
* @property showColor Int 显示颜色 | |||||
* @property lessonType Int 课时类型 | |||||
* @constructor | |||||
*/ | |||||
open class BaseWord(val subjectId: Int, | |||||
val coursePackId: Long, | |||||
val courseId: Long, | |||||
val coursePackType: Int, | |||||
val courseType: Int, | |||||
val chapterId: Long, | |||||
val lessonId: Long, | |||||
val wordId: Long, | |||||
val first: Boolean, | |||||
val lessonType: Int) { | |||||
/** 大复习次数 */ | |||||
var reviewNum: Int = 0 | |||||
/**复习时间*/ | |||||
var reviewTime: Long = 0 | |||||
/** 创建时间 */ | |||||
var createTime: Long = 0 | |||||
/**重复的次数*/ | |||||
var repeatNum: Int = 0 | |||||
/**显示颜色*/ | |||||
var showColor: Int = 0 | |||||
get() { | |||||
return when (repeatNum) { | |||||
0 -> R.color.num0 | |||||
1 -> R.color.num1 | |||||
2 -> R.color.num2 | |||||
3 -> R.color.num3 | |||||
4 -> R.color.num4 | |||||
5 -> R.color.num5 | |||||
6 -> R.color.num6 | |||||
7 -> R.color.num7 | |||||
else -> R.color.num0 | |||||
} | |||||
} | |||||
private set | |||||
} |
package com.xkl.cdl.data.bean | |||||
import com.xkl.cdl.data.bean.course.Lesson | |||||
/** | |||||
* author suliang | |||||
* create 2022/4/2 14:55 | |||||
* Describe: 课时学习时的传参 | |||||
*/ | |||||
class IntentLearnData(val lesson: Lesson) { | |||||
} |
package com.xkl.cdl.data.bean | |||||
/** | |||||
* author suliang | |||||
* create 2022/3/31 17:52 | |||||
* Describe: 用于学习的数据 | |||||
*/ | |||||
class LearnWord(subjectId: Int, | |||||
coursePackId: Long, | |||||
courseId: Long, | |||||
coursePackType: Int, | |||||
courseType: Int, | |||||
chapterId: Long, | |||||
lessonId: Long, | |||||
wordId: Long, | |||||
first: Boolean, | |||||
lessonType: Int) : BaseWord(subjectId, | |||||
coursePackId, | |||||
courseId, | |||||
coursePackType, | |||||
courseType, | |||||
chapterId, | |||||
lessonId, | |||||
wordId, | |||||
first, | |||||
lessonType) { | |||||
var word: String? = null //词汇 | |||||
var phonetic_uk: String? = null // 英式音标 | |||||
var phonetic_us: String? = null // 美式音标 | |||||
var phonetic_cn: String? = null // 中文拼音 | |||||
var photo: String? = null // 图片 | |||||
var audio: String? = null // 音频 | |||||
var basic_explanation: String? = null //基本释义 | |||||
var all_explanation: String? = null //扩展释义 | |||||
var phrase: String? = null //词组 | |||||
var example: String? = null //例句 | |||||
var reference: String? = null //参考 | |||||
var literacyIspolyphone = false //识字课程,是否是多音字标识 | |||||
var pattern: String? = null //口语: 语法 | |||||
} |
package com.xkl.cdl.data.bean | |||||
/** | |||||
* author suliang | |||||
* create 2022/3/21 17:10 | |||||
* Describe: | |||||
*/ | |||||
data class Lesson( | |||||
val subjectId: Long, | |||||
val coursePackId:Long, | |||||
val courseId:Long, | |||||
val chapterId:Long, | |||||
val chapterName: String, | |||||
val lessonId:Long, | |||||
val lessonName:String | |||||
) { | |||||
/** 课时类型 */ | |||||
var lessonType : Int = 0 | |||||
} |
package com.xkl.cdl.data.course | |||||
import com.xkl.cdl.data.bean.Lesson | |||||
package com.xkl.cdl.data.bean.course | |||||
/** | /** | ||||
* author suliang | * author suliang | ||||
val totalWords: Int, | val totalWords: Int, | ||||
val dbPathName: String | val dbPathName: String | ||||
) { | ) { | ||||
var allLesson: ArrayList<Lesson>? = null | |||||
var courseLearnProgress : Double = 0.0 //课程学习进度 | var courseLearnProgress : Double = 0.0 //课程学习进度 | ||||
var courseReviewNumber : Int = 0 //课程复习数 | var courseReviewNumber : Int = 0 //课程复习数 | ||||
} | } |
package com.xkl.cdl.data.bean.course | |||||
import android.R.bool | |||||
/** | |||||
* author suliang | |||||
* create 2022/3/29 9:52 | |||||
* Describe: 课程学习的详情 | |||||
*/ | |||||
class CourseDetail { | |||||
var courseLearnProgress: Double = 0.0 //课程学习进度 | |||||
var st_before: Double = -1.0 //学前总成绩 : -1代表没有进行学前总测试 | |||||
var st_after: Double = -1.0 //学后总成绩 : -1代表没有进行学后总测试 | |||||
var before: HashMap<String, Double> = hashMapOf() //章节学前测试成绩,key=>{chapter_id}_{lesson_id} value=>成绩 | |||||
var after: HashMap<String, Double> = hashMapOf() //章节学后测试成绩,key=>{chapter_id}_{lesson_id} value=>成绩 | |||||
var right = hashMapOf<String, Int>() //正确条目数,key=>{chapter_id}_{lesson_id} value=>条目数量 | |||||
var wrong: HashMap<String, Int> = hashMapOf() //错误条目数,key=>{chapter_id}_{lesson_id} value=>条目数量 | |||||
var lesson_learn_point: HashMap<String, Long> = hashMapOf() //章节学习点 key=>{chapter_id}_{lesson_id} value=>{entity_id) | |||||
var exam_w_r_list: HashMap<String, bool> = hashMapOf() //课程/课时学前测试正确错误列表 key=> {chapter_id}_{lesson_id}_{entity_id} value=>正确 true;错误 false | |||||
var course_learn_point: String = "" //课程学习进度点 {chapter_id}_{lesson_id}_{entity_id} | |||||
var rl: Int = 0 //课程重学次数;有值表示是重新学,默认不是重新学习,对应数值表示第几次重学 用于辨音,拼写判断是否解锁, | |||||
var chapter_rl: HashMap<String, Long> = hashMapOf() //章节重学次数,key =>{chapter_id}_{lesson_id} value=> relearn times | |||||
var ct: Long = 0 //课程已学词汇量 | |||||
var e = 0.0 //学习效率 | |||||
var valid: HashMap<Long, Long> = hashMapOf() //有效学习时长,单位毫秒 key=>分时标记,value=>时长 | |||||
var review: HashMap<Long, Long> = hashMapOf() //有效复习时长,单位毫秒 key=>分时标记,value=>时长 | |||||
var total: HashMap<Long, Long> = hashMapOf() //总时长,单位毫秒 key=>分时标记,value=>时长 | |||||
var current_week_total_durations: Long = 0 | |||||
var last_e: Double = 0.0 //上周期学习效率 | |||||
var temporary_words: HashMap<String, String> = hashMapOf() //课程错误本,重学会删除 key=>{chapter_id}_{lesson_id}_{entity_id} value=> first learn time | |||||
var vp: HashMap<Long, String> = hashMapOf() //视频播放点,记录最新的就行 时间点 key=>video_id value=>{时间点} | |||||
var exercise_schedule: HashMap<Long, Double> = hashMapOf() //课程练习进度(仅作文有效) | |||||
} |
package com.xkl.cdl.data.course | |||||
package com.xkl.cdl.data.bean.course | |||||
import androidx.databinding.BaseObservable | import androidx.databinding.BaseObservable | ||||
import androidx.databinding.Bindable | import androidx.databinding.Bindable | ||||
val subjectId: Int, | val subjectId: Int, | ||||
val coursePackType: Int, | val coursePackType: Int, | ||||
) : BaseObservable() { | ) : BaseObservable() { | ||||
//在CourseManger中的subjectWithCoursePackMap对应subject下的list中所在的位置 | |||||
var inCoursePackPosition : Int = 0 | |||||
var childrenCourses = mutableListOf<Course>() | var childrenCourses = mutableListOf<Course>() | ||||
package com.xkl.cdl.data.bean.course | |||||
import androidx.databinding.BaseObservable | |||||
import androidx.databinding.Bindable | |||||
import com.suliang.common.BR | |||||
import com.xkl.cdl.data.AppConstants | |||||
/** | |||||
* author suliang | |||||
* create 2022/3/21 17:10 | |||||
* Describe: 课时,通过lessonType判断课时类型 | |||||
*/ | |||||
data class Lesson( | |||||
val subjectId: Int, | |||||
val coursePackId:Long, | |||||
val courseId:Long, | |||||
var courseType: Int, | |||||
val chapterId:Long, | |||||
val chapterName: String, | |||||
val lessonId:Long, | |||||
val lessonName:String | |||||
):BaseObservable() { | |||||
/** 课时类型 : 默认为单词类型 */ | |||||
var lessonType : Int = 0 | |||||
/** 课时在列表中的位置 */ | |||||
var lessonPositionInList : Int = 0 | |||||
/** 该课时的总数据 或者作文关联的数据,如视频关联的内容*/ | |||||
var wordIds = mutableListOf<Long>() | |||||
/** 学习进度位置,为医学下标的位置,在作文课堂练习时,学习取当前条,其他取下一条*/ | |||||
var learnedIndex: Int = 0 | |||||
/**课时学前测试成绩 */ | |||||
var beforeTestScore = -1.0 | |||||
/** 课时学后测试 */ | |||||
var afterTestScore = -1.0 | |||||
/**是否学习完成: 为学习内容是否完成,不包含学前,学后测试*/ | |||||
var learnIsOver = false | |||||
/**是否是最后一个课时 */ | |||||
var lastLesson : Boolean = false | |||||
//总数量 | |||||
@get:Bindable | |||||
var totalNumber:Int = 0 | |||||
set(value) { | |||||
field = value | |||||
notifyPropertyChanged(BR.totalNumber) | |||||
} | |||||
//正确数 | |||||
@get:Bindable | |||||
var correctNumber:Int = 0 | |||||
set(value) { | |||||
field = value | |||||
notifyPropertyChanged(BR.correctNumber) | |||||
} | |||||
//错误数 | |||||
@get:Bindable | |||||
var errorNumber:Int = 0 | |||||
set(value) { | |||||
field = value | |||||
notifyPropertyChanged(BR.errorNumber) | |||||
} | |||||
//作文视频使用 | |||||
/** 视频播放时长 */ | |||||
var videoPlayTime : Int = 0 | |||||
/** 视频总时长 */ | |||||
var videoTotalTime : Int = 0 | |||||
} |
package com.xkl.cdl.data.binding | package com.xkl.cdl.data.binding | ||||
import android.graphics.BitmapFactory | |||||
import android.graphics.drawable.Drawable | import android.graphics.drawable.Drawable | ||||
import android.widget.ImageView | import android.widget.ImageView | ||||
import android.widget.TextView | import android.widget.TextView | ||||
import androidx.core.graphics.drawable.DrawableCompat | |||||
import androidx.databinding.BindingAdapter | import androidx.databinding.BindingAdapter | ||||
import com.suliang.common.util.DrawableUti | import com.suliang.common.util.DrawableUti | ||||
import com.suliang.common.util.image.ImageLoader | import com.suliang.common.util.image.ImageLoader | ||||
import com.suliang.common.util.image.ImageLoaderOption | import com.suliang.common.util.image.ImageLoaderOption | ||||
import com.xkl.cdl.R | import com.xkl.cdl.R | ||||
import kotlinx.coroutines.NonCancellable.start | |||||
import org.w3c.dom.Text | |||||
import java.math.BigDecimal | import java.math.BigDecimal | ||||
import java.math.RoundingMode | import java.math.RoundingMode | ||||
import java.text.DecimalFormat | import java.text.DecimalFormat | ||||
// view.setImageBitmap(BitmapFactory.decodeByteArray(imageByteArray, 0, imageByteArray.size)) | // view.setImageBitmap(BitmapFactory.decodeByteArray(imageByteArray, 0, imageByteArray.size)) | ||||
} | } | ||||
@BindingAdapter(value = ["imgByteArray","blur"]) | |||||
@BindingAdapter(value = ["imgBytes","blur"]) | |||||
@JvmStatic | @JvmStatic | ||||
fun imageByteArray(view:ImageView,imgByteArray:ByteArray,blur:Boolean){ | fun imageByteArray(view:ImageView,imgByteArray:ByteArray,blur:Boolean){ | ||||
ImageLoader.loadImage(ImageLoaderOption().apply { | ImageLoader.loadImage(ImageLoaderOption().apply { |
package com.xkl.cdl.data.manager | package com.xkl.cdl.data.manager | ||||
import com.suliang.common.util.file.FileUtil | import com.suliang.common.util.file.FileUtil | ||||
import com.xkl.cdl.data.course.Course | |||||
import com.xkl.cdl.data.course.CoursePack | |||||
import com.xkl.cdl.data.bean.course.CoursePack | |||||
import java.io.File | import java.io.File | ||||
import java.math.BigDecimal | |||||
import java.math.RoundingMode | |||||
import java.text.DecimalFormat | |||||
/** | /** | ||||
* author suliang | * author suliang | ||||
* 检查课程包下课程的db数据文件是否存在,不存在,则复制过去 | * 检查课程包下课程的db数据文件是否存在,不存在,则复制过去 | ||||
*/ | */ | ||||
fun checkCourseDb() { | fun checkCourseDb() { | ||||
subjectWithCoursePackMap.forEach{entry -> | |||||
entry.value.forEach{ coursePack -> | |||||
subjectWithCoursePackMap.forEach { entry -> | |||||
entry.value.forEach { coursePack -> | |||||
coursePack.childrenCourses.forEach { | coursePack.childrenCourses.forEach { | ||||
val file = File( | val file = File( | ||||
FileUtil.getSaveDirPath("db"), | FileUtil.getSaveDirPath("db"), | ||||
"${entry.key}/${coursePack.coursePackId}/${it.courseId}/${it.dbPathName}" | |||||
"${entry.key}/${coursePack.coursePackId}/${it.courseId}/course.db" | |||||
) | ) | ||||
//不存在,复制,存在则不操作 | //不存在,复制,存在则不操作 | ||||
if (!file.exists()){ | |||||
FileUtil.copyAsset(it.dbPathName,file) | |||||
if (!file.exists()) { | |||||
FileUtil.copyAsset(it.dbPathName, file) | |||||
} | } | ||||
} | } | ||||
} | } | ||||
} | } | ||||
} | |||||
/** | |||||
* 用于显示的进度 | |||||
* @param progress Double 课程的进度 | |||||
* @return String | |||||
*/ | |||||
@JvmStatic | |||||
fun useToShowProgress(progress: Double): String { | |||||
return when { | |||||
progress == 0.0 -> "0" | |||||
progress < 0.1 -> "0.1" | |||||
progress < 100 -> DecimalFormat("#.#").apply { | |||||
//直接舍弃 | |||||
roundingMode = RoundingMode.DOWN | |||||
}.format(BigDecimal(progress)) | |||||
else -> "100" | |||||
} | |||||
} | } | ||||
} | } |
package com.xkl.cdl.data.manager | |||||
import com.suliang.common.util.file.FileUtil | |||||
import com.xkl.cdl.data.manager.db.DbControlBase | |||||
import java.io.File | |||||
/** | |||||
* author suliang | |||||
* create 2022/4/1 11:23 | |||||
* Describe: 地址管理 | |||||
*/ | |||||
class FilePathManager { | |||||
companion object{ | |||||
/** | |||||
* 获取课程包目录数据所在的地址 | |||||
* @return File | |||||
*/ | |||||
@JvmStatic | |||||
fun getCoursePackDbPath(): File{ | |||||
return File(FileUtil.getSaveDirPath("db"), "course-pack.db") | |||||
} | |||||
/** 获取课程数据地址 */ | |||||
@JvmStatic | |||||
fun getCourseDbPath(base:DbControlBase): File{ | |||||
return File(FileUtil.getSaveDirPath("db"), "${base.subjectId}/${base.coursePackId}/${base.courseId}/course.db") | |||||
} | |||||
/** 获取课程数据地址 */ | |||||
@JvmStatic | |||||
fun getCourseDbPath(subjectId:Int,coursePackId:Long,courseId:Long): File{ | |||||
return File(FileUtil.getSaveDirPath("db"), "subjectId/coursePackId/courseId/course.db") | |||||
} | |||||
} | |||||
} |
package com.xkl.cdl.data.manager.db | |||||
/** | |||||
* author suliang | |||||
* create 2022/3/21 16:10 | |||||
* Describe: 作文数据库 | |||||
*/ | |||||
object CompositionDbManager : IDB { | |||||
} |
package com.xkl.cdl.data.manager.db | package com.xkl.cdl.data.manager.db | ||||
import com.xkl.cdl.data.Constants | |||||
import com.xkl.cdl.data.bean.Lesson | |||||
import android.annotation.SuppressLint | |||||
import android.widget.Toast | |||||
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.course.CourseDetail | |||||
import com.xkl.cdl.data.bean.course.Lesson | |||||
import com.xkl.cdl.data.manager.FilePathManager | |||||
import net.sqlcipher.database.SQLiteDatabase | |||||
/** | /** | ||||
* author suliang | * author suliang | ||||
* Describe: 课程数据库管理类,主要用于读取数据 | * Describe: 课程数据库管理类,主要用于读取数据 | ||||
*/ | */ | ||||
object DBCourseManager { | object DBCourseManager { | ||||
private var currentBase = DbControlBase() | |||||
private const val NORMAL = "XKL_COURSE_DATA_KEY" | |||||
private const val SPOKEN = "XKL_SPOKEN_COURSE_DATA_KEY" | |||||
private const val COMPOSITION = "XKL_LOCAL_COMPOSITION_DATA_KEY" | |||||
private const val LITERACY = "XKL_LOCAL_CHINESE_COURSE_KEY" | |||||
private var mDataBase: SQLiteDatabase? = null | |||||
fun getDb(subjectId:Int,coursePackId:Long,courseId:Long):IDB{ | |||||
return if (subjectId == Constants.SUBJECT_ENGLISH){ | |||||
EnglishDbManager | |||||
}else{ | |||||
CompositionDbManager | |||||
private fun open(base: DbControlBase) { | |||||
synchronized(DBCourseManager) { | |||||
if (mDataBase != null && currentBase != base) { | |||||
mDataBase?.close() | |||||
mDataBase = null | |||||
} | |||||
if (mDataBase == null) { | |||||
currentBase = base | |||||
val p = when (base.courseType) { | |||||
AppConstants.COURSE_TYPE_CHINESE_COMPOSITION -> COMPOSITION | |||||
AppConstants.COURSE_TYPE_ENGLISH_SPOKEN -> SPOKEN | |||||
AppConstants.COURSE_TYPE_CHINESE_LITERACY -> LITERACY | |||||
else -> NORMAL | |||||
} | |||||
mDataBase = SQLiteDatabase.openDatabase(FilePathManager.getCourseDbPath(currentBase).path, | |||||
p, | |||||
null, | |||||
SQLiteDatabase.OPEN_READONLY) | |||||
} | |||||
if (mDataBase == null) { | |||||
AppExecutors.mainThread.run { | |||||
Toast.makeText(AppGlobals.application, "课程数据获取失败,请重启应用或联系业务员", Toast.LENGTH_LONG) | |||||
} | |||||
} | |||||
} | } | ||||
} | } | ||||
/**获取该课程的所有课时 | |||||
* @param base DbControlBase | |||||
* @param detail CourseDetail 课程信息 | |||||
* @return List<Lesson> | |||||
*/ | |||||
@SuppressLint("Range") | |||||
fun queryAllLesson(base: DbControlBase, detail: CourseDetail): List<Lesson> { | |||||
val mutableList = mutableListOf<Lesson>() | |||||
open(base) | |||||
//聚合所有课时,先所有chapter_sort和word_sort排序,然后根据leesonId分组并聚合leeson_id到 | |||||
val rawQurySql = when (base.courseType) { | |||||
AppConstants.COURSE_TYPE_CHINESE_COMPOSITION -> { | |||||
"SELECT * FROM chapter ORDER by chapter_sort asc" | |||||
} | |||||
AppConstants.COURSE_TYPE_ENGLISH_SPOKEN -> { //口语查询暂时与 单词一致 | |||||
"SELECT *,group_concat(word_id,',') as wordIds FROM (select * from chapter ORDER By chapter_sort asc, word_sort asc) GROUP by lesson_id" | |||||
} | |||||
else -> { | |||||
"SELECT *,group_concat(word_id,',') as wordIds FROM (select * from chapter ORDER By chapter_sort asc, word_sort asc) GROUP by lesson_id" // ORDER By chapter_sort asc, word_sort asc " | |||||
} | |||||
} | |||||
var positionIndex = 0 | |||||
mDataBase?.rawQuery(rawQurySql, null)?.let { | |||||
while (it.moveToNext()) { | |||||
val chapterId: Long = it.getLong(it.getColumnIndex("chapter_id")) | |||||
val chapterName: String = it.getString(it.getColumnIndex("chapter_title")) | |||||
val lessonId = it.getLong(it.getColumnIndex("lesson_id")) | |||||
val lessonName = when (base.courseType) { | |||||
AppConstants.COURSE_TYPE_CHINESE_COMPOSITION -> it.getString(it.getColumnIndex("lesson_title")) | |||||
else -> it.getString(it.getColumnIndex("lesson")) | |||||
} | |||||
val wordIds = when (base.courseType) { | |||||
AppConstants.COURSE_TYPE_CHINESE_COMPOSITION -> it.getString(it.getColumnIndex("relation_id")) | |||||
.split(",") | |||||
else -> it.getString(it.getColumnIndex("wordIds")).split(",") | |||||
}.map { value -> value.toLong() }.toMutableList() | |||||
val lessonType: Int = when (base.courseType) { | |||||
AppConstants.COURSE_TYPE_CHINESE_COMPOSITION -> it.getInt(it.getColumnIndex("type")) | |||||
AppConstants.COURSE_TYPE_ENGLISH_SPOKEN -> it.getInt(it.getColumnIndex("lesson_type")) | |||||
else -> AppConstants.LESSON_TYPE_WORD | |||||
} | |||||
val key = "${chapterId}_${lessonId}" | |||||
val learnIndex = wordIds.indexOf(detail.lesson_learn_point.getOrElse(key, { -1 })) //学习位置,当前位置为已学 | |||||
// 注:针对口语对话课时,如果没有学习完,是不会设置进度点的。 | |||||
val learnIsOver = wordIds.size - 1 == learnIndex | |||||
val lesson = Lesson(base.subjectId, | |||||
base.coursePackId, | |||||
base.courseId, | |||||
base.courseType, | |||||
chapterId, | |||||
chapterName, | |||||
lessonId, | |||||
lessonName).apply { | |||||
lessonPositionInList = positionIndex | |||||
this.wordIds = wordIds //内容 | |||||
totalNumber = this.wordIds.size //总数 | |||||
correctNumber = detail.right.getOrElse(key, { 0 }) //正确数 | |||||
errorNumber = detail.wrong.getOrElse(key, { 0 }) //错误数 | |||||
beforeTestScore = detail.before.getOrElse(key, { -1.0 }) //课时学前测试成绩 | |||||
afterTestScore = detail.after.getOrElse(key, { -1.0 }) //课时学后测试成绩 | |||||
this.learnedIndex = learnIndex //学习位置,当前位置为已学 | |||||
this.learnIsOver = learnIsOver | |||||
this.lessonType = lessonType | |||||
} | |||||
mutableList.add(lesson) | |||||
positionIndex += 1 | |||||
} | |||||
it.close() | |||||
} | |||||
mutableList.last().lastLesson = true | |||||
return mutableList.toList() | |||||
} | |||||
/** 获取总测试的数据 */ | |||||
fun queryTotalTest(coursePackId: Long, courseId: Long) { | |||||
} | |||||
/** 获取课时测试数据 */ | |||||
fun queryLessonTest(coursePackId: Long, courseId: Long, chapterId: Long, lessonId: Long, courseType: Long) { | |||||
} | |||||
/** 获取指定课时(指定数据源wordIds)的随机个数测试数据 */ | |||||
fun queryLessonTestRandomSize(coursePackId: Long, | |||||
courseId: Long, | |||||
chapterId: Long, | |||||
lessonId: Long, | |||||
courseType: Long, | |||||
limitSize: Int, | |||||
wordIds: ArrayList<Long>? = null) { | |||||
} | |||||
/** 获取课时学习内容 */ | |||||
fun queryLessonLearnData(coursePackId: Long, | |||||
courseId: Long, | |||||
chapterId: Long, | |||||
lessonId: Long, | |||||
wordIds: ArrayList<Long>) { | |||||
} | |||||
/** 获取课程今日需要复习的数据 */ | |||||
fun queryCourseReviewDatas(coursePackId: Long, courseId: Long, wordIds: ArrayList<Long>) { | |||||
} | |||||
} | } |
package com.xkl.cdl.data.manager.db | |||||
/** | |||||
* author suliang | |||||
* create 2022/4/1 11:06 | |||||
* Describe: 用于查询数据库需要的基本信息 | |||||
*/ | |||||
data class DbControlBase( | |||||
val subjectId: Int = 0, | |||||
val coursePackId: Long = 0, | |||||
val courseId: Long = 0, | |||||
var courseType: Int = 0) |
package com.xkl.cdl.data.manager.db | package com.xkl.cdl.data.manager.db | ||||
import com.suliang.common.util.file.FileUtil | import com.suliang.common.util.file.FileUtil | ||||
import com.xkl.cdl.data.Constants | |||||
import com.xkl.cdl.data.course.Course | |||||
import com.xkl.cdl.data.course.CoursePack | |||||
import com.xkl.cdl.data.AppConstants | |||||
import com.xkl.cdl.data.bean.course.Course | |||||
import com.xkl.cdl.data.bean.course.CoursePack | |||||
import com.xkl.cdl.data.manager.CourseManager | import com.xkl.cdl.data.manager.CourseManager | ||||
import com.xkl.cdl.data.manager.FilePathManager | |||||
import net.sqlcipher.database.SQLiteDatabase | import net.sqlcipher.database.SQLiteDatabase | ||||
import net.sqlcipher.database.SQLiteDatabase.OPEN_READONLY | import net.sqlcipher.database.SQLiteDatabase.OPEN_READONLY | ||||
import java.io.File | |||||
/** | /** | ||||
* author suliang | * author suliang | ||||
private val database: SQLiteDatabase | private val database: SQLiteDatabase | ||||
init { | init { | ||||
val coursePackDbPath = FileUtil.getSaveDirPath("db") + File.separator + "course-pack.db" | |||||
database = SQLiteDatabase.openDatabase(coursePackDbPath, "XUEKAOLE_COURSE_LIST_KEY", null, OPEN_READONLY) | |||||
//数据文件是否存在 | |||||
val coursePackFile = FilePathManager.getCoursePackDbPath() | |||||
if (!coursePackFile.exists()) { | |||||
val copyAssetResult = FileUtil.copyAsset("course-pack.db", coursePackFile) | |||||
} | |||||
database = SQLiteDatabase.openDatabase(coursePackFile.path, "XUEKAOLE_COURSE_LIST_KEY", null, OPEN_READONLY) | |||||
} | } | ||||
/*** | /*** | ||||
cursor.close() | cursor.close() | ||||
} | } | ||||
} | } | ||||
if (subjectId == Constants.SUBJECT_ENGLISH) { | |||||
if (subjectId == AppConstants.SUBJECT_ENGLISH) { | |||||
coursePack.inCoursePackPosition = englishCoursePack.size | |||||
englishCoursePack.add(coursePack) | englishCoursePack.add(coursePack) | ||||
} else { | } else { | ||||
coursePack.inCoursePackPosition = englishCoursePack.size | |||||
chineseCoursePack.add(coursePack) | chineseCoursePack.add(coursePack) | ||||
} | } | ||||
} | } | ||||
it.close() | it.close() | ||||
} | } | ||||
CourseManager.subjectWithCoursePackMap[Constants.SUBJECT_ENGLISH] = englishCoursePack.toList() | |||||
CourseManager.subjectWithCoursePackMap[Constants.SUBJECT_CHINESE] = chineseCoursePack.toList() | |||||
CourseManager.subjectWithCoursePackMap[AppConstants.SUBJECT_ENGLISH] = englishCoursePack.toList() | |||||
CourseManager.subjectWithCoursePackMap[AppConstants.SUBJECT_CHINESE] = chineseCoursePack.toList() | |||||
database.close() | database.close() | ||||
return true | return true | ||||
} | } |
package com.xkl.cdl.data.manager.db | |||||
/** | |||||
* author suliang | |||||
* create 2022/3/21 16:09 | |||||
* Describe: 英语数据库 | |||||
*/ | |||||
object EnglishDbManager : IDB { | |||||
} |
package com.xkl.cdl.data.manager.db | |||||
/** | |||||
* author suliang | |||||
* create 2022/3/21 16:34 | |||||
* Describe: 英语数据库接口 | |||||
*/ | |||||
interface IDB { | |||||
// fun open(subjectId:Long,coursePackId:Long,courseId:Long) | |||||
// | |||||
// /**获取该课程的所有课时*/ | |||||
// fun queryAllLesson() | |||||
// | |||||
// /** 获取总测试的数据 */ | |||||
// fun queryTotalTest(coursePackId: Long,courseId: Long) | |||||
// /** 获取课时测试数据 */ | |||||
// fun queryLessonTest(coursePackId: Long,courseId: Long,chapterId:Long,lessonId:Long,courseType:Long) | |||||
// /** 获取指定课时(指定数据源wordIds)的随机个数测试数据 */ | |||||
// fun queryLessonTestRandomSize(coursePackId: Long,courseId: Long,chapterId: Long,lessonId: Long,courseType: Long,limitSize:Int,wordIds:ArrayList<Long>? = null) | |||||
// | |||||
// /** 获取课时学习内容 */ | |||||
// fun queryLessonLearnData(coursePackId: Long,courseId: Long,chapterId: Long,lessonId: Long,wordIds:ArrayList<Long>) | |||||
// | |||||
// /** 获取课程今日需要复习的数据 */ | |||||
// fun queryCourseReviewDatas(coursePackId: Long,courseId: Long,wordIds: ArrayList<Long>) | |||||
} |
package com.xkl.cdl.data.repository | |||||
import android.graphics.Bitmap | |||||
import android.util.LruCache | |||||
import java.security.Key | |||||
/** | |||||
* author suliang | |||||
* create 2022/4/1 9:53 | |||||
* Describe: 音频缓存获取规则 | |||||
*/ | |||||
object AudioCache { | |||||
var lruCache : LruCache<String, ByteArray> | |||||
init { | |||||
lruCache = object : LruCache<String,ByteArray>((Runtime.getRuntime().maxMemory()/16).toInt()){ | |||||
//告知每个对象的存储大小 | |||||
override fun sizeOf(key: String?, value: ByteArray?): Int { | |||||
if (value == null){ | |||||
return 0 | |||||
} | |||||
return value.size | |||||
} | |||||
} | |||||
} | |||||
/** | |||||
* 获取对应音频 | |||||
* @param key String | |||||
* @return ByteArray? | |||||
*/ | |||||
fun get(key:String) : ByteArray? { | |||||
return null | |||||
} | |||||
} |
package com.xkl.cdl.data.repository | |||||
import com.xkl.cdl.data.bean.course.CourseDetail | |||||
import com.xkl.cdl.data.bean.course.Lesson | |||||
import com.xkl.cdl.data.manager.db.DBCourseManager | |||||
import com.xkl.cdl.data.manager.db.DbControlBase | |||||
import io.reactivex.rxjava3.core.Observable | |||||
/** | |||||
* author suliang | |||||
* create 2022/3/29 10:24 | |||||
* Describe: 数据提供 | |||||
*/ | |||||
object DataRepository { | |||||
/** 获取课程的收藏本 */ | |||||
fun getCourseCollect() : Observable<HashMap<String,Long>>{ | |||||
return Observable.create{ | |||||
it.onNext(hashMapOf()) | |||||
it.onComplete() | |||||
} | |||||
} | |||||
/** 获取复习的内容 */ | |||||
fun getReviewData() : Observable<Array<String>> { | |||||
return Observable.create{ | |||||
mutableListOf<String>() | |||||
it.onNext(Array<String>(1){"1"}) | |||||
it.onComplete() | |||||
} | |||||
} | |||||
/** 获取课程的详情 */ | |||||
fun getCourseStatistics(): Observable<CourseDetail>{ | |||||
return Observable.create{ | |||||
val courseDetail = CourseDetail() | |||||
it.onNext(courseDetail) | |||||
it.onComplete() | |||||
} | |||||
} | |||||
/** 获取课程课时 */ | |||||
fun getCourseAllLesson(base: DbControlBase,courseDetail: CourseDetail):Observable<List<Lesson>>{ | |||||
return Observable.create{ | |||||
it.onNext(DBCourseManager.queryAllLesson(base,courseDetail)) | |||||
it.onComplete() | |||||
} | |||||
} | |||||
} |
package com.xkl.cdl.dialog | |||||
import android.view.View | |||||
import com.suliang.common.base.BaseDialogFragment | |||||
import com.suliang.common.extension.click | |||||
import com.suliang.common.util.LogUtil | |||||
import com.xkl.cdl.R | |||||
import com.xkl.cdl.databinding.DialogLessonLearnBinding | |||||
/** | |||||
* author suliang | |||||
* create 2022/4/2 15:47 | |||||
* Describe: 学习的通用弹窗 | |||||
*/ | |||||
class LearnDialog : BaseDialogFragment<DialogLessonLearnBinding>() { | |||||
private lateinit var dialogListener : DialogFragmentListener | |||||
override fun initFragment() { | |||||
initClick() | |||||
// initLessonBeforeTest() | |||||
initLessonBeforeTestOver() | |||||
} | |||||
fun initClick(){ | |||||
dialogListener = if (parentFragment != null){ | |||||
parentFragment as DialogFragmentListener | |||||
}else{ | |||||
activity as DialogFragmentListener | |||||
} | |||||
} | |||||
fun initLessonBeforeTest(){ | |||||
binding.tvTitle.text = "课时学前测试" | |||||
binding.tvLessonName.text = "章节课时名称" | |||||
binding.tvCountTime.text = "测试题目时间" | |||||
binding.tvRight.text = "开始测试" | |||||
binding.tvLeft.visibility = View.VISIBLE | |||||
binding.tvLeft.text = "随便设置" | |||||
binding.tvRight.click { | |||||
LogUtil.e("Dialog -- > show()") | |||||
dialogListener.rightClick() | |||||
} | |||||
binding.tvLeft.click { | |||||
LogUtil.e("Dialog -- > hide()") | |||||
dialogListener.leftClick() | |||||
} | |||||
} | |||||
fun initLessonBeforeTestOver(){ | |||||
binding.tvScore.run { | |||||
visibility = View.VISIBLE | |||||
text = "100分" | |||||
} | |||||
binding.tvTip.visibility = View.VISIBLE | |||||
binding.tvTitle.text = "恭喜你,完成了课时学前测试" | |||||
binding.tvLessonName.visibility = View.GONE | |||||
binding.tvCountTime.visibility = View.GONE | |||||
binding.tvTip1.visibility = View.VISIBLE | |||||
binding.tvTip1.setText(resources.getString(R.string.test_before_test_over_tip)) | |||||
binding.incStatisticsNumber.root.visibility = View.VISIBLE | |||||
binding.tvLeft.visibility = View.GONE | |||||
binding.tvRight.setText(resources.getString(R.string.start_learn)) | |||||
binding.tvRight.click { | |||||
// TODO: 2022/4/2 开始学习 | |||||
} | |||||
} | |||||
fun initLessonAfterTestOver(){ | |||||
//未通过 | |||||
//已通过 | |||||
//已通过的再通过 | |||||
} | |||||
public interface DialogFragmentListener{ | |||||
fun rightClick() | |||||
fun leftClick() | |||||
} | |||||
} |
package com.xkl.cdl.module.learn | |||||
import androidx.viewbinding.ViewBinding | |||||
import com.suliang.common.base.activity.BaseActivityVM | |||||
abstract class LearnBaseActivity<vb:ViewBinding,vm: LearnBaseViewModel> : BaseActivityVM<vb,vm>() { | |||||
override fun onRestart() { | |||||
super.onRestart() | |||||
} | |||||
override fun onResume() { | |||||
super.onResume() | |||||
} | |||||
override fun onPause() { | |||||
super.onPause() | |||||
} | |||||
} |
package com.xkl.cdl.module.learn | |||||
import com.suliang.common.base.viewmodel.BaseViewModel | |||||
/** | |||||
* author suliang | |||||
* create 2022/4/2 14:06 | |||||
* Describe: 学习基类: 实现统一流程接口和计时实现 | |||||
*/ | |||||
abstract class LearnBaseViewModel : BaseViewModel() { | |||||
} |
package com.xkl.cdl.module.m_center_learn | |||||
package com.xkl.cdl.module.learn | |||||
import androidx.appcompat.app.AppCompatActivity | import androidx.appcompat.app.AppCompatActivity | ||||
import android.os.Bundle | import android.os.Bundle | ||||
import com.xkl.cdl.R | import com.xkl.cdl.R | ||||
/** | |||||
* 课程中心 | |||||
*/ | |||||
class CourseMainActivity : AppCompatActivity() { | |||||
class LearnCReadingActivity : AppCompatActivity() { | |||||
override fun onCreate(savedInstanceState: Bundle?) { | override fun onCreate(savedInstanceState: Bundle?) { | ||||
super.onCreate(savedInstanceState) | super.onCreate(savedInstanceState) | ||||
setContentView(R.layout.activity_course_main) | |||||
setContentView(R.layout.activity_learn_creading) | |||||
} | } | ||||
} | } |
package com.xkl.cdl.module.learn | |||||
import androidx.appcompat.app.AppCompatActivity | |||||
import android.os.Bundle | |||||
import com.xkl.cdl.R | |||||
class LearnCTaskActivity : AppCompatActivity() { | |||||
override fun onCreate(savedInstanceState: Bundle?) { | |||||
super.onCreate(savedInstanceState) | |||||
setContentView(R.layout.activity_learn_ctask) | |||||
} | |||||
} |
package com.xkl.cdl.module.learn | |||||
import androidx.appcompat.app.AppCompatActivity | |||||
import android.os.Bundle | |||||
import com.xkl.cdl.R | |||||
class LearnCVideoActivity : AppCompatActivity() { | |||||
override fun onCreate(savedInstanceState: Bundle?) { | |||||
super.onCreate(savedInstanceState) | |||||
setContentView(R.layout.activity_learn_cvideo) | |||||
} | |||||
} |
package com.xkl.cdl.module.learn | |||||
import androidx.appcompat.app.AppCompatActivity | |||||
import android.os.Bundle | |||||
import com.xkl.cdl.R | |||||
class LearnExamSpellActivity : AppCompatActivity() { | |||||
override fun onCreate(savedInstanceState: Bundle?) { | |||||
super.onCreate(savedInstanceState) | |||||
setContentView(R.layout.activity_exam_learn_spell) | |||||
} | |||||
} |
package com.xkl.cdl.module.learn | |||||
import androidx.appcompat.app.AppCompatActivity | |||||
import android.os.Bundle | |||||
import com.xkl.cdl.R | |||||
class LearnExamWordActivity : AppCompatActivity() { | |||||
override fun onCreate(savedInstanceState: Bundle?) { | |||||
super.onCreate(savedInstanceState) | |||||
setContentView(R.layout.activity_learn_exam_word) | |||||
} | |||||
} |
package com.xkl.cdl.module.learn | |||||
import androidx.appcompat.app.AppCompatActivity | |||||
import android.os.Bundle | |||||
import com.xkl.cdl.R | |||||
class LearnSpellActivity : AppCompatActivity() { | |||||
override fun onCreate(savedInstanceState: Bundle?) { | |||||
super.onCreate(savedInstanceState) | |||||
setContentView(R.layout.activity_learn_spell) | |||||
} | |||||
} |
package com.xkl.cdl.module.learn | |||||
import androidx.appcompat.app.AppCompatActivity | |||||
import android.os.Bundle | |||||
import com.xkl.cdl.R | |||||
class LearnWordActivity : AppCompatActivity() { | |||||
override fun onCreate(savedInstanceState: Bundle?) { | |||||
super.onCreate(savedInstanceState) | |||||
setContentView(R.layout.activity_learn_word) | |||||
} | |||||
} |
package com.xkl.cdl.module.m_center_learn | |||||
import com.suliang.common.base.viewmodel.BaseViewModel | |||||
import com.xkl.cdl.data.course.Course | |||||
/** | |||||
* author suliang | |||||
* create 2022/3/24 17:42 | |||||
* Describe: 课程主页 | |||||
*/ | |||||
class CourseMainActivityViewModel(val course: Course) : BaseViewModel() { | |||||
} |
import androidx.lifecycle.ViewModelProvider | import androidx.lifecycle.ViewModelProvider | ||||
import androidx.recyclerview.widget.DividerItemDecoration | import androidx.recyclerview.widget.DividerItemDecoration | ||||
import androidx.recyclerview.widget.LinearLayoutManager | import androidx.recyclerview.widget.LinearLayoutManager | ||||
import com.suliang.common.Config | |||||
import com.suliang.common.AppConfig | |||||
import com.suliang.common.base.fragment.BaseFragmentVM | import com.suliang.common.base.fragment.BaseFragmentVM | ||||
import com.suliang.common.util.LogUtil | import com.suliang.common.util.LogUtil | ||||
import com.xkl.cdl.R | import com.xkl.cdl.R | ||||
import com.xkl.cdl.data.course.CoursePack | |||||
import com.xkl.cdl.databinding.FragmentCoursePackBinding | import com.xkl.cdl.databinding.FragmentCoursePackBinding | ||||
import com.xkl.cdl.module.main.MainActivityViewModel | import com.xkl.cdl.module.main.MainActivityViewModel | ||||
@JvmStatic | @JvmStatic | ||||
fun newInstance(projectId: Int) = CoursePackFragment().apply { | fun newInstance(projectId: Int) = CoursePackFragment().apply { | ||||
arguments = Bundle().apply { | arguments = Bundle().apply { | ||||
putInt(Config.INTENT_1,projectId) | |||||
putInt(AppConfig.INTENT_1,projectId) | |||||
} | } | ||||
} | } | ||||
} | } | ||||
override fun initViewModel(): CoursePackFragmentViewModel { | override fun initViewModel(): CoursePackFragmentViewModel { | ||||
val projectId = requireArguments().getInt(Config.INTENT_1) | |||||
val projectId = requireArguments().getInt(AppConfig.INTENT_1) | |||||
return ViewModelProvider(this,ViewModelFactory(projectId)).get(CoursePackFragmentViewModel::class.java).apply { | return ViewModelProvider(this,ViewModelFactory(projectId)).get(CoursePackFragmentViewModel::class.java).apply { | ||||
this.mainActivityViewModel = ViewModelProvider(requireActivity()).get(MainActivityViewModel::class.java) | this.mainActivityViewModel = ViewModelProvider(requireActivity()).get(MainActivityViewModel::class.java) | ||||
this.learnCenterFragmentViewModel = ViewModelProvider(requireParentFragment()).get(LearnCenterFragmentViewModel::class.java) | this.learnCenterFragmentViewModel = ViewModelProvider(requireParentFragment()).get(LearnCenterFragmentViewModel::class.java) | ||||
binding.contentLayout.recyclerView.apply { | binding.contentLayout.recyclerView.apply { | ||||
layoutManager = LinearLayoutManager(requireContext(),LinearLayoutManager.VERTICAL,false) | layoutManager = LinearLayoutManager(requireContext(),LinearLayoutManager.VERTICAL,false) | ||||
adapter = vm.adpater.apply { | adapter = vm.adpater.apply { | ||||
onItemClick = { v,position,courePack -> | |||||
//点击时事件,跳转 | |||||
onItemClick = { v,position,coursePack -> | |||||
CoursePackMainActivity.newInstance(requireContext(),coursePack.subjectId,coursePack.inCoursePackPosition) | |||||
} | } | ||||
} | } | ||||
//分割线 | //分割线 |
import androidx.lifecycle.MutableLiveData | import androidx.lifecycle.MutableLiveData | ||||
import com.suliang.common.base.viewmodel.BaseViewModel | import com.suliang.common.base.viewmodel.BaseViewModel | ||||
import com.xkl.cdl.adapter.AdapterCoursePackWithLearCenter | import com.xkl.cdl.adapter.AdapterCoursePackWithLearCenter | ||||
import com.xkl.cdl.data.course.CoursePack | |||||
import com.xkl.cdl.data.bean.course.CoursePack | |||||
import com.xkl.cdl.data.manager.CourseManager | import com.xkl.cdl.data.manager.CourseManager | ||||
import com.xkl.cdl.module.main.MainActivityViewModel | import com.xkl.cdl.module.main.MainActivityViewModel | ||||
package com.xkl.cdl.module.m_center_learn | |||||
import android.content.Context | |||||
import android.content.Intent | |||||
import android.graphics.Color | |||||
import android.os.Bundle | |||||
import android.view.View | |||||
import androidx.core.content.ContextCompat | |||||
import androidx.core.content.res.ResourcesCompat | |||||
import androidx.databinding.DataBindingUtil | |||||
import androidx.fragment.app.Fragment | |||||
import androidx.lifecycle.ViewModel | |||||
import androidx.lifecycle.ViewModelProvider | |||||
import androidx.viewpager2.widget.ViewPager2 | |||||
import com.google.android.material.bottomsheet.BottomSheetDialog | |||||
import com.suliang.common.AppConfig | |||||
import com.suliang.common.base.activity.BaseActivityVM | |||||
import com.suliang.common.extension.click | |||||
import com.suliang.common.util.LogUtil | |||||
import com.suliang.common.util.os.ScreenUtil | |||||
import com.xkl.cdl.R | |||||
import com.xkl.cdl.adapter.AdapterAutoPlaySelectRepeat | |||||
import com.xkl.cdl.adapter.ViewPagerAdapter | |||||
import com.xkl.cdl.data.AppConstants | |||||
import com.xkl.cdl.data.binding.BindingAdapter | |||||
import com.xkl.cdl.data.manager.CourseManager | |||||
import com.xkl.cdl.databinding.ActivityCourseMainBinding | |||||
import com.xkl.cdl.databinding.DialogBottomAutoPlaySelectBinding | |||||
import com.xkl.cdl.databinding.DialogBottomCourseMoreBinding | |||||
import com.xkl.cdl.module.m_center_learn.coursechildren.CourseMainFragment | |||||
import com.zackratos.ultimatebarx.ultimatebarx.statusBarOnly | |||||
/** | |||||
* 课程中心 | |||||
*/ | |||||
class CoursePackMainActivity : BaseActivityVM<ActivityCourseMainBinding, CoursePackMainActivityViewModel>() { | |||||
companion object { | |||||
@JvmStatic | |||||
fun newInstance(context: Context, subjectId: Int, coursePackInPosition: Int) { | |||||
context.startActivity(Intent(context, CoursePackMainActivity::class.java).apply { | |||||
putExtra(AppConfig.INTENT_1, subjectId) | |||||
putExtra(AppConfig.INTENT_2, coursePackInPosition) | |||||
}) | |||||
} | |||||
} | |||||
//子课程对应的Fragment | |||||
private var childFragments = mutableListOf<Fragment>() | |||||
//更多按钮的弹窗显示 | |||||
private var moreDialog: BottomSheetDialog? = null | |||||
//自动播放次数的弹窗选择 | |||||
private var autoPlaySeletDialog: BottomSheetDialog? = null | |||||
override fun initViewModel(): CoursePackMainActivityViewModel { | |||||
val subjectId = intent.getIntExtra(AppConfig.INTENT_1, 0) | |||||
val coursePackInListPosition = intent.getIntExtra(AppConfig.INTENT_2, 0) | |||||
return ViewModelProvider( | |||||
this, ViewModelFactory(subjectId, coursePackInListPosition) | |||||
)[CoursePackMainActivityViewModel::class.java] | |||||
} | |||||
override fun initStatusBar() { | |||||
statusBarOnly { | |||||
fitWindow = false //布局是否侵入状态栏 | |||||
color = Color.TRANSPARENT //透明 | |||||
light = true | |||||
} | |||||
} | |||||
override fun initActivity(savedInstanceState: Bundle?) { | |||||
LogUtil.e("CoursePackMainActivity coursePackMainActivityVM hashCode -> ${vm.hashCode()}") | |||||
//设置布局数据 | |||||
binding.coursePack = vm.coursePack | |||||
//状态栏高度设置 | |||||
binding.statusBarView.layoutParams.height = ScreenUtil.getStatusBarHeight() | |||||
//设置简介的箭头大小 | |||||
ResourcesCompat.getDrawable(resources, R.drawable.ic_arrow_right, null)?.apply { | |||||
setBounds(0, 0, 36, 36) | |||||
binding.textViewIntroduction.setCompoundDrawables(null, null, this, null) | |||||
} | |||||
//返回事件 | |||||
binding.includeTitleBar.titleBar.run { | |||||
onBackClick = {_ -> finish() } | |||||
} | |||||
//初始化tab和viewPager | |||||
initTabAndViewPager() | |||||
} | |||||
private fun initTabAndViewPager() { | |||||
//英语课程包且为英语单词课程包才显示tab | |||||
if (vm.coursePack.subjectId == AppConstants.SUBJECT_ENGLISH && vm.coursePack.coursePackType == AppConstants.COURSEPACK_TYPE_ENGLISH_WORD) { | |||||
binding.includeCourseTypeTab.root.visibility = View.VISIBLE | |||||
vm.coursePack.childrenCourses.forEachIndexed { index, course -> | |||||
when (course.courseType) { | |||||
AppConstants.COURSE_TYPE_ENGLISH_DISCERN -> { | |||||
binding.includeCourseTypeTab.tabDiscern.visibility = View.VISIBLE | |||||
childFragments.add(CourseMainFragment.newInstance(index)) | |||||
} | |||||
AppConstants.COURSE_TYPE_ENGLISH_SPELL -> { | |||||
binding.includeCourseTypeTab.ivArrow1.visibility = View.VISIBLE | |||||
binding.includeCourseTypeTab.tabSpell.visibility = View.VISIBLE | |||||
childFragments.add(CourseMainFragment.newInstance(index)) | |||||
} | |||||
AppConstants.COURSE_TYPE_ENGLISH_VOICE -> { | |||||
binding.includeCourseTypeTab.ivArrow2.visibility = View.VISIBLE | |||||
binding.includeCourseTypeTab.tabVoice.visibility = View.VISIBLE | |||||
childFragments.add(CourseMainFragment.newInstance(index)) | |||||
} | |||||
} | |||||
} | |||||
} else { //其他课程tab为空 | |||||
binding.includeCourseTypeTab.root.visibility = View.GONE | |||||
childFragments.add(CourseMainFragment.newInstance(0)) | |||||
} | |||||
//ViewPager初始 | |||||
binding.viewPager2.apply { | |||||
adapter = ViewPagerAdapter(this@CoursePackMainActivity, childFragments) | |||||
//注册页面改变监听 | |||||
registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { | |||||
override fun onPageSelected(position: Int) { | |||||
super.onPageSelected(position) | |||||
//改变tab的选中颜色 | |||||
if (binding.includeCourseTypeTab.root.visibility == View.VISIBLE) { //可见,才做操作 | |||||
binding.includeCourseTypeTab.apply { | |||||
tabDiscern.run { | |||||
setTextColor( | |||||
ContextCompat.getColor( | |||||
this@CoursePackMainActivity, | |||||
if (position == 0) R.color.theme_color else R.color.gray_2 | |||||
) | |||||
) | |||||
BindingAdapter.loadVectorDrawable( | |||||
this, ContextCompat.getColor( | |||||
this@CoursePackMainActivity, | |||||
if (position == 0) R.color.theme_color else R.color.gray_2 | |||||
) | |||||
) | |||||
} | |||||
tabSpell.run { | |||||
setTextColor( | |||||
ContextCompat.getColor( | |||||
this@CoursePackMainActivity, | |||||
if (position == 1) R.color.theme_color else R.color.gray_2 | |||||
) | |||||
) | |||||
BindingAdapter.loadVectorDrawable( | |||||
this, ContextCompat.getColor( | |||||
this@CoursePackMainActivity, | |||||
if (position == 1) R.color.theme_color else R.color.gray_2 | |||||
) | |||||
) | |||||
} | |||||
tabVoice.run { | |||||
setTextColor( | |||||
ContextCompat.getColor( | |||||
this@CoursePackMainActivity, | |||||
if (position == 2) R.color.theme_color else R.color.gray_2 | |||||
) | |||||
) | |||||
BindingAdapter.loadVectorDrawable( | |||||
this, ContextCompat.getColor( | |||||
this@CoursePackMainActivity, | |||||
if (position == 2) R.color.theme_color else R.color.gray_2 | |||||
) | |||||
) | |||||
} | |||||
} | |||||
} | |||||
//改变page后设置进度 | |||||
vm.currentCourseProgress.value = vm.coursePack.childrenCourses[position].courseLearnProgress | |||||
} | |||||
}) | |||||
} | |||||
//tab点击 | |||||
binding.includeCourseTypeTab.apply { | |||||
tabDiscern.click { binding.viewPager2.currentItem = 0 } | |||||
tabSpell.click { binding.viewPager2.currentItem = 1 } | |||||
tabVoice.click { binding.viewPager2.currentItem = 2 } | |||||
} | |||||
//监听进度,设置进度 | |||||
vm.currentCourseProgress.observe(this) { | |||||
binding.includeCourseProgress.apply { | |||||
//进度格式化 | |||||
progressbar.progress = it.toInt() | |||||
tvProgress.text = if (binding.includeCourseTypeTab.root.visibility == View.VISIBLE) { | |||||
val format = when (binding.viewPager2.currentItem) { | |||||
0 -> "认读进度:%s" | |||||
1 -> "拼写进度:%s" | |||||
2 -> "辨音进度:%s" | |||||
else -> "进度:%s" | |||||
} | |||||
String.format(format, CourseManager.useToShowProgress(it)) | |||||
} else { | |||||
String.format("进度:%s", CourseManager.useToShowProgress(it)) | |||||
} | |||||
} | |||||
} | |||||
//更多按钮点击 | |||||
binding.includeCourseProgress.ivMore.click { | |||||
showMoreDialog() | |||||
} | |||||
} | |||||
override fun loadData() { | |||||
} | |||||
/** 点击显示更多的弹窗 */ | |||||
private fun showMoreDialog() { | |||||
if (moreDialog == null) { | |||||
moreDialog = BottomSheetDialog(this, R.style.dialog_style).apply { | |||||
val moreBinding = DataBindingUtil.inflate<DialogBottomCourseMoreBinding>( | |||||
layoutInflater, R.layout.dialog_bottom_course_more, null, false | |||||
) | |||||
setContentView(moreBinding.root) | |||||
//体验账号、拼些、口语课程、作文课程不显示自动播放 | |||||
when (vm.coursePack.childrenCourses[binding.viewPager2.currentItem].courseType) { | |||||
AppConstants.COURSE_TYPE_ENGLISH_SPELL, AppConstants.COURSE_TYPE_ENGLISH_SPOKEN, AppConstants.COURSE_TYPE_CHINESE_COMPOSITION -> moreBinding.tvAutoPlay.visibility = | |||||
View.GONE | |||||
else -> moreBinding.tvAutoPlay.visibility = View.VISIBLE | |||||
} | |||||
moreBinding.ivCancel.click { | |||||
dismiss() | |||||
} | |||||
moreBinding.tvAutoPlay.click { | |||||
dismiss() | |||||
showAutoPlaySelectDialog() | |||||
} | |||||
moreBinding.tvClearLearnRecord.click { | |||||
dismiss() | |||||
// TODO: 2022/3/29 弹窗显示清除学习记录 | |||||
} | |||||
} | |||||
} | |||||
moreDialog?.show() | |||||
} | |||||
/** 自动播放次数选择: 仅单词会有该选项 */ | |||||
private fun showAutoPlaySelectDialog() { | |||||
if (autoPlaySeletDialog == null) { | |||||
autoPlaySeletDialog = 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.ivCancel.click { v -> dismiss() } | |||||
autoPlayBinding.rvRepeat.run { | |||||
adapter = AdapterAutoPlaySelectRepeat().apply { | |||||
onItemClick = { _, position, _ -> | |||||
dismiss() | |||||
startAutoPlay(position + 1) | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} | |||||
autoPlaySeletDialog?.show() | |||||
} | |||||
/** | |||||
* 开始自动播放 | |||||
* @param time Int | |||||
*/ | |||||
private fun startAutoPlay(time: Int) { | |||||
} | |||||
/** ViewModel Factory工厂 */ | |||||
inner class ViewModelFactory(private val subjectId: Int, private val coursePackInPosition: Int) : | |||||
ViewModelProvider.Factory { | |||||
override fun <T : ViewModel?> create(modelClass: Class<T>): T { | |||||
return CoursePackMainActivityViewModel(subjectId, coursePackInPosition) as T | |||||
} | |||||
} | |||||
} |
package com.xkl.cdl.module.m_center_learn | |||||
import androidx.lifecycle.MutableLiveData | |||||
import com.suliang.common.base.viewmodel.BaseViewModel | |||||
import com.xkl.cdl.data.manager.CourseManager | |||||
/** | |||||
* author suliang | |||||
* create 2022/3/24 17:42 | |||||
* Describe: 课程主页 | |||||
*/ | |||||
class CoursePackMainActivityViewModel(subjectId: Int , coursePackInPosition : Int) : BaseViewModel() { | |||||
//操作的课程包 | |||||
val coursePack = CourseManager.subjectWithCoursePackMap[subjectId]!![coursePackInPosition] | |||||
//设置显示当前课程的进度值和显示内容 | |||||
val currentCourseProgress = MutableLiveData<Double>() | |||||
} |
import androidx.lifecycle.MutableLiveData | import androidx.lifecycle.MutableLiveData | ||||
import com.suliang.common.base.viewmodel.BaseViewModel | import com.suliang.common.base.viewmodel.BaseViewModel | ||||
import com.xkl.cdl.R | import com.xkl.cdl.R | ||||
import com.xkl.cdl.data.Constants | |||||
import com.xkl.cdl.data.AppConstants | |||||
import com.xkl.cdl.module.main.MainActivityViewModel | import com.xkl.cdl.module.main.MainActivityViewModel | ||||
/** | /** | ||||
/** 实例化项目课程包Fragment和显示Title */ | /** 实例化项目课程包Fragment和显示Title */ | ||||
fun initLearnCenterFragment(){ | fun initLearnCenterFragment(){ | ||||
if (mProjectFragments.isEmpty()){ | if (mProjectFragments.isEmpty()){ | ||||
mProjectFragments.add(CoursePackFragment.newInstance(Constants.SUBJECT_ENGLISH)) | |||||
mProjectFragments.add(CoursePackFragment.newInstance(Constants.SUBJECT_CHINESE)) | |||||
mProjectFragments.add(CoursePackFragment.newInstance(AppConstants.SUBJECT_ENGLISH)) | |||||
mProjectFragments.add(CoursePackFragment.newInstance(AppConstants.SUBJECT_CHINESE)) | |||||
} | } | ||||
if (mProjectTitles.isEmpty()){ | if (mProjectTitles.isEmpty()){ | ||||
mProjectTitles.add(R.string.project_english) | mProjectTitles.add(R.string.project_english) |
package com.xkl.cdl.module.m_center_learn.coursechildren | |||||
import android.view.View | |||||
import androidx.lifecycle.ViewModelProvider | |||||
import androidx.recyclerview.widget.LinearLayoutManager | |||||
import com.suliang.common.base.fragment.BaseFragmentVM | |||||
import com.xkl.cdl.adapter.AdapterLesson | |||||
import com.xkl.cdl.data.AppConstants | |||||
import com.xkl.cdl.data.bean.course.Lesson | |||||
import com.xkl.cdl.databinding.FragmentCourseLessonBinding | |||||
/** | |||||
* 课程章节目录 | |||||
*/ | |||||
class CourseLessonFragment : BaseFragmentVM<FragmentCourseLessonBinding, CourseMainFragmentViewModel>() { | |||||
companion object { | |||||
@JvmStatic | |||||
fun newInstance() = CourseLessonFragment() | |||||
} | |||||
override fun initViewModel(): CourseMainFragmentViewModel { | |||||
return ViewModelProvider(requireParentFragment())[CourseMainFragmentViewModel::class.java] | |||||
} | |||||
override fun initFragment() { | |||||
//口语显示顶部的自动播放与跟读模式 | |||||
if (vm.course.courseType == AppConstants.COURSE_TYPE_ENGLISH_SPOKEN){ | |||||
binding.spokenTopLayout.visibility = View.VISIBLE | |||||
} | |||||
binding.recyclerView.apply { | |||||
layoutManager = LinearLayoutManager(requireContext(),LinearLayoutManager.VERTICAL,false) | |||||
adapter = AdapterLesson(vm).apply { | |||||
onItemClick = onLessonClick | |||||
} | |||||
} | |||||
//设置数据 | |||||
(binding.recyclerView.adapter as AdapterLesson).setData(vm.allLesson.toMutableList()) | |||||
} | |||||
override fun loadData() { | |||||
} | |||||
/** 课时点击实现 */ | |||||
private val onLessonClick : (v:View,position: Int, leeson: Lesson) -> Unit = { view, position, entity -> | |||||
// TODO: 2022/3/31 根据情况具体跳转实现 学前、学习、学后 | |||||
when(entity.lessonType){ | |||||
AppConstants.LESSON_TYPE_WORD -> { | |||||
if (entity.beforeTestScore == AppConstants.NOT_DOING){ | |||||
}else if (!entity.learnIsOver){ | |||||
}else if (entity.afterTestScore != AppConstants.NOT_DOING){ | |||||
}else{ | |||||
} | |||||
} | |||||
AppConstants.LESSON_TYPE_SENTENCE -> { | |||||
} | |||||
AppConstants.LESSON_TYPE_DIALOGUE -> { | |||||
} | |||||
AppConstants.LESSON_TYPE_COMPOSITION_VIDEO -> { | |||||
} | |||||
AppConstants.LESSON_TYPE_COMPOSITION_KNOWLEDGE -> { | |||||
} | |||||
AppConstants.LESSON_TYPE_COMPOSITION_EXAM -> { | |||||
} | |||||
AppConstants.LESSON_TYPE_COMPOSITION_READING -> { | |||||
} | |||||
AppConstants.LESSON_TYPE_COMPOSITION_TASK -> { | |||||
} | |||||
} | |||||
} | |||||
} |
package com.xkl.cdl.module.m_center_learn.coursechildren | |||||
import android.os.Bundle | |||||
import androidx.lifecycle.ViewModel | |||||
import androidx.lifecycle.ViewModelProvider | |||||
import com.suliang.common.AppConfig | |||||
import com.suliang.common.base.fragment.BaseFragmentVM | |||||
import com.suliang.common.extension.replaceFragment | |||||
import com.suliang.common.util.LogUtil | |||||
import com.xkl.cdl.R | |||||
import com.xkl.cdl.data.manager.db.DbControlBase | |||||
import com.xkl.cdl.databinding.FragmentCourseMainBinding | |||||
import com.xkl.cdl.module.m_center_learn.CoursePackMainActivityViewModel | |||||
/** | |||||
* 学习中心@[LearnCenterFragment] @[CoursePackFragment]下课程包主页@[CoursePackMainActivity]下的 | |||||
* 主课程Fragment[CourseMainFragment] | |||||
* 用于加载该课程的多种状态: 复习、章节目录、总测试 | |||||
*/ | |||||
class CourseMainFragment : BaseFragmentVM<FragmentCourseMainBinding, CourseMainFragmentViewModel>() { | |||||
companion object { | |||||
@JvmStatic | |||||
fun newInstance(courseIndex:Int) = CourseMainFragment().apply { | |||||
arguments = Bundle().apply { | |||||
putInt(AppConfig.INTENT_1,courseIndex) | |||||
} | |||||
} | |||||
} | |||||
override fun initViewModel(): CourseMainFragmentViewModel { | |||||
return ViewModelProvider(this,ViewModelFactory(requireArguments().getInt(AppConfig.INTENT_1)))[CourseMainFragmentViewModel::class.java].apply { | |||||
coursePackMainActivityVM = ViewModelProvider(requireActivity())[CoursePackMainActivityViewModel::class.java] | |||||
LogUtil.e("CourseMainFragment coursePackMainActivityVM hashCode -> ${coursePackMainActivityVM.hashCode()}") | |||||
} | |||||
} | |||||
override fun initFragment() { | |||||
//设置课程 和 需要操作的类型 | |||||
vm.course = vm.coursePackMainActivityVM.coursePack.childrenCourses[vm.courseIndex].apply { | |||||
vm.dbControlBase = DbControlBase(subjectId,coursePackId,courseId,courseType) | |||||
} | |||||
} | |||||
override fun loadData() { | |||||
LogUtil.e("CourseMainFragment 加载数据 --》 ${vm.courseIndex}") | |||||
vm.loadMain().observe(this){ | |||||
changeChildrenFragment() | |||||
} | |||||
} | |||||
/** | |||||
* 改变加载的子Fragment | |||||
*/ | |||||
private fun changeChildrenFragment(){ | |||||
// //加载复习 | |||||
// replaceFragment(R.id.layout_root, CourseReviewFragment.newInstance()) | |||||
// //学前总测 | |||||
// replaceFragment(R.id.layout_root, CourseTotalTestFragment.newInstance(AppConstants.TEST_TYPE_BEFORE_TOTAL)) | |||||
//学后总测 | |||||
// replaceFragment(R.id.layout_root, CourseTotalTestFragment.newInstance(AppConstants.TEST_TYPE_AFTER_TOTAL)) | |||||
//学习目录 | |||||
replaceFragment(R.id.layout_root, CourseLessonFragment.newInstance()) | |||||
} | |||||
inner class ViewModelFactory(private val courseIndex: Int) : ViewModelProvider.Factory{ | |||||
override fun <T : ViewModel?> create(modelClass: Class<T>): T { | |||||
return CourseMainFragmentViewModel(courseIndex) as T | |||||
} | |||||
} | |||||
} |
package com.xkl.cdl.module.m_center_learn.coursechildren | |||||
import android.provider.ContactsContract | |||||
import androidx.lifecycle.MutableLiveData | |||||
import com.suliang.common.base.viewmodel.BaseViewModel | |||||
import com.suliang.common.extension.diskIo2DiskIo | |||||
import com.xkl.cdl.data.bean.course.Course | |||||
import com.xkl.cdl.data.bean.course.CourseDetail | |||||
import com.xkl.cdl.data.bean.course.Lesson | |||||
import com.xkl.cdl.data.manager.db.DbControlBase | |||||
import com.xkl.cdl.data.repository.DataRepository | |||||
import com.xkl.cdl.module.m_center_learn.CoursePackMainActivityViewModel | |||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers | |||||
import io.reactivex.rxjava3.core.Observable | |||||
import io.reactivex.rxjava3.core.Observer | |||||
import io.reactivex.rxjava3.disposables.Disposable | |||||
import java.util.* | |||||
import kotlin.collections.ArrayList | |||||
import kotlin.collections.HashMap | |||||
/** | |||||
* author suliang | |||||
* create 2022/3/28 15:26 | |||||
* Describe: | |||||
* @property courseIndex 该课程在课程包的课程集合中的位置 | |||||
*/ | |||||
class CourseMainFragmentViewModel(val courseIndex: Int) : BaseViewModel() { | |||||
//课程包主页的ViewModel | |||||
lateinit var coursePackMainActivityVM: CoursePackMainActivityViewModel | |||||
lateinit var dbControlBase: DbControlBase | |||||
//当前操作课程 | |||||
lateinit var course: Course | |||||
/** 课程的收藏本: 目前仅作用在口语课程会使用到该数据 */ | |||||
lateinit var collectList: HashMap<String, Long> | |||||
/** 复习的数据 */ | |||||
lateinit var reviewDataList: MutableList<String> | |||||
/** 课程所有课时 */ | |||||
lateinit var allLesson: List<Lesson> | |||||
//课程的详细信息 | |||||
lateinit var courseDetail: CourseDetail | |||||
//获取课程的统计信息 | |||||
//课程收藏本: 主要用于口语对话学习的数据 | |||||
//获取课程的复习数据 | |||||
//获取课程的章节数据 | |||||
fun loadMain() : MutableLiveData<Boolean> { | |||||
showHideLoading(true) | |||||
val mutableLiveData = MutableLiveData<Boolean>() | |||||
Observable.concat( | |||||
DataRepository.getCourseStatistics().flatMap { | |||||
courseDetail = it | |||||
return@flatMap DataRepository.getCourseAllLesson(dbControlBase, it) | |||||
}, DataRepository.getReviewData() | |||||
, DataRepository.getCourseCollect()) | |||||
.compose(diskIo2DiskIo()) | |||||
.subscribe(object :Observer<Any>{ | |||||
override fun onSubscribe(d: Disposable?) { | |||||
} | |||||
override fun onNext(t: Any?) { | |||||
t?.let { it -> | |||||
if (it is List<*>){ | |||||
allLesson = it as List<Lesson> | |||||
} | |||||
} | |||||
} | |||||
override fun onError(e: Throwable?) { | |||||
e?.printStackTrace() | |||||
} | |||||
override fun onComplete() { | |||||
showHideLoading(false) | |||||
mutableLiveData.postValue(true) | |||||
} | |||||
}) | |||||
return mutableLiveData | |||||
} | |||||
} |
package com.xkl.cdl.module.m_center_learn.coursechildren | |||||
import android.os.Bundle | |||||
import androidx.lifecycle.ViewModelProvider | |||||
import com.suliang.common.AppConfig | |||||
import com.suliang.common.base.fragment.BaseFragmentVM | |||||
import com.suliang.common.extension.click | |||||
import com.xkl.cdl.data.AppConstants | |||||
import com.xkl.cdl.databinding.FragmentCourseLessonBinding | |||||
import com.xkl.cdl.databinding.FragmentCourseReviewBinding | |||||
/** | |||||
* 课程章节目录 | |||||
* @property param1 String? | |||||
* @property param2 String? | |||||
*/ | |||||
class CourseReviewFragment : BaseFragmentVM<FragmentCourseReviewBinding, CourseMainFragmentViewModel>() { | |||||
companion object { | |||||
@JvmStatic | |||||
fun newInstance() = CourseReviewFragment() | |||||
} | |||||
override fun initFragment() { | |||||
//根据课程类型进行显示 | |||||
binding.tvTips.text = when(vm.course.courseType){ | |||||
AppConstants.COURSE_TYPE_ENGLISH_DISCERN -> "你将进行 [认读] 课程智能复习" | |||||
AppConstants.COURSE_TYPE_ENGLISH_VOICE -> "你将进行 [辨音] 课程智能复习" | |||||
AppConstants.COURSE_TYPE_ENGLISH_SPELL -> "你将进行 [拼写] 课程智能复习" | |||||
else -> "你将进行课程智能复习" | |||||
} | |||||
binding.tvReviewCount.text = String.format("本次智能复习数%d",vm.course.courseReviewNumber) | |||||
//开始测试事件 | |||||
binding.tvStartReview.click { | |||||
showToast("开始复习") | |||||
} | |||||
} | |||||
override fun loadData() { | |||||
} | |||||
override fun initViewModel(): CourseMainFragmentViewModel { | |||||
return ViewModelProvider(requireParentFragment())[CourseMainFragmentViewModel::class.java] | |||||
} | |||||
} |
package com.xkl.cdl.module.m_center_learn.coursechildren | |||||
import android.os.Bundle | |||||
import android.view.View | |||||
import androidx.lifecycle.ViewModelProvider | |||||
import com.suliang.common.AppConfig | |||||
import com.suliang.common.base.fragment.BaseFragmentVM | |||||
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.databinding.FragmentCourseTotalTestBinding | |||||
/** | |||||
* 课程总测试: 学前总,学后总 | |||||
* @property param1 String? | |||||
* @property param2 String? | |||||
*/ | |||||
class CourseTotalTestFragment : BaseFragmentVM<FragmentCourseTotalTestBinding, CourseMainFragmentViewModel>() { | |||||
companion object { | |||||
@JvmStatic | |||||
fun newInstance(totalTestType: Int) = CourseTotalTestFragment().apply { | |||||
arguments = Bundle().apply { | |||||
putInt(AppConfig.INTENT_1, totalTestType) | |||||
} | |||||
} | |||||
} | |||||
override fun initViewModel(): CourseMainFragmentViewModel { | |||||
return ViewModelProvider(requireParentFragment())[CourseMainFragmentViewModel::class.java] | |||||
} | |||||
//传递过来的总测类型: 学前,学后 | |||||
private var totalTestType = 0 | |||||
override fun initFragment() { | |||||
totalTestType = requireArguments().getInt(AppConfig.INTENT_1) | |||||
when (totalTestType) { | |||||
AppConstants.TEST_TYPE_BEFORE_TOTAL -> { | |||||
//学前总测 | |||||
binding.run { | |||||
tvTitle.setText(R.string.test_total_before_title) | |||||
tvCountTip.text = "共25题,预计3分钟" | |||||
//按钮初始 | |||||
button2.run { | |||||
setText(R.string.start_test) | |||||
click { view -> | |||||
startTest(view) | |||||
} | |||||
} | |||||
} | |||||
} | |||||
AppConstants.TEST_TYPE_AFTER_TOTAL -> { | |||||
//学后总测 | |||||
binding.run { | |||||
ivIcon.setImageResource(if (java.util.Random().nextBoolean()) R.mipmap.boy_2 else R.mipmap.girl_2) | |||||
tvTitle.setText(R.string.tips_current_course_learn_over) | |||||
tvMainTip.visibility = View.VISIBLE | |||||
//根据测试成绩处理 | |||||
vm.courseDetail.st_before = 81.0 | |||||
vm.courseDetail.st_before.let { | |||||
when { | |||||
it == -1.0 -> { //未测 | |||||
tvMainTip.setText(R.string.test_total_after_tip_1) | |||||
tvCountTip.text = "共25题,预计3分钟" | |||||
button2.run { | |||||
setText(R.string.test_type_after_total) | |||||
click { view -> | |||||
startTest(view) | |||||
} | |||||
} | |||||
} | |||||
it < AppConstants.TEST_SCORE_LEVEL_1 -> { //测试未通过 | |||||
tvMainTip.setHtml("你还未通过学后总测试,上次得分: <font color=\'#F26255\'>$it</font>") | |||||
button1.run { | |||||
visibility = View.VISIBLE | |||||
setText(R.string.continue_learn) | |||||
click { view -> | |||||
continueLearn(view) | |||||
} | |||||
} | |||||
button2.run { | |||||
setText(R.string.start_test) | |||||
click { view -> | |||||
startTest(view) | |||||
} | |||||
} | |||||
} | |||||
it >= AppConstants.TEST_SCORE_LEVEL_1 -> { //测试通过 | |||||
tvMainTip.setHtml("你已通过学后总测试,上次得分: <font color=\'#5082E6\'>$it</font>") | |||||
tvTips.visibility = View.VISIBLE | |||||
tvCountTip.visibility = View.GONE | |||||
button1.run { | |||||
visibility = View.VISIBLE | |||||
setText(R.string.test_again) | |||||
click { view -> | |||||
startTest(view) | |||||
} | |||||
} | |||||
button2.run { | |||||
setText(R.string.continue_learn) | |||||
click { view -> | |||||
continueLearn(view) | |||||
} | |||||
} | |||||
tvClearLearnRecord.visibility = View.VISIBLE | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} | |||||
override fun loadData() { | |||||
} | |||||
/**继续学习*/ | |||||
private fun continueLearn(view: View) { | |||||
showToast("继续学习") | |||||
} | |||||
/** 开始测试 */ | |||||
private fun startTest(view: View) { | |||||
showToast("开始测试") | |||||
} | |||||
} |
import android.annotation.SuppressLint | import android.annotation.SuppressLint | ||||
import android.os.Bundle | import android.os.Bundle | ||||
import com.suliang.common.base.activity.BaseActivity | 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.file.FileUtil | ||||
import com.suliang.common.util.thread.AppExecutors | import com.suliang.common.util.thread.AppExecutors | ||||
import com.xkl.cdl.data.manager.CourseManager | 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.data.manager.db.DbCoursePackManager | ||||
import com.xkl.cdl.databinding.ActivitySplashBinding | import com.xkl.cdl.databinding.ActivitySplashBinding | ||||
import com.xkl.cdl.dialog.LearnDialog | |||||
import com.xkl.cdl.module.main.MainActivity | import com.xkl.cdl.module.main.MainActivity | ||||
import mobile_cache.Mobile_cache | |||||
import java.io.File | import java.io.File | ||||
import java.util.concurrent.TimeUnit | import java.util.concurrent.TimeUnit | ||||
@SuppressLint("CustomSplashScreen") | @SuppressLint("CustomSplashScreen") | ||||
class SplashActivity : BaseActivity<ActivitySplashBinding>() { | |||||
class SplashActivity : BaseActivity<ActivitySplashBinding>(), LearnDialog.DialogFragmentListener { | |||||
override fun onCreate(savedInstanceState: Bundle?) { | override fun onCreate(savedInstanceState: Bundle?) { | ||||
if (!isTaskRoot) { | if (!isTaskRoot) { | ||||
} | } | ||||
override fun loadData() { | override fun loadData() { | ||||
// try { | |||||
// val file: String = File(FileUtil.getSaveDirFile("db"), "mydb").absolutePath | |||||
// val mobile = Mobile_cache.new_(file) | |||||
// mobile.delete() | |||||
// println(" -------------> " + mobile.get("abc")) | |||||
// | |||||
// } catch (e: Exception) { | |||||
// e.printStackTrace() | |||||
// } | |||||
learnDialog = LearnDialog().apply { | |||||
show(supportFragmentManager,javaClass.name) | |||||
} | |||||
LogUtil.e("Dialog -- > ${learnDialog.hashCode()}") | |||||
if (true) return | |||||
showHideLoading(true) | showHideLoading(true) | ||||
AppExecutors.io.execute { | AppExecutors.io.execute { | ||||
//数据文件是否存在 | |||||
val coursePackFile = File(FileUtil.getSaveDirPath("db"), "course-pack.db") | |||||
if (!coursePackFile.exists()) { | |||||
val copyAssetResult = FileUtil.copyAsset("course-pack.db", coursePackFile) | |||||
} | |||||
//读取课程数据 | //读取课程数据 | ||||
// TODO: 2022/3/22 读取当前app绑定的课程数据, | // TODO: 2022/3/22 读取当前app绑定的课程数据, | ||||
DbCoursePackManager().queryBindingCoursePack("262,261,264") | |||||
DbCoursePackManager().queryBindingCoursePack("262,261,264,136,547,615") | |||||
//复制课程的数据库到对应位置 | //复制课程的数据库到对应位置 | ||||
CourseManager.checkCourseDb() | CourseManager.checkCourseDb() | ||||
//定时跳跃到住主界面 | //定时跳跃到住主界面 | ||||
AppExecutors.scheduledExecutor.schedule({ | AppExecutors.scheduledExecutor.schedule({ | ||||
AppExecutors.mainThread.execute { | |||||
showHideLoading(false) | |||||
startActivity(MainActivity::class.java) | |||||
finish() | |||||
} | |||||
}, 1, TimeUnit.SECONDS) | |||||
AppExecutors.mainThread.execute { | |||||
showHideLoading(false) | |||||
startActivity(MainActivity::class.java) | |||||
finish() | |||||
} | |||||
}, 1, TimeUnit.SECONDS) | |||||
} | } | ||||
} | } | ||||
lateinit var learnDialog :LearnDialog | |||||
lateinit var learnDialog1: LearnDialog | |||||
override fun rightClick() { | |||||
if (!this::learnDialog1.isInitialized) { | |||||
learnDialog1 = LearnDialog() | |||||
} | |||||
LogUtil.e("Dialog 1 -- > ${learnDialog1.hashCode()}") | |||||
learnDialog1.show(supportFragmentManager,javaClass.name) | |||||
} | |||||
override fun leftClick() { | |||||
learnDialog1.dismiss() | |||||
} | |||||
} | } |
<?xml version="1.0" encoding="utf-8"?> | |||||
<!--按钮:按下字体--> | |||||
<selector xmlns:android="http://schemas.android.com/apk/res/android"> | |||||
<item android:color="@color/theme_color" android:state_pressed="true"/> | |||||
<item android:color="@color/main_text_color" android:state_pressed="false"/> | |||||
</selector> |
<?xml version="1.0" encoding="utf-8"?> | |||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"> | |||||
<corners android:radius="12dp"/> | |||||
<solid android:color="@color/white"/> | |||||
</shape> |
<variable | <variable | ||||
name="coursePack" | name="coursePack" | ||||
type="com.xkl.cdl.data.course.CoursePack" /> | |||||
type="com.xkl.cdl.data.bean.course.CoursePack" /> | |||||
<import type="android.view.View"/> | |||||
</data> | </data> | ||||
<androidx.constraintlayout.widget.ConstraintLayout | <androidx.constraintlayout.widget.ConstraintLayout | ||||
android:layout_width="match_parent" | android:layout_width="match_parent" | ||||
android:layout_height="match_parent" | android:layout_height="match_parent" | ||||
tools:context=".module.m_center_learn.CourseMainActivity"> | |||||
tools:context=".module.m_center_learn.CoursePackMainActivity" | |||||
android:background="@color/white"> | |||||
<!--模糊图--> | <!--模糊图--> | ||||
<ImageView | <ImageView | ||||
android:id="@+id/img_course_pack_cover_blur" | android:id="@+id/img_course_pack_cover_blur" | ||||
android:layout_width="0dp" | android:layout_width="0dp" | ||||
android:layout_height="0dp" | android:layout_height="0dp" | ||||
android:scaleType="matrix" | |||||
bind:imgByteArray="@{coursePack.cover}" | |||||
bind:blur= "@{false}" | |||||
android:scaleType="fitXY" | |||||
bind:imgBytes="@{coursePack.cover}" | |||||
bind:blur= "@{true}" | |||||
app:layout_constraintBottom_toBottomOf="@+id/view_placeholder_1" | app:layout_constraintBottom_toBottomOf="@+id/view_placeholder_1" | ||||
app:layout_constraintEnd_toEndOf="parent" | app:layout_constraintEnd_toEndOf="parent" | ||||
app:layout_constraintStart_toStartOf="parent" | app:layout_constraintStart_toStartOf="parent" | ||||
app:layout_constraintTop_toTopOf="parent" | app:layout_constraintTop_toTopOf="parent" | ||||
tools:background="@color/gray_2" /> | |||||
tools:background="@color/gray_2" | |||||
android:alpha="0.5"/> | |||||
<!--状态栏--> | <!--状态栏--> | ||||
<View | <View | ||||
<include | <include | ||||
android:id="@+id/include_title_bar" | android:id="@+id/include_title_bar" | ||||
android:layout_width="match_parent" | |||||
android:layout_height="@dimen/title_bar_height" | |||||
layout="@layout/include_title_bar" | layout="@layout/include_title_bar" | ||||
app:layout_constraintTop_toBottomOf="@+id/status_bar_view" | app:layout_constraintTop_toBottomOf="@+id/status_bar_view" | ||||
bind:title="@string/course_detail" /> | |||||
bind:titleValue="@{@string/course_detail}" /> | |||||
<View | <View | ||||
android:id="@+id/view_placeholder_1" | android:id="@+id/view_placeholder_1" |
<?xml version="1.0" encoding="utf-8"?> | |||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" | |||||
xmlns:app="http://schemas.android.com/apk/res-auto" | |||||
xmlns:tools="http://schemas.android.com/tools" | |||||
android:layout_width="match_parent" | |||||
android:layout_height="match_parent" | |||||
tools:context=".module.learn.LearnExamSpellActivity"> | |||||
</androidx.constraintlayout.widget.ConstraintLayout> |
<?xml version="1.0" encoding="utf-8"?> | |||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" | |||||
xmlns:app="http://schemas.android.com/apk/res-auto" | |||||
xmlns:tools="http://schemas.android.com/tools" | |||||
android:layout_width="match_parent" | |||||
android:layout_height="match_parent" | |||||
tools:context=".module.learn.LearnCReadingActivity"> | |||||
</androidx.constraintlayout.widget.ConstraintLayout> |
<?xml version="1.0" encoding="utf-8"?> | |||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" | |||||
xmlns:app="http://schemas.android.com/apk/res-auto" | |||||
xmlns:tools="http://schemas.android.com/tools" | |||||
android:layout_width="match_parent" | |||||
android:layout_height="match_parent" | |||||
tools:context=".module.learn.LearnCTaskActivity"> | |||||
</androidx.constraintlayout.widget.ConstraintLayout> |
<?xml version="1.0" encoding="utf-8"?> | |||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" | |||||
xmlns:app="http://schemas.android.com/apk/res-auto" | |||||
xmlns:tools="http://schemas.android.com/tools" | |||||
android:layout_width="match_parent" | |||||
android:layout_height="match_parent" | |||||
tools:context=".module.learn.LearnCVideoActivity"> | |||||
</androidx.constraintlayout.widget.ConstraintLayout> |
<?xml version="1.0" encoding="utf-8"?> | |||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" | |||||
xmlns:app="http://schemas.android.com/apk/res-auto" | |||||
xmlns:tools="http://schemas.android.com/tools" | |||||
android:layout_width="match_parent" | |||||
android:layout_height="match_parent" | |||||
tools:context=".module.learn.LearnExamWordActivity"> | |||||
</androidx.constraintlayout.widget.ConstraintLayout> |
<?xml version="1.0" encoding="utf-8"?> | |||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" | |||||
xmlns:app="http://schemas.android.com/apk/res-auto" | |||||
xmlns:tools="http://schemas.android.com/tools" | |||||
android:layout_width="match_parent" | |||||
android:layout_height="match_parent" | |||||
tools:context=".module.learn.LearnSpellActivity"> | |||||
</androidx.constraintlayout.widget.ConstraintLayout> |
<?xml version="1.0" encoding="utf-8"?> | |||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" | |||||
xmlns:app="http://schemas.android.com/apk/res-auto" | |||||
xmlns:tools="http://schemas.android.com/tools" | |||||
android:layout_width="match_parent" | |||||
android:layout_height="match_parent" | |||||
tools:context=".module.learn.LearnWordActivity"> | |||||
</androidx.constraintlayout.widget.ConstraintLayout> |
<?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"> | |||||
<data> | |||||
</data> | |||||
<androidx.constraintlayout.widget.ConstraintLayout | |||||
android:layout_width="match_parent" | |||||
android:layout_height="match_parent" | |||||
android:background="@drawable/shape_rounder_toplr_24_white"> | |||||
<TextView | |||||
android:id="@+id/tv_title" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="46dp" | |||||
android:text="@string/please_select_the_operation_you_want_to_do" | |||||
android:textColor="@color/gray_2" | |||||
android:textSize="@dimen/smallSize" | |||||
android:gravity="center" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintTop_toTopOf="parent" /> | |||||
<ImageView | |||||
android:id="@+id/iv_cancel" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
app:layout_constraintTop_toTopOf="@id/tv_title" | |||||
app:layout_constraintBottom_toBottomOf="@+id/tv_title" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
android:src="@drawable/ic_delete" | |||||
android:layout_marginEnd="24dp" /> | |||||
<View | |||||
android:id="@+id/v_line" | |||||
android:layout_width="match_parent" | |||||
android:layout_height="@dimen/line_height" | |||||
android:background="@color/gray_1" | |||||
app:layout_constraintTop_toBottomOf="@+id/tv_title" /> | |||||
<androidx.recyclerview.widget.RecyclerView | |||||
android:id="@+id/rv_repeat" | |||||
android:layout_width="match_parent" | |||||
android:layout_height="wrap_content" | |||||
app:layout_constraintTop_toBottomOf="@id/v_line" | |||||
android:overScrollMode="never" | |||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" | |||||
android:orientation="vertical"/> | |||||
</androidx.constraintlayout.widget.ConstraintLayout> | |||||
</layout> |
<?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"> | |||||
<data> | |||||
</data> | |||||
<androidx.constraintlayout.widget.ConstraintLayout | |||||
android:layout_width="match_parent" | |||||
android:layout_height="match_parent" | |||||
android:background="@drawable/shape_rounder_toplr_24_white"> | |||||
<TextView | |||||
android:id="@+id/tv_title" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="46dp" | |||||
android:gravity="center" | |||||
android:text="@string/please_select_the_operation_you_want_to_do" | |||||
android:textColor="@color/gray_2" | |||||
android:textSize="@dimen/smallSize" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintTop_toTopOf="parent" /> | |||||
<ImageView | |||||
android:id="@+id/iv_cancel" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
android:layout_marginEnd="24dp" | |||||
android:src="@drawable/ic_delete" | |||||
app:layout_constraintBottom_toBottomOf="@+id/tv_title" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintTop_toTopOf="@id/tv_title" /> | |||||
<View | |||||
android:id="@+id/v_line" | |||||
android:layout_width="match_parent" | |||||
android:layout_height="@dimen/line_height" | |||||
android:background="@color/gray_1" | |||||
app:layout_constraintTop_toBottomOf="@+id/tv_title" /> | |||||
<TextView | |||||
android:id="@+id/tv_auto_play" | |||||
android:layout_width="match_parent" | |||||
android:layout_height="48dp" | |||||
android:gravity="center" | |||||
android:text="@string/auto_play_the_words_learned" | |||||
android:textColor="@color/main_text_color" | |||||
android:textSize="@dimen/normalSize" | |||||
app:layout_constraintTop_toBottomOf="@+id/v_line" /> | |||||
<TextView | |||||
android:id="@+id/tv_clear_learn_record" | |||||
android:layout_width="match_parent" | |||||
android:layout_height="48dp" | |||||
android:gravity="center" | |||||
android:text="@string/clear_learn_record" | |||||
android:textColor="@color/main_text_color" | |||||
android:textSize="@dimen/normalSize" | |||||
app:layout_constraintTop_toBottomOf="@+id/tv_auto_play" /> | |||||
</androidx.constraintlayout.widget.ConstraintLayout> | |||||
</layout> |
<?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"> | |||||
<TextView | |||||
android:id="@+id/tv_option" | |||||
android:layout_width="match_parent" | |||||
android:layout_height="48dp" | |||||
android:textColor="@color/gray_2" | |||||
android:textSize="@dimen/normalSize" | |||||
tools:text="重复次数" | |||||
android:gravity="center" | |||||
app:layout_constraintTop_toTopOf="parent" | |||||
/> | |||||
</androidx.constraintlayout.widget.ConstraintLayout> | |||||
</layout> |
<?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="300dp" | |||||
android:layout_height="wrap_content"> | |||||
<androidx.constraintlayout.widget.ConstraintLayout | |||||
android:layout_width="match_parent" | |||||
android:layout_height="0dp" | |||||
android:layout_marginTop="76dp" | |||||
android:background="@drawable/shape_rounder_12_white" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintHorizontal_bias="0.0" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintTop_toTopOf="parent"> | |||||
<ImageView | |||||
android:id="@+id/iv_close" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
android:layout_marginTop="8dp" | |||||
android:layout_marginEnd="8dp" | |||||
android:src="@drawable/ic_delete" | |||||
android:visibility="gone" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintTop_toTopOf="parent" | |||||
tools:visibility="visible" /> | |||||
<TextView | |||||
android:id="@+id/tv_score" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
android:layout_marginTop="80dp" | |||||
android:textColor="@color/theme_color" | |||||
android:textSize="28dp" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintTop_toTopOf="parent" | |||||
tools:text="%d分" | |||||
android:visibility="gone" | |||||
tools:visibility="visible"/> | |||||
<TextView | |||||
android:id="@+id/tv_tip" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
android:text="@string/current_test_score" | |||||
android:textColor="@color/gray_2" | |||||
android:textSize="@dimen/miniSize" | |||||
app:layout_constraintEnd_toEndOf="@+id/tv_score" | |||||
app:layout_constraintStart_toStartOf="@+id/tv_score" | |||||
app:layout_constraintTop_toBottomOf="@+id/tv_score" | |||||
android:visibility="gone" | |||||
tools:visibility="visible"/> | |||||
<TextView | |||||
android:id="@+id/tv_title" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
android:layout_marginTop="12dp" | |||||
app:layout_goneMarginTop="80dp" | |||||
android:textColor="@color/main_text_color" | |||||
android:textSize="@dimen/smallSize" | |||||
android:textStyle="bold" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintTop_toBottomOf="@+id/tv_tip" | |||||
tools:text="课时学前测试" /> | |||||
<TextView | |||||
android:id="@+id/tv_lesson_name" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
android:layout_marginTop="8dp" | |||||
android:gravity="center" | |||||
android:paddingStart="@dimen/global_spacing" | |||||
android:paddingEnd="@dimen/global_spacing" | |||||
android:textColor="@color/theme_color" | |||||
android:textSize="@dimen/miniSize" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintTop_toBottomOf="@+id/tv_title" | |||||
tools:text="[%s%s]"/> | |||||
<TextView | |||||
android:id="@+id/tv_count_time" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
android:layout_marginTop="4dp" | |||||
android:textColor="@color/gray_2" | |||||
android:textSize="@dimen/miniSize" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintTop_toBottomOf="@+id/tv_lesson_name" | |||||
tools:text="@string/test_count_time_format"/> | |||||
<TextView | |||||
android:id="@+id/tv_tip_1" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
android:layout_marginTop="4dp" | |||||
android:textColor="@color/gray_2" | |||||
android:textSize="@dimen/miniSize" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintTop_toBottomOf="@+id/tv_title" | |||||
tools:text="@string/test_before_test_over_tip" | |||||
android:visibility="gone" | |||||
tools:visibility="visible"/> | |||||
<include | |||||
android:id="@+id/inc_statistics_number" | |||||
layout="@layout/inc_over_number" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintTop_toBottomOf="@+id/tv_tip_1" | |||||
android:visibility="gone"/> | |||||
<androidx.constraintlayout.widget.Barrier | |||||
android:id="@+id/barrier" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
app:barrierDirection="bottom" | |||||
app:barrierMargin="@dimen/miniSize" | |||||
app:constraint_referenced_ids="tv_count_time,inc_statistics_number" /> | |||||
<View | |||||
android:id="@+id/bottom_top_line" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="@dimen/line_height" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
android:background="@color/gray_3" | |||||
app:layout_constraintTop_toBottomOf="@+id/barrier" /> | |||||
<!--一直显示的按钮: 即常驻按钮 --> | |||||
<TextView | |||||
android:id="@+id/tv_right" | |||||
android:layout_width="0dp" | |||||
android:layout_height="40dp" | |||||
android:gravity="center" | |||||
android:text="@string/start_test" | |||||
android:textColor="@color/theme_color" | |||||
android:textSize="@dimen/smallSize" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintTop_toBottomOf="@+id/bottom_top_line" | |||||
app:layout_constraintStart_toEndOf="@id/vSplit" | |||||
/> | |||||
<View | |||||
android:id="@+id/vSplit" | |||||
android:layout_width="@dimen/line_height" | |||||
android:layout_height="0dp" | |||||
app:layout_constraintEnd_toStartOf="@+id/tv_right" | |||||
app:layout_constraintStart_toEndOf="@+id/tv_left" | |||||
android:background="@color/gray_3" | |||||
app:layout_constraintTop_toTopOf="@+id/tv_right" | |||||
app:layout_constraintBottom_toBottomOf="@+id/tv_right" /> | |||||
<!--左边按钮--> | |||||
<TextView | |||||
android:id="@+id/tv_left" | |||||
android:layout_width="0dp" | |||||
android:layout_height="40dp" | |||||
android:gravity="center" | |||||
android:text="@string/start_test" | |||||
android:textColor="@color/main_text_color" | |||||
android:textSize="@dimen/smallSize" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintEnd_toStartOf="@+id/vSplit" | |||||
app:layout_constraintTop_toTopOf="@+id/vSplit" | |||||
app:layout_constraintBottom_toBottomOf="@+id/vSplit" | |||||
android:visibility="gone" | |||||
/> | |||||
</androidx.constraintlayout.widget.ConstraintLayout> | |||||
<ImageView | |||||
android:id="@+id/img_iv" | |||||
android:layout_width="160dp" | |||||
android:layout_height="160dp" | |||||
android:layout_centerHorizontal="true" | |||||
app:layout_constraintTop_toTopOf="parent" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
android:src="@mipmap/girl_2" | |||||
/> | |||||
</androidx.constraintlayout.widget.ConstraintLayout> | |||||
</layout> |
<?xml version="1.0" encoding="utf-8"?> | |||||
<layout xmlns:android="http://schemas.android.com/apk/res/android" | |||||
xmlns:app="http://schemas.android.com/apk/res-auto" | |||||
xmlns:tools="http://schemas.android.com/tools"> | |||||
<data> | |||||
</data> | |||||
<androidx.constraintlayout.widget.ConstraintLayout | |||||
android:layout_width="match_parent" | |||||
android:layout_height="match_parent" | |||||
tools:context=".module.m_center_learn.coursechildren.CourseLessonFragment"> | |||||
<!-- LinearLayout 仅在口语课程时显示--> | |||||
<LinearLayout | |||||
android:id="@+id/spoken_top_layout" | |||||
android:layout_width="0dp" | |||||
android:layout_height="wrap_content" | |||||
android:background="@color/gray_3" | |||||
android:orientation="horizontal" | |||||
android:visibility="gone" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintTop_toTopOf="parent" | |||||
tools:visibility="visible"> | |||||
<TextView | |||||
android:id="@+id/tv_auto_dialogue" | |||||
android:layout_width="0dp" | |||||
android:layout_height="match_parent" | |||||
android:layout_weight="1" | |||||
android:gravity="center" | |||||
android:paddingTop="8dp" | |||||
android:paddingBottom="8dp" | |||||
android:text="@string/english_spoken_pattern_auto_play" | |||||
android:textColor="@color/selectpress_maintextcolor_to_themcolor" | |||||
android:textSize="@dimen/normalSize" /> | |||||
<TextView | |||||
android:id="@+id/tv_follow_dialogue" | |||||
android:layout_width="0dp" | |||||
android:layout_height="match_parent" | |||||
android:layout_weight="1" | |||||
android:gravity="center" | |||||
android:paddingTop="8dp" | |||||
android:paddingBottom="8dp" | |||||
android:text="@string/english_spoken_pattern_follow" | |||||
android:textColor="@color/selectpress_maintextcolor_to_themcolor" | |||||
android:textSize="@dimen/normalSize" /> | |||||
</LinearLayout> | |||||
<androidx.recyclerview.widget.RecyclerView | |||||
android:id="@+id/recyclerView" | |||||
android:layout_width="0dp" | |||||
android:layout_height="0dp" | |||||
android:overScrollMode="never" | |||||
android:scrollbars="none" | |||||
app:layout_constraintBottom_toBottomOf="parent" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintTop_toBottomOf="@+id/spoken_top_layout" /> | |||||
</androidx.constraintlayout.widget.ConstraintLayout> | |||||
</layout> |
<?xml version="1.0" encoding="utf-8"?> | |||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" | |||||
xmlns:tools="http://schemas.android.com/tools" | |||||
android:id="@+id/layout_root" | |||||
android:layout_width="match_parent" | |||||
android:layout_height="match_parent" | |||||
tools:context=".module.m_center_learn.coursechildren.CourseMainFragment"> | |||||
</FrameLayout> |
<?xml version="1.0" encoding="utf-8"?> | |||||
<layout xmlns:android="http://schemas.android.com/apk/res/android" | |||||
xmlns:app="http://schemas.android.com/apk/res-auto" | |||||
xmlns:tools="http://schemas.android.com/tools"> | |||||
<data> | |||||
</data> | |||||
<androidx.constraintlayout.widget.ConstraintLayout | |||||
android:layout_width="match_parent" | |||||
android:layout_height="match_parent" | |||||
tools:context=".module.m_center_learn.coursechildren.CourseReviewFragment"> | |||||
<ImageView | |||||
android:id="@+id/iv_icon" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
android:src="@mipmap/boy_3" | |||||
app:layout_constraintBottom_toTopOf="@+id/tv_tips" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintHorizontal_bias="0.497" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintTop_toTopOf="parent" | |||||
app:layout_constraintVertical_bias="0.2" | |||||
app:layout_constraintVertical_chainStyle="packed"/> | |||||
<TextView | |||||
android:id="@+id/tv_tips" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
android:layout_marginTop="12dp" | |||||
android:textColor="@color/main_text_color" | |||||
android:textSize="@dimen/normalSize" | |||||
android:textStyle="bold" | |||||
app:layout_constraintBottom_toTopOf="@+id/tv_start_review" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintTop_toBottomOf="@+id/iv_icon" | |||||
tools:text="你将进行智能复习/你将进行[%s]课程智能复习" /> | |||||
<TextView | |||||
android:id="@+id/tv_review_count" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
android:layout_marginTop="4dp" | |||||
android:textColor="@color/main_text_color" | |||||
android:textSize="@dimen/smallSize" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintTop_toBottomOf="@+id/tv_tips" | |||||
tools:text="本次智能复习数%d" /> | |||||
<Button | |||||
android:id="@+id/tv_start_review" | |||||
style="@style/common_button_style" | |||||
android:text="@string/start_review" | |||||
app:cornerRadius="8dp" | |||||
app:layout_constraintBottom_toBottomOf="parent" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintTop_toBottomOf="@+id/tv_tips" /> | |||||
</androidx.constraintlayout.widget.ConstraintLayout> | |||||
</layout> |
<?xml version="1.0" encoding="utf-8"?> | |||||
<layout xmlns:android="http://schemas.android.com/apk/res/android" | |||||
xmlns:app="http://schemas.android.com/apk/res-auto" | |||||
xmlns:tools="http://schemas.android.com/tools"> | |||||
<data> | |||||
</data> | |||||
<androidx.constraintlayout.widget.ConstraintLayout | |||||
android:layout_width="match_parent" | |||||
android:layout_height="match_parent" | |||||
android:background="@color/white" | |||||
tools:context=".module.m_center_learn.coursechildren.CourseTotalTestFragment"> | |||||
<ImageView | |||||
android:id="@+id/iv_icon" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
android:src="@mipmap/boy_1" | |||||
app:layout_constraintBottom_toTopOf="@+id/tv_title" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintTop_toTopOf="parent" | |||||
app:layout_constraintVertical_bias="0.2" | |||||
app:layout_constraintVertical_chainStyle="packed" /> | |||||
<TextView | |||||
android:id="@+id/tv_title" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
android:layout_marginTop="12dp" | |||||
android:text="@string/test_total_after_tip_1" | |||||
android:textColor="@color/main_text_color" | |||||
android:textSize="@dimen/normalSize" | |||||
android:textStyle="bold" | |||||
app:layout_constraintBottom_toTopOf="@+id/tv_main_tip" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintTop_toBottomOf="@+id/iv_icon" | |||||
android:visibility="visible" /> | |||||
<TextView | |||||
android:id="@+id/tv_main_tip" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
android:layout_marginTop="12dp" | |||||
android:text="@string/test_total_before_title" | |||||
android:textColor="@color/main_text_color" | |||||
android:textSize="@dimen/normalSize" | |||||
app:layout_constraintBottom_toTopOf="@+id/tv_tips" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintTop_toBottomOf="@+id/tv_title" | |||||
android:visibility="gone" | |||||
tools:visibility="visible"/> | |||||
<TextView | |||||
android:id="@+id/tv_tips" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
android:layout_marginTop="4dp" | |||||
android:text="@string/test_total_after_tip_3" | |||||
android:textColor="@color/gray_2" | |||||
android:textSize="@dimen/smallSize" | |||||
app:layout_constraintBottom_toTopOf="@+id/tv_count_tip" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintTop_toBottomOf="@+id/tv_main_tip" | |||||
android:visibility="gone" | |||||
tools:visibility="visible"/> | |||||
<TextView | |||||
android:id="@+id/tv_count_tip" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
android:layout_marginTop="4dp" | |||||
android:textColor="@color/theme_color" | |||||
android:textSize="@dimen/smallSize" | |||||
app:layout_constraintBottom_toTopOf="@+id/button_2" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintTop_toBottomOf="@+id/tv_tips" | |||||
tools:text="@string/test_count_time_format" /> | |||||
<Button | |||||
android:id="@+id/button_1" | |||||
style="@style/Widget.MaterialComponents.Button.UnelevatedButton" | |||||
android:layout_width="0dp" | |||||
android:layout_height="@dimen/common_button_height" | |||||
android:layout_marginStart="@dimen/global_spacing" | |||||
android:insetTop="0dp" | |||||
android:insetBottom="0dp" | |||||
app:cornerRadius="8dp" | |||||
android:textColor="@color/theme_color" | |||||
android:textSize="@dimen/smallSize" | |||||
app:layout_constraintEnd_toStartOf="@+id/button_2" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintTop_toTopOf="@+id/button_2" | |||||
app:strokeColor="@color/theme_color" | |||||
app:strokeWidth="@dimen/line_height" | |||||
android:visibility="gone" | |||||
tools:visibility="visible"/> | |||||
<Button | |||||
android:id="@+id/button_2" | |||||
style="@style/common_button_style" | |||||
android:layout_width="0dp" | |||||
android:layout_height="@dimen/common_button_height" | |||||
android:layout_marginStart="12dp" | |||||
android:layout_marginTop="40dp" | |||||
android:layout_marginEnd="@dimen/global_spacing" | |||||
app:cornerRadius="8dp" | |||||
app:layout_constraintBottom_toBottomOf="parent" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintStart_toEndOf="@+id/button_1" | |||||
app:layout_constraintTop_toBottomOf="@+id/tv_count_tip" | |||||
app:layout_goneMarginStart="@dimen/global_spacing" /> | |||||
<TextView | |||||
android:id="@+id/tv_clear_learn_record" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
android:layout_marginTop="24dp" | |||||
android:text="@string/clear_learn_record" | |||||
android:textColor="@color/gray_2" | |||||
android:textSize="@dimen/smallSize" | |||||
android:visibility="gone" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintTop_toBottomOf="@+id/button_2" | |||||
tools:visibility="visible"/> | |||||
</androidx.constraintlayout.widget.ConstraintLayout> | |||||
</layout> |
<?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="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
tools:showIn="@layout/dialog_lesson_learn"> | |||||
<androidx.constraintlayout.widget.Guideline | |||||
android:id="@+id/guideline_1" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
android:orientation="vertical" | |||||
app:layout_constraintGuide_percent="0.5" /> | |||||
<TextView | |||||
android:id="@+id/tv_correct_tip" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
android:layout_marginTop="8dp" | |||||
android:layout_marginRight="28dp" | |||||
android:text="@string/correct" | |||||
android:textColor="@color/main_text_color" | |||||
android:textSize="@dimen/miniSize" | |||||
app:layout_constraintEnd_toEndOf="@+id/guideline_1" | |||||
app:layout_constraintTop_toTopOf="parent" /> | |||||
<TextView | |||||
android:id="@+id/tv_error_tip" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
android:layout_marginStart="28dp" | |||||
android:layout_marginTop="8dp" | |||||
android:text="@string/error" | |||||
android:textColor="@color/gray_2" | |||||
android:textSize="@dimen/miniSize" | |||||
app:layout_constraintStart_toEndOf="@+id/guideline_1" | |||||
app:layout_constraintTop_toTopOf="parent" /> | |||||
<TextView | |||||
android:id="@+id/tv_correct_number" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
android:layout_marginTop="4dp" | |||||
android:textColor="@color/green_1" | |||||
android:textSize="@dimen/bigSize" | |||||
android:textStyle="bold" | |||||
app:layout_constraintEnd_toEndOf="@+id/tv_correct_tip" | |||||
app:layout_constraintStart_toStartOf="@+id/tv_correct_tip" | |||||
app:layout_constraintTop_toBottomOf="@+id/tv_correct_tip" | |||||
tools:text="20" /> | |||||
<TextView | |||||
android:id="@+id/tv_error_number" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
android:layout_marginTop="4dp" | |||||
android:textColor="@color/red_1" | |||||
android:textSize="@dimen/bigSize" | |||||
android:textStyle="bold" | |||||
app:layout_constraintEnd_toEndOf="@+id/tv_error_tip" | |||||
app:layout_constraintStart_toStartOf="@+id/tv_error_tip" | |||||
app:layout_constraintTop_toBottomOf="@+id/tv_error_tip" | |||||
tools:text="0" /> | |||||
</androidx.constraintlayout.widget.ConstraintLayout> | |||||
</layout> |
<?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="28dp" | |||||
android:background="@color/gray_3" | |||||
android:paddingStart="@dimen/global_spacing" | |||||
android:paddingEnd="@dimen/global_spacing" | |||||
tools:showIn="@layout/activity_course_main"> | |||||
<TextView | |||||
android:id="@+id/tv_progress" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
android:textColor="@color/theme_color" | |||||
android:textSize="@dimen/miniSize" | |||||
app:layout_constraintBottom_toBottomOf="parent" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintTop_toTopOf="parent" | |||||
tools:text="%s学习进度: %d%" /> | |||||
<ProgressBar | |||||
android:id="@+id/progressbar" | |||||
style="@android:style/Widget.ProgressBar.Horizontal" | |||||
android:layout_width="0dp" | |||||
android:layout_height="4dp" | |||||
android:layout_marginStart="26dp" | |||||
android:layout_marginEnd="26dp" | |||||
android:layout_weight="1" | |||||
android:max="1000" | |||||
android:progressDrawable="@drawable/progress_center" | |||||
app:layout_constraintBottom_toBottomOf="parent" | |||||
app:layout_constraintEnd_toStartOf="@+id/iv_more" | |||||
app:layout_constraintStart_toEndOf="@+id/tv_progress" | |||||
app:layout_constraintTop_toTopOf="parent" /> | |||||
<com.google.android.material.imageview.ShapeableImageView | |||||
android:id="@+id/iv_more" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
android:src="@drawable/ic_more" | |||||
app:layout_constraintBottom_toBottomOf="parent" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintStart_toEndOf="@+id/progressbar" | |||||
app:layout_constraintTop_toTopOf="parent" /> | |||||
</androidx.constraintlayout.widget.ConstraintLayout> | |||||
xmlns:tools="http://schemas.android.com/tools"> | |||||
<data> | |||||
</data> | |||||
<androidx.constraintlayout.widget.ConstraintLayout | |||||
android:layout_width="match_parent" | |||||
android:layout_height="28dp" | |||||
android:background="@color/gray_3" | |||||
android:paddingStart="@dimen/global_spacing" | |||||
android:paddingEnd="@dimen/global_spacing" | |||||
tools:showIn="@layout/activity_course_main"> | |||||
<TextView | |||||
android:id="@+id/tv_progress" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
android:textColor="@color/theme_color" | |||||
android:textSize="@dimen/miniSize" | |||||
app:layout_constraintBottom_toBottomOf="parent" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintTop_toTopOf="parent" | |||||
tools:text="%s学习进度: %d%" /> | |||||
<ProgressBar | |||||
android:id="@+id/progressbar" | |||||
style="@android:style/Widget.ProgressBar.Horizontal" | |||||
android:layout_width="0dp" | |||||
android:layout_height="4dp" | |||||
android:layout_marginStart="26dp" | |||||
android:layout_marginEnd="26dp" | |||||
android:layout_weight="1" | |||||
android:max="1000" | |||||
android:progressDrawable="@drawable/progress_center" | |||||
app:layout_constraintBottom_toBottomOf="parent" | |||||
app:layout_constraintEnd_toStartOf="@+id/iv_more" | |||||
app:layout_constraintStart_toEndOf="@+id/tv_progress" | |||||
app:layout_constraintTop_toTopOf="parent" /> | |||||
<com.google.android.material.imageview.ShapeableImageView | |||||
android:id="@+id/iv_more" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
android:src="@drawable/ic_more" | |||||
app:layout_constraintBottom_toBottomOf="parent" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintStart_toEndOf="@+id/progressbar" | |||||
app:layout_constraintTop_toTopOf="parent" /> | |||||
</androidx.constraintlayout.widget.ConstraintLayout> | |||||
</layout> | |||||
android:drawableStart="@drawable/ic_discern" | android:drawableStart="@drawable/ic_discern" | ||||
android:text="认读" | android:text="认读" | ||||
bind:svgColor="@{@color/theme_color}" | bind:svgColor="@{@color/theme_color}" | ||||
android:textColor="@color/theme_color" | |||||
app:layout_constraintStart_toStartOf="parent" | app:layout_constraintStart_toStartOf="parent" | ||||
app:layout_constraintTop_toTopOf="parent" | app:layout_constraintTop_toTopOf="parent" | ||||
app:layout_constraintBottom_toBottomOf="parent" | app:layout_constraintBottom_toBottomOf="parent" | ||||
app:layout_constraintEnd_toStartOf="@+id/iv_arrow_1" | app:layout_constraintEnd_toStartOf="@+id/iv_arrow_1" | ||||
android:gravity="center" | android:gravity="center" | ||||
android:drawablePadding="4dp" /> | |||||
android:drawablePadding="4dp" | |||||
android:visibility="gone" | |||||
tools:visibility="visible"/> | |||||
<ImageView | <ImageView | ||||
android:id="@+id/iv_arrow_1" | android:id="@+id/iv_arrow_1" | ||||
android:layout_height="match_parent" | android:layout_height="match_parent" | ||||
android:drawableStart="@drawable/ic_spell" | android:drawableStart="@drawable/ic_spell" | ||||
bind:svgColor="@{@color/theme_color}" | bind:svgColor="@{@color/theme_color}" | ||||
android:textColor="@color/theme_color" | |||||
android:text="拼写" | android:text="拼写" | ||||
app:layout_constraintStart_toEndOf="@+id/iv_arrow_1" | app:layout_constraintStart_toEndOf="@+id/iv_arrow_1" | ||||
app:layout_constraintTop_toTopOf="parent" | app:layout_constraintTop_toTopOf="parent" | ||||
app:layout_constraintBottom_toBottomOf="parent" | app:layout_constraintBottom_toBottomOf="parent" | ||||
app:layout_constraintEnd_toStartOf="@+id/iv_arrow_2" | app:layout_constraintEnd_toStartOf="@+id/iv_arrow_2" | ||||
android:gravity="center" | android:gravity="center" | ||||
android:drawablePadding="4dp" /> | |||||
android:drawablePadding="4dp" | |||||
android:visibility="gone" | |||||
tools:visibility="visible"/> | |||||
<ImageView | <ImageView | ||||
android:id="@+id/iv_arrow_2" | android:id="@+id/iv_arrow_2" | ||||
android:drawableStart="@drawable/ic_voice" | android:drawableStart="@drawable/ic_voice" | ||||
android:text="辨音" | android:text="辨音" | ||||
bind:svgColor="@{@color/theme_color}" | bind:svgColor="@{@color/theme_color}" | ||||
android:textColor="@color/theme_color" | |||||
app:layout_constraintStart_toEndOf="@+id/iv_arrow_2" | app:layout_constraintStart_toEndOf="@+id/iv_arrow_2" | ||||
app:layout_constraintTop_toTopOf="parent" | app:layout_constraintTop_toTopOf="parent" | ||||
app:layout_constraintBottom_toBottomOf="parent" | app:layout_constraintBottom_toBottomOf="parent" | ||||
app:layout_constraintEnd_toEndOf="parent" | app:layout_constraintEnd_toEndOf="parent" | ||||
android:gravity="center" | android:gravity="center" | ||||
android:drawablePadding="4dp" /> | |||||
android:drawablePadding="4dp" | |||||
android:visibility="gone" | |||||
tools:visibility="visible"/> | |||||
</androidx.constraintlayout.widget.ConstraintLayout> | </androidx.constraintlayout.widget.ConstraintLayout> | ||||
</layout> | </layout> |
<layout xmlns:android="http://schemas.android.com/apk/res/android" | <layout xmlns:android="http://schemas.android.com/apk/res/android" | ||||
xmlns:tools="http://schemas.android.com/tools" | xmlns:tools="http://schemas.android.com/tools" | ||||
xmlns:app="http://schemas.android.com/apk/res-auto"> | xmlns:app="http://schemas.android.com/apk/res-auto"> | ||||
<!--使用bind添加属性值最好添加一个默认值,否则会将没有设置的属性设置未默认值,如:设置标题和颜色,如果没有设置颜色默认值,则标题将为透明色--> | |||||
<data> | <data> | ||||
<variable | <variable | ||||
name="title" | |||||
name="titleValue" | |||||
type="java.lang.String" /> | type="java.lang.String" /> | ||||
<variable | |||||
name="titleColor" | |||||
type="Integer" /> | |||||
</data> | </data> | ||||
<com.suliang.common.widget.TitleBar | <com.suliang.common.widget.TitleBar | ||||
app:layout_constraintTop_toTopOf="parent" | app:layout_constraintTop_toTopOf="parent" | ||||
app:layout_constraintStart_toStartOf="parent" | app:layout_constraintStart_toStartOf="parent" | ||||
app:layout_constraintEnd_toEndOf="parent" | app:layout_constraintEnd_toEndOf="parent" | ||||
app:titleTextValue="@{title}" | |||||
app:titleTextValue="@{titleValue}" | |||||
app:titleTextColor="@{titleColor??@color/main_text_color}" | |||||
/> | /> | ||||
</layout> | </layout> |
<?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="data" | |||||
type="com.xkl.cdl.data.bean.course.Lesson" /> | |||||
</data> | |||||
<LinearLayout | |||||
android:layout_width="match_parent" | |||||
android:layout_height="wrap_content" | |||||
android:orientation="vertical"> | |||||
<TextView | |||||
android:id="@+id/tv_chapter_name" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
android:textColor="@color/gray_2" | |||||
android:textSize="@dimen/smallSize" | |||||
android:layout_marginStart="@dimen/global_spacing" | |||||
android:layout_marginEnd="@dimen/global_spacing" | |||||
android:paddingTop="8dp" | |||||
android:text="@{data.chapterName}" | |||||
tools:text="unit1" | |||||
android:visibility="gone" | |||||
tools:visibility="visible" /> | |||||
<androidx.constraintlayout.widget.ConstraintLayout | |||||
android:id="@+id/layout_content" | |||||
android:layout_width="match_parent" | |||||
android:layout_height="wrap_content" | |||||
android:paddingTop="5dp" | |||||
android:paddingBottom="5dp"> | |||||
<TextView | |||||
android:id="@+id/tv_serial_number" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
tools:text="01" | |||||
android:textSize="28dp" | |||||
android:textColor="@color/gray_1" | |||||
android:text='@{String.format("%02d",data.lessonPositionInList + 1)}' | |||||
app:layout_constraintTop_toTopOf="parent" | |||||
app:layout_constraintBottom_toBottomOf="parent" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
android:layout_marginStart="@dimen/global_spacing"/> | |||||
<com.google.android.material.imageview.ShapeableImageView | |||||
android:id="@+id/iv_arrow_right" | |||||
android:layout_width="36dp" | |||||
android:layout_height="36dp" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintTop_toTopOf="parent" | |||||
app:layout_constraintBottom_toBottomOf="parent" | |||||
android:layout_marginEnd="@dimen/global_spacing" | |||||
android:scaleType="centerInside" | |||||
android:src="@drawable/ic_arrow_right" | |||||
app:shapeAppearance="@style/roundedCornerStyle" | |||||
app:strokeColor="@color/gray_2" | |||||
app:strokeWidth="@dimen/line_height" | |||||
android:padding="@dimen/line_height" | |||||
/> | |||||
<TextView | |||||
android:id="@+id/tv_lesson_name" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
tools:text="单词体验课01" | |||||
android:textSize="@dimen/normalSize" | |||||
android:textColor="@color/gray_2" | |||||
android:layout_marginStart="@dimen/global_spacing" | |||||
app:layout_constraintStart_toEndOf="@+id/tv_serial_number" | |||||
app:layout_constraintEnd_toStartOf="@+id/iv_arrow_right" | |||||
app:layout_constraintTop_toTopOf="parent" | |||||
app:layout_constraintBottom_toTopOf="@+id/tv_lesson_number" | |||||
app:layout_constraintHorizontal_bias="0" | |||||
app:layout_constraintVertical_chainStyle="packed" | |||||
android:text="@{data.lessonName}"/> | |||||
<TextView | |||||
android:id="@+id/tv_lesson_number" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
app:layout_constraintStart_toStartOf="@+id/tv_lesson_name" | |||||
app:layout_constraintTop_toBottomOf="@+id/tv_lesson_name" | |||||
app:layout_constraintEnd_toEndOf="@+id/iv_arrow_right" | |||||
app:layout_constraintBottom_toBottomOf="parent" | |||||
app:layout_constraintHorizontal_bias="0" | |||||
tools:text="@string/lesson_number_format" | |||||
android:text="@{@string/lesson_number_format(data.totalNumber,data.correctNumber,data.errorNumber)}"/> | |||||
</androidx.constraintlayout.widget.ConstraintLayout> | |||||
</LinearLayout> | |||||
</layout> |
<variable | <variable | ||||
name="coursePack" | name="coursePack" | ||||
type="com.xkl.cdl.data.course.CoursePack" /> | |||||
type="com.xkl.cdl.data.bean.course.CoursePack" /> | |||||
</data> | </data> | ||||
<resources> | |||||
<dimen name="fab_margin">48dp</dimen> | |||||
</resources> |
<resources> | |||||
<dimen name="fab_margin">200dp</dimen> | |||||
</resources> |
<resources> | |||||
<dimen name="fab_margin">48dp</dimen> | |||||
</resources> |
<color name="theme_color">#FF5082E6</color> | <color name="theme_color">#FF5082E6</color> | ||||
<color name="main_text_color">#323233</color> | <color name="main_text_color">#323233</color> | ||||
<color name="translation">#00000000</color> | |||||
<color name="gray_1">#FFE6E6E6</color> | <color name="gray_1">#FFE6E6E6</color> | ||||
<color name="gray_2">#8A8A99</color> | <color name="gray_2">#8A8A99</color> | ||||
<color name="white">#FFFFFFFF</color> | <color name="white">#FFFFFFFF</color> | ||||
<color name="blue_1">#52CC52</color> | <color name="blue_1">#52CC52</color> | ||||
<color name="gray_3">#FAFAFA</color> | <color name="gray_3">#FAFAFA</color> | ||||
<color name="green_1">#40A540</color> | <color name="green_1">#40A540</color> | ||||
<color name="red_1">#FFF26255</color> | |||||
<color name="num0">#E50213</color> | |||||
<color name="num1">#E50251</color> | |||||
<color name="num2">#E4560F</color> | |||||
<color name="num3">#7D7530</color> | |||||
<color name="num4">#048F3A</color> | |||||
<color name="num5">#1680C4</color> | |||||
<color name="num6">#014262</color> | |||||
<color name="num7">#505050</color> | |||||
</resources> | </resources> |
<dimen name="biggerSize">20dp</dimen> | <dimen name="biggerSize">20dp</dimen> | ||||
<dimen name="title_bar_height">44dp</dimen> | <dimen name="title_bar_height">44dp</dimen> | ||||
<dimen name="global_spacing">16dp</dimen> | <dimen name="global_spacing">16dp</dimen> | ||||
<dimen name="common_button_height">44dp</dimen> | |||||
<dimen name="fab_margin">16dp</dimen> | |||||
<dimen name="common_dialog_width">300dp</dimen> | |||||
</resources> | </resources> |
<string name="empty_nothing_search">没有搜索到任何内容</string> | <string name="empty_nothing_search">没有搜索到任何内容</string> | ||||
<string name="course_detail">课程详情</string> | <string name="course_detail">课程详情</string> | ||||
<string name="introduction">简介</string> | <string name="introduction">简介</string> | ||||
<string name="start_review">开始复习</string> | |||||
<string name="please_select_the_operation_you_want_to_do">请选择你要进行的操作</string> | |||||
<string name="auto_play_the_words_learned">自动播放已学单词</string> | |||||
<string name="clear_learn_record">清空学习记录</string> | |||||
<string name="auto_play_repeat_1">重复1次</string> | |||||
<string name="auto_play_repeat_2">重复2次</string> | |||||
<string name="auto_play_repeat_3">重复3次</string> | |||||
<string name="auto_play_repeat_4">重复4次</string> | |||||
<string name="auto_play_repeat_5">重复5次</string> | |||||
<string name="english_spoken_pattern_auto_play">自动播放</string> | |||||
<string name="english_spoken_pattern_follow">跟读模式</string> | |||||
<string name="lesson_number_format">条目%d - 正确%d | 错误%d</string> | |||||
<string name="test_total_before_title">我当前掌握的知识量量是?去学前总测试一下吧!</string> | |||||
<string name="test_count_time_format">共%1$d题,预计%2$d分钟</string> | |||||
<string name="tips_current_course_learn_over">本课程学习完毕</string> | |||||
<string name="test_total_after_tip_1">我的学习效果是?快去学后总测试吧!</string> | |||||
<string name="test_total_after_tip_2">你还未通过学后总测试,上次得分:</string> | |||||
<string name="test_total_after_tip_3">系统将为你安排智能复习</string> | |||||
<string name="start_test">开始测试</string> | |||||
<string name="continue_learn">继续学习</string> | |||||
<string name="test_again">再测一次</string> | |||||
<string name="test_type_after_total">学后总测试</string> | |||||
<string name="title_activity_learn_base">LearnBaseActivity</string> | |||||
<!-- Strings used for fragments for navigation --> | |||||
<string name="first_fragment_label">First Fragment</string> | |||||
<string name="second_fragment_label">Second Fragment</string> | |||||
<string name="next">Next</string> | |||||
<string name="previous">Previous</string> | |||||
<string name="hello_first_fragment">Hello first fragment</string> | |||||
<string name="hello_second_fragment">Hello second fragment. Arg: %1$s</string> | |||||
<string name="current_test_score">本次测试成绩</string> | |||||
<string name="test_before_test_over_tip">测试成绩不理想?别分心,学考乐让你快速提分!</string> | |||||
<string name="correct">正确</string> | |||||
<string name="error">错误</string> | |||||
<string name="start_learn">开始学习</string> | |||||
</resources> | </resources> |
<item name="cornerSize">8dp</item> | <item name="cornerSize">8dp</item> | ||||
</style> | </style> | ||||
<!--通用按钮style https://blog.csdn.net/weixin_42046829/article/details/110224702 | |||||
https://www.jianshu.com/p/bc71b4179cb2--> | |||||
<style name="common_button_style" parent="Widget.MaterialComponents.Button.UnelevatedButton"> | |||||
<item name="android:layout_width">0dp</item> | |||||
<item name="android:layout_height">@dimen/common_button_height</item> | |||||
<item name="android:gravity">center</item> | |||||
<item name="android:insetTop">0dp</item> | |||||
<item name="android:insetBottom">0dp</item> | |||||
<item name="android:textSize">@dimen/smallSize</item> | |||||
<item name="android:textColor">@color/white</item> | |||||
<item name="android:layout_marginStart">38dp</item> | |||||
<item name="android:layout_marginEnd">38dp</item> | |||||
<item name="android:layout_marginTop">66dp</item> | |||||
<item name="android:backgroundTint">@color/theme_color</item> | |||||
</style> | |||||
<!--dialog style --> | |||||
<style name="dialog_style" parent="@android:style/Theme.Dialog"> | |||||
<item name="android:windowBackground">@android:color/transparent</item> <!--窗口背景透明--> | |||||
<item name="android:windowFrame">@null</item> <!--边框--> | |||||
<item name="android:windowNoTitle">true</item> <!--无标题--> | |||||
<item name="android:windowIsFloating">true</item> <!--是否浮现在activity之上--> | |||||
<item name="android:windowIsTranslucent">true</item> <!--是否半透明--> | |||||
<item name="android:backgroundDimEnabled">true</item> <!--模糊,背景透明是这个- 弹窗背景是否变暗 --> | |||||
</style> | |||||
</resources> | </resources> |
<style name="Theme.XklLocal" parent="Theme.MaterialComponents.Light.DarkActionBar"> | <style name="Theme.XklLocal" parent="Theme.MaterialComponents.Light.DarkActionBar"> | ||||
<!-- Primary brand color. --> | <!-- Primary brand color. --> | ||||
<item name="colorPrimary">@color/white</item> <!--AppBar背景色--> | <item name="colorPrimary">@color/white</item> <!--AppBar背景色--> | ||||
<!-- <item name="colorPrimaryVariant">@color/white</item>--> | |||||
<!-- <item name="colorPrimaryVariant">@color/white</item>--> | |||||
<item name="colorOnPrimary">@color/black</item> | <item name="colorOnPrimary">@color/black</item> | ||||
<!-- <!– Secondary brand color. –>--> | |||||
<!-- <item name="colorSecondary">@color/white</item>--> | |||||
<!-- <item name="colorSecondaryVariant">@color/white</item>--> | |||||
<!-- <item name="colorOnSecondary">@color/white</item>--> | |||||
<!-- <!– Status bar color. –>--> | |||||
<!-- <!– Secondary brand color. –>--> | |||||
<!-- <item name="colorSecondary">@color/white</item>--> | |||||
<!-- <item name="colorSecondaryVariant">@color/white</item>--> | |||||
<!-- <item name="colorOnSecondary">@color/white</item>--> | |||||
<!-- <!– Status bar color. –>--> | |||||
<item name="android:statusBarColor" tools:targetApi="l">@color/white</item> | <item name="android:statusBarColor" tools:targetApi="l">@color/white</item> | ||||
<!-- Customize your theme here. --> | <!-- Customize your theme here. --> | ||||
<item name="android:textAllCaps">false</item> | <item name="android:textAllCaps">false</item> | ||||
<item name="android:windowBackground">@drawable/theme_splash_bg</item> | <item name="android:windowBackground">@drawable/theme_splash_bg</item> | ||||
</style> | </style> | ||||
<style name="Theme.XklLocal.NoActionBar"> | |||||
<item name="windowActionBar">false</item> | |||||
<item name="windowNoTitle">true</item> | |||||
</style> | |||||
<style name="Theme.XklLocal.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" /> | |||||
<style name="Theme.XklLocal.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" /> | |||||
</resources> | </resources> |
//SmartRefreshLayout | //SmartRefreshLayout | ||||
SmartRefreshLayout: "io.github.scwang90:refresh-layout-kernel:2.0.5", | SmartRefreshLayout: "io.github.scwang90:refresh-layout-kernel:2.0.5", | ||||
//Lottie | //Lottie | ||||
Lottie : "com.airbnb.android:lottie:5.0.3" | |||||
Lottie : "com.airbnb.android:lottie:5.0.3", | |||||
//Rxjava RxAndroid | |||||
RxJava : "io.reactivex.rxjava3:rxjava:3.1.4", | |||||
RxAndroid: "io.reactivex.rxjava3:rxandroid:3.0.0" | |||||
] | ] | ||||
} | } | ||||
dependencies { | dependencies { | ||||
// implementation fileTree(include: ['*.jar',"*.aar"], dir: 'libs') | |||||
implementation 'androidx.legacy:legacy-support-v4:1.0.0' | implementation 'androidx.legacy:legacy-support-v4:1.0.0' | ||||
rootProject.ext.dependencies_required.each{ k, v -> implementation v} | rootProject.ext.dependencies_required.each{ k, v -> implementation v} | ||||
testImplementation rootProject.ext.dependencies_testImplementation.junit | testImplementation rootProject.ext.dependencies_testImplementation.junit | ||||
kapt customDependencies.GlideCompiler | kapt customDependencies.GlideCompiler | ||||
//glide translation | //glide translation | ||||
api customDependencies.GlideTranslation | api customDependencies.GlideTranslation | ||||
//RxJava RxAndroid | |||||
api customDependencies.RxJava | |||||
api customDependencies.RxAndroid | |||||
* create 2022/3/17 17:04 | * create 2022/3/17 17:04 | ||||
* Describe: | * Describe: | ||||
*/ | */ | ||||
object Config { | |||||
object AppConfig { | |||||
const val INTENT_1 = "intent_1" | const val INTENT_1 = "intent_1" | ||||
const val INTENT_2 = "intent_2" | const val INTENT_2 = "intent_2" | ||||
const val INTENT_3 = "intent_3" | const val INTENT_3 = "intent_3" |
abstract fun initFragment() | abstract fun initFragment() | ||||
/** 是否布局背景透明 */ | /** 是否布局背景透明 */ | ||||
abstract fun isTransparent():Boolean | |||||
open fun isTransparent():Boolean { | |||||
return true | |||||
} | |||||
} | } |
package com.suliang.common.base | package com.suliang.common.base | ||||
import android.graphics.drawable.AnimationDrawable | import android.graphics.drawable.AnimationDrawable | ||||
import com.suliang.common.Config | |||||
import com.suliang.common.AppConfig | |||||
import com.suliang.common.databinding.LoadingFragmentBinding | import com.suliang.common.databinding.LoadingFragmentBinding | ||||
/** | /** | ||||
@JvmStatic | @JvmStatic | ||||
fun newInstance(msg : String): LoadingDialog { | fun newInstance(msg : String): LoadingDialog { | ||||
return LoadingDialog().apply { | return LoadingDialog().apply { | ||||
arguments?.putString(Config.INTENT_1,msg) | |||||
arguments?.putString(AppConfig.INTENT_1,msg) | |||||
} | } | ||||
} | } | ||||
} | } | ||||
override fun initFragment() { | override fun initFragment() { | ||||
//外部设置 | //外部设置 | ||||
arguments?.getString(Config.INTENT_1,null)?.let { | |||||
arguments?.getString(AppConfig.INTENT_1,null)?.let { | |||||
binding.loadText.text = it | binding.loadText.text = it | ||||
} | } | ||||