Search code examples
androidandroid-custom-viewright-to-leftandroid-framelayoutandroid-picture-in-picture

Custom views inside FrameLayout issue in Picture-in-picture RTL layout


I have a full screen FrameLayout which contains four Views that I add at runtime:

Full screen LTR FrameLayout

repeat(4) { i ->
    val view = View(this).apply {
        setBackgroundColor(COLOR[i])
    }
    views += view
    container.addView(view)
}

and to handle Picture-in-picture mode size change I've implemented onSizeChanged method:

container = object : FrameLayout(this) {
    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        resizeViews(w, h)
    }
}

and resize my views according to new width and height:

private fun resizeViews(width: Int, height: Int) {
    val isRtl = resources.configuration.layoutDirection == View.LAYOUT_DIRECTION_RTL
    val rtlFactor = if (isRtl) -1.0F else 1.0F

    views.forEachIndexed { i, view ->
        val x = width * LAYOUT[i].first * rtlFactor
        val y = height * LAYOUT[i].second
        val w = width / 2
        val h = height / 2
        val layoutParams = FrameLayout.LayoutParams(w, h)

        view.x = x
        view.y = y
        view.layoutParams = layoutParams
    }

    container.post {
        container.requestLayout()
    }
}

here are my consts:

    companion object {
        private val LAYOUT = listOf(
            0.0F to 0.0F,
            0.5F to 0.0F,
            0.0F to 0.5F,
            0.5F to 0.5F,
        )

        private val COLOR = listOf(
            Color.RED,
            Color.GREEN,
            Color.YELLOW,
            Color.BLUE,
        )
    }

PiP size LTR FrameLayout

BUT after switching to RTL layout the PiP window start acting differently:

PiP size RTL FrameLayout

Layout inspector shows that my views has been drawn somewhere off the screen

PiP size RTL in Layout inspector

and when I return to full screen from PiP this happens:

Full size RTL FrameLayout

I've logged all size calculations and there is no difference between LTR and RTL mode except negative value for Xs since it is how it works in Android.

I also tried different solutions like removing all views and adding them again with the new layout option, or posting requestLayout on every view and none of them worked.

Any comment or suggestion would be appreciated.


Solution

  • I didn't manage to find the root cause or a proper solution.

    I was lucky that my inner layouts had no UI element that required to be drawn RTL and therefore I switched my layout direction to LTR at runtime and it works fine:

    container.layoutDirection = View.LAYOUT_DIRECTION_LTR
    

    But still looking for the reason and a proper fix.