recently used a password and lock function. It needs a digital password interface. It wants to be encapsulated into a View to facilitate management and use.

waste not much said, first on the final effect map:

ideas generally can be divided into 2 parts to be realized, 1. top is the 4 password bit filling; 2 Digital keyboard part. The whole can be a vertical LinearLayout, and 4 cipher bits can be used with horizontal LinearLayout, because the keyboard is in the form of a palace, so it can be laid out by GridLayout. Because password bits and keyboard numbers are in the background of a circle, a custom circular background ImageView is used here.

implements

1. page layout

first definition of a round background ImageView, because the ultimate realization of the effect is to fill the round background when clicking, the non click state is the empty circle, so can be changed by changing Paint to move

 / * * * circular background ImageView (set solid or hollow) * / public class CircleImageView extends ImageView{private Paint mPaint; Public CircleImageView (Context context, AttributeSet attrs) {this (context, attrs, 0);} public CircleImageView. {mPaint = new Paint (); mPaint.setStyle (Paint.Style.STROKE); mPaint.setColor (mPanelColor); mPaint.setStrokeWidth (mStrokeWidth); mPaint.setAntiAlias (true); {} {} SizeChanged (W, h, oldw, oldh); mWidth = w; mHeight = h; @Override public void. Circle {() {mPaint.setStyle (Paint.Style.FILL); invalidate ();} / * * setting the circle as hollow state * / public void setStrokeCircle () {mPaint.setStyle (Paint.Style.STROKE); invalidate ();}} 

can be seen, plotted in a circle, silent It is considered that the hollow state defines two methods of setFillCircle and setStrokeCircle so that the outside can be conveniently switched to solid or hollow. The

circular ImageView is well defined, and the password bit is added, and the layout is as follows:

 inputResultView = new LinearLayout (context); for (int i=0); New LinearLayout.LayoutParams (mResultIvRadius, mResultIvRadius); params.leftMargin = dip2px (context, 4); params.rightMargin = dip2px (context, 4); mResultItem.setPadding (dip2px (2), 2, 2); ; inputResultView.addView (mResultItem);} LinearLayout.LayoutParams params = new LinearLayout.LayoutParams (ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); params.gravity = Gravity.CENTER_HORIZONTAL; params.bottomMargin = dip2px (34); YoutParams (params); addView (inputResultView); 

then add the layout of the digital keyboard part:

 GridLayout numContainer = new GridLayout; NumItem.setPadding (mPaddingLeftRight, mPaddingTopBottom, mPaddingLeftRight, mPaddingTopBottom); RelativeLayout.LayoutParams gridItemParams = new RelativeLayout.LayoutParams (mNumRadius, mNumRadius); gridItemParams.addRule. Tv.setText (numArr[i]); numTv.setTextColor (mPanelColor); numTv.setTextSize (30); numTv.setGravity (Gravity.CENTER); numTv.setLayoutParams (gridItemParams); final CircleImageView numBgIv =; ); numItem.addView (numTv); numContainer.addView (numItem); if (I = = 9) {numItem.setVisibility (INVISIBLE)}} / / / / / / / delete button RelativeLayout deleteItem = new RelativeLayout; RelativeLayout.LayoutParams gridItemParams = new RelativeLayout.LayoutParams (mNumRadius, mNumRadius); gridItemParams.addRule (CENTER_IN_PARENT); / / / / / / if the delete button is set up a custom picture resource, you can annotate this segment //ImageView deleteIv = new ImageView. CE (R.drawable.icn_delete_pw); //deleteIv.setLayoutParams (gridItemParams); //deleteItem.addView (deleteIv); TextView deleteTv = new TextView (context); deleteTv.setText. MS); deleteTv.setGravity (Gravity.CENTER); deleteItem.addView (deleteTv); numContainer.addView (deleteItem); LinearLayout.LayoutParams gridParams = new LinearLayout.LayoutParams (ViewGroup.LayoutParams.WRAP_CONTENT,); NTAL; numContainer.setLayoutParams (gridParams); addView (numContainer); 

digital keyboard here uses an array to save digital content, traversing addition, notice that the tenth sub View is blank here, so it can be hidden when the tenth elements are traversed. After traversing, the delete button is added separately. The

2. input logic

page layout is completed, the next is the logical part of the password input, the final effect is a number per click, the password bit fills one, each click Delete button once, the password bit back one, input 4 numbers. After that, the input is completed, the result is obtained, and the password bit is reset. Here, a StringBuilder variable is used to record the currently entered password. Every time append is added, the deleteCharAt is called after each deletion.

is filled at the time of clicking the number, and it is hollow when it is loosened, so it can be operated separately in the ACTION_DOWN and ACTION_UP events:

 numTv.setOnTouchListener (New OnTouchListener () {@Override public Boolean] EtAction ()) {case MotionEvent.ACTION_DOWN: numBgIv.setFillCircle (); numTv.setTextColor (Color.WHITE); if (mPassWord.length () < 4) {mPassWord.append (numTv.getText ()); mResultIvList.get (); If (mInputListener! =null & & mPassWord.length () = = 4) {/ / / / / / has been fully input 4}} break; case MotionEvent.ACTION_UP: numBgIv.setStrokeCircle (); numTv.setTextColor (mPanelColor);};} Return true;}}); when 

clicks each time, determine whether the current password bit has exceeded 4 bits, and if not more, continue to add. If it is equal to 4, the input is completed, and the content of mPassWord at this time is the final password, which can be callback with an interface to get the input password in Activity:

 / * * monitor the completed interface * / private InputListener mInputListener; public void setInputListener. (InputListener mInputListener) {his.mInputListener = mInputListener;} public interface InputListener{void inputFinish (String result);} 

thereafter, and when the input number in the above is equal to the number equal to 4. SWord.length () = = = 4) {mInputListener.inputFinish (mPassWord.toString ());}

in addition, the deleted operation is encapsulated as a single method:

 / * * delete * / public void delete () {if (mPassWord.length () = = = 0) {} EtStrokeCircle (); mPassWord.deleteCharAt (mPassWord.length () -1);} 

attention point: currently without input password, direct return does not do any operation, if there is a number of input, delete the most tail of the number.

finally, also consider a situation, that is, some feedback when the user enters a password error, referring to usual habits, usually the 4 password bits swing and the cell phone vibration effect. After the vibration ends, the current password bit is reset to the initial state, as follows:

 / * * input error form. State display (including vibration, the rocking effect of the cipher bit, reset the cryptographic bit) * / public void showErrorStatus () {mVibrator.vibrate (New long[]{100100100100}, -1); List< Animator> animators = new ArrayList< "TranslationX, -50.0f, 50.0f, -50.0f, 0.0F); translationXAnim.setDuration (400); animators.add (translationXAnim); AnimatorSet btnSexAnimatorSet = new AnimatorSet. AtorListener () {@Override public void onAnimationStart (Animator animation) {} @Override public void onAnimationEnd (Animator) {{};} {} Public void onAnimationRepeat (Animator animation) {}});} 

can be seen to call resetResult in onAnimationEnd, that is, to reset the password at the end of the animation. The resetResult method is as follows:

 / * * * reset password input {} {} T; mResultIvList.size (); i++) {mResultIvList.get (I).SetStrokeCircle ();} mPassWord.d


This concludes the body part