¿Cómo pongo un borde alrededor de una vista de texto de Android?

Respuestas:

1274

Puede establecer una forma dibujable (un rectángulo) como fondo para la vista.

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

Y rectángulo dibujable back.xml (poner en la carpeta 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>

Puede usar @android:color/transparentpara que el color sólido tenga un fondo transparente. También puede usar relleno para separar el texto del borde. Para obtener más información, consulte: http://developer.android.com/guide/topics/resources/drawable-resource.html

Konstantin Burov
fuente
83
¿Qué pasa si solo quiero el borde superior?
happyhardik
19
@whyoz Su método agrega complejidad innecesaria para ver la jerarquía. Necesitará dos vistas adicionales (un contenedor de diseño y la vista de borde) para usar su método. Por lo tanto, si tiene muchas vistas a las que necesita agregar bordes, su árbol de vistas se volverá inmanejable.
Konstantin Burov
55
@whyoz, sin embargo, este método puede aplicarse a través de estilos y temas, mientras que el método de YongGu no puede usarse de esta manera.
Konstantin Burov
12
Para única frontera superior , vea esta pregunta .
Pang
77
Puede usar esta herramienta http://shapes.softartstudio.com para generar elementos dibujables.
Arda Basoglu
187

Permítanme resumir algunos métodos diferentes (no programáticos).

Usando una forma dibujable

Guarde lo siguiente como un archivo XML en su carpeta dibujable (por ejemplo, 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>

Luego, configúrelo como el fondo de su TextView:

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

Más ayuda:

Usando un parche de 9

Un parche 9 es una imagen de fondo extensible. Si crea una imagen con un borde, le dará un borde a su TextView. Todo lo que necesita hacer es crear la imagen y luego establecerla en segundo plano en su TextView.

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

Aquí hay algunos enlaces que mostrarán cómo hacer una imagen de 9 parches:

¿Qué pasa si solo quiero el borde superior?

Usando una lista de capas

Puede usar una lista de capas para apilar dos rectángulos uno encima del otro. Al hacer que el segundo rectángulo sea un poco más pequeño que el primer rectángulo, puede crear un efecto de borde. El primer rectángulo (inferior) es el color del borde y el segundo rectángulo es el color de fondo.

<?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>

El ajuste android:top="2dp"compensa la parte superior (la hace más pequeña) en 2dp. Esto permite que se muestre el primer rectángulo (inferior), dando un efecto de borde. Puede aplicar esto al fondo TextView de la misma manera queshape se realizó anterior.

Aquí hay algunos enlaces más sobre listas de capas:

Usando un parche de 9

Simplemente puede hacer una imagen de 9 parches con un solo borde. Todo lo demás es igual a lo discutido anteriormente.

Usar una vista

Esto es una especie de truco, pero funciona bien si necesita agregar un separador entre dos vistas o un borde a un solo 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>

Aquí hay algunos enlaces más:

Suragch
fuente
24
Dios mío, border: 1px solid #999;se supone que a no es tan complicado.
Achshar
¿Qué sucede si quiero un borde de la vista de texto, que también tiene efecto de sombra y ondulación?
Akash Dubey
@AkashDubey, lo siento, no he hecho eso antes. Le sugiero que pruebe cada uno por separado y luego los combine. Si se atasca, haga una nueva pregunta sobre Desbordamiento de pila.
Suragch
49

La manera simple es agregar una vista para su TextView. Ejemplo para la línea del borde 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 los otros bordes de dirección, ajuste la ubicación de la vista del separador.

Joven gu
fuente
3
Según mi experiencia, esta solución, en dispositivos antiguos, tiene un impacto visible y silencioso en el rendimiento de la aplicación.
Roberto Lombardini
43
Esta es una solución horrible desde el punto de vista de la inflación. Crea 3 nuevos elementos de vista y agrega un nivel más en la profundidad de la jerarquía de vista
philipp
La peor solución debido a la perspectiva de la inflación vista como dijo philipp. ¿Sabe que textView tiene una etiqueta xml específica para hacer eso ?: defina una imagen para dibujar a la izquierda / derecha / arriba / abajo en su TextView, y se conocen como android: drawable ****
Mathias Seguy Android2ee
32

He resuelto este problema extendiendo la vista de texto y dibujando un borde manualmente. Incluso agregué para que pueda seleccionar si un borde está punteado o punteado.

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;
        }
}

Y la clase fronteriza:

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 esto ayude a alguien :)

Bojan Jovanovic
fuente
¿Cómo inicializar fronteras?
zionpi
No puede funcionar correctamente, ya que el código muestra que dibuja los bordes en la mitad del tamaño del valor definido
ucMedia
14

Solo estaba mirando una respuesta similar: se puede hacer con un derrame cerebral y la siguiente anulación:

@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
fuente
¡Excelente! Mi única preocupación es que el trazo es feo en las esquinas cuando uso drawRoundRect, tanto en el teléfono como en el emulador.
erdomester
1
@erdomester Tal vez Paint StrokePaint = nueva pintura (Paint.ANTI_ALIAS_FLAG); va a resolver "feo" en las esquinas de emisión
P-RAD
14

Puede establecer el borde por dos métodos. Uno es dibujable y el segundo es 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
fuente
¿Cómo se relacionaría esa forma XML con el textView?
Neo42
14

La solución más simple que he encontrado (y que realmente funciona):

<TextView
    ...
    android:background="@android:drawable/editbox_background" />
Proteico
fuente
¿Es posible aplicar esto a todas las vistas de texto desde un solo lugar?
Ian Warburton
Agradable para un rapidito. Pero dependiendo de la versión del dispositivo en ejecución, esto puede tener efectos muy inusuales. Esto se debe a que Google sigue cambiando el aspecto de EditTexts (¡tienes que estar a la moda!)
Scott Biggs
11

Encontré una mejor manera de poner un borde alrededor de un TextView.

Use una imagen de nueve parches para el fondo. Es bastante simple, el SDK viene con una herramienta para hacer la imagen de 9 parches, y no implica absolutamente nada codificación.

El enlace es http://developer.android.com/guide/topics/graphics/2d-graphics.html#nine-patch .

Mella
fuente
2
Útil, sí, pero ¿cómo es esto mejor?
agregado11686877
2
Usar una forma como dice la respuesta aceptada es mejor que un parche de 9, un archivo XML es más flexible que un recurso gráfico
Jose_GD 12/12/2013
Claro, si desea limitarse a crear los gráficos que desea mediante programación, entonces es más flexible.
Nick
2
El enfoque de la forma es inútil. Tal vez soy el único que experimenta, que la etiqueta "sólido" siempre se procesa, sin importar si se establece como transparente o no. Y si quiero crear una FRONTERA, quiero decir, una FRONTERA y no un rectángulo con bordes interiores coloreados y de otro color. Y NUNCA es sólido transparente. Siempre perturba el color. Además, una clase, que hereda de otra, también debe tener todas las características, porque se hereda. Realmente no puedo entender por qué Android rompe las pautas de diseño OO elementales. Por ejemplo, heredé del botón. Todas las características desaparecieron. Por qué ?
icbytes
2
@Jeremie ¿Visiblemente más lento? ¿Cómo lo observas?
IgorGanapolsky
11

Puede agregar algo como esto en su 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
fuente
¿Por qué es necesario un derrame cerebral?
IgorGanapolsky
@IgorGanapolsky, trazo crear el borde real?
Tash Pemhiwa
10

Consulte el siguiente enlace para hacer esquinas redondeadas http://androidcookbook.com/Recipe.seam?recipeId=2318

La carpeta dibujable, en resolución, en un proyecto de Android no está restringida a mapas de bits (archivos PNG o JPG), pero también puede contener formas definidas en archivos XML.

Estas formas se pueden reutilizar en el proyecto. Se puede usar una forma para poner un borde alrededor de un diseño. Este ejemplo muestra un borde rectangular con esquinas curvas. Se crea un nuevo archivo llamado customborder.xml en la carpeta dibujable (en Eclipse use el menú Archivo y seleccione Nuevo luego Archivo, con la carpeta dibujable, escriba el nombre del archivo y haga clic en Finalizar).

Se ingresa el XML que define la forma del borde:

<?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>

El atributo android:shapese establece en rectángulo (los archivos de forma también admiten óvalo, línea y anillo). Rectángulo es el valor predeterminado, por lo que este atributo podría omitirse si se está definiendo un rectángulo. Consulte la documentación de Android sobre formas en http://developer.android.com/guide/topics/resources/drawable-resource.html#Shape para obtener información detallada sobre un archivo de formas.

Las esquinas del elemento configuran las esquinas del rectángulo que se redondearán. Es posible establecer un radio diferente en cada esquina (consulte la referencia de Android).

Los atributos de relleno se utilizan para mover el contenido de la Vista a la que se aplica la forma, para evitar que el contenido se superponga al borde.

El color del borde aquí se establece en gris claro (valor RGB hexadecimal).

Las formas también admiten gradientes, pero eso no se usa aquí. Nuevamente, vea los recursos de Android para ver cómo se define un gradiente. La forma se aplica al laypout usandoandroid:background="@drawable/customborder" .

Dentro del diseño, se pueden agregar otras vistas de forma normal. En este ejemplo, se ha agregado un único TextView y el texto es blanco (FFFFFF hexadecimal RGB). El fondo se establece en azul, más algo de transparencia para reducir el brillo (valor alfa RGB hexadecimal A00000FF). Finalmente, el diseño se compensa desde el borde de la pantalla colocándolo en otro diseño con una pequeña cantidad de relleno. El archivo de diseño completo es así:

<?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
fuente
Las respuestas de solo enlace están altamente desaconsejadas, ya que los enlaces tienden a romperse en algún momento en el futuro. Incluya partes relevantes de su enlace en esta respuesta para que la información permanezca disponible, incluso si el enlace no lo tiene.
Andy
8

Tengo una manera de hacerlo muy simple, y me gustaría compartirlo.

Cuando quiero cuadrar mis TextViews, solo las pongo en un LinearLayout. Establezco el color de fondo de mi LinearLayout y agrego un margen a mi TextView. El resultado es exactamente como si cuadraras el TextView.

Panaget romano
fuente
2

Cambiar la respuesta de Konstantin Burov porque no funciona en mi 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, implementación 'com.android.support:appcompat-v7:26.1.0', gradle: 4.1

Ejrr1085
fuente
2

Puede crear un fondo personalizado para su vista de texto. Pasos 1. Vaya a su proyecto. 2. Vaya a recursos y haga clic derecho en dibujable. 3. Haga clic en Nuevo -> Archivo de recursos dibujables 4. Asigne un nombre al archivo 5. Pegue el siguiente código en el archivo

<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 su vista de texto donde desea usarlo como fondo,

    android: background = "@ drawable / your_fileName"

Rakesh P.
fuente
1

Aquí está mi clase auxiliar 'simple' que devuelve un ImageView con el borde. Simplemente suelte esto en su carpeta de utilidades y llámelo así:

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

Aquí está el 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;
    }
}
Agresor
fuente
¿Cómo lo uso selectionBorder?
Tash Pemhiwa
@TashPemhiwa Button.setBackgroundDrawable ();
NinjaOnSafari
0

Esto puede ayudarte.

<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
Asignar
fuente
0

Cree una vista de borde con el color de fondo como el color del borde y el tamaño de su vista de texto. establecer el relleno de vista de borde como el ancho del borde. Establezca el color de fondo de la vista de texto como el color que desea para la vista de texto. Ahora agregue su vista de texto dentro de la vista de borde.

Praveen Agrawal
fuente
0

Prueba esto:

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

Hay muchas formas de agregar un borde a textView. El más simple es creando un dibujo personalizado y configurándolo como android:background="@drawable/textview_bg"para su textView.

Textview_bg.xml irá debajo de Drawables y puede ser algo como esto. Puede tener un solido un gradientfondo (o nada si no es necesario), cornerspara agregar un radio de esquina ystroke agregar borde.

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
fuente
0
  <View
    android:layout_width="match_parent"
    android:layout_height="2dp"
    android:background="@android:color/black" />

este código lo puedes colocar donde quieras

sanjay
fuente
0

setBackground en su vista de texto xml,

agregue el archivo rounded_textview.xml a su directorio dibujable.

<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>

establecer archivo dibujable en textView background.

Rohit Soni
fuente
-1

En realidad, es muy simple. Si desea un rectángulo negro simple detrás de la vista de texto, simplemente agregue android:background="@android:color/black"dentro de las etiquetas TextView. Me gusta esto:

<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"/>
usuario3631822
fuente
él pide frontera no fondo completo.
Guy