You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Fatal Exception: java.lang.IndexOutOfBoundsException: Index: 4, Size: 4
at java.util.ArrayList.get(ArrayList.java:437)
at com.example.ui.quiz.info.InfoViewModel$init$1.onPageSelected(InfoViewModel.java:47)
at com.github.islamkhsh.viewpager2.CompositeOnPageChangeCallback.onPageSelected(CompositeOnPageChangeCallback.java:72)
at com.github.islamkhsh.viewpager2.CompositeOnPageChangeCallback.onPageSelected(CompositeOnPageChangeCallback.java:72)
at com.github.islamkhsh.viewpager2.ScrollEventAdapter.dispatchSelected(ScrollEventAdapter.java:386)
at com.github.islamkhsh.viewpager2.ScrollEventAdapter.onScrolled(ScrollEventAdapter.java:176)
at androidx.recyclerview.widget.RecyclerView.dispatchOnScrolled(RecyclerView.java:5173)
at androidx.recyclerview.widget.RecyclerView$ViewFlinger.run(RecyclerView.java:5338)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:988)
at android.view.Choreographer.doCallbacks(Choreographer.java:765)
at android.view.Choreographer.doFrame(Choreographer.java:697)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:967)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7156)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:975)
Sample code:
class PrizeAdapter1 @Inject constructor() : CardSliderAdapter<PrizeAdapter1.PrizeViewHolder>() {
val items = ArrayList<Prize>()
private val backgrounds = arrayListOf(
R.drawable.frame_1,
R.drawable.frame_2,
R.drawable.frame_3,
R.drawable.frame_3
)
override fun bindVH(holder: PrizeViewHolder, position: Int) {
holder.bind(items[position], backgrounds[position % backgrounds.size])
}
override fun getItemCount(): Int = items.size
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PrizeViewHolder {
return PrizeViewHolder(
ViewholderQuizPrize1Binding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
)
}
class PrizeViewHolder(val binding: ViewholderQuizPrize1Binding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(item: Prize, background: Int) {
binding.item = item
binding.ivBackground.setImageResource(background)
}
}
}
@PerController
class InfoViewModel @Inject constructor() : BaseViewModel<InfoCallback>() {
@Inject
lateinit var mPrizesAdapter: PrizeAdapter1
@Inject
lateinit var mCategoriesAdapter: CategoryAdapter
@Inject
lateinit var mTopMembersAdapter: TopMemberAdapter
@Inject
lateinit var mHistoryAdapter: HistoryAdapter
lateinit var onPrizeChangeListener: ViewPager2.OnPageChangeCallback
val shouldShowHistory = ObservableBoolean(true)
val havePointsText = ObservableField<String>()
val fromPointsPerDayText = ObservableField<String>()
val shouldShowContent = ObservableBoolean(false)
var isDirty = false
var mLoadGameStateDisposable: Disposable? = null
override fun init(args: Bundle) {
onPrizeChangeListener = object : ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
if (isDirty) {
val prize = mPrizesAdapter.items[position]
loadGameState(prize.index)
if (prize.index == 0 || prize.index == 1)
fromPointsPerDayText.set(
mContext.getString(
R.string.from_n_points_per_day,
mDecimalFormat.format(prize.maxScore)
)
)
else
fromPointsPerDayText.set(
mContext.getString(
R.string.out_of_n_available,
mDecimalFormat.format(prize.maxScore)
)
)
}
isDirty = true
}
}
mCategoriesAdapter.listener = object : CategoryAdapter.Listener {
override fun onScrollToPosition(position: Int) {
mCallback.setCategoriesCurrentPosition(position)
}
override fun onPlayClick() {
mCallback.openQuestions()
}
}
mCallback.bindPrizes(mPrizesAdapter)
mCallback.bindCategories(mCategoriesAdapter)
mCallback.bindTopMembers(mTopMembersAdapter)
mCallback.bindHistory(mHistoryAdapter)
}
override fun onAttach() {
super.onAttach()
loadQuizInfo(false)
}
@SuppressLint("CheckResult")
fun loadQuizInfo(getNewData: Boolean) {
mLoadGameStateDisposable?.dispose()
mRepository.getQuizInfoAggregated(
mPreferencesHelper.myPhoneNumber,
mPreferencesHelper.subAccount,
mPreferencesHelper.locale,
getNewData
)
.compose(RxUtil.applyDefaults(this))
.subscribe({
handleQuizInfoResponse(it)
}, {
handleError(it)
})
}
@SuppressLint("CheckResult")
fun loadGameState(topType: Int) {
mLoadGameStateDisposable?.dispose()
mLoadGameStateDisposable = mNetworkHelper.getQuizGameState(
mPreferencesHelper.myPhoneNumber,
mPreferencesHelper.subAccount,
topType
)
.compose(RxUtil.applySchedulers())
.subscribe({ response ->
mTopMembersAdapter.items.clear()
mTopMembersAdapter.items.addAll(response.top)
mTopMembersAdapter.notifyDataSetChanged()
}, {
handleError(it)
})
}
private fun handleQuizInfoResponse(response: InfoAggregated) {
shouldShowContent.set(true)
havePointsText.set(
mContext.getString(
R.string.i_have_n_points,
mDecimalFormat.format(response.gameStateResult.score)
)
)
for (prize in response.prizeResult.prizes)
if (prize.index == response.stateResult.gameLevel) {
fromPointsPerDayText.set(
mContext.getString(
R.string.from_n_points_per_day,
mDecimalFormat.format(prize.maxScore)
)
)
break
}
mPrizesAdapter.items.clear()
mPrizesAdapter.items.addAll(response.prizeResult.prizes)
mPrizesAdapter.notifyDataSetChanged()
mCallback.removeOnPrizeChangeListener(onPrizeChangeListener)
mCallback.setPrizesCurrentPosition(0)
mCallback.setOnPrizeChangeListener(onPrizeChangeListener)
mCategoriesAdapter.items.clear()
mCategoriesAdapter.items.addAll(response.levelResult.levels)
mCategoriesAdapter.notifyDataSetChanged()
mCallback.setCategoriesCurrentPosition(Integer.MAX_VALUE / 2)
mTopMembersAdapter.items.clear()
mTopMembersAdapter.items.addAll(response.gameStateResult.top)
mTopMembersAdapter.notifyDataSetChanged()
mHistoryAdapter.items.clear()
mHistoryAdapter.items.addAll(response.gameStateResult.history)
mHistoryAdapter.notifyDataSetChanged()
}
fun onMoreDetailsButtonClick() {
mCallback.openParticipateRules()
}
fun onShowHistoryClick(toggle: Boolean) {
shouldShowHistory.set(toggle)
if (toggle)
mCallback.scrollToBottom()
}
fun onCloseClick() {
mCallback.closeController()
}
}
interface InfoCallback : BaseViewModel.BaseCallback {
fun openParticipateRules()
fun bindPrizes(adapter: PrizeAdapter1)
fun bindCategories(adapter: CategoryAdapter)
fun bindTopMembers(adapter: TopMemberAdapter)
fun bindHistory(adapter: HistoryAdapter)
fun setOnPrizeChangeListener(listener: ViewPager2.OnPageChangeCallback)
fun removeOnPrizeChangeListener(listener: ViewPager2.OnPageChangeCallback)
fun setCategoriesCurrentPosition(position: Int)
fun setPrizesCurrentPosition(position: Int)
fun openQuestions()
fun closeController()
fun scrollToBottom()
}
class InfoController : BaseController(), InfoCallback {
@Inject
lateinit var mViewModel: InfoViewModel
lateinit var binding: ControllerQuizInfoBinding
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup, savedViewState: Bundle?): View {
BaseApplication.getComponent().controllerComponent(ControllerModule(activity)).inject(this)
binding = ControllerQuizInfoBinding.inflate(inflater, container, false)
binding.viewmodel = mViewModel
mViewModel.setCallback(this, args)
binding.swipeLayout.setColorSchemeResources(R.color.colorPrimary, R.color.black)
return binding.root
}
override fun openParticipateRules() {
router.pushController(
RouterTransaction.with(ParticipateRulesController())
.pushChangeHandler(HorizontalChangeHandler())
.popChangeHandler(HorizontalChangeHandler())
)
}
override fun openQuestions() {
router.pushController(
RouterTransaction.with(QuestionController())
.pushChangeHandler(HorizontalChangeHandler())
.popChangeHandler(HorizontalChangeHandler())
)
}
override fun bindPrizes(adapter: PrizeAdapter1) {
binding.vpPrizes.adapter = adapter
}
override fun bindCategories(adapter: CategoryAdapter) {
binding.vpCategories.adapter = adapter
}
override fun bindTopMembers(adapter: TopMemberAdapter) {
binding.rvTopMembers.layoutManager = LinearLayoutManager(activity)
binding.rvTopMembers.adapter = adapter
}
override fun bindHistory(adapter: HistoryAdapter) {
binding.rvHistory.layoutManager = LinearLayoutManager(activity)
binding.rvHistory.adapter = adapter
}
override fun setOnPrizeChangeListener(listener: ViewPager2.OnPageChangeCallback) {
binding.vpPrizes.registerOnPageChangeCallback(listener)
}
override fun removeOnPrizeChangeListener(listener: ViewPager2.OnPageChangeCallback) {
binding.vpPrizes.unregisterOnPageChangeCallback(listener)
}
override fun setCategoriesCurrentPosition(position: Int) {
binding.vpCategories.currentItem = position
}
override fun setPrizesCurrentPosition(position: Int) {
binding.vpPrizes.currentItem = position
}
override fun closeController() {
router.handleBack()
}
override fun scrollToBottom() {
binding.root.postDelayed({
binding.nestedScrollView.fullScroll(View.FOCUS_DOWN)
}, 30)
}
override fun onChangeStarted(
changeHandler: ControllerChangeHandler,
changeType: ControllerChangeType
) {
super.onChangeStarted(changeHandler, changeType)
if (!changeType.isEnter) {
mViewModel.onDetach()
} else {
binding.root.postDelayed({
mTabStateManager.setTab(TabStateManager.Tabs.QUIZ_INFO_SCREEN)
mViewModel.onAttach()
}, 30)
}
}
override fun showMessage(message: String, vararg duration: Int) {
showToast(binding.root, message)
}
override fun showMessage(message: Int, vararg duration: Int) {
showToast(binding.root, message)
}
}
The text was updated successfully, but these errors were encountered:
The callback method onPageSelected receives a position greater than the list of elements.
CardSlider version:
implementation 'com.github.IslamKhSh:CardSlider:1.0.1'
API level:
Android 6, 9
Error log:
Sample code:
The text was updated successfully, but these errors were encountered: