Как поставить рамку вокруг текстового представления Android?

Ответы:

1275

Вы можете установить форму для рисования (прямоугольник) в качестве фона для вида.

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

И прямоугольник drawable back.xml (положить в папку 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>

Вы можете использовать @android:color/transparentдля сплошного цвета, чтобы иметь прозрачный фон. Вы также можете использовать отступы, чтобы отделить текст от границы. Для получения дополнительной информации см .: http://developer.android.com/guide/topics/resources/drawable-resource.html

Константин Буров
источник
83
Что если я просто хочу верхнюю границу?
happyhardik
19
@whyoz Его метод добавляет ненужную сложность для просмотра иерархии. Вам понадобятся два дополнительных вида (контейнер макета и вид границы), чтобы использовать его метод. Таким образом, если у вас много представлений, к которым нужно добавить границу, ваше дерево представлений станет неуправляемым.
Константин Буров
5
@whyoz, но этот метод может быть применен через стили темы, в то время как метод YongGu не может быть использован таким образом.
Константин Буров
12
Только для верхней границы , см. Этот вопрос .
Панг
7
Вы можете использовать этот инструмент http://shapes.softartstudio.com для создания чертежей.
Арда Басоглу
187

Позвольте мне обобщить несколько различных (непрограммных) методов.

Использование формы для рисования

Сохраните следующее в виде XML-файла в папке для рисования (например, 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>

Затем просто установите его в качестве фона для вашего TextView:

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

Дополнительная помощь:

Использование 9-патча

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

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

Вот несколько ссылок, которые покажут, как сделать изображение из 9 патчей:

Что если я просто хочу верхнюю границу?

Использование списка слоев

Вы можете использовать список слоев, чтобы сложить два прямоугольника друг на друга. Сделав второй прямоугольник чуть меньше первого, вы можете создать эффект границы. Первый (нижний) прямоугольник - это цвет границы, а второй прямоугольник - это цвет фона.

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

Установка android:top="2dp"смещает верх (делает его меньше) на 2dp. Это позволяет первому (нижнему) прямоугольнику просвечивать, создавая эффект границы. Вы можете применить это к фону TextView так же, как shapeрисование было сделано выше.

Вот еще несколько ссылок о списках слоев:

Использование 9-патча

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

Использование представления

Это своего рода хитрость, но она хорошо работает, если вам нужно добавить разделитель между двумя представлениями или границу для одного 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>

Вот еще несколько ссылок:

Suragch
источник
24
Господи, а border: 1px solid #999;не должно быть так сложно.
Ахшар
Что делать, если мне нужна граница textview, которая также имеет эффект тени и ряби?
Акаш Дубей
@AkashDubey, извини, я этого раньше не делал. Я предлагаю вам попробовать каждый из них в отдельности, а затем объединить их. Если вы застряли, задайте новый вопрос о переполнении стека.
Сурагч,
49

Простой способ - добавить представление для вашего TextView. Пример для нижней границы:

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

Для других границ направления, пожалуйста, отрегулируйте расположение вида разделителя.

Молодой гу
источник
3
По моему опыту, это решение на старых устройствах оказывает тихое видимое влияние на производительность приложения.
Роберто Ломбардини
43
Это ужасное решение с точки зрения инфляции. Вы создаете 3 новых элемента вида и добавляете еще один уровень в глубину иерархии
видов
Худшее решение из-за перспективы инфляции, как сказал Филипп. Знаете ли вы, что у textView есть специальный тег xml, чтобы просто сделать это: определите картинку для рисования влево / вправо / сверху / снизу вокруг вашего TextView, и они известны как android: drawable ****
Mathias Seguy Android2ee
32

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

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

И пограничный класс:

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

Надеюсь, это поможет кому-то :)

Боян Йованович
источник
Как инициализировать границы?
zionpi
Он не может работать правильно, так как код показывает, что он рисует границы с половиной размера определенного значения
ucMedia
14

Я просто смотрел на аналогичный ответ - это можно сделать с помощью Stroke и следующего переопределения:

@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
источник
Большой! Единственное, что меня беспокоит, это то, что при использовании drawRoundRect и в телефоне, и в эмуляторе обводки выглядят ужасно.
erdomester
1
@erdomester Maybe Paint StrokePaint = new Paint (Paint.ANTI_ALIAS_FLAG); решит проблему "уродливых на углах"
P-RAD
14

Вы можете установить границу двумя способами. Один отрисовывается, а второй - программный.

Используя 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>

программный


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;
}
Маулик Сантоки
источник
Как бы эта форма XML относилась к textView?
Neo42
14

Самое простое решение, которое я нашел (и которое действительно работает):

<TextView
    ...
    android:background="@android:drawable/editbox_background" />
изменчивый
источник
Можно ли применить это ко всем текстовым представлениям из одного места?
Ян Варбертон,
Хорошо для быстрого Но в зависимости от версии работающего устройства это может иметь очень необычные эффекты. Это потому, что Google постоянно меняет внешний вид EditTexts (ты должен оставаться в моде!)
Скотт Биггс,
11

Я нашел лучший способ поместить границу вокруг TextView.

Используйте изображение из девяти пятен для фона. Это довольно просто, SDK поставляется с инструментом для создания изображения из 9 патчей и абсолютно не требует кодирования.

Ссылка http://developer.android.com/guide/topics/graphics/2d-graphics.html#nine-patch .

Ник
источник
2
Полезно, да, но как это лучше?
aggregate1166877
2
Использование формы, как говорит принятый ответ, лучше, чем 9-патч, XML-файл более гибок, чем графический актив
Jose_GD
Конечно, если вы хотите ограничиться созданием графики, которую вы хотите программным способом, то она более гибкая.
Ник
2
Подход формы бесполезен. Возможно, я единственный, кто испытывает, что тег «solid» всегда обрабатывается, независимо от того, установлен он на прозрачный или нет. И если я хочу создать BORDER, я имею в виду BORDER, а не прямоугольник с цветными внутренними и иными цветными границами. И это НИКОГДА не прозрачное тело. Это всегда мешает цвету. Кроме того, класс, который наследуется от другого, также должен иметь все функции, поскольку он наследуется. действительно не могу понять, почему элементарные ОО-дизайн-директивы нарушаются андроидом. Например, я унаследовал от кнопки. Все функции исчезли. Почему ?
icbytes
2
@ Джереми Заметно медленнее? Как вы это наблюдаете?
Игорь Ганапольский
11

Вы можете добавить что-то вроде этого в свой код:

<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>
новичок
источник
Почему инсульт необходим?
Игорь Ганапольский
@IgorGanapolsky, инсульт создает реальную границу?
Таш Пемхива
10

Проверьте ссылку ниже, чтобы сделать закругленные углы http://androidcookbook.com/Recipe.seam?recipeId=2318

Папка Drawable в разделе res в проекте Android не ограничивается растровыми изображениями (файлы PNG или JPG), но также может содержать формы, определенные в файлах XML.

Эти формы затем могут быть повторно использованы в проекте. Форма может быть использована для наложения границы вокруг макета. В этом примере показана прямоугольная граница с изогнутыми углами. В папке drawable создается новый файл customborder.xml (в Eclipse используйте меню «Файл» и выберите «Создать», затем «Файл», в выбранной папке для рисования введите имя файла и нажмите «Готово»).

XML, определяющий форму границы, вводится:

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

Атрибут android:shapeустановлен на прямоугольник (файлы формы также поддерживают овал, линию и кольцо). Прямоугольник является значением по умолчанию, поэтому этот атрибут можно было бы опустить, если он является определяемым прямоугольником. Обратитесь к документации Android по фигурам по адресу http://developer.android.com/guide/topics/resources/drawable-resource.html#Shape для получения подробной информации о файле фигур .

Углы элемента задают скругленные углы прямоугольника. Можно установить разные радиусы на каждом углу (см. Ссылку на Android).

Атрибуты заполнения используются для перемещения содержимого представления, к которому применяется форма, для предотвращения перекрытия границы содержимым.

Цвет границы здесь светло-серый (шестнадцатеричное значение RGB).

Фигуры также поддерживают градиенты, но здесь они не используются. Снова, посмотрите ресурсы Android, чтобы увидеть, как определяется градиент. Форма применяется к макету с помощью android:background="@drawable/customborder".

В макете другие виды могут быть добавлены как обычно. В этом примере был добавлен один TextView, а текст белый (шестнадцатеричный RGB FFFFFF). Фон установлен в синий цвет, плюс некоторая прозрачность для уменьшения яркости (шестнадцатеричное альфа-RGB-значение A00000FF). Наконец, макет смещается от края экрана, помещая его в другой макет с небольшим количеством отступов. Полный файл макета, таким образом:

<?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>
Бахаа Хани
источник
Ответы только на ссылки крайне не приветствуются, так как ссылки имеют тенденцию разрываться в какой-то момент в будущем. Вставьте соответствующие части вашей ссылки в этот ответ, чтобы информация оставалась доступной, даже если ссылка отсутствует.
Энди
8

У меня есть способ сделать это очень просто, и я хотел бы поделиться этим.

Когда я хочу возвести в квадрат значения TextViews, я просто помещаю их в LinearLayout. Я устанавливаю цвет фона моего LinearLayout и добавляю поле для моего TextView. Результат в точности такой, как если бы вы поместили квадрат в TextView.

Роман Панагет
источник
2

Меняется ответ Константина Бурова, потому что не работают в моем случае:

<?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, реализация 'com.android.support:appcompat-v7:26.1.0', gradle: 4.1

Ejrr1085
источник
2

Вы можете создать собственный фон для вашего текстового представления. Шаги 1. Зайдите в свой проект. 2. Перейдите к ресурсам и щелкните правой кнопкой мыши, чтобы нарисовать. 3. Нажмите New -> Drawable Resource File 4. Присвойте имя файлу 5. Вставьте следующий код в файл

<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. Для вашего просмотра текста, где вы хотите использовать его в качестве фона,

    Android: фон = "@ вытяжка / your_fileName"

Ракеш П.
источник
1

Вот мой «простой» вспомогательный класс, который возвращает ImageView с границей. Просто поместите это в свою папку утилит и назовите это так:

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

Вот код

/**
 * 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;
    }
}
агрессор
источник
Как я могу использовать selectionBorder?
Таш Пемхива
@TashPemhiwa Button.setBackgroundDrawable ();
NinjaOnSafari
0

Это может помочь вам.

<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
Мета
источник
0

Создайте вид границы с цветом фона в качестве цвета границы и размера вашего текстового представления. установить заполнение вида границы как ширину границы. Установите цвет фона текстового представления как цвет, который вы хотите для текстового представления. Теперь добавьте ваш текстовый вид внутри вид границы.

Правин Агравал
источник
0

Попробуй это:

<shape>
    <solid android:color="@color/txt_white"/>
    <stroke android:width="1dip" android:color="@color/border_black"/>
</shape>
Мохамад Шейхи
источник
0

Есть много способов добавить границу в textView. Самый простой android:background="@drawable/textview_bg"способ - создать пользовательский объект рисования и настроить его так же, как для вашего textView.

Textview_bg.xml будет идти под Drawables и может быть что-то вроде этого. Вы можете иметь solidили gradientфон (или ничего, если не требуется), cornersчтобы добавить угловой радиус иstroke добавить границу.

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>
Аканши Шривастава
источник
0
  <View
    android:layout_width="match_parent"
    android:layout_height="2dp"
    android:background="@android:color/black" />

этот код достаточно вы можете разместить где вы хотите

Санджай
источник
0

setBackground в вашем текстовом представлении xml,

добавьте файл rounded_textview.xml в каталог для рисования.

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

установить рисуемый файл в фоновом режиме textView.

Рохит Сони
источник
-1

На самом деле, это очень просто. Если вам нужен простой черный прямоугольник за Textview, просто добавьте android:background="@android:color/black"теги TextView. Нравится:

<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
источник
он просит границы не полный фон.
Парень