Округлые обрезанные углы Android XML

Я установил LinearLayout со следующим выделенным фоном:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <corners android:radius="10dp" />
    <solid android:color="#CCFFFFFF"/>
</shape>

Проблема, с которой я столкнулась, заключается в LinearLayout. У меня есть другой элемент LinearLayout, который находится внизу его родителя. Так как у этого нет закругленных углов, его углы проходят мимо левого и правого углов родителей.

Выводимый фон для дочернего LinearLayout выглядит следующим образом:

<?xml version="1.0" encoding="utf-8"?>
<bitmap
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:src="@drawable/pedometer_stats_background" 
    android:tileMode="repeat"   
/>

Проблема выглядит следующим образом: http://kttns.org/hn2zm на устройстве более неприглядное.

Каков наилучший способ выполнения обрезки?

Ответ 1

Какое ваше описание звучит так:

<LinearLayout android:shape="rounded">
   <LinearLayout android:background="@drawable/pedometer_stats_background">
   </LinearLayout>
</LinearLayout>

И внутренняя компоновка выдвигается за пределы закругленных углов, потому что она не закруглена. Вам придется обойти углы вашего растрового изображения. Если у вас есть повторяющееся растровое изображение, вы захотите посмотреть, как вырезать девять патчей. Вокруг ваших углов затем определите часть графического объекта, который может расширяться.

http://developer.android.com/guide/topics/resources/drawable-resource.html#Shape

Было бы неплохо, если бы мы могли просто добавить растровое изображение в форму, пригодную для рисования, и использовать ее в качестве скина над любой фигурой, которую мы рисуем. И, держу пари, если вы знаете, что делаете, вы можете создать подкласс Shape, который рисует растровое изображение, но, к сожалению, он не включен в Android.

Ответ 2

Мне нужны скругленные макеты в стиле iPhone, с серым фоном позади них. (вздох - всегда копирование iPhone)

Я был расстроен, я не мог найти способ маскировать макет. Большинство ответов здесь говорят, чтобы использовать фоновое изображение, но это не то, что мне нужно.


Изменить. Предыдущий ответ предлагается с помощью FrameLayout и установки android:foreground drawable. Это ввело некоторые странные дополнения в представление. Я обновил свой ответ, чтобы использовать более простой метод RelativeLayout.


Хитрость заключается в использовании RelativeLayout; разместите в нем макет. Ниже вашего макета добавьте еще один ImageView, установив его background в подходящую рамку маскирующего изображения. Это приведет к тому, что поверх вашего другого макета.

В моем случае я сделал файл 9Patch, который был серым фоном, с вырезанным из него прозрачным округленным прямоугольником.

frame

Это создает идеальную маску для вашего основного макета.

Ниже приведен код XML - это обычный XML файл макета:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_height="wrap_content" android:layout_width="fill_parent">

    <!-- this can be any layout that you want to mask -->
    <LinearLayout android:id="@+id/mainLayout"
        android:layout_height="wrap_content"
        android:layout_width="fill_parent" android:orientation="vertical"
        android:background="@android:color/white">

        <TextView android:layout_height="wrap_content"
            android:layout_width="wrap_content" android:layout_gravity="center"
            android:text="Random text..." />

    </LinearLayout>

    <!-- FRAME TO MASK UNDERLYING VIEW -->
    <ImageView android:layout_height="fill_parent" 
        android:layout_width="fill_parent" 
        android:background="@drawable/grey_frame"
        android:layout_alignTop="@+id/mainLayout"
        android:layout_alignBottom="@+id/mainLayout" />

</RelativeLayout>

Обратите внимание на ImageView внизу, выровненный сверху и снизу к основному макету, с набором маскирующих изображений:

  • android:background="@drawable/grey_frame"

Это ссылается на мой файл 9Patch - и маскирует базовый макет, рисуя его на переднем плане.

Вот пример, показывающий серые закругленные углы над стандартным макетом.

maskedLayout

HTH

Ответ 3

Уровень API 21 (Jellybean) добавлен View.setClipToOutline. Из документации для Android на Определение теней и обложек Просмотров:

Чтобы скопировать представление в форму drawable, установите для рисования в качестве фона представления... и вызовите метод View.setClipToOutline().

Я проверил это, установив родительский вид фона в GradientDrawable с радиусом угла, а дочерние представления правильно обрезаны, чтобы соответствовать тем же закругленным углам родителя.