1. 程式人生 > >Android 手勢解鎖詳解(包括一次解鎖、二次設定密碼)

Android 手勢解鎖詳解(包括一次解鎖、二次設定密碼)

最近看到手勢解鎖功能,網上有一些大牛寫了很多原始碼,不過功能或多或少對自己的專案有些不同,琢磨著自己也寫一個,技術還不到家,有些東西是參照網上的demo大笑

主要自定義View如下:

package com.example.androidgesture;
//                  _ooOoo_
//                 o8888888o
//                 88" . "88
//                 (| -_- |)
//                 O\  =  /O
//              ____/`---'\____
//            .'  \\|     |//  `.
//           /  \\|||  :  |||//  \
//          /  _||||| -:- |||||-  \
//          |   | \\\  -  /// |   |
//          | \_|  ''\---/''  |   |
//           \  .-\__  `-`  ___/-. /
//         ___`. .'  /--.--\  `. . __
//      ."" '<  `.___\_<|>_/___.'  >'"".
//    | | :  `- \`.;`\ _ /`;.`/ - ` : | |
//    \  \ `-.   \_ __\ /__ _/   .-` /  /
//=====`-.____`-.___\_____/___.-`____.-'======
//                  `=---='
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//         佛祖保佑       永無BUG

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.RelativeLayout;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;

/**
 * 作者:huangl on 2016-12-02 14:59
 * 郵箱:
[email protected]
* <p> * 類說明: */ public class GestureCustomView extends RelativeLayout { private String TAG = GestureCustomView.class.getSimpleName(); private int LINE_NUMBER; //行數 private int COLUMN_NUMBER; //列數 private GestureRound gestureViews[][]; //二維陣列儲存圓點總數 private int gestureViewWidth; //每個圓點的寬度 private int gestureBetweenWidth; //相鄰圓點的距離 private GestureData gestureData; private Context context; private Paint paintLine; //畫連線線的畫筆 private Path pathLine; //畫連線線的畫圖 private float moveX; //移動時X點座標 private float moveY; //移動時Y點座標 private float startX; //連線線起始點X座標 private float startY; //連線線起始點Y座標 private List<GestureRound> list; //儲存已經選中的圓點 private StringBuffer orderData; //儲存選中圓點的順序 private String fristData; //儲存第一次選擇的資料,用來判斷第二次選擇的資料,是否跟第一次一樣 private boolean isRound; //用來判斷第一次按下去的時候,是否在某一個圓點內 private int ID_NUMBER = 130059; //用來設定每個圓點的ID,可隨便設定,防止在自定義其他View的時候,ID重複 private int ROUND_NUMBER; //每次最少選中圓點個數 private boolean isAgain = true; //是否需要二次選擇 private OnResultListener resultListener; //回撥介面 private boolean isClick = true; //是否能夠點選選擇,用於當第一次選擇完成後,直線還沒消失的時候,不能直接第二次選擇 public GestureCustomView(Context context) { this(context, null); } public GestureCustomView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public GestureCustomView(Context context, AttributeSet attrs, int defStyleAttr) { this(context, attrs, defStyleAttr, 0); } public GestureCustomView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.Gesture_Styles); gestureData = new GestureData(); gestureData.setLine_Number(attributes.getInt(R.styleable.Gesture_Styles_Gesture_Line_Number, getResources().getInteger(R.integer.Line_Number))); gestureData.setColumn_Number(attributes.getInt(R.styleable.Gesture_Styles_Gesture_Column_Number, getResources().getInteger(R.integer.Column_Number))); gestureData.setBorderWidth(attributes.getFloat(R.styleable.Gesture_Styles_Gesture_BorderWidth, Float.parseFloat(getResources().getString(R.string.BorderWidth)))); gestureData.setFilletWidth(attributes.getFloat(R.styleable.Gesture_Styles_Gesture_FilletWidth, Float.parseFloat(getResources().getString(R.string.FilletWidth)))); gestureData.setBetweenWidth(attributes.getFloat(R.styleable.Gesture_Styles_Gesture_BetweenWidth, Float.parseFloat(getResources().getString(R.string.BetweenWidth)))); gestureData.setAgain(attributes.getBoolean(R.styleable.Gesture_Styles_Gesture_isAgain, getResources().getBoolean(R.bool.isAgain))); gestureData.setRound_Number(attributes.getInt(R.styleable.Gesture_Styles_Gesture_Round_Number, getResources().getInteger(R.integer.Round_Number))); gestureData.setDelay(attributes.getInt(R.styleable.Gesture_Styles_Gesture_Delay, getResources().getInteger(R.integer.Delay))); gestureData.setLineWidth(attributes.getFloat(R.styleable.Gesture_Styles_Gesture_LineWidth, Float.parseFloat(getResources().getString(R.string.LineWidth)))); gestureData.setDefaultBorderColor(attributes.getColor(R.styleable.Gesture_Styles_Gesture_DefaultBorderColor, getResources().getColor(R.color.DefaultBorderColor))); gestureData.setDefaultFilletColor(attributes.getColor(R.styleable.Gesture_Styles_Gesture_DefaultFilletColor, getResources().getColor(R.color.DefaultFilletColor))); gestureData.setDefaultExcircleColor(attributes.getColor(R.styleable.Gesture_Styles_Gesture_DefaultExcircleColor, getResources().getColor(R.color.DefaultExcircleColor))); gestureData.setSelectBorderColor(attributes.getColor(R.styleable.Gesture_Styles_Gesture_SelectBorderColor, getResources().getColor(R.color.SelectBorderColor))); gestureData.setSelectFilletColor(attributes.getColor(R.styleable.Gesture_Styles_Gesture_SelectFilletColor, getResources().getColor(R.color.SelectFilletColor))); gestureData.setSelectExcircleColor(attributes.getColor(R.styleable.Gesture_Styles_Gesture_SelectExcircleColor, getResources().getColor(R.color.SelectExcircleColor))); gestureData.setSelectLineColor(attributes.getColor(R.styleable.Gesture_Styles_Gesture_SelectLineColor, getResources().getColor(R.color.SelectLineColor))); gestureData.setErrorBorderColor(attributes.getColor(R.styleable.Gesture_Styles_Gesture_ErrorBorderColor, getResources().getColor(R.color.ErrorBorderColor))); gestureData.setErrorFilletColor(attributes.getColor(R.styleable.Gesture_Styles_Gesture_ErrorFilletColor, getResources().getColor(R.color.ErrorFilletColor))); gestureData.setErrorExcircleColor(attributes.getColor(R.styleable.Gesture_Styles_Gesture_ErrorExcircleColor, getResources().getColor(R.color.ErrorExcircleColor))); gestureData.setErrorLineColor(attributes.getColor(R.styleable.Gesture_Styles_Gesture_ErrorLineColor, getResources().getColor(R.color.ErrorLineColor))); gestureData.setCorrectBorderColor(attributes.getColor(R.styleable.Gesture_Styles_Gesture_CorrectBorderColor, getResources().getColor(R.color.CorrectBorderColor))); gestureData.setCorrectFilletColor(attributes.getColor(R.styleable.Gesture_Styles_Gesture_CorrectFilletColor, getResources().getColor(R.color.CorrectFilletColor))); gestureData.setCorrectExcircleColor(attributes.getColor(R.styleable.Gesture_Styles_Gesture_CorrectExcircleColor, getResources().getColor(R.color.CorrectExcircleColor))); gestureData.setCorrectLineColor(attributes.getColor(R.styleable.Gesture_Styles_Gesture_CorrectLineColor, getResources().getColor(R.color.CorrectLineColor))); this.context = context; paintLine = new Paint(Paint.ANTI_ALIAS_FLAG); //初始化鋸齒 paintLine.setStyle(Paint.Style.STROKE); //空心 paintLine.setStrokeCap(Paint.Cap.ROUND); //設定筆刷的圖形樣式,圓形樣式 paintLine.setStrokeJoin(Paint.Join.ROUND);//設定繪製時各圖形的結合方式,圓形效果 pathLine = new Path(); list = new ArrayList<>(); ROUND_NUMBER = gestureData.getRound_Number();//每次最少選中圓點個數 isAgain = gestureData.isAgain(); //是否需要二次選擇 LINE_NUMBER = gestureData.getLine_Number(); //每行圓點數目 COLUMN_NUMBER = gestureData.getColumn_Number();//每列圓點數目 gestureViews = new GestureRound[LINE_NUMBER][COLUMN_NUMBER]; orderData = new StringBuffer(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int measuredHeight = MeasureSpec.getSize(heightMeasureSpec); int measuredWidth = MeasureSpec.getSize(widthMeasureSpec); measuredWidth = measuredWidth < measuredHeight ? measuredWidth : measuredHeight; //每個圓點的寬度 gestureViewWidth = (int) (COLUMN_NUMBER * measuredWidth * 1.0f / ((COLUMN_NUMBER + 1) * COLUMN_NUMBER + 1)); //每行之間的距離 gestureBetweenWidth = (int) (gestureViewWidth * gestureData.getBetweenWidth()); //設定直線的寬度 paintLine.setStrokeWidth(gestureViewWidth * gestureData.getLineWidth()); for (int i = 0; i < LINE_NUMBER; i++) { //每一行 for (int j = 0; j < COLUMN_NUMBER; j++) { //每一列 int ID = i + j + (COLUMN_NUMBER - 1) * i + ID_NUMBER + 1; GestureRound gestureRound = new GestureRound(context, gestureData); gestureRound.setId(ID); //設定每一個圓點的ID,從ID_NUMBER+1開始 LayoutParams params = new LayoutParams(gestureViewWidth, gestureViewWidth); // 第一列設定LEFT,其他列不設定。 // 第一行設定TOP,其他行不設定。 // 最後一列不設定RIGHT,其他列設定。 // 最後一行不設定BOTTOM,其他行設定。 params.setMargins((COLUMN_NUMBER == 0) ? gestureBetweenWidth : 0, (LINE_NUMBER == 0) ? gestureBetweenWidth : 0, (j == (COLUMN_NUMBER - 1)) ? 0 : gestureBetweenWidth, (i == LINE_NUMBER - 1) ? 0 : gestureBetweenWidth); params.addRule(RIGHT_OF, (j != 0) ? ID - 1 : 0); //第一列不設定,其他圓點都在上一個圓點右側 params.addRule(BELOW, (i != 0) ? ID - COLUMN_NUMBER : 0); //第一行不設定,其他圓點都在上一行下面 gestureRound.setLayoutParams(params); gestureViews[i][j] = gestureRound; addView(gestureRound); } } super.onMeasure(widthMeasureSpec, heightMeasureSpec); } @Override protected void dispatchDraw(Canvas canvas) { super.dispatchDraw(canvas); if (isRound) { //若第一次按下去不在圓點內,則不畫直線 if (pathLine != null) canvas.drawPath(pathLine, paintLine); if (this.moveX != 0 && this.moveY != 0) { //移動後才開始劃線 canvas.drawLine(this.startX, this.startY, this.moveX, this.moveY, paintLine); } } } @Override public boolean onTouchEvent(MotionEvent event) { float x = event.getX(); float y = event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: //按下 GestureRound ro = getRound(x, y); if (ro != null && isClick) { //isRound 判斷按下去的時候,是否在圓點內 isClick = false; paintLine.setColor(gestureData.getSelectLineColor()); ro.setState(1); //改變選中圓點的狀態 isRound = true; list.add(ro); //把選中的圓點儲存起來 getStartPosition(ro); //獲取直線的起始位置的XY值 pathLine.moveTo(this.startX, this.startY); //設定直線的起始位置 orderData.append(ro.getId() - ID_NUMBER); //儲存選中圓點的順序 } else { isRound = false; } break; case MotionEvent.ACTION_MOVE: //移動 if (isRound == true) { //能否畫直線 this.moveX = x; this.moveY = y; GestureRound round = getRound(this.moveX, this.moveY); if (round != null && !list.contains(round)) { //判斷round是否為空以及round是否已經選擇過了 round.setState(1); //改變選中圓點的狀態 getStartPosition(round);//重新獲取直線的起始位置的XY值 list.add(round); //把選中圓點儲存起來 orderData.append(round.getId() - ID_NUMBER); //儲存選中圓點的順序 pathLine.lineTo((round.getLeft() + round.getRight()) / 2, (round.getTop() + round.getBottom()) / 2); } } break; case MotionEvent.ACTION_UP: //放開 if (isRound == true) { //將最後的直線位置定位到最後一個圓點 this.moveX = this.startX; this.moveY = this.startY; if (list.size() >= ROUND_NUMBER) { //選擇的圓點個數是否超過最少選中圓點個數 if (isAgain) { //是否需要二次選擇 if (fristData == null) { //是否第一次選擇圓點 fristData = orderData.toString(); } else { if (fristData.equals(orderData.toString())) { //第一次選擇圓點順序跟第二次選擇圓點順序是否相同 changeMode(2); //成功 paintLine.setColor(gestureData.getCorrectLineColor()); } else { changeMode(3); //錯誤 paintLine.setColor(gestureData.getErrorLineColor()); } } } resultListener.Result(orderData.toString()); // } else Toast.makeText(context, "至少連線" + ROUND_NUMBER + "個點,請重試!", Toast.LENGTH_SHORT).show(); orderData.delete(0, orderData.length()); restoreState();//還原狀態 } break; default: break; } invalidate(); //重新整理介面,才能呼叫dispatchDraw方法 return true; //返回true 才能不斷呼叫onTouchEvent方法 } /** * 改變已選圓點的狀態 */ private void changeMode(int i) { for (GestureRound round : list) { round.setState(i); } } /** * 獲取直線的起始位置的XY值 */ private void getStartPosition(GestureRound round) { this.startX = (round.getLeft() + round.getRight()) / 2; this.startY = (round.getTop() + round.getBottom()) / 2; } /** * 還原狀態 */ private void restoreState() { new Handler().postDelayed(new Runnable() { //延遲還原狀態 public void run() { pathLine.reset(); //重置筆畫 moveX = 0; moveY = 0; for (int i = 0; i < COLUMN_NUMBER; i++) { //迴圈遍歷二維陣列,先遍歷 列 貌似速度快一些 for (int j = 0; j < LINE_NUMBER; j++) { GestureRound round = gestureViews[j][i]; if (list.contains(round)) { //判斷當前的觸控點是否在圓點內 round.setState(0); } } } list.clear(); invalidate(); isClick = true; } }, gestureData.getDelay()); } /** * 獲取滑動時選擇的圓點 */ private GestureRound getRound(float x, float y) { for (int i = 0; i < COLUMN_NUMBER; i++) { //迴圈遍歷二維陣列,先遍歷 列 貌似速度快一些 for (int j = 0; j < LINE_NUMBER; j++) { if (judgeRound(gestureViews[j][i], x, y)) { //判斷當前的觸控點是否在圓點內 return gestureViews[j][i]; //返回圓點 } } } return null; } /** * 判斷當前的觸控點是否在圓點內 */ private boolean judgeRound(GestureRound gestureRound, float x, float y) { float DIFFER = gestureViewWidth * 0.2f; //DIFFER是誤差點 if (x >= gestureRound.getLeft() + DIFFER && x <= gestureRound.getRight() - DIFFER && y >= gestureRound.getTop() + DIFFER && y <= gestureRound.getBottom() - DIFFER) return true; else return false; } /** * 設定是否二次選擇 */ public void setAgain(boolean b) { this.isAgain = b; } public void setOnResultListener(OnResultListener listener) { this.resultListener = listener; } public interface OnResultListener { void Result(String result); } }

像這些功能設定

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="Gesture_Styles">
        <attr name="Gesture_Line_Number" format="integer"></attr><!--每行圓點的個數-->
        <attr name="Gesture_Column_Number" format="integer"></attr><!--每列圓點的個數-->
        <attr name="Gesture_BorderWidth" format="float"></attr> <!--邊框大小-->
        <attr name="Gesture_FilletWidth" format="float"></attr> <!--內圓大小-->
        <attr name="Gesture_BetweenWidth" format="float"></attr> <!--每行之間的距離大小-->
        <attr name="Gesture_LineWidth" format="float"></attr> <!--直線的寬度大小-->
        <attr name="Gesture_Round_Number" format="integer"></attr><!--每次最少選中圓點個數-->
        <attr name="Gesture_isAgain" format="boolean"></attr><!--是否需要二次選擇-->
        <attr name="Gesture_Delay" format="integer"></attr><!--延遲還原狀態的時間,單位 秒-->

        <attr name="Gesture_DefaultBorderColor" format="color|reference"></attr> <!--預設邊框顏色-->
        <attr name="Gesture_DefaultFilletColor" format="color|reference"></attr> <!--預設內圓顏色-->
        <attr name="Gesture_DefaultExcircleColor" format="color|reference"></attr> <!--預設外圓顏色-->


        <attr name="Gesture_SelectBorderColor" format="color|reference"></attr> <!--選擇邊框顏色-->
        <attr name="Gesture_SelectFilletColor" format="color|reference"></attr> <!--選擇內圓顏色-->
        <attr name="Gesture_SelectExcircleColor" format="color|reference"></attr> <!--選擇外圓顏色-->
        <attr name="Gesture_SelectLineColor" format="color|reference"></attr> <!--選擇線條顏色-->

        <attr name="Gesture_ErrorBorderColor" format="color|reference"></attr> <!--錯誤邊框顏色-->
        <attr name="Gesture_ErrorFilletColor" format="color|reference"></attr> <!--錯誤內圓顏色-->
        <attr name="Gesture_ErrorExcircleColor" format="color|reference"></attr> <!--錯誤外圓顏色-->
        <attr name="Gesture_ErrorLineColor" format="color|reference"></attr> <!--錯誤線條顏色-->

        <attr name="Gesture_CorrectBorderColor" format="color|reference"></attr> <!--正確邊框顏色-->
        <attr name="Gesture_CorrectFilletColor" format="color|reference"></attr> <!--正確內圓顏色-->
        <attr name="Gesture_CorrectExcircleColor" format="color|reference"></attr> <!--正確外圓顏色-->
        <attr name="Gesture_CorrectLineColor" format="color|reference"></attr> <!--正確線條顏色-->

    </declare-styleable>
    <string name="BorderWidth" format="float" type="dimen">2</string><!--預設邊框大小-->
    <string name="FilletWidth" format="float" type="dimen">0.3</string><!--預設內圓大小-->
    <string name="BetweenWidth" format="float" type="dimen">0.25</string><!--預設每行之間的距離大小-->
    <string name="LineWidth" format="float" type="dimen">0.3</string><!--預設直線的寬度大小-->
    <bool name="isAgain">true</bool>
    <integer name="Round_Number">4</integer><!--預設每次最少選中圓點個數-->
    <integer name="Delay">500</integer><!--延遲還原狀態的時間,單位 秒-->
    <integer name="Line_Number">3</integer><!--每行圓點的個數-->
    <integer name="Column_Number">3</integer><!--每列圓點的個數-->
</resources>

全部在XML裡面就可以設定,非常方便


感覺沒漏下什麼了大笑有缺少的,大家可以加上去,註釋已經非常詳細了,基本上看一眼就能知道是什麼邏輯,什麼功能,自己修改也很方便

最後 這是程式碼下載,已經編譯過了,可以直接在build-->outputs裡面找到APK先安裝看一下效果: 

http://download.csdn.net/detail/yanmantian/9716762

原始碼下載

相關推薦

android多條折線圖表顯示秒動畫過渡hellocharts

因為做畢業設計的時候使用到了github中的原始碼hellochart來做圖表,所以把個人修改後的程式碼做一個總結。多條折線同時顯示在一個圖裡,並且帶有一秒的動畫過渡,這裡的橫座標是定長,效果類似於譜線變化。 1.MainActivity.java p

Hibernate查詢方法總結包括條件分頁查詢外來鍵id查詢

每天進步一點點,最近做專案用到了很多的hibernate的查詢方法。正好騰出時間來總結,希望對自己和他人都有幫助。 首先非常感謝施楊 's think out 和suntao1983做的總結,幫我解決的很多問題。 hibernate 的 六種基本查詢方法:分別是HQL查詢

Python輸入數組維數組維數組

python aac off class 二維數組 之間 pan wrapper == 一維數組: arr = input("") //輸入一個一維數組,每個數之間使空格隔開 num = [int(n) for n in arr.split()] //將輸入每

leetcode----- Validate Binary Search Tree判斷棵樹是否是叉搜尋樹

1、題目描述 給定一棵二叉樹,判斷這棵樹是否是二叉搜尋樹。 二叉搜尋樹的定義如下: 二叉搜尋樹(Binary Search Tree),又稱二叉排序樹,它或者是一顆空樹,或者具有如下性質的樹: 若它的左子樹不為空,則左子樹上所有節點的值都小於根節點的值 若它的右子樹

Android 手勢包括設定密碼

最近看到手勢解鎖功能,網上有一些大牛寫了很多原始碼,不過功能或多或少對自己的專案有些不同,琢磨著自己也寫一個,技術還不到家,有些東西是參照網上的demo 主要自定義View如下: package com.example.androidgesture; //

Android手勢識別GestureDetector

一、概述當用戶觸控式螢幕幕的時候,會產生許多手勢,例如down,up,scroll,filing等等。一般情況下,我們知道View類有個View.OnTouchListener內部介面,通過重寫他的onTouch(View v, MotionEvent event)方法,我們

Java呼叫 新浪微博API 介面發微博包含js微博元件springMVC新浪登入

參考自:http://www.myexception.cn/program/1930025.html 最近做了一個活動,要用到微博分享,就捉急忙慌的去研究,因為我們公司域名的問題還有專案的問題白白浪費我一天時間。。。 1、js微博元件分享 當然你再配置資訊的

Android微信支付詳細流程包括手機端和伺服器端

相關檔案下載地址:http://download.csdn.net/detail/s_alics/9383437點選開啟連結 **************************************************************************

Hadoop Mapreduce分割槽分組排序過程[轉]

徐海蛟 教學用途 1、MapReduce中資料流動    (1)最簡單的過程:  map - reduce    (2)定製了partitioner以將map的結果送往指定reducer的過程: map - partition - reduce    (3)增加了在本地先進性一次reduce(優化)過程: 

Hadoop Mapreduce分割槽分組排序過程

這篇文章分析的特別好,耐心看下去。。1、MapReduce中資料流動   (1)最簡單的過程:  map - reduce   (2)定製了partitioner以將map的結果送往指定reducer的過程: map - partition - reduce   (3)增加了

android與js互動的方式包括三種

關於android月js或者說html互動的方式,在很早的版本中是通過android端新增js支援,然後傳遞一個js操作本地方法的物件,然後就可以呼叫本地的方法。在後邊的版本為了統一管理,添加了@JavascriptInterface  ,只有添加了這個標誌的方法才能被js

完整版unity安卓發布流程包括SDK有原生系統依賴關系的工程

產品 應用 技術分享 之前 完整 mage http .so ger 要3個東西!NDS,SDK,JDK, NDK官網下載:https://developer.android.google.cn/ndk/downloads/index.html(註意系統是不是64位) JD

Makefile常用萬能模板包括靜態鏈接庫動態鏈接庫可執行文件

lib post targe class 到你 param 圖片 spa log 本文把makefile 分成了三份:生成可執行文件的makefile,生成靜態鏈接庫的makefile,生成動態鏈接庫的makefile。   這些makefile都很簡單,一般都是一看就會用

2017.5.3最新申請公司開發者賬號整個流程包括鄧白氏申請詳細流程帶截圖

地址 .html .com 分享 key appid 第一步 eid 技術 第一步:申請蘋果賬號 點擊這裏申請個蘋果賬號吧!(申請過請忽略) 第二步:申請鄧白氏 登陸上到這個地址 點擊這裏: 這個郵件之後就等著鄧白氏那邊的人給你留的手機號打電話,會確認你填寫

ionic3 實現app版本更新下載並開啟進行安裝包括android7+無法自動安裝apk問題的解決方法

記錄一下實現app版本一鍵更新下載的功能。 我的專案的總體的檔案: 使用的外掛列表如下: 需要純實現該功能用到的基本上是除了後三個。 首先,安裝這些外掛,在app.component.ts頁面上加入 import { Component, ViewChild } f

前端面試題之HTTP請求包括請求的方法型別請求與響應get和post的區別

經歷了一波秋招,整理了一部分面試題,也是趁這個機會再鞏固一下知識點。(本來想把所有的知識點都寫在一篇部落格中,感覺太冗長了,不如一篇一篇的整潔。) 一、HTTP請求(主要從請求的方法型別、請求訊息和響應訊息、get和post的區別這幾部分來說) 1、請求的方法:HTTP1.0定義了三種請求方

PL/SQL Developer的安裝及配置OCI庫包括漢化和快捷鍵失效問題的解決

安裝 1.下載安裝不多說 2.破解 開啟Developer,開啟幫助(Help)中的註冊(Register),對照著破解工具中,輸入產品代號(Product Code)、序列號(Serial Number)、密碼(Password),即可破解。 3.配置OCI庫以連線遠端資料庫

SVM分類器的實現包括交叉驗證選擇引數,Dlib,視覺化

慣例先放結果圖,左側為訓練樣本,右側為訓練完後的分類演示圖 Dlib的支援向量機用起來比Opencv的爽多了, 支援交叉驗證, 降低支援向量的個數 以及兩種方式判別類別(正負以及可能性兩種) 然後就是簡單粗暴的程式碼了: //需要配置Opencv以及Dlib的環境

Android--使用原生技術實現ListView原生技術實現網路非同步請求,解析json資料

涉及到的原生技術: 1.原生技術實現網路非同步請求 1.原生技術解析json資料 實現步驟: 實現程式碼: **第一二步比較簡單,直接跳過 import android.content.Context; import

Android開發---手機號碼輸入框滿11位自動跳到下個輸入框

package com.jixiong.teen.view; import android.content.Context; import android.text.Editable; import android.text.Selection; import androi