最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android實現(xiàn)滑塊拼圖驗證碼功能

 更新時間:2021年02月23日 09:35:36   作者:longxuanzhigu  
這篇文章主要介紹了Android實現(xiàn)滑塊拼圖驗證碼功能,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

滑塊拼圖驗證碼應(yīng)該算是很常見的功能了,驗證碼是可以區(qū)分用戶是人還是機器。可以防止破解密碼、刷票等惡意行為。本文將介紹Android拼圖滑塊驗證碼控件的實現(xiàn)過程。希望能幫助到大家。

先看最終的效果圖:

本文只是做了個Demo,并沒有加入到實際的項目中,所以各位童鞋可以根據(jù)自己的需求就行修改即可。

一、實現(xiàn)步驟:

1、定義自定義屬性; 2、確認(rèn)目標(biāo)位置,這里使用的是陰影圖片來遮蓋背景圖片; 3、創(chuàng)建與目標(biāo)位置相結(jié)合的滑塊圖片; 4、設(shè)置目標(biāo)陰影圖片和滑塊圖片可以隨機旋轉(zhuǎn),并保持一致; 5、創(chuàng)建拖拽條,使滑塊隨著拖拽條的拖拽而移動; 6、判斷是否驗證成功。

二、實現(xiàn)流程:

1、定義自定義屬性 創(chuàng)建一個attr文件來定義一些自定義屬性

   <declare-styleable name="ImageAuthenticationView">
    <!--滑塊的高度-->
    <attr name="unitHeight" format="dimension" />
    <!--滑塊的寬度-->
    <attr name="unitWidth" format="dimension" />
    <!--滑塊占圖片高度的比例-->
    <attr name="unitHeightScale" format="integer" />
    <!--滑塊占圖片寬度的比例-->
    <attr name="unitWidthScale" format="integer" />
    <!--滑塊邊框的圖片資源-->
    <attr name="unitShadeSrc" format="reference" />
    <!--陰影部分的圖片資源-->
    <attr name="unitShowSrc" format="reference" />
    <!--是否需要旋轉(zhuǎn)-->
    <attr name="needRotate" format="boolean" />
    <!--驗證時的誤差值-->
    <attr name="deviate" format="integer" />
  </declare-styleable>

2、確認(rèn)目標(biāo)位置,這里使用的是陰影圖片來遮蓋背景圖片

 /**
   * 創(chuàng)建目標(biāo)圖片(陰影部分)
   */
  private Bitmap drawTargetBitmap() {
    // 繪制圖片
    Bitmap showB;
    if (null != mShowBp) {
      showB = handleBitmap(mShowBp, mUintWidth, mUintHeight);
    } else {
      showB = handleBitmap(BitmapFactory.decodeResource(getResources(), R.mipmap.puzzle_show), mUintWidth, mUintHeight);
    }
    // 如果需要旋轉(zhuǎn)圖片,進行旋轉(zhuǎn),旋轉(zhuǎn)后為了保持和滑塊大小一致,需要重新縮放比例
    if (needRotate) {
      showB = handleBitmap(rotateBitmap(rotate, showB), mUintWidth, mUintHeight);
    }
    return showB;
  }

3、創(chuàng)建與目標(biāo)位置相結(jié)合的滑塊圖片

 /**
   * 創(chuàng)建結(jié)滑塊圖片
   *
   * @param bp
   */
  private Bitmap drawResultBitmap(Bitmap bp) {
    // 繪制圖片
    Bitmap shadeB;
    if (null != mShadeBp) {
      shadeB = handleBitmap(mShadeBp, mUintWidth, mUintHeight);
    } else {
      shadeB = handleBitmap(BitmapFactory.decodeResource(getResources(), R.mipmap.puzzle_shade), mUintWidth, mUintHeight);
    }
    // 如果需要旋轉(zhuǎn)圖片,進行旋轉(zhuǎn),旋轉(zhuǎn)后為了和畫布大小保持一致,避免出現(xiàn)圖像顯示不全,需要重新縮放比例
    if (needRotate) {
      shadeB = handleBitmap(rotateBitmap(rotate, shadeB), mUintWidth, mUintHeight);
    }
    Bitmap resultBmp = Bitmap.createBitmap(mUintWidth, mUintHeight,
        Bitmap.Config.ARGB_8888);
    Paint paint = new Paint();
    paint.setAntiAlias(true);
    Canvas canvas = new Canvas(resultBmp);
    canvas.drawBitmap(shadeB, new Rect(0, 0, mUintWidth, mUintHeight),
        new Rect(0, 0, mUintWidth, mUintHeight), paint);
    // 選擇交集去上層圖片
    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY));
    canvas.drawBitmap(bp, new Rect(0, 0, mUintWidth, mUintHeight),
        new Rect(0, 0, mUintWidth, mUintHeight), paint);
    return resultBmp;
  }

4、設(shè)置目標(biāo)陰影圖片和滑塊圖片可以隨機旋轉(zhuǎn),并保持一致

 /**
   * 旋轉(zhuǎn)圖片
   *
   * @param degree
   * @param bitmap
   * @return
   */
  public Bitmap rotateBitmap(int degree, Bitmap bitmap) {
    Matrix matrix = new Matrix();
    matrix.postRotate(degree);
    Bitmap bm = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
        bitmap.getHeight(), matrix, true);
    return bm;
  }

5、創(chuàng)建拖拽條,使滑塊隨著拖拽條的拖拽而移動

  //滑塊監(jiān)聽
    mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
      @Override
      public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
        //設(shè)置滑塊移動距離
        mDY.setUnitMoveDistance(mDY.getAverageDistance(seekBar.getMax()) * i);
      }

      @Override
      public void onStartTrackingTouch(SeekBar seekBar) {

      }

      @Override
      public void onStopTrackingTouch(SeekBar seekBar) {
        //驗證是否拼接成功
        mDY.testPuzzle();
      }
    });

6、判斷是否驗證成功

/**
   * 驗證是否拼接成功
   */
  public void testPuzzle() {
    if (Math.abs(mUnitMoveDistance - mUnitRandomX) <= DEFAULT_DEVIATE) {
      if (null != mlistener) {
        mlistener.onSuccess();
      }
    } else {
      if (null != mlistener) {
        mlistener.onFail();
      }
    }
  }

三、完整代碼

1、自定義控件內(nèi)容太多這里就不放出來了,完整Demo源碼會放在文章后面;

2、代碼邏輯

public class MainActivity extends Activity {

  //滑塊
  private SeekBar mSeekBar;
  //自定義的控件
  private ImageAuthenticationView mDY;
  private Button btn;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    initView();
    initListener();
  }

  private void initView() {
    mDY = findViewById(R.id.dy_v);
    mSeekBar = findViewById(R.id.sb_dy);
    btn = findViewById(R.id.btn);
  }

  private void initListener() {
    //滑塊監(jiān)聽
    mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
      @Override
      public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
        //設(shè)置滑塊移動距離
        mDY.setUnitMoveDistance(mDY.getAverageDistance(seekBar.getMax()) * i);
      }

      @Override
      public void onStartTrackingTouch(SeekBar seekBar) {

      }

      @Override
      public void onStopTrackingTouch(SeekBar seekBar) {
        //驗證是否拼接成功
        mDY.testPuzzle();
      }
    });

    //控件監(jiān)聽
    mDY.setPuzzleListener(new ImageAuthenticationView.onPuzzleListener() {
      @Override
      public void onSuccess() {
        //mSeekBar.setEnabled(false);//禁止滑動
        Toast.makeText(MainActivity.this, "驗證成功", Toast.LENGTH_SHORT).show();
      }

      @Override
      public void onFail() {
        Toast.makeText(MainActivity.this, "驗證失敗", Toast.LENGTH_SHORT).show();
        mSeekBar.setProgress(0);
      }
    });

    //重置
    btn.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {
        //mSeekBar.setEnabled(true);
        mSeekBar.setProgress(0);
        mDY.reSet();
      }
    });
  }
}

3、布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:dy="http://schemas.android.com/apk/res-auto"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:gravity="center"
  android:orientation="vertical"
  android:paddingLeft="10dp"
  android:paddingTop="10dp"
  android:paddingRight="10dp"
  android:paddingBottom="10dp"
  tools:context=".MainActivity">

  <com.sjl.keeplive.slideImg.ImageAuthenticationView
    android:id="@+id/dy_v"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:scaleType="centerCrop"
    android:layout_marginBottom="10dp"
    android:src="@mipmap/test"
    dy:needRotate="true"
    dy:unitHeight="60dp"
    dy:unitShadeSrc="@mipmap/puzzle_shade"
    dy:unitShowSrc="@mipmap/puzzle_show"
    dy:unitWidth="80dp" />

  <SeekBar
    android:id="@+id/sb_dy"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/bg_seekbar"
    android:max="100" />

  <Button
    android:id="@+id/btn"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="重置"/>
</LinearLayout>

源碼下載

到此這篇關(guān)于Android實現(xiàn)滑塊拼圖驗證碼功能的文章就介紹到這了,更多相關(guān)Android 滑塊拼圖驗證碼內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Compose?的?Navigation組件使用示例詳解

    Compose?的?Navigation組件使用示例詳解

    這篇文章主要為大家介紹了Compose?的?Navigation組件使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-10-10
  • Android編程學(xué)習(xí)之抽象類AbsListView用法實例分析

    Android編程學(xué)習(xí)之抽象類AbsListView用法實例分析

    這篇文章主要介紹了Android編程學(xué)習(xí)之抽象類AbsListView用法,較為詳細(xì)的分析了抽象類AbsListView的功能、結(jié)構(gòu)、定義及使用注意事項等,需要的朋友可以參考下
    2015-10-10
  • Android10?客戶端事務(wù)管理ClientLifecycleManager源碼解析

    Android10?客戶端事務(wù)管理ClientLifecycleManager源碼解析

    這篇文章主要介紹了Android10?客戶端事務(wù)管理ClientLifecycleManager源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-10-10
  • Kotlin 封裝萬能SharedPreferences存取任何類型詳解

    Kotlin 封裝萬能SharedPreferences存取任何類型詳解

    這篇文章主要介紹了Kotlin 封裝萬能SharedPreferences存取任何類型詳解的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • Android Jetpack架構(gòu)中ViewModel接口暴露的不合理探究

    Android Jetpack架構(gòu)中ViewModel接口暴露的不合理探究

    這篇文章主要介紹了Android Jetpack架構(gòu)組件 ViewModel詳解,ViewModel類讓數(shù)據(jù)可在發(fā)生屏幕旋轉(zhuǎn)等配置更改后繼續(xù)存在,ViewModel類旨在以注重生命周期的方式存儲和管理界面相關(guān)的數(shù)據(jù)。感興趣可以來學(xué)習(xí)一下
    2022-07-07
  • Android的HTTP多線程下載示例代碼

    Android的HTTP多線程下載示例代碼

    本篇文章主要介紹了Android的HTTP多線程下載示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-03-03
  • 最新評論

    教育| 阜平县| 南京市| 高要市| 扎兰屯市| 临泽县| 克什克腾旗| 中山市| 永寿县| 琼中| 交口县| 张家口市| 长岛县| 沈阳市| 岫岩| 荔浦县| 民权县| 磴口县| 房山区| 德庆县| 营口市| 白玉县| 德兴市| 军事| 姚安县| 高邮市| 专栏| 武夷山市| 和田县| 林甸县| 苍梧县| 紫云| 汝阳县| 城固县| 清水河县| 沅陵县| 赫章县| 马公市| 遂平县| 黑水县| 内江市|