| @@ -53,6 +53,8 @@ | |||
| <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_bottom_course_pack_introducation.xml" value="0.1956521739130435" /> | |||
| <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/dialog_bottom_course_pack_introduction.xml" value="0.21203703703703702" /> | |||
| <entry key="..\:/Work/XKL/XKL/XklLocal/app/src/main/res/layout/dialog_common.xml" value="0.30978260869565216" /> | |||
| <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" /> | |||
| @@ -48,4 +48,8 @@ google 给与的唯一标识符最佳做法: | |||
| 如何实现防快速点击 aspectJ | |||
| SpellTipsLinearLayout onDraw为什么不调用?为什么设置背景后就有效过了? | |||
| 实现dialog动画:从底部进入和从底部滑出 | |||
| DialogFragment原理 | |||
| BottomSheetDialog 固定高度和原理 | |||
| BottomSheetDialog中使用TextView滑动的冲突? | |||
| Behavior | |||
| @@ -22,43 +22,52 @@ import com.xkl.cdl.databinding.IncWordDetailBinding | |||
| * @param refrence String? 参考 | |||
| */ | |||
| @SuppressLint("SetTextI18n") | |||
| fun IncWordDetailBinding.initValue(phrase : String?, example : String?, refrence : String?){ | |||
| phrase?.let { | |||
| tvPhraseFlag.visibility = View.VISIBLE | |||
| layoutPhrase.run { | |||
| visibility = View.VISIBLE | |||
| removeAllViews() | |||
| val params = LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT) | |||
| it.split("\n").forEach { | |||
| val child = TextView(context).apply { | |||
| layoutParams = params | |||
| text = it | |||
| setTextColor(ContextCompat.getColor(context, R.color.main_text_color)) | |||
| setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14f) | |||
| fun IncWordDetailBinding.initValue(phrase : String?, example : String?, refrence : String?) { | |||
| when{ | |||
| phrase.isNullOrEmpty() -> { | |||
| tvPhraseFlag.visibility = View.GONE | |||
| layoutPhrase.visibility = View.GONE | |||
| } | |||
| else -> phrase.let { | |||
| tvPhraseFlag.visibility = View.VISIBLE | |||
| layoutPhrase.run { | |||
| visibility = View.VISIBLE | |||
| removeAllViews() | |||
| val params = LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, | |||
| LinearLayout.LayoutParams.WRAP_CONTENT) | |||
| it.split("\n").forEach { | |||
| val child = TextView(context).apply { | |||
| layoutParams = params | |||
| text = it | |||
| setTextColor(ContextCompat.getColor(context, R.color.main_text_color)) | |||
| setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14f) | |||
| } | |||
| addView(child) | |||
| } | |||
| addView(child) | |||
| } | |||
| } | |||
| }?:let { | |||
| tvPhraseFlag.visibility = View.GONE | |||
| layoutPhrase.visibility = View.GONE | |||
| } | |||
| example?.let { | |||
| tvExampleFlag.visibility = View.VISIBLE | |||
| tvExample.visibility = View.VISIBLE | |||
| tvExample.text = "▪ ${it.replace("\n", "\n▪ ")}" | |||
| }?:let { | |||
| tvExampleFlag.visibility = View.GONE | |||
| tvExample.visibility = View.GONE | |||
| when{ | |||
| example.isNullOrEmpty() -> { | |||
| tvExampleFlag.visibility = View.GONE | |||
| tvExample.visibility = View.GONE | |||
| } | |||
| else -> example.let { | |||
| tvExampleFlag.visibility = View.VISIBLE | |||
| tvExample.visibility = View.VISIBLE | |||
| tvExample.text = "▪ ${it.replace("\n", "\n▪ ")}" | |||
| } | |||
| } | |||
| refrence?.let { | |||
| tvReferenceFlag.visibility = View.VISIBLE | |||
| tvReference.visibility = View.VISIBLE | |||
| tvReference.text = refrence | |||
| }?:let { | |||
| tvReferenceFlag.visibility = View.GONE | |||
| tvReference.visibility = View.GONE | |||
| when{ | |||
| refrence.isNullOrEmpty() -> { | |||
| tvReferenceFlag.visibility = View.GONE | |||
| tvReference.visibility = View.GONE | |||
| } | |||
| else -> example.let { | |||
| tvReferenceFlag.visibility = View.VISIBLE | |||
| tvReference.visibility = View.VISIBLE | |||
| tvReference.text = refrence | |||
| } | |||
| } | |||
| } | |||
| @@ -201,10 +201,8 @@ object DBCourseManager { | |||
| mDataBase?.rawQuery(sql, null)?.run { | |||
| when (base.courseType) { | |||
| AppConstants.COURSE_TYPE_ENGLISH_DISCERN, AppConstants.COURSE_TYPE_ENGLISH_VOICE, | |||
| AppConstants.COURSE_TYPE_ENGLISH_SOUNDMARK, AppConstants.COURSE_TYPE_CHINESE_LITERACY, | |||
| AppConstants.COURSE_TYPE_CHINESE_PINYIN, | |||
| -> { | |||
| while (moveToNext()) { | |||
| AppConstants.COURSE_TYPE_CHINESE_LITERACY, | |||
| AppConstants.COURSE_TYPE_CHINESE_PINYIN -> while (moveToNext()) { | |||
| result.add(ExamBean().apply { | |||
| id = getLong(0) | |||
| word_id = getLong(1) | |||
| @@ -218,6 +216,19 @@ object DBCourseManager { | |||
| lessonId = getLong(9) | |||
| }) | |||
| } | |||
| AppConstants.COURSE_TYPE_ENGLISH_SOUNDMARK -> while (moveToNext()) { | |||
| result.add(ExamBean().apply { | |||
| id = getLong(0) | |||
| word_id = getLong(1) | |||
| word = getString(2) | |||
| correct = getString(3) | |||
| error1 = getString(4) | |||
| error2 = getString(5) | |||
| error3 = getString(6) | |||
| type = AppConstants.TEST_QUEST_TYPE_CHOICE // 为1 | |||
| chapterId = getLong(11) | |||
| lessonId = getLong(12) | |||
| }) | |||
| } | |||
| AppConstants.COURSE_TYPE_ENGLISH_SPELL -> { | |||
| while (moveToNext()) { | |||
| @@ -0,0 +1,96 @@ | |||
| package com.xkl.cdl.dialog | |||
| import android.annotation.SuppressLint | |||
| import android.app.Dialog | |||
| import android.os.Bundle | |||
| import android.view.LayoutInflater | |||
| import android.view.View | |||
| import android.view.ViewGroup | |||
| import android.view.WindowManager | |||
| import android.widget.FrameLayout | |||
| import androidx.coordinatorlayout.widget.CoordinatorLayout | |||
| import androidx.databinding.DataBindingUtil | |||
| import com.google.android.material.bottomsheet.BottomSheetBehavior | |||
| import com.google.android.material.bottomsheet.BottomSheetDialog | |||
| import com.google.android.material.bottomsheet.BottomSheetDialogFragment | |||
| import com.suliang.common.AppConfig | |||
| import com.suliang.common.extension.setHtml | |||
| import com.suliang.common.util.os.ScreenUtil | |||
| import com.xkl.cdl.R | |||
| import com.xkl.cdl.databinding.DialogBottomCoursePackIntroductionBinding | |||
| /** | |||
| * author suliang | |||
| * create 2022/5/13 10:51 | |||
| * Describe: | |||
| */ | |||
| class CoursePackIntroductionBottomSheetDialog: BottomSheetDialogFragment() { | |||
| companion object{ | |||
| fun newInstance(coursePackName : String, introduction : String) : CoursePackIntroductionBottomSheetDialog { | |||
| val args = Bundle() | |||
| args.putString(AppConfig.INTENT_1, coursePackName) | |||
| args.putString(AppConfig.INTENT_2,introduction) | |||
| val fragment = CoursePackIntroductionBottomSheetDialog() | |||
| fragment.arguments = args | |||
| return fragment | |||
| } | |||
| } | |||
| var behavior : BottomSheetBehavior<FrameLayout>? = null | |||
| override fun onCreateDialog(savedInstanceState : Bundle?) : Dialog { | |||
| return context?.let { | |||
| BottomSheetDialog(it,R.style.dialog_style) | |||
| }?: super.onCreateDialog(savedInstanceState) | |||
| } | |||
| @SuppressLint("ClickableViewAccessibility") | |||
| override fun onCreateView(inflater : LayoutInflater, container : ViewGroup?, savedInstanceState : Bundle?) : View? { | |||
| val introductionBinding = DataBindingUtil.inflate<DialogBottomCoursePackIntroductionBinding>(layoutInflater, | |||
| R.layout.dialog_bottom_course_pack_introduction, | |||
| null, false) | |||
| //标题 | |||
| introductionBinding.tvTitle.text = requireArguments()[AppConfig.INTENT_1] as String | |||
| //内容 | |||
| (requireArguments()[AppConfig.INTENT_2] as String).let { | |||
| if (it.isNotEmpty()) { | |||
| introductionBinding.tvIntroduction.setHtml(it) | |||
| } | |||
| } | |||
| return introductionBinding.root | |||
| } | |||
| override fun onStart() { | |||
| super.onStart() | |||
| dialog?.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN) | |||
| (dialog as BottomSheetDialog).delegate.findViewById<FrameLayout>(R.id.design_bottom_sheet)?.let { | |||
| (it.layoutParams as CoordinatorLayout.LayoutParams).height = ScreenUtil.getScreenHeight() / 6 * 5 | |||
| behavior = BottomSheetBehavior.from(it).apply { | |||
| state = BottomSheetBehavior.STATE_EXPANDED | |||
| } | |||
| } | |||
| } | |||
| // override fun onCreate(savedInstanceState : Bundle?) { | |||
| // super.onCreate(savedInstanceState) | |||
| // setCancelable(true) | |||
| // setCanceledOnTouchOutside(true) | |||
| // behavior.peekHeight = ScreenUtil.getScreenHeight() / 6 * 5 | |||
| // window?.apply { | |||
| // setLayout(ViewGroup.LayoutParams.MATCH_PARENT,behavior.peekHeight) | |||
| // setGravity(Gravity.BOTTOM) | |||
| // } | |||
| // } | |||
| // | |||
| // override fun onStart() { | |||
| // super.onStart() | |||
| // if (behavior.state == BottomSheetBehavior.STATE_HIDDEN) { | |||
| // behavior.state = BottomSheetBehavior.STATE_EXPANDED | |||
| // } | |||
| // } | |||
| } | |||
| @@ -135,11 +135,15 @@ class LearnExamActivity : BaseActivityVM<ActivityLearnExamBinding, LearnExamView | |||
| /** 新单词来了的发音事件 */ | |||
| private fun initNewWordRead(it : ExamBean) { | |||
| when (vm.intentData.courseType) { | |||
| //拼写初始不发音,作文不发音 | |||
| //拼写初始不发音,作文不发音, 音标课程测试不发音 | |||
| AppConstants.COURSE_TYPE_ENGLISH_SOUNDMARK, | |||
| AppConstants.COURSE_TYPE_ENGLISH_SPELL, AppConstants.COURSE_TYPE_CHINESE_COMPOSITION -> { | |||
| } | |||
| //英语认读,英语音标,英语口语,语文识字,语文拼音 出现即发音一次 | |||
| AppConstants.COURSE_TYPE_ENGLISH_DISCERN, AppConstants.COURSE_TYPE_ENGLISH_SOUNDMARK, AppConstants.COURSE_TYPE_ENGLISH_SPOKEN, AppConstants.COURSE_TYPE_CHINESE_LITERACY, AppConstants.COURSE_TYPE_CHINESE_PINYIN, | |||
| AppConstants.COURSE_TYPE_ENGLISH_DISCERN, | |||
| AppConstants.COURSE_TYPE_ENGLISH_SPOKEN, | |||
| AppConstants.COURSE_TYPE_CHINESE_LITERACY, | |||
| AppConstants.COURSE_TYPE_CHINESE_PINYIN, | |||
| // 英语辨音 重复播放 | |||
| AppConstants.COURSE_TYPE_ENGLISH_VOICE -> { | |||
| wordChooseBinding.ivVoice.performClick() | |||
| @@ -160,6 +164,7 @@ class LearnExamActivity : BaseActivityVM<ActivityLearnExamBinding, LearnExamView | |||
| //发音方式 | |||
| when (vm.intentData.subjectId) { | |||
| AppConstants.COURSE_TYPE_ENGLISH_SOUNDMARK -> voiceSwitch.visibility = View.GONE | |||
| AppConstants.SUBJECT_CHINESE -> { | |||
| vm.defaultSoundWay = AppConstants.SOUND_TYPE_CN | |||
| voiceSwitch.visibility = View.GONE | |||
| @@ -254,11 +259,13 @@ class LearnExamActivity : BaseActivityVM<ActivityLearnExamBinding, LearnExamView | |||
| /** 初始四选一的点击事件 只处理问题和单词的事件,选项事件,每个新的单词开始时设置,答题后再取消设置 | |||
| * 拼写,释义、单词都不发音,只有拼写在拼写完成发音 | |||
| * 作文知识点测试,没有发音 | |||
| * 音标测试也不发音 | |||
| * 辨音、口语单词与音频均可发音, | |||
| * 其他单词可以发音 | |||
| * */ | |||
| private fun initChooseQuestionListener() { | |||
| when (vm.intentData.courseType) { | |||
| AppConstants.COURSE_TYPE_ENGLISH_SOUNDMARK, | |||
| AppConstants.COURSE_TYPE_ENGLISH_SPELL, AppConstants.COURSE_TYPE_CHINESE_COMPOSITION -> { | |||
| } | |||
| else -> { | |||
| @@ -487,8 +487,8 @@ class LearnWordActivity : BaseActivityVM<ActivityLearnWordBinding, LearnWordView | |||
| tag = LEFT_TAG_ANSWER | |||
| } | |||
| binding.incControlButton.tvCenter.visibility = View.INVISIBLE | |||
| binding.incControlButton.tvRight.visibility = when (vm.learnData.lesson.courseType) { | |||
| AppConstants.COURSEPACK_TYPE_CHINESE_LITERACY, AppConstants.COURSE_TYPE_CHINESE_PINYIN, AppConstants.COURSE_TYPE_ENGLISH_SOUNDMARK -> View.INVISIBLE | |||
| binding.incControlButton.tvRight.visibility = when (vm.learnData.lesson.coursePackType) { | |||
| AppConstants.COURSEPACK_TYPE_CHINESE_COMPOSITION,AppConstants.COURSEPACK_TYPE_ENGLISH_SOUNDMARK -> View.INVISIBLE | |||
| else -> View.VISIBLE | |||
| } | |||
| @@ -550,11 +550,15 @@ class LearnWordActivity : BaseActivityVM<ActivityLearnWordBinding, LearnWordView | |||
| tag = LEFT_TAG_CORRECT | |||
| } | |||
| binding.incControlButton.tvCenter.visibility = View.VISIBLE | |||
| //音标,显示重读 | |||
| when(vm.learnData.lesson.coursePackType){ | |||
| AppConstants.COURSEPACK_TYPE_ENGLISH_SOUNDMARK -> View.VISIBLE | |||
| } | |||
| } | |||
| /**点击正确*/ | |||
| private fun clickCorrect() { | |||
| readWord() | |||
| //设tag为0 ,避免出现异常情况 | |||
| binding.incControlButton.tvLeft.tag = 0 | |||
| adapterHistorical.currentLearnOver() | |||
| @@ -4,6 +4,8 @@ import android.content.Context | |||
| import android.content.Intent | |||
| import android.graphics.Color | |||
| import android.os.Bundle | |||
| import android.text.Html | |||
| import android.text.method.ScrollingMovementMethod | |||
| import android.view.View | |||
| import androidx.core.content.ContextCompat | |||
| import androidx.core.content.res.ResourcesCompat | |||
| @@ -12,29 +14,26 @@ import androidx.fragment.app.Fragment | |||
| import androidx.lifecycle.ViewModel | |||
| import androidx.lifecycle.ViewModelProvider | |||
| import androidx.viewpager2.widget.ViewPager2 | |||
| import com.google.android.material.bottomsheet.BottomSheetBehavior | |||
| 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.extension.setHtml | |||
| 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.DataTransferHolder | |||
| import com.xkl.cdl.data.bean.LearnDialogBean | |||
| import com.xkl.cdl.data.bean.LearnWord | |||
| import com.xkl.cdl.data.bean.course.Lesson | |||
| import com.xkl.cdl.data.bean.intentdata.LearnData | |||
| import com.xkl.cdl.data.binding.BindingAdapter | |||
| import com.xkl.cdl.data.manager.CourseManager | |||
| import com.xkl.cdl.data.repository.DataRepository | |||
| import com.xkl.cdl.databinding.ActivityCourseMainBinding | |||
| import com.xkl.cdl.databinding.DialogBottomAutoPlaySelectBinding | |||
| import com.xkl.cdl.databinding.DialogBottomCourseMoreBinding | |||
| import com.xkl.cdl.databinding.* | |||
| import com.xkl.cdl.dialog.CommonDialog | |||
| import com.xkl.cdl.dialog.CommonDialogBean | |||
| import com.xkl.cdl.dialog.CoursePackIntroductionBottomSheetDialog | |||
| import com.xkl.cdl.module.learn.LearnWordActivity | |||
| import com.xkl.cdl.module.m_center_learn.coursechildren.CourseMainFragment | |||
| import com.zackratos.ultimatebarx.ultimatebarx.statusBarOnly | |||
| @@ -87,12 +86,21 @@ class CoursePackMainActivity : BaseActivityVM<ActivityCourseMainBinding, CourseP | |||
| //设置简介的箭头大小 | |||
| ResourcesCompat.getDrawable(resources, R.drawable.ic_arrow_right, null)?.apply { | |||
| setBounds(0, 0, 36, 36) | |||
| binding.textViewIntroduction.setCompoundDrawables(null, null, this, null) | |||
| binding.tvIntroduction.setCompoundDrawables(null, null, this, null) | |||
| } | |||
| //简介点击 | |||
| binding.tvIntroduction.click { | |||
| showIntroductionDialog() | |||
| } | |||
| //返回事件 | |||
| binding.includeTitleBar.titleBar.run { | |||
| onBackClick = { _ -> finish() } | |||
| } | |||
| //更多按钮点击 | |||
| binding.includeCourseProgress.ivMore.click { | |||
| if ((childFragments[binding.viewPager2.currentItem] as CourseMainFragment).vm.showMoreIsEnable()) showMoreDialog() | |||
| else showToast("请先进行学习") | |||
| } | |||
| //初始化tab和viewPager | |||
| initTabAndViewPager() | |||
| @@ -183,20 +191,21 @@ class CoursePackMainActivity : BaseActivityVM<ActivityCourseMainBinding, CourseP | |||
| } | |||
| } | |||
| } | |||
| //更多按钮点击 | |||
| binding.includeCourseProgress.ivMore.click { | |||
| if ((childFragments[binding.viewPager2.currentItem] as CourseMainFragment).vm.showMoreIsEnable()) showMoreDialog() | |||
| else showToast("请先进行学习") | |||
| } | |||
| } | |||
| override fun loadData() { | |||
| } | |||
| /** 简介弹窗 */ | |||
| private fun showIntroductionDialog() { | |||
| CoursePackIntroductionBottomSheetDialog.newInstance(vm.coursePack.coursePackName,vm.coursePack.summary).show(supportFragmentManager,"introducation") | |||
| } | |||
| /** 点击显示更多的弹窗 */ | |||
| private fun showMoreDialog() { | |||
| val moreDialog = BottomSheetDialog(this, R.style.dialog_style).apply { | |||
| BottomSheetDialog(this, R.style.dialog_style).apply { | |||
| val moreBinding = DataBindingUtil.inflate<DialogBottomCourseMoreBinding>(layoutInflater, | |||
| R.layout.dialog_bottom_course_more, null, | |||
| false) | |||
| @@ -53,7 +53,7 @@ class SplashActivity : BaseActivity<ActivitySplashBinding>(){ | |||
| //读取课程数据 | |||
| // TODO: 2022/3/22 读取当前app绑定的课程数据, | |||
| DbCoursePackManager().queryBindingCoursePack("262,261,264,136,547,615") | |||
| DbCoursePackManager().queryBindingCoursePack("262,261,264,136,547,615,516,411") | |||
| //复制课程的数据库到对应位置 | |||
| CourseManager.checkCourseDb() | |||
| //定时跳跃到住主界面 | |||
| @@ -92,7 +92,7 @@ | |||
| <!--简介--> | |||
| <TextView | |||
| android:id="@+id/text_view_introduction" | |||
| android:id="@+id/tv_introduction" | |||
| android:layout_width="wrap_content" | |||
| android:layout_height="wrap_content" | |||
| android:layout_marginEnd="@dimen/global_spacing" | |||
| @@ -0,0 +1,75 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | |||
| <layout xmlns:android="http://schemas.android.com/apk/res/android" | |||
| xmlns:tools="http://schemas.android.com/tools" | |||
| xmlns:app="http://schemas.android.com/apk/res-auto"> | |||
| <data> | |||
| </data> | |||
| <LinearLayout | |||
| android:layout_width="match_parent" | |||
| android:layout_height="match_parent" | |||
| android:background="@drawable/shape_rounder_toplr_24_white" | |||
| android:orientation="vertical" | |||
| android:paddingStart="@dimen/global_spacing" | |||
| android:paddingTop="24dp" | |||
| android:paddingEnd="@dimen/global_spacing" | |||
| android:paddingBottom="10dp"> | |||
| <TextView | |||
| android:id="@+id/tv_title" | |||
| android:layout_width="match_parent" | |||
| android:layout_height="wrap_content" | |||
| android:textColor="@color/main_text_color" | |||
| android:textSize="22dp" | |||
| android:textStyle="bold" | |||
| tools:text="学考乐小学英语单词班" /> | |||
| <TextView | |||
| android:layout_width="match_parent" | |||
| android:layout_height="wrap_content" | |||
| android:layout_marginTop="12dp" | |||
| android:text="@string/course_introduction" | |||
| android:textColor="@color/main_text_color" | |||
| android:textSize="@dimen/bigSize" | |||
| android:textStyle="bold" /> | |||
| <!-- <androidx.core.widget.NestedScrollView--> | |||
| <!-- android:layout_width="match_parent"--> | |||
| <!-- android:layout_height="match_parent"--> | |||
| <!-- android:overScrollMode="never"--> | |||
| <!-- >--> | |||
| <TextView | |||
| android:id="@+id/tv_introduction" | |||
| android:layout_width="match_parent" | |||
| android:layout_height="match_parent" | |||
| app:layout_behavior="@string/appbar_scrolling_view_behavior" | |||
| android:layout_marginTop="12dp" | |||
| android:textColor="@color/gray_2" | |||
| android:textSize="@dimen/smallSize" | |||
| android:text="getLayoutPosition,顾名思义,就是获取该ViewHolder在实际布局中的位置。我们都知道,RecyclerView使用LayoutManager来管理数据集的现实。当开发者调用notifyData*()等方法通知RecyclerView刷新UI时,出于性能的考虑,RecyclerView的UI并不会立刻刷新,和Data保持一致,而是通过LayoutManager惰性更新相关布局——这个过程伴随着时间上的等待,通常情况下,这个等待时间小于16ms。所以,从感官上讲,getLayoutPosition与getAbsoluteAdapterPosition十分相似:getAbsoluteAdapterPosition返回的是该ViewHolder相对于RecyclerView的绝对位置,而getLayoutPosition返回的是该ViewHolder相对于RecyclerView实际布局的绝对位置。 | |||
| 说具体点,就是adapter和layout的位置会有时间差(通常情况下16ms), 如果你改变了Adapter的数据然后刷新视图, layout需要过一段时间才会更新视图, 在这段时间里面, 这两个方法返回的position会不一样。 | |||
| 在notifyDataSetChanged之后并不能马上获取Adapter中的position, 要等布局结束之后才能获取到. | |||
| 而对于Layout的position, 在notifyItemInserted之后, Layout不能马上获取到新的position, 因为布局还没更新(需要16ms的时间刷新视图), 所以只能获取到旧的, 但是Adapter中的position就可以马上获取到最新的position。 | |||
| 所以,对于上面的点击事件的场景,我们在获取用户点击位置的时候,使用getLayoutPosition可能效果更好,这样,就能确保用户点击的始终是他看到的那个数据(消除16ms带来的时间差问题),代码可以改造成下面这样 | |||
| ———————————————— | |||
| 版权声明:本文为CSDN博主「普通网友」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 | |||
| 原文链接:https://blog.csdn.net/u012165769/article/details/119706823遇到这种方法模棱两可,让人傻傻getLayoutPosition,顾名思义,就是获取该ViewHolder在实际布局中的位置。我们都知道,RecyclerView使用LayoutManager来管理数据集的现实。当开发者调用notifyData*()等方法通知RecyclerView刷新UI时,出于性能的考虑,RecyclerView的UI并不会立刻刷新,和Data保持一致,而是通过LayoutManager惰性更新相关布局——这个过程伴随着时间上的等待,通常情况下,这个等待时间小于16ms。所以,从感官上讲,getLayoutPosition与getAbsoluteAdapterPosition十分相似:getAbsoluteAdapterPosition返回的是该ViewHolder相对于RecyclerView的绝对位置,而getLayoutPosition返回的是该ViewHolder相对于RecyclerView实际布局的绝对位置。 | |||
| 说具体点,就是adapter和layout的位置会有时间差(通常情况下16ms), 如果你改变了Adapter的数据然后刷新视图, layout需要过一段时间才会更新视图, 在这段时间里面, 这两个方法返回的position会不一样。 | |||
| 在notifyDataSetChanged之后并不能马上获取Adapter中的position, 要等布局结束之后才能获取到. | |||
| 而对于Layout的position, 在notifyItemInserted之后, Layout不能马上获取到新的position, 因为布局还没更新(需要16ms的时间刷新视图), 所以只能获取到旧的, 但是Adapter中的position就可以马上获取到最新的position。 | |||
| 所以,对于上面的点击事件的场景,我们在获取用户点击位置的时候,使用getLayoutPosition可能效果更好,这样,就能确保用户点击的始终是他看到的那个数据(消除16ms带来的时间差问题),代码可以改造成下面这样 | |||
| ———————————————— | |||
| 版权声明:本文为CSDN博主「普通网友」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 | |||
| 原文链接:https://blog.csdn.net/u012165769/article/details/119706823遇到这种方法模棱两可,让人傻傻分不清楚的情况,作为API调用者的我们,需要我们做到的就是适当的阅读源码注释,结合官方文档,正确理解他们各自所代表的含义以及可能带来的影响,合理使用他们。" /> | |||
| <!-- </androidx.core.widget.NestedScrollView>--> | |||
| </LinearLayout> | |||
| </layout> | |||
| @@ -1,3 +0,0 @@ | |||
| <resources> | |||
| <dimen name="fab_margin">48dp</dimen> | |||
| </resources> | |||
| @@ -1,3 +0,0 @@ | |||
| <resources> | |||
| <dimen name="fab_margin">200dp</dimen> | |||
| </resources> | |||
| @@ -1,3 +0,0 @@ | |||
| <resources> | |||
| <dimen name="fab_margin">48dp</dimen> | |||
| </resources> | |||
| @@ -84,5 +84,6 @@ | |||
| <string name="course_relearn_sure">确认清空</string> | |||
| <string name="quit_auto_play_title">你确定要退出自动播放吗?</string> | |||
| <string name="quit_auto_play_title_over">本课程自动播放完毕</string> | |||
| <string name="course_introduction">课程简介</string> | |||
| </resources> | |||