둥근 모서리

Android 12(API 수준 31)부터 RoundedCornerWindowInsets.getRoundedCorner(int position)를 사용하여 둥근 모서리의 반경과 중심점을 설정합니다. 이러한 API를 통해 앱은 모서리가 둥근 화면에서 UI 요소가 잘리지 않도록 할 수 있습니다. 또한 프레임워크는 보이는 마이크 및 카메라 표시기의 제한된 직사각형을 반환하는 getPrivacyIndicatorBounds() API를 제공합니다.

앱에서 구현될 때 이러한 API는 화면이 둥글지 않은 기기에는 영향을 미치지 않습니다.

반경과 중심점이 있는 둥근 모서리를 보여주는 이미지
그림 1: 반경과 중심점이 있는 둥근 모서리

이 기능을 구현하려면 애플리케이션 경계를 기준으로 WindowInsets.getRoundedCorner(int position)를 통해 RoundedCorner 정보를 가져옵니다. 앱이 전체 화면을 차지하지 않으면 API는 둥근 모서리의 중심점을 앱의 창 경계에 기반하여 둥근 모서리를 적용합니다.

다음 코드 스니펫은 RoundedCorner의 정보에 따라 뷰의 여백을 설정하여 앱이 UI 잘림을 방지하는 간단한 예를 보여줍니다. 이 경우에는 오른쪽 상단 둥근 모서리입니다.

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

자바

// 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);