SoFunction
Updated on 2025-03-11

Android homemade nine-grid unlock control

This article shares the specific code of Android's homemade nine-grid unlocking control for your reference. The specific content is as follows

Two days ago, I learned how to customize a nine-grid unlocked control from the Internet, so I wrote it according to the logic, and the code of the custom control is as follows:

public class LockedView extends View {
 
    private boolean isFirst = true;//Set true when loading for the first time, and then re-draw the picture and no longer execute it    private int width, height;//Get the width and height of the control    private int offsetX, offsetY;//Get the offsets of the X-axis and Y-axis when the point coordinates are obtained    private Point[][] pointList;//Array of coordinates of each point stored    private int r;//The radius of each circle    private Bitmap map1, map2, map3;//Bitmap of 3 states    private float eventX, eventY;//X and Y coordinates when touching the control    private boolean isPressed;//Judge whether the control is touched    private boolean moveOnPoint;//Judge whether it has moved to a point    private boolean isFinish;//Judge whether the gesture ends    private List<Point> list = new ArrayList<>();//Storing the collection of passing points    private Point checkedPoint;
    private Paint paint;//brush    public static final int LOCKED_FIRST=0;//The return value when setting password when loading the first time the activity is loaded    public static final int LOCKED_TRUE=1;//Return value when unlocking successfully    public static final int LOCKED_FALSE=2;//Return value for failed unlock    private OnLockedChangedListener onLocked;//Interface callback 
    public LockedView(Context context, AttributeSet attrs) {
        super(context, attrs);
 
    }
 
    @Override
    protected void onDraw(Canvas canvas) {
        (canvas);
        //Judge whether it is loaded for the first time        if (isFirst) {
            //Initialize point coordinates            initPoints();
            //Initialize the brush            initPaint();
            isFirst = false;
        }
        //Draw the corresponding bitmap according to the state of each point        drawPoints(canvas);
        //Draw lines during gesture sliding        drawLines(canvas);
    }
 
    //Initialize the brush    private void initPaint() {
        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        //Set the brush color to blue        (getResources().getColor());
        //Set the width of the brush to 8        (8);
    }
 
    //Draw lines    private void drawLines(Canvas canvas) {
        //If the set has a value        if (() > 0) {
            //Get the example of starting point            Point startPoint = (0);
            for (int i = 1; i < (); i++) {
                //Get an instance of the stop point                Point stopPoint = (i);
                //Draw lines based on the coordinates of the starting point and the stop point coordinates                ((), (), (), (), paint);
                // Assign the stop point to the starting point, so that the starting point is the previous point every time iterates                startPoint = stopPoint;
            }
            //If it does not move to a point            if (moveOnPoint == false) {
                //Draw lines based on the coordinates of the last point and the coordinates of the current gesture moving                ((), (), eventX, eventY, paint);
            }
 
        }
    }
 
    //Set touch events    @Override
    public boolean onTouchEvent(MotionEvent event) {
        //Get the X coordinate of the touch        eventX = ();
        //Get the Y coordinate of the touch        eventY = ();
        //Every time you touch it and leave the screen, it defaults to not complete        isFinish = false;
        //The default move to the point        moveOnPoint = true;
        //Selected point        checkedPoint = null;
        switch (()) {
            case MotionEvent.ACTION_DOWN:
                //If pressed, reset the next point                reset();
                //Judge whether a circle is touched based on the X and Y coordinates and the radius of the circle. If there is, return to the instance, and if there is no, return to empty                checkedPoint = checkPoint(eventX, eventY, r);
                if (checkedPoint != null) {
                    //If the instance is not empty, set the selected point status to select                    (Point.POINT_XUANZHONG);
                    //Set to true when pressing to point for the first time                    isPressed = true;
                }
                break;
            case MotionEvent.ACTION_MOVE:
                //If pressed on a point, the logic of the movement action will be executed                if (isPressed) {
                    //Same as above                    checkedPoint = checkPoint(eventX, eventY, r);
                    if (checkedPoint != null) {
                        (Point.POINT_XUANZHONG);
                        //If the instance is not empty, the setting moves to the point                        moveOnPoint = true;
                    } else {
                        // Otherwise the settings are not moved to the point                        moveOnPoint = false;
                    }
                }
                break;
            case MotionEvent.ACTION_UP:
                //When lifting, set the first parameter pressed on the point to false and complete the touch process                isPressed = false;
                isFinish = true;
                break;
            case MotionEvent.ACTION_CANCEL:
                isPressed = false;
                isFinish = true;
                break;
        }
        //If the first press is pressed on the point and the touch is not completed and the instance of the selected point is not empty        if (isPressed && !isFinish && checkedPoint != null) {
            //Judge whether this instance is in the list collection            if (isInList(checkedPoint)) {
                //If in, the setting is not moved on point                moveOnPoint = false;
            } else {
                //Otherwise add it to the collection                (checkedPoint);
            }
            //If touch is completed        } else if (isFinish) {
            if (() > 0) {
                //If the set length is 1, it means that only a point has been touched and reset it directly                if(()==1){
                    reset();
                    //If the set length is less than 5, it means that the password is too short and does not meet the requirements. Set the selected point to the error state and return the data through the interface callback                }else if(()<5){
                    errorPoint();
                    if(onLocked!=null){
                        ("The password is too short");
                    }
                    //If the set length meets the requirements, the return value of the interface can be used to determine different situations.                }else if(()>=5){
                    StringBuffer buffer=new StringBuffer();
                    for(int i=0;i<();i++){
                        ((i).getIndex());
                    }
                    if(onLocked!=null){
                        switch ((())){
                            // When you open the activity for the first time, there is no value in shared, and the current password is stored in shared                            case LOCKED_FIRST:
                                ("Set password successfully");
                                reset();
                                break;
                            //If there is a value in shared, compare the current password value according to the value. If the same, the unlocking will be successful, and if the difference will be failure.                            case LOCKED_TRUE:
                                ("Unlocked successfully");
                                reset();
                                break;
                            case LOCKED_FALSE:
                                ("Unlock failed");
                                errorPoint();
                                break;
                        }
                        //Recall the onDraw method                        postInvalidate();
                        //This time I touched it to consume                        return true;
                    }
 
                }
            }
        }
 
        postInvalidate();
        return true;
    }
 
    //Set the status of the wrong point    private void errorPoint() {
        for(int i=0;i<();i++){
            (i).setState(Point.POINT_XUANCUO);
        }
    }
 
    //Discribing whether the point is in the set    private boolean isInList(Point checkedPoint) {
        return (checkedPoint);
    }
 
    //Judge whether a circle has been touched based on the X, Y axis coordinates and circle radius of the touch point    private Point checkPoint(float eventX, float eventY, int r) {
        for (int i = 0; i < ; i++) {
            for (int j = 0; j < pointList[i].length; j++) {
                Point point = pointList[i][j];
                double juli = getPointJuli(eventX, eventY, (), ());
                if (juli < r) {
                    return point;
                }
            }
        }
        return null;
    }
 
    //Reset Point    private void reset() {
        for (int i = 0; i < (); i++) {
            (i).setState(Point.POINT_MOREN);
        }
        ();
    }
 
    //Get the distance between two points    private double getPointJuli(float eventX, float eventY, int x, int y) {
        return ((eventX - x) * (eventX - x) + (eventY - y) * (eventY - y));
    }
 
 
    //Draw points according to the status of the points    private void drawPoints(Canvas canvas) {
        for (int i = 0; i < ; i++) {
            for (int j = 0; j < pointList[i].length; j++) {
                Point point = pointList[i][j];
                switch (()) {
                    case Point.POINT_MOREN:
                        (map1, () - r, () - r, null);
                        break;
                    case Point.POINT_XUANZHONG:
                        (map2, () - r, () - r, null);
                        break;
                    case Point.POINT_XUANCUO:
                        (map3, () - r, () - r, null);
                        break;
                }
            }
        }
    }
 
    //Initialize point coordinates and bitmap    private void initPoints() {
        //Get the width of the control        width = getWidth();
        //Get the height of the control        height = getHeight();
        //Set the offset of X to 0        offsetX = 0;
        //Set the offset of Y to 0        offsetY = 0;
        //If it is a vertical screen        if (width < height) {
            offsetY = (height - width) / 2;
            height = width;
        } else {
            offsetX = (width - height) / 2;
            width = height;
        }
        //Create a Point array to store the coordinates of points        pointList = new Point[3][3];
        //Set the index to judge the password        int index=1;
        //Travel, use the algorithm to calculate the coordinates of each point        for (int i = 0; i < ; i++) {
            for (int j = 0; j < pointList[i].length; j++) {
                pointList[i][j] = new Point(offsetX + width / 4 * (i + 1), offsetY + height / 4 * (j + 1));
                pointList[i][j].setIndex(index);
                index++;
            }
        }
        //Set 3 bitmaps, which are the default state, selected state, and the wrong state are the default state.        map1 = (getResources(), );
        map2 = (getResources(), );
        map3 = (getResources(), );
        //Get the radius of the circle        r = () / 2;
    }
 
    public void setOnLockedChangedListener(OnLockedChangedListener onLocked){
        =onLocked;
    }
 
    //Set the callback interface    public interface OnLockedChangedListener{
        public int onPassword(String password);
        public void onResult(String result);
    }
}

activity code:

public class LockedActivity extends Activity {
 
    private LockedView lockedView;
    private TextView textView;
    private SharedPreferences preferences;
    private String pass;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        (savedInstanceState);
        setContentView(.activity_locked);
        //Initialize the control        lockedView= (LockedView) findViewById();
        textView= (TextView) findViewById();
        //Get shared        preferences=getSharedPreferences("Locked",MODE_PRIVATE);
        //Get password value based on the key stored in shared        pass=("password","");
        //If there is no activity that represents the first time, the textview sets the text to set the password. If it is not the first time, the text is set to unlock.        if(("")){
            ("Please set password");
        }else{
            ("Please unlock");
        }
        (new () {
            @Override
            public int onPassword(String password) {
                //Get the value from shared                pass=("password","");
                //If the value is empty, save the password returned by the interface into shared                if(("")){
                     editor=();
                    ("password",password);
                    ();
                    ("Please unlock");
                    return 0;
                }else if((password)){
                    //If the password is matched, return the number 1 means that the unlocking is successful                    return 1;
                }
                //If the password does not match, return 2                return 2;
            }
 
            @Override
            public void onResult(String result) {
                //Get the data to be toast from the interface according to the password matching situation                (,result,Toast.LENGTH_SHORT).show();
                //The data is unlocked successfully, then jump to the activity                if(("Unlocked successfully")){
                    Intent intent=new Intent(,);
                    startActivity(intent);
                }
            }
        });
    }
}

The layout code is as follows:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:andro
    xmlns:tools="/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
 
    <.
        android:
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    <TextView
        android:
        android:textSize="20sp"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="50dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</RelativeLayout>

The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.