Using XML to implement borders
The original use of the TextView with a border is usually done with an XML definition, in the drawable directory, the following XML file is defined as follows:
<?xml version="1.0"encoding="Utf-8"? ><selector xmlns:android="http://schemas.android.com/apk/res/android"> <!--Click button background Style-<item android:state_pressed="true"> <shape android:shape="Rectangle"> <corners android:radius="2DP"/> <solid android:color="@android: Color/transparent"/> <stroke android:width="1DP"Android:color="#ff48beab"/> </shape> </item> <!--normal Click button Background style--<item android:state_pressed="false"> <shape android:shape="Rectangle"> <corners android:radius="2DP"/> <solid android:color="@android: Color/transparent"/> <stroke android:width="1DP"Android:color="#ff48baab"/> </shape> </item></selector>
This enables rounded borders, but the colors are fixed, and if you need to place different textview (such as multiple-color buttons) in different locations, define multiple XML files with different colors.
Customizing the TextView with borders
Recently in the project encountered a variety of color labeling requirements, if still follow the above approach, then need more than a set of XML file mates, so I thought about it, can not customize a control, so that the border color when used to specify.
In the project's design diagram is mainly used for some labels, as shown in:
Then I tried it and found it feasible, so I have the following customization, which is basically enough for a personal project.
This control is inherited from TextView, just a border is drawn in the OnDraw method, and several custom properties are designed to control the control more flexibly.
The custom attributes are as follows:
<declare-styleable name="Bordertextview"> <attr name="Strokewidth"format="Dimension"/> <attr name="Cornerradius"format="Dimension"/> <attr name="Strokecolor"format="Color"/> <attr name="Followtextcolor"format="Boolean"/></declare-styleable>
These properties are briefly explained in the following sections:
- Strokewidth
Width of border, default is 1DP
- Cornerradius
Fillet radius, default is 2DP
- Strokecolor
Border color, default is no border that color is color.transparent
- Followtextcolor
Whether the border follows the text color, which is true by default
Custom control Code (BORDERTEXTVIEW):
Package Com.witmoon.eab.widget;import Android.content.context;import android.content.res.typedarray;import Android.graphics.canvas;import Android.graphics.color;import Android.graphics.paint;import Android.graphics.RectF ; import Android.support.annotation.nonnull;import Android.util.attributeset;import android.util.DisplayMetrics; Import Android.util.typedvalue;import android.widget.textview;import COM.WITMOON.EAB.R;/** * The TextView * border is used as a label to display the default text color consistent with * Created by chuxin on 2015/9/11.*/ Public classBordertextview extends TextView { Public StaticFinalfloatDefault_stroke_width =1.0f;//default border width, 1DP Public StaticFinalfloatDefault_corner_radius =2.0f;//default fillet radius, 2DP Public StaticFinalfloatdefault_lr_padding = 6f;//default left and right padding Public StaticFinalfloatdefault_tb_padding = 2f;//default up and down padding Private intStrokewidth;//Border line width Private intStrokecolor;//Border Color Private intCornerradius;//Fillet radius PrivateBoolean mfollowtextcolor;//whether the border color follows the text color PrivatePaint Mpaint =NewPaint ();//draw a border using the Brush object PrivateRECTF MRECTF;//draw a border to use the rectangle PublicBordertextview (Context context) { This(Context,NULL); } PublicBordertextview (Context context, AttributeSet attrs) { This(Context, Attrs,0); } PublicBordertextview (context context, AttributeSet attrs,intdefstyleattr) {Super (context, attrs, defstyleattr); //Convert Dip Unit default value to PXDisplaymetrics Displaymetrics =context.getresources (). Getdisplaymetrics (); Strokewidth= (int) typedvalue.applydimension (Typedvalue.complex_unit_dip, Default_stroke_width, displaymetrics); Cornerradius= (int) typedvalue.applydimension (Typedvalue.complex_unit_dip, Default_corner_radius, displaymetrics); //Reading property valuesTypedArray TA =context.obtainstyledattributes (Attrs, R.styleable.bordertextview); Strokewidth=ta.getdimensionpixelsize (R.styleable.bordertextview_strokewidth, strokewidth); Cornerradius=ta.getdimensionpixelsize (R.styleable.bordertextview_cornerradius, Cornerradius); Strokecolor=Ta.getcolor (R.styleable.bordertextview_strokecolor, color.transparent); Mfollowtextcolor= Ta.getboolean (R.styleable.bordertextview_followtextcolor,true); Ta.recycle (); MRECTF=NewRECTF (); //Border default color is the same as text color//if (Strokecolor = = color.transparent)//Strokecolor = Getcurrenttextcolor (); //Set default margins if no padding is set when using intPaddingleft = getpaddingleft () = =0? (int) typedvalue.applydimension (Typedvalue.complex_unit_dip, Default_lr_padding, displaymetrics): GetPadd Ingleft (); intPaddingright = getpaddingright () = =0? (int) typedvalue.applydimension (Typedvalue.complex_unit_dip, default_lr_padding, Displaymet RICS): Getpaddingright (); intPaddingtop = getpaddingtop () = =0? (int) typedvalue.applydimension (Typedvalue.complex_unit_dip, Default_tb_padding, displaymetrics): GetPadd Ingtop (); intPaddingbottom = Getpaddingbottom () = =0? (int) typedvalue.applydimension (Typedvalue.complex_unit_dip, default_tb_padding, Displaymet RICS): Getpaddingbottom (); Setpadding (Paddingleft, Paddingtop, Paddingright, paddingbottom); } @Overrideprotected voidonDraw (@NonNull canvas canvas) {super.ondraw (canvas); Mpaint.setstyle (Paint.Style.STROKE); //Hollow EffectMpaint.setantialias (true);//set the brush to be non-aliasedMpaint.setstrokewidth (Strokewidth);//line width//sets the color of the border line, if it is declared as a border following the text color and the current border color and the text color do not reset the border color if(Mfollowtextcolor && Strokecolor! =Getcurrenttextcolor ()) Strokecolor=Getcurrenttextcolor (); Mpaint.setcolor (Strokecolor); //draw a rectangle with hollow rounded cornersMrectf.left = Mrectf.top =0.5f*Strokewidth; Mrectf.right= Getmeasuredwidth ()-Strokewidth; Mrectf.bottom= Getmeasuredheight ()-Strokewidth; Canvas.drawroundrect (MRECTF, Cornerradius, Cornerradius, Mpaint); }}
The comments in the code are also more detailed and very simple, so there should be no need to repeat them here. The only thing to note is the RECTF size used when drawing the border, if the border width is wide, because the paint stroke is in the center of the border, so if the upper-left corner is specified as (0,0), half the border width of the line is drawn in the invisible area; Specify the upper-left coordinate at 0.5f * Strokewidth (that is, half the border width), the lower right corner also needs to be considered.
Use
The use of custom controls is even simpler, where I do not set custom properties, all with default values:
<com.witmoon.eab.widget.BorderTextView android:layout_width="wrap_content " android:layout_height="wrap_content" android:text= " Identity Verification " Android:textcolor="@color/tag_text_blue"/>
The display looks like this:
Basically meet the requirements.
Use as a button
At some point, we may need some of these middle cutout buttons, Bordertextview can also be used in this case, below is an example.
Start by creating a new colors directory in the values directory, where you create an XML file (Button_text_color.xml) with the following
<?xml version="1.0"encoding="Utf-8"? ><selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:color="@color/secondary_text"Android:state_pressed="true"/> <item android:color="@color/hint_text"Android:state_enabled="false"/> <item android:color="@color/primary_text"/></selector>
In fact, for the button in different states to specify a different color in response to click or disable the operation, increase the user experience.
<Com.witmoon.eab.widget.BorderTextView Android:id="@+id/retrieve_check_code_again"Android:layout_width="wrap_content"Android:layout_height="wrap_content"Android:paddingbottom="6DP"android:enabled="false"Android:textcolor="@color/button_text_color"Android:paddingtop="6DP"Android:text="re-send"/>
Because the border is followed by the text color by default, TextView is redrawn when clicked or disabled, and the border changes color.
Android custom Controls--TextView with borders