Como faço para colocar uma borda em torno de uma visualização de texto do Android?

Respostas:

1274

Você pode definir uma forma desenhável (um retângulo) como plano de fundo para a vista.

<TextView android:text="Some text" android:background="@drawable/back"/>

E retângulo drawable back.xml (colocado na pasta res / drawable):

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
   <solid android:color="@android:color/white" />
   <stroke android:width="1dip" android:color="#4fa5d5"/>
</shape>

Você pode usar @android:color/transparentpara que a cor sólida tenha um fundo transparente. Você também pode usar preenchimento para separar o texto da borda. para obter mais informações, consulte: http://developer.android.com/guide/topics/resources/drawable-resource.html

Konstantin Burov
fonte
83
E se eu só quiser a borda superior?
happyhardik
19
@whyoz Seu método adiciona complexidade desnecessária para visualizar a hierarquia. Você precisará de duas visualizações adicionais (um contêiner de layout e a visualização de borda) para usar seu método. Portanto, se você tiver muitas visualizações às quais precisa adicionar borda, sua árvore de visualizações ficará incontrolável.
Konstantin Burov
5
@whyoz ainda este método pode ser aplicado através de estilos e temas, enquanto o método YongGu não pode ser usado dessa maneira.
Konstantin Burov
12
Somente para a borda superior , consulte esta pergunta .
Pang
7
Você pode usar esta ferramenta http://shapes.softartstudio.com para gerar desenháveis.
Arda Basoglu
187

Deixe-me resumir alguns métodos diferentes (não programáticos).

Usando um desenho de forma

Salve o seguinte como um arquivo XML na sua pasta extraível (por exemplo, my_border.xml):

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >

    <!-- View background color -->
    <solid
        android:color="@color/background_color" >
    </solid>

    <!-- View border color and width -->
    <stroke
        android:width="1dp"
        android:color="@color/border_color" >
    </stroke>

    <!-- The radius makes the corners rounded -->
    <corners
        android:radius="2dp"   >
    </corners>

</shape>

Em seguida, basta defini-lo como plano de fundo para o seu TextView:

<TextView
    android:id="@+id/textview1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/my_border" />

Mais ajuda:

Usando um patch de 9

Um patch 9 é uma imagem de plano de fundo extensível. Se você criar uma imagem com uma borda, ela fornecerá uma borda ao TextView. Tudo o que você precisa fazer é criar a imagem e defini-la como plano de fundo no seu TextView.

<TextView
    android:id="@+id/textview1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/my_ninepatch_image" />

Aqui estão alguns links que mostrarão como criar uma imagem de 9 patches:

E se eu só quiser a borda superior?

Usando uma lista de camadas

Você pode usar uma lista de camadas para empilhar dois retângulos um sobre o outro. Ao tornar o segundo retângulo um pouco menor que o primeiro, você pode criar um efeito de borda. O primeiro retângulo (inferior) é a cor da borda e o segundo retângulo é a cor do plano de fundo.

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

    <!-- Lower rectangle (border color) -->
    <item>
        <shape android:shape="rectangle">
            <solid android:color="@color/border_color" />
        </shape>
    </item>

    <!-- Upper rectangle (background color) -->
    <item android:top="2dp">
        <shape android:shape="rectangle">
            <solid android:color="@color/background_color" />
        </shape>
    </item>
</layer-list>

A configuração android:top="2dp"compensa a parte superior (diminui) em 2dp. Isso permite que o primeiro retângulo (inferior) seja exibido, fornecendo um efeito de borda. Você pode aplicar isso ao plano de fundo do TextView da mesma maneira que o shapedrawable foi feito acima.

Aqui estão mais alguns links sobre listas de camadas:

Usando um patch de 9

Você pode criar uma imagem de 9 patches com uma única borda. Tudo o resto é o mesmo que discutido acima.

Usando uma vista

Isso é meio que um truque, mas funciona bem se você precisar adicionar um separador entre duas visualizações ou uma borda a um único TextView.

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/textview1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <!-- This adds a border between the TextViews -->
    <View
        android:layout_width="match_parent"
        android:layout_height="2dp"
        android:background="@android:color/black" />

    <TextView
        android:id="@+id/textview2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

Aqui estão mais alguns links:

Suragch
fonte
24
Puxa, cara, border: 1px solid #999;não é para ser tão complicado assim.
Achshar
E se eu quiser uma borda do modo de exibição de texto, que também tem efeitos de sombra e ondulação?
Akash Dubey
@AkashDubey, desculpe, eu não fiz isso antes. Eu sugiro que você tente cada um separadamente e depois os combine. Se você ficar preso, faça uma nova pergunta no Stack Overflow.
Suragch
49

A maneira mais simples é adicionar uma exibição para o seu TextView. Exemplo para a linha de borda inferior:

<LinearLayout android:orientation="vertical"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent">
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:layout_marginLeft="10dp"
        android:text="@string/title"
        android:id="@+id/title_label"
        android:gravity="center_vertical"/>
    <View
        android:layout_width="fill_parent"
        android:layout_height="0.2dp"
        android:id="@+id/separator"
        android:visibility="visible"
        android:background="@android:color/darker_gray"/>

</LinearLayout>

Para as outras bordas da direção, ajuste o local da vista do separador.

Young Gu
fonte
3
Pela minha experiência, esta solução, em dispositivos antigos, tem um impacto visível silencioso no desempenho do aplicativo.
Roberto Lombardini
43
Esta é uma solução horrível do ponto de vista da inflação. Você cria 3 novos elementos visualizar e adicionar mais um nível na profundidade da vista hierarquia
Philipp
Pior solução por causa da perspectiva da inflação, como disse philipp. Você sabe que o textView tem uma tag xml específica para fazer isso: defina uma imagem para desenhar à esquerda / direita / superior / inferior em torno do TextView e eles são conhecidos como android: drawable ****
Mathias Seguy Android2ee
32

Resolvi esse problema estendendo a exibição de texto e desenhando uma borda manualmente. Eu até adicionei para que você possa selecionar se uma borda é pontilhada ou tracejada.

public class BorderedTextView extends TextView {
        private Paint paint = new Paint();
        public static final int BORDER_TOP = 0x00000001;
        public static final int BORDER_RIGHT = 0x00000002;
        public static final int BORDER_BOTTOM = 0x00000004;
        public static final int BORDER_LEFT = 0x00000008;

        private Border[] borders;

        public BorderedTextView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            init();
        }

        public BorderedTextView(Context context, AttributeSet attrs) {
            super(context, attrs);
            init();
        }

        public BorderedTextView(Context context) {
            super(context);
            init();
        }
        private void init(){
            paint.setStyle(Paint.Style.STROKE);
            paint.setColor(Color.BLACK);
            paint.setStrokeWidth(4);        
        }
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            if(borders == null) return;

            for(Border border : borders){
                paint.setColor(border.getColor());
                paint.setStrokeWidth(border.getWidth());

                if(border.getStyle() == BORDER_TOP){
                    canvas.drawLine(0, 0, getWidth(), 0, paint);                
                } else
                if(border.getStyle() == BORDER_RIGHT){
                    canvas.drawLine(getWidth(), 0, getWidth(), getHeight(), paint);
                } else
                if(border.getStyle() == BORDER_BOTTOM){
                    canvas.drawLine(0, getHeight(), getWidth(), getHeight(), paint);
                } else
                if(border.getStyle() == BORDER_LEFT){
                    canvas.drawLine(0, 0, 0, getHeight(), paint);
                }
            }
        }

        public Border[] getBorders() {
            return borders;
        }

        public void setBorders(Border[] borders) {
            this.borders = borders;
        }
}

E a classe da fronteira:

public class Border {
    private int orientation;
    private int width;
    private int color = Color.BLACK;
    private int style;
    public int getWidth() {
        return width;
    }
    public void setWidth(int width) {
        this.width = width;
    }
    public int getColor() {
        return color;
    }
    public void setColor(int color) {
        this.color = color;
    }
    public int getStyle() {
        return style;
    }
    public void setStyle(int style) {
        this.style = style;
    }
    public int getOrientation() {
        return orientation;
    }
    public void setOrientation(int orientation) {
        this.orientation = orientation;
    }
    public Border(int Style) {
        this.style = Style;
    }
}

Espero que isso ajude alguém :)

Bojan Jovanovic
fonte
Como inicializar bordas?
Zionpi 29/07/2015
Ele não pode trabalhar corretamente, como mostra o código que chama as fronteiras com o tamanho da metade do valor definido
ucMedia
14

Eu estava apenas procurando uma resposta semelhante - ela pode ser feita com um Stroke e a seguinte substituição:

@Override
public void draw(Canvas canvas, MapView mapView, boolean shadow) {

Paint strokePaint = new Paint();
strokePaint.setARGB(255, 0, 0, 0);
strokePaint.setTextAlign(Paint.Align.CENTER);
strokePaint.setTextSize(16);
strokePaint.setTypeface(Typeface.DEFAULT_BOLD);
strokePaint.setStyle(Paint.Style.STROKE);
strokePaint.setStrokeWidth(2);

Paint textPaint = new Paint();
textPaint.setARGB(255, 255, 255, 255);
textPaint.setTextAlign(Paint.Align.CENTER);
textPaint.setTextSize(16);
textPaint.setTypeface(Typeface.DEFAULT_BOLD);

canvas.drawText("Some Text", 100, 100, strokePaint);
canvas.drawText("Some Text", 100, 100, textPaint);

super.draw(canvas, mapView, shadow); 
}
sdtechcomm
fonte
Ótimo! Minha única preocupação é que o golpe seja feio nos cantos quando eu uso o drawRoundRect, tanto no telefone quanto no emulador.
Erdomester 15/05
1
@erdomester Talvez o Paint StrokePaint = new Paint (Paint.ANTI_ALIAS_FLAG); vai resolver "feio nos cantos" questão
P-RAD
14

Você pode definir a borda por dois métodos. Um é por meio de drawable e o segundo é programático.

Usando Drawable

<shape>
    <solid android:color="@color/txt_white"/>
    <stroke android:width="1dip" android:color="@color/border_gray"/>
    <corners android:bottomLeftRadius="10dp"
             android:bottomRightRadius="0dp"
             android:topLeftRadius="10dp"
             android:topRightRadius="0dp"/>
    <padding android:bottom="0dip"
             android:left="0dip"
             android:right="0dip"
             android:top="0dip"/>
</shape>

Programático


public static GradientDrawable backgroundWithoutBorder(int color) {

    GradientDrawable gdDefault = new GradientDrawable();
    gdDefault.setColor(color);
    gdDefault.setCornerRadii(new float[] { radius, radius, 0, 0, 0, 0,
                                           radius, radius });
    return gdDefault;
}
Maulik Santoki
fonte
Como esse XML de forma se relacionaria com o textView?
Neo42
14

Solução mais simples que encontrei (e que realmente funciona):

<TextView
    ...
    android:background="@android:drawable/editbox_background" />
Protean
fonte
É possível aplicar isso a todas as visualizações de texto em um único local?
22818 Ian Warburton
Bom para uma rapidinha. Mas, dependendo da versão do dispositivo em execução, isso pode ter efeitos muito incomuns. Isso ocorre porque o Google continua a mudar como EditTexts olhar (você tem que manter em forma!)
Scott Biggs
11

Eu encontrei uma maneira melhor de colocar uma borda em torno de um TextView.

Use uma imagem de nove correções para o fundo. É bem simples, o SDK vem com uma ferramenta para criar a imagem de 9 patches e não envolve absolutamente nenhuma codificação.

O link é http://developer.android.com/guide/topics/graphics/2d-graphics.html#nine-patch .

usuario
fonte
2
Útil, sim, mas como isso é melhor?
aggregate1166877
2
Usando uma forma como a resposta aceita diz que é melhor do que um 9-patch, um arquivo XML é mais flexível do que um recurso gráfico
Jose_GD
Claro, se você deseja limitar-se a criar os gráficos que deseja programaticamente, é mais flexível.
Nick
2
A abordagem de forma é inútil.Talvez eu seja a única a experimentar, que a tag "solid" sempre seja processada, independentemente de definida como transparente ou não.E se eu quiser criar uma BORDER, quero dizer, BORDER e não um retângulo com bordas coloridas internas e coloridas. E nunca é sólido transparente. Sempre perturba a cor. Além disso, uma classe, que herda de outra, também deve ter todos os recursos, porque é herdada. realmente não consigo entender, por que diretrizes elementares de design de OO são quebradas pelo Android. Por exemplo, eu herdei do botão. Todos os recursos foram embora. Por quê ?
icbytes
2
@ Jeremie Visivelmente mais lento? Como você observa isso?
IgorGanapolsky
11

Você pode adicionar algo assim no seu código:

<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="rectangle" >
    <solid android:color="#ffffff" />
    <stroke android:width="1dip" android:color="#4fa5d5"/>
</shape>
novato
fonte
Por que o AVC é necessário?
IgorGanapolsky
@IgorGanapolsky, acidente vascular cerebral cria a borda real?
Tash Pemhiwa
10

Verifique o link abaixo para fazer cantos arredondados http://androidcookbook.com/Recipe.seam?recipeId=2318

A pasta de desenho, em res, em um projeto Android não está restrita a bitmaps (arquivos PNG ou JPG), mas também pode conter formas definidas em arquivos XML.

Essas formas podem ser reutilizadas no projeto. Uma forma pode ser usada para colocar uma borda ao redor de um layout. Este exemplo mostra uma borda retangular com cantos curvos. Um novo arquivo chamado customborder.xml é criado na pasta drawable (no Eclipse, use o menu File e selecione New then File, com a pasta drawable selecionada, digite o nome do arquivo e clique em Finish).

O XML que define a forma da borda é inserido:

<?xml version="1.0" encoding="UTF-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
    <corners android:radius="20dp"/>
    <padding android:left="10dp" android:right="10dp" android:top="10dp" android:bottom="10dp"/>
    <solid android:color="#CCCCCC"/>
</shape>

O atributo android:shapeestá definido como retângulo (os arquivos de forma também suportam oval, linha e anel). Retângulo é o valor padrão; portanto, esse atributo pode ser deixado de fora se for um retângulo definido. Consulte a documentação do Android sobre formas em http://developer.android.com/guide/topics/resources/drawable-resource.html#Shape para obter informações detalhadas sobre um arquivo de forma.

Os cantos do elemento definem os cantos do retângulo a serem arredondados. É possível definir um raio diferente em cada canto (consulte a referência do Android).

Os atributos de preenchimento são usados ​​para mover o conteúdo da Vista na qual a forma é aplicada, para impedir que o conteúdo se sobreponha à borda.

A cor da borda aqui é definida como cinza claro (valor RGB hexadecimal).

As formas também suportam gradientes, mas isso não está sendo usado aqui. Mais uma vez, consulte os recursos do Android para ver como um gradiente é definido. A forma é aplicada ao layout usandoandroid:background="@drawable/customborder" .

Dentro do layout, outras visualizações podem ser adicionadas normalmente. Neste exemplo, um único TextView foi adicionado e o texto é branco (FFFFFF hexadecimal RGB). O plano de fundo está definido como azul, mais alguma transparência para reduzir o brilho (valor A00000FF hexadecimal alfa RGB). Finalmente, o layout é deslocado da borda da tela, colocando-o em outro layout com uma pequena quantidade de preenchimento. O arquivo de layout completo é assim:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent"
              android:padding="5dp">
    <LinearLayout android:orientation="vertical"
                  android:layout_width="fill_parent"
                  android:layout_height="fill_parent"
                  android:background="@drawable/customborder">
        <TextView android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:text="Text View"
                android:textSize="20dp"
                android:textColor="#FFFFFF"
                android:gravity="center_horizontal"
                android:background="#A00000FF" />
    </LinearLayout>
</LinearLayout>
Bahaa Hany
fonte
As respostas apenas para links são altamente desencorajadas, pois os links tendem a se romper em algum momento no futuro. Puxe partes relevantes do seu link para esta resposta para que as informações permaneçam disponíveis, mesmo que o link não o faça.
Andy
8

Eu tenho uma maneira de fazê-lo de maneira muito simples e gostaria de compartilhá-lo.

Quando eu quero quadrado mi TextViews, basta colocá-los em um LinearLayout. Defino a cor de fundo do meu LinearLayout e adiciono uma margem ao meu TextView. O resultado é exatamente como se você quadrasse o TextView.

Roman Panaget
fonte
2

Alterando a resposta de Konstantin Burov, porque não funciona no meu caso:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="rectangle">
            <solid android:color="@android:color/white" />
            <stroke android:width="2dip" android:color="#4fa5d5"/>
            <corners android:radius="7dp"/>
        </shape>
    </item>
</selector>

compileSdkVersion 26 (Android 8.0), minSdkVersion 21 (Android 5.0), targetSdkVersion 26, implementação 'com.android.support:appcompat-v7:26.1.0', nível: 4.1

Ejrr1085
fonte
2

Você pode criar um plano de fundo personalizado para sua exibição de texto. Etapas 1. Vá para o seu projeto. 2. Acesse recursos e clique com o botão direito do mouse em drawable. 3. Clique em Novo -> Arquivo de Recursos Drawable 4. Dê um nome ao seu arquivo 5. Cole o seguinte código no arquivo

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

  1. Para a sua exibição de texto onde você deseja usá-la como backgroud,

    android: background = "@ drawable / your_fileName"

Rakesh P.
fonte
1

Aqui está minha classe auxiliar 'simples' que retorna um ImageView com a borda. Basta colocar isso na sua pasta utils e chamá-lo assim:

ImageView selectionBorder = BorderDrawer.generateBorderImageView(context, borderWidth, borderHeight, thickness, Color.Blue);

Aqui está o código.

/**
 * Because creating a border is Rocket Science in Android.
 */
public class BorderDrawer
{
    public static ImageView generateBorderImageView(Context context, int borderWidth, int borderHeight, int borderThickness, int color)
    {
        ImageView mask = new ImageView(context);

        // Create the square to serve as the mask
        Bitmap squareMask = Bitmap.createBitmap(borderWidth - (borderThickness*2), borderHeight - (borderThickness*2), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(squareMask);

        Paint paint = new Paint();
        paint.setStyle(Paint.Style.FILL);
        paint.setColor(color);
        canvas.drawRect(0.0f, 0.0f, (float)borderWidth, (float)borderHeight, paint);

        // Create the darkness bitmap
        Bitmap solidColor = Bitmap.createBitmap(borderWidth, borderHeight, Bitmap.Config.ARGB_8888);
        canvas = new Canvas(solidColor);

        paint.setStyle(Paint.Style.FILL);
        paint.setColor(color);
        canvas.drawRect(0.0f, 0.0f, borderWidth, borderHeight, paint);

        // Create the masked version of the darknessView
        Bitmap borderBitmap = Bitmap.createBitmap(borderWidth, borderHeight, Bitmap.Config.ARGB_8888);
        canvas = new Canvas(borderBitmap);

        Paint clearPaint = new Paint();
        clearPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));

        canvas.drawBitmap(solidColor, 0, 0, null);
        canvas.drawBitmap(squareMask, borderThickness, borderThickness, clearPaint);

        clearPaint.setXfermode(null);

        ImageView borderView = new ImageView(context);
        borderView.setImageBitmap(borderBitmap);

        return borderView;
    }
}
Agressor
fonte
Como eu uso selectionBorder?
Tash Pemhiwa
@TashPemhiwa Button.setBackgroundDrawable ();
NinjaOnSafari
0

Isso pode ajudá-lo.

<RelativeLayout
    android:id="@+id/textbox"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerHorizontal="true"
    android:layout_centerVertical="true"
    android:background="@android:color/darker_gray" >

    <TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:layout_margin="3dp"
        android:background="@android:color/white"
        android:gravity="center"
        android:text="@string/app_name"
        android:textSize="20dp" />

</RelativeLayout
Mete
fonte
0

Crie uma vista de borda com a cor de fundo como a cor da borda e o tamanho da vista de texto. defina o preenchimento da vista da borda como a largura da borda. Defina a cor de fundo da exibição de texto como a cor desejada para a exibição de texto. Agora adicione sua exibição de texto dentro da borda.

praveen agrawal
fonte
0

Tente o seguinte:

<shape>
    <solid android:color="@color/txt_white"/>
    <stroke android:width="1dip" android:color="@color/border_black"/>
</shape>
mohamad sheikhi
fonte
0

Existem várias maneiras de adicionar uma borda a um textView. O mais simples é criar um drawable personalizado e configurá-lo como android:background="@drawable/textview_bg"para o seu textView.

O textview_bg.xml irá para Drawables e pode ser algo como isto. Você pode ter um solidou um gradientplano de fundo (ou nada, se não for necessário), cornerspara adicionar um raio de canto estroke adicionar borda.

textview_bg.xml

<?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle">

        <corners
            android:radius="@dimen/dp_10"/>

        <gradient
            android:angle="225"
            android:endColor="#FFFFFF"
            android:startColor="#E0E0E0" />

        <stroke
            android:width="2dp"
            android:color="#000000"/>

    </shape>
Akanshi Srivastava
fonte
0
  <View
    android:layout_width="match_parent"
    android:layout_height="2dp"
    android:background="@android:color/black" />

este código o suficiente, você pode colocar onde quiser

Sanjay
fonte
0

setBackground em seu texto em xml,

adicione o arquivo rounded_textview.xml ao seu diretório drawable.

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
   <solid android:color="@android:color/white" />
   <stroke android:width="2dip" android:color="#4f5g52"/>
</shape>

definir arquivo drawable em segundo plano textView.

Rohit Soni
fonte
-1

Na verdade, é muito simples. Se você deseja um simples retângulo preto atrás do Textview, basta adicionar android:background="@android:color/black"dentro das tags TextView. Como isso:

<TextView
    android:textSize="15pt" android:textColor="#ffa7ff04"
    android:layout_alignBottom="@+id/webView1"
    android:layout_alignParentRight="true"
    android:layout_alignParentEnd="true"
    android:background="@android:color/black"/>
user3631822
fonte
ele pede uma fronteira que não seja completa.
Guy