822 votes

Comment mettre une bordure autour d'une fenêtre de texte Android ?

Est-il possible de dessiner une bordure autour d'une fenêtre de texte ?

0 votes

J'ai posté une sale solution ici : stackoverflow.com/a/45242147/4291937

2 votes

Regardez mon réponse en une phrase ci-dessous.

0 votes

Avec le Composants matériels utilisez simplement un MaterialShapeDrawable : stackoverflow.com/questions/18781902/

1408voto

Konstantin Burov Points 34011

Vous pouvez définir une forme traçable (un rectangle) comme arrière-plan pour la vue.

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

Et rectangle drawable back.xml (mis dans le dossier 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>

Vous pouvez utiliser @android:color/transparent pour que la couleur solide ait un fond transparent. Vous pouvez également utiliser le padding pour séparer le texte de la bordure. Pour plus d'informations, voir : http://developer.Android.com/guide/topics/resources/drawable-resource.html

90 votes

Et si je ne veux que la bordure supérieure ?

21 votes

@whyoz Sa méthode ajoute une complexité inutile à la hiérarchie des vues. Vous aurez besoin de deux vues supplémentaires (un conteneur de mise en page et la vue de la bordure) pour utiliser sa méthode. Ainsi, si vous avez de nombreuses vues auxquelles vous devez ajouter une bordure, votre arbre de vues deviendra ingérable.

5 votes

@whyoz pourtant cette méthode peut être appliquée via des styles et des thèmes, alors que la méthode de YongGu ne peut pas être utilisée de cette façon.

52voto

Young Gu Points 331

Le moyen le plus simple est d'ajouter une vue pour votre TextView. Exemple pour la ligne de bordure inférieure :

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

Pour les bordures dans l'autre sens, veuillez ajuster l'emplacement de la vue séparatrice.

3 votes

D'après mon expérience, cette solution, sur les anciens appareils, a un impact discret et visible sur les performances de l'application.

47 votes

C'est une solution horrible du point de vue de l'inflation. Vous créez 3 nouveaux éléments de vue et ajoutez un niveau supplémentaire dans la profondeur de la hiérarchie des vues.

0 votes

La pire solution en raison de la perspective d'inflation de la vue comme l'a dit Philipp. Savez-vous que les TextView ont des balises xml spécifiques pour faire cela : définir une image à dessiner à gauche/droite/haut/bas autour de votre TextView, et elles sont connues sous le nom de Android:drawable****.

34voto

Bojan Jovanovic Points 339

J'ai résolu ce problème en étendant la fenêtre de texte et en dessinant une bordure manuellement. J'ai même ajouté la possibilité de choisir si la bordure est en pointillés ou en tirets.

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

Et la classe frontalière :

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

J'espère que cela aidera quelqu'un :)

0 votes

Comment initialiser les frontières ?

0 votes

Cela ne peut pas fonctionner correctement, car le code montre qu'il dessine les frontières à la moitié de la taille de la valeur définie.

15voto

sdtechcomm Points 306

J'étais justement en train de regarder une réponse similaire - il est possible de le faire avec un Stroke et la commande suivante :

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

0 votes

Super ! Mon seul souci est que le trait est moche dans les coins lorsque j'utilise drawRoundRect, à la fois sur le téléphone et dans l'émulateur.

1 votes

@erdomester Maybe Paint StrokePaint = new Paint(Paint.ANTI_ALIAS_FLAG) ; résoudra le problème du "laid dans les coins".

11voto

Nick Points 976

J'ai trouvé une meilleure façon de mettre une bordure autour d'un TextView.

Utilisez une image de neuf patchs pour le fond. C'est assez simple, le SDK est fourni avec un outil permettant de créer l'image 9-patch, et cela implique absolument pas de le codage.

Le lien est le suivant http://developer.Android.com/guide/topics/graphics/2d-graphics.html#nine-patch .

3 votes

Utile, oui, mais en quoi est-ce mieux ?

3 votes

L'utilisation d'une forme, comme le dit la réponse acceptée, est meilleure qu'un 9-patch, un fichier XML est plus flexible qu'un actif graphique.

0 votes

Bien sûr, si vous voulez être limité à la création programmatique des graphiques que vous voulez, alors c'est plus flexible.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X