Search code examples
androidkotlinimageviewandroid-imageviewandroid-viewpager2

ViewPager2 appears only after a focus change


I have a ViewPager2 in my app that gets populated with fragments dynamically based on a response from a websocket request. I also have a AppCompatImageView that has an image set in the XML layout(but later gets a new bitmap to display dynamically).

Now I have a problem that the ViewPager2 and the AppCompatImageView does not show when the app starts, the only way to show them is to force a focus change like opening a popupmenu or alertdialog.

The really weird thing is that I have another imageview in the layout that is set to a static color that is always shown...

Can someone give me a suggestion why those two views gets hidden (like if they were set to View.INVISIBLE, even though they aren't) on app launch, and even better, why do they get displayed after a focus change?

Could the fact that they get populated dynamically interfere in some way with them being rendered correctly?


Solution

  • I realized that my problems was because I had two race conditions.

    The first was due to this code:

    class ViewPagerFragmentAdapter(fragmentActivity: FragmentActivity) : FragmentStateAdapter(fragmentActivity) {
        private var arrayList: MutableList<Fragment> = mutableListOf()
    
        fun addFragment(fragment: Fragment) {
            arrayList.add(fragment)
        }
    
        fun removeFragment(index: Int) {
            arrayList.removeAt(index)
        }
    
        override fun getItemCount(): Int {
            return arrayList.size
        }
    
        override fun createFragment(position: Int): Fragment {
            return arrayList[position]
        }
    }
    

    This is the adapter for the ViewPager2 and to solve it I hade to change the addFragment function to:

    fun addFragment(fragment: Fragment) {
        arrayList.add(fragment)
        this.notifyItemInserted(this.itemCount - 1)
    }
    

    This due to the fact that if my view rendered after my websocket request finished then I got content but if it rendered before I got the reply I would only have an empty viewpager. By adding the notify call the viewpager gets notified when a fragment is added.(probably need something similar on the remove function as well)

    To solve the AppCompatImageView I only changed app:srcCompat="..." in the XML to android:src="...", don't ask me why but then the view rendered...