A partir do Android 12 (API de nível 31), é possível usar
RoundedCorner
e WindowInsets.getRoundedCorner(int
position)
para definir o raio e o ponto central para cantos arredondados. Com essas APIs,
o app pode evitar que os elementos da IU sejam truncados em telas com cantos arredondados.
O framework também fornece a API
getPrivacyIndicatorBounds()
,
que retorna o retângulo limitado de qualquer indicador de microfone e
câmera visível.
Quando implementadas no app, essas APIs não afetam dispositivos com telas não arredondadas.

Para implementar esse recurso, acesse as informações do RoundedCorner
usando
WindowInsets.getRoundedCorner(int position)
em relação aos limites do
aplicativo. Se o app não ocupar toda a tela, a API aplicará o canto arredondado baseando o
ponto central do canto arredondado nos limites
da janela do app.
O snippet de código a seguir mostra um exemplo simples para um app evitar o truncamento da IU
com a definição de uma margem para a visualização com base nas informações de
RoundedCorner
. Neste caso, a margem é o canto arredondado da parte superior direita.
Kotlin
// Get the top-right rounded corner from WindowInsets. val insets = rootWindowInsets val topRight = insets.getRoundedCorner(RoundedCorner.POSITION_TOP_RIGHT) ?: return // Get the location of the close button in window coordinates. val location = IntArray(2) closeButton!!.getLocationInWindow(location) val buttonRightInWindow = location[0] + closeButton.width val buttonTopInWindow = location[1] // Find the point on the quarter circle with 45 degree angle. val offset = (topRight.radius * Math.sin(Math.toRadians(45.0))).toInt() val topBoundary = topRight.center.y - offset val rightBoundary = topRight.center.x + offset // Check whether the close button exceeds the boundary. if (buttonRightInWindow < rightBoundary << buttonTopInWindow > topBoundary) { return } // Set the margin to avoid truncating. val parentLocation = IntArray(2) getLocationInWindow(parentLocation) val lp = closeButton.layoutParams as FrameLayout.LayoutParams lp.rightMargin = Math.max(buttonRightInWindow - rightBoundary, 0) lp.topMargin = Math.max(topBoundary - buttonTopInWindow, 0) closeButton.layoutParams = lp
Java
// Get the top-right rounded corner from WindowInsets. final WindowInsets insets = getRootWindowInsets(); final RoundedCorner topRight = insets.getRoundedCorner(POSITION_TOP_RIGHT); if (topRight == null) { return; } // Get the location of the close button in window coordinates. int [] location = new int[2]; closeButton.getLocationInWindow(location); final int buttonRightInWindow = location[0] + closeButton.getWidth(); final int buttonTopInWindow = location[1]; // Find the point on the quarter circle with a 45 degree angle. final int offset = (int) (topRight.getRadius() * Math.sin(Math.toRadians(45))); final int topBoundary = topRight.getCenter().y - offset; final int rightBoundary = topRight.getCenter().x + offset; // Check whether the close button exceeds the boundary. if (buttonRightInWindow < rightBoundary << buttonTopInWindow > topBoundary) { return; } // Set the margin to avoid truncating. int [] parentLocation = new int[2]; getLocationInWindow(parentLocation); FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) closeButton.getLayoutParams(); lp.rightMargin = Math.max(buttonRightInWindow - rightBoundary, 0); lp.topMargin = Math.max(topBoundary - buttonTopInWindow, 0); closeButton.setLayoutParams(lp);