@@ -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> |