Android Custom View Implementation Verification code _android

Source: Internet
Author: User
Tags drawtext getcolor stringbuffer

This article is based on some of the extensions of the Android Custom view (i) and some of the contents of the Android Custom view constructor.

First, we define a declare-styleable tag declare-styleable tag that is used to add custom attributes to a custom control.
(We define the color, size, length, and background color of the text)

<declare-styleable name= "Customtitleview" >
 <attr name= "titlecolor" format= "color"/>
 <attr Name= "Titlesize" format= "Dimension"/> <attr name= "titlebackground"
 format= "color"/>
 <attr Name = "Titlelenth" format= "integer"/>
 </declare-styleable>

Android provides a way to customize properties, where the parameters for the format are
(Reference, Color, Boolean, dimension, Float, Integer, String, fraction, enum, flag)

1.reference: Resource ID:
If this property is set, then this property corresponds to the function of invoking a resource file, such as @string| @drawable
2. Color:
the function of this property is to set a color value of 8 or 6 bits of the 16 color value, such as setting TextView TextColor properties such as the same (such as #ff000 set to red, etc.)
3.boolean:
The function of this parameter is to set TRUE or False
4.dimension:
The function of this parameter is to set the dimension value, such as PX, dip, DP, SP, etc.
5.float:
The function of this parameter is to set the floating-point data
6.integer:
The function of this parameter is to set the shaping data
7.string:
the function of this parameter is to set string data, such as TextView's Text property
8.fraction:
the function of this parameter is to set the percent data
9:enum:
This parameter is equivalent to setting a fixed parameter to the Attr Name property, such as the orientation property of the linear layout can only be set vertical or horizontal
10:flag:
This parameter functions as: bit or operation

The steps for a custom view are

1. Customize View Properties
2, in the view of the construction method to get our custom attributes
3. Rewrite onmeasure
4. Rewrite OnDraw

Sometimes onmeasure methods are not rewritten, such as system self-contained components, etc.
And then we define the attributes we need.

 Text
 private StringBuffer mtitletext;
 The color of the text is
 private int mtitlecolor;
 The size of the text is
 private int mtitlesize;
 Background color
 private int mbackground;
 Control generated random string length
 private int mlenth;
 Control the range of text rendering when drawing
 private Rect mbound;
 Brush
 private Paint mpaint;
 Random Number Object
 private Random Random = new Random ();
 String margin
 private int padding_left;
 Random value
 string[] data = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "s" , "T", "U", "V", "w", "X", "Y", "Z", "
  A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "
  0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};

And then we rewrite three construction methods, and we need to be aware that

1, the first constructor is called when you directly new a custom view instance in your code.
2. When a custom view is invoked in an XML layout file, the second constructor is invoked.
3. Call the custom view in the XML layout file, and the second constructor is called here when there are custom attributes in the custom label.

That is, the system defaults to only the first two constructors of custom view, and the invocation of the third constructor, which is usually our own active invocation in the constructor (for example, invoking the third constructor in the second constructor).
as to the acquisition of custom attributes, it is usually done through the Obtainstyledattributes function in the constructor.

Public Customtitleview {This (context, NULL);
 Public Customtitleview (context, AttributeSet attrs) {This (context, attrs, 0);
 Public Customtitleview (context, AttributeSet attrs, int defstyleattr) {Super (context, attrs, defstyleattr);
 Setonclicklistener (this);
 TypedArray TypedArray = context.obtainstyledattributes (Attrs, R.styleable.customtitleview);
 int n = typedarray.getindexcount ();
  for (int i = 0; i < n; i++) {int attr = Typedarray.getindex (i);
   Switch (attr) {Case r.styleable.customtitleview_titlecolor:mtitlecolor = Typedarray.getcolor (attr, Color.Black);
  Break Case r.styleable.customtitleview_titlesize:mtitlesize = Typedarray.getdimensionpixelsize (attr, (int)
   Typedvalue.applydimension (TYPEDVALUE.COMPLEX_UNIT_SP, Getresources (). Getdisplaymetrics ()));
  Break
   Case r.styleable.customtitleview_titlebackground:mbackground = Typedarray.getcolor (attr, Color.Black);
  Break Case R.STYLEABLE.CUSTOMTITleview_titlelenth:mlenth = Typedarray.getinteger (attr, 4);
  Break
 }///recycle typedarray.recycle ();
 Mpaint = new Paint ();
 Randomtext ();
 Mpaint.settextsize (mtitlesize);
 Create a rectangle mbound = new Rect (); The first parameter is the text to be measured, the second parameter is the starting position of the measurement, the third parameter is the position of the last string to measure, and the fourth parameter is the Rect object Mpaint.gettextbounds (mtitletext.tostring (), 0,
 Mtitletext.length (), mbound);

 }

The second property of the

Obtainstyledattributes is to invoke the name of the declare-styleable tag that you just had in Attrs.xml file, and then we rewrite the Onmeasure method, The width and height

is computed by the Getmeasuredlength method.

/** * COMPUTE Width High * * @param lenth widthmeasurespec or Heightmeasurespec * @param iswidth true to compute width, false to calculated height */private int Getmeasuredlength (int lenth, Boolean iswidth) {if (iswidth) {if (Measurespec.getmode (lenth) = = measurespec.exactly)
  {//Set the exact size, get the dimension return width by measurespec.getsize () measurespec.getsize (lenth); else {//set warp_content, we need to compute/** * First set the text size for the brush * The width of the drawn text is obtained by the Gettextbounds method * and then because our custom view has only one TE XT so we only need Getpaddingleft () +getpaddingright () +textwidth to calculate the minimum width required to display the view * The general calculation width is getpaddingleft () + Getpaddingright () + own painting of the text or the width of the picture, because the calculation is the desired width, if we draw the picture + text, then we need to judge the width of the picture and the width of the text that larger such as getpaddingleft () + Getpaddingright () +math.max (the width of the picture, the width of the text) is the desired width */if (Measurespec.getmode (lenth) = Measurespec.at_most) {mpaint.
   Settextsize (mtitlesize);
   Mpaint.gettextbounds (mtitletext.tostring (), 0, Mtitletext.length (), mbound);
   float textwidth = Mbound.width ();
   int desired = (int) (Getpaddingleft () + textwidth + getpaddingright ()); Return Math.min (Desired,measurespec.getsize (lenth));
  '}} else {if (Measurespec.getmode (lenth) = = measurespec.exactly) {//the user has set the exact size, obtains the dimension return height through measurespec.getsize ()
  Return Measurespec.getsize (lenth); else {if (Measurespec.getmode (lenth) = = Measurespec.at_most) {//Set warp_content, then we need to compute mpaint.settextsize (m
   Titlesize);
   Mpaint.gettextbounds (mtitletext.tostring (), 0, Mtitletext.length (), mbound);
   float texthgeight = Mbound.height ();
   int desired = (int) (Getpaddingtop () + Texthgeight + getpaddingbottom ());
  Return Math.min (Desired,measurespec.getsize (lenth));
 }} return 0;

 }

And then call in the Onmeasure method.

@Override
 protected void onmeasure (int widthmeasurespec, int heightmeasurespec) {
 setmeasureddimension ( Getmeasuredlength (Widthmeasurespec, True), Getmeasuredlength (Heightmeasurespec, false));
 

The system helps us measure the height and width is match_parnet, when we set the clear width and height, the system helps us to measure the result is the result that we set, when we set to Wrap_content, or Match_ The parent system helps us measure the result is the length of the match_parent.
So, when Wrap_content is set, we need to measure ourselves, that is, to rewrite the Onmeasure method

Before rewriting, understand Measurespec's specmode, altogether three types:
exactly: usually set a definite value or a match_parent
At_most: indicates that the child layout is restricted to a maximum value, typically warp_content
UNSPECIFIED: indicates how big the child layout wants, and is rarely used

Here some beginners may not understand the role of GetMode and GetSize, first getmode () used to determine the mode of wide-height settings, after which can be judged, for example

xx denotes widthmeasurespec or heightmeasurespec

if (Measurespec.getmode (XX) ==measurespec.exactly) {
 // Entering here means setting up match_parent or designating the control's layout_width or Layout_height as a specific value, such as andorid:layout_width= "100DP", This allows us to get a wide or high 
}else if (Measurespec.getmode (XX) ==measurespec.exactly) by Measurespec.getsize (XX)
 Enter here to set the wrap_content, then we need to compute their own width or high
}else{
 //Enter this representative is not specified size, this situation is not much, usually the parent control is Adapterview, Mode passed through the measure method
}

And then we rewrite the OnDraw method,

 @Override protected void OnDraw (Canvas Canvas) {Super.ondraw (Canvas);
 Padding_left = 0;
 Mpaint.setcolor (Mbackground);
 Canvas.drawrect (0, 0, getmeasuredwidth (), Getmeasuredheight (), mpaint);
 Mpaint.setcolor (Mtitlecolor);
  for (int i = 0; i < mtitletext.length (); i++) {Randomtextstyle (mpaint);
  Padding_left + + mpaint.measuretext (string.valueof (Mtitletext.charat (i))) +10;
 Canvas.drawtext (string.valueof (Mtitletext.charat (i)), Padding_left, GetHeight ()/2 + mbound.height ()/2, mPaint); }} private void Randomtextstyle (Paint Paint) {Paint.setfakeboldtext (Random.nextboolean ());//true is bold and false is not bold float
 Skewx = Random.nextint (11)/10; Skewx = Random.nextboolean ()?
 SKEWX:-skewx; Paint.settextskewx (SKEWX); Float type parameter, negative number indicates right oblique, integer left oblique paint.setunderlinetext (true); True is underlined, false is not underlined paint.setstrikethrutext (false); True is strikethrough, false is not strikethrough} 

There are a number of strings drawn here, and each drawn string is crooked so that we use Randomtextstyle () to set each character to a different style each time we draw the character, and here we'll talk about some of the DrawText parameters, The first parameter is the text to be drawn, the second parameter is the x axis, the function is equal to the left margin, the third parameter is the Y axis, the fourth parameter is paint instance, my friend specifically spoke about the DrawText's plotting coordinates interested can go to see Android canvas DrawText () text centered

Finally, we reference our custom view in the layout file.

<?xml version= "1.0" encoding= "Utf-8"?> <relativelayout xmlns:android=
"http://schemas.android.com/apk" /res/android "
 xmlns:cq=" Http://schemas.android.com/apk/res-auto "
 android:layout_width=" Match_parent "
 android:layout_height= "match_parent"
 android:orientation= "Horizontal" >

 < Chapter.com.rxjavachapter.CustomTitleView
 android:layout_width= "wrap_content"
 android:layout_height= " Wrap_content "
 android:layout_centerinparent=" true "
 android:padding=" 10DP "
 cq:titlebackground=" @ Android:color/black "
 cq:titlecolor=" #ff0000 "
 cq:titlelenth=" 4 "
 cq:titlesize=" 10sp "/>

</RelativeLayout>

Add xmlns:xx= "Http://schemas.android.com/apk/res-auto" in the root layout the XX here can be any letter
And then use XX to point us in the attr name to set the value, and finally realize the effect is this

Since it is the verification code view, then we naturally want to open the click to change the content of the verification Code click event, in the third construction method to add the Click event

 @Override public
 void OnClick (View v) {
 randomtext ();
 Postinvalidate ();
 }
/**
 * Obtains a random string
 *
 * @return
 /private void Randomtext () {
 mtitletext = new StringBuffer (); c12/>for (int i = 0; i < Mlenth i++) {
  mtitletext.append (data[(int) (Math.random () * data.length)]);
 }

 /**
 * Obtained to a random value
 *
 * @return
 /Public String GetCode () {return
 mtitletext.tostring ();
 }

 /**
 * To determine whether the same
 *
 * @return
 /Public
 boolean isequal (String code) {
 if (code!= NULL) {return
  code.touppercase (). Equals (GetCode (). toUpperCase ())? True:false;
 } else {return
  false;
 }
 }

So you can click to change the content of the verification code, and we open up two methods as a verification code or get the verification code, I this is just a simple verification code, you can add more things themselves.

The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.