Android - desenhável apenas com cantos arredondados na parte superior


151

Eu tinha esse desenho para ter um retângulo arredondado como pano de fundo:

<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="@color/white" />
    <stroke android:width="1dp" android:color="@color/light_gray" />
    <padding android:left="10dp" android:top="10dp" android:right="10dp" android:bottom="10dp" />
    <corners android:radius="6dp" />
</shape>

Isso está funcionando bem, como esperado.

Agora, eu quero mudar isso para apenas arredondar os cantos superiores, então eu mudo para isso:

<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="@color/white" />
    <stroke android:width="1dp" android:color="@color/light_gray" />
    <padding android:left="10dp" android:top="10dp" android:right="10dp" android:bottom="10dp" />
    <corners android:topLeftRadius="6dp" android:topRightRadius="6dp"
             android:bottomLeftRadius="0dp" android:bottomRightRadius="0dp"/>
</shape>

Mas agora nenhum dos cantos é arredondado e recebo um retângulo simples. O que estou perdendo aqui?


Isso realmente não é uma solução, mas acho que já tive um problema semelhante. Aumentar o stoke para 2 pixels ajudou, mas você sabe, isso não é uma solução.
Code Poet

Aqui está um problema com os cantos das formas: code.google.com/p/android/issues/detail?id=939
Knickedi

Respostas:


303

Tente fornecer estes valores:

 <corners android:topLeftRadius="6dp" android:topRightRadius="6dp"
         android:bottomLeftRadius="0.1dp" android:bottomRightRadius="0.1dp"/>

Observe que eu mudei 0dppara 0.1dp.

EDIT: Veja o comentário de Aleks G abaixo para uma versão mais limpa


131
Explorando isso mais, encontrei uma solução ainda melhor: <corners android:radius="1dp" android:topLeftRadius="6dp" android:topRightRadius="6dp" android:bottomLeftRadius="0dp" android:bottomRightRadius="0dp"/>- isso produz cantos inferiores perfeitamente quadrados, sem nem mesmo um toque de arredondamento. No entanto, sua solução praticamente funciona.
Aleks G

Como fazer isso no código, dado um bitmap? E como adicionar contorno (acidente vascular cerebral) em torno dele?
desenvolvedor android

@Aleks G eu não ver que é necessário especificarandroid:radius="1dp"
hmac

@hmac é necessário. Leia a documentação, deixa claro.
Aleks G

@AleksG Sim, a documentação está errada, testando no Samsung 10, Android 9: "Cada canto deve (inicialmente) receber um raio de canto maior que 1, ou então nenhum canto é arredondado. Se você deseja que cantos específicos não sejam arredondados, a solução alternativa é usar android: radius para definir um raio de canto padrão maior que 1, mas substituir "- não é verdade, eu especifico canto inferior direito, canto superior direito, canto superior esquerdo como zero e canto inferior esquerdo + ve e canto inferior esquerdo corretamente curvados
hmac

14

Tente fazer algo assim:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:bottom="-20dp" android:left="-20dp">
        <shape android:shape="rectangle">
            <solid android:color="@color/white" />

            <corners android:radius="20dp" />
        </shape>
    </item>
</layer-list>

Parece que não é adequado definir um raio de canto diferente do retângulo. Então você pode usar esse hack.


Veja minha própria resposta - é perfeitamente aceitável ter um raio diferente para cantos diferentes.
Aleks L

Eu tentei esta abordagem, não é aceitável, ide diz que não faz appropriatr ter rsdius diferente e ignora-lo
busylee

11

No meu caso, abaixo do código

    <?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:top="10dp" android:bottom="-10dp"
        >

        <shape android:shape="rectangle">
            <solid android:color="@color/maincolor" />

            <corners
                android:topLeftRadius="10dp"
                android:topRightRadius="10dp"
                android:bottomLeftRadius="0dp"
                android:bottomRightRadius="0dp"
            />
        </shape>

    </item>
    </layer-list>

1
As propriedades superior e inferior do item não são necessárias, a menos que você queira um preenchimento na exibição, mas, caso contrário, isso funcionará.
RominaV

9

Baseando-se a resposta de busylee , isto é como você pode fazer um drawableque tem apenas uma un canto arredondado (canto superior esquerdo, neste exemplo):

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="rectangle">
            <solid android:color="@color/white" />
            <!-- A numeric value is specified in "radius" for demonstrative purposes only,
                  it should be @dimen/val_name -->
            <corners android:radius="10dp" />
        </shape>
    </item>
    <!-- To keep the TOP-LEFT corner UNROUNDED set both OPPOSITE offsets (bottom+right): -->
    <item
        android:bottom="10dp"
        android:right="10dp">
        <shape android:shape="rectangle">
            <solid android:color="@color/white" />
        </shape>
    </item>
</layer-list>

Observe que o acima nãodrawable é exibido corretamente na visualização do Android Studio (2.0.0p7). Para visualizá-lo de qualquer maneira, crie outra visualização e use-a como .android:background="@drawable/..."


6
@AleksG - Claro. É relevante hoje como era na época (como evidência - eu precisava de algo assim). Você deve saber que, ao longo dos anos, algumas maneiras de fazer as coisas se tornam obsoletas e podem precisar ser substituídas por outras mais modernas. Como o busylee mencionou, o IDE reclama ao definir raios de canto diferentes, o que não é o caso do método atual. Além disso, como essa pergunta foi meu primeiro hit no Google (iirc), fazia sentido atualizá-la. De qualquer forma, eu tenho certeza que isso não vai se importar mais alguns KB de código ... :)
Dev-IL

2

Testei seu código e obtive um botão no canto superior arredondado. Eu dei as cores como @ffffffe derramei #C0C0C0.

experimentar

  1. Fornecendo android: bottomLeftRadius = "0.1dp" em vez de 0. se não estiver funcionando
  2. Verifique qual desenho e a resolução do emulador. Eu criei uma pasta drawable em res e usando-a. (hdpi, mdpi ldpi) a pasta em que você possui esse XML. esta é a minha saída.

insira a descrição da imagem aqui


Qual versão do Android é essa? Meu aplicativo deve ser executado no 1.6 - e o emulador 1.6 teve o problema.
Aleks G

1

Você pode precisar ler este https://developer.android.com/guide/topics/resources/drawable-resource.html#Shape

e abaixo há uma nota.

Nota Cada canto deve (inicialmente) receber um raio de canto maior que 1, ou então nenhum canto é arredondado. Se você deseja que cantos específicos não sejam arredondados, uma solução alternativa é usar android: radius para definir um raio de canto padrão maior que 1, mas substitua cada canto pelos valores que você realmente deseja, fornecendo zero ("0dp" ) onde você não deseja cantos arredondados.


1

Crie roung_top_corners.xml no drawable e copie o código abaixo

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
<corners
    android:topLeftRadius="22dp"
    android:topRightRadius="22dp"
    android:bottomLeftRadius="0dp"
    android:bottomRightRadius="0dp"
    />
<gradient
    android:angle="180"
    android:startColor="#1d2b32"
    android:centerColor="#465059"
    android:endColor="#687079"
    android:type="linear" />
<padding
    android:left="0dp"
    android:top="0dp"
    android:right="0dp"
    android:bottom="0dp"
    />
<size
    android:width="270dp"
    android:height="60dp"
    /></shape>
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.