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

Android自定義控件通用驗證碼輸入框的實現(xiàn)

 更新時間:2018年03月15日 09:20:30   作者:Android草根王  
這篇文章主要介紹了Android自定義控件通用驗證碼輸入框的實現(xiàn),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

需求

4位驗證碼輸入框:

效果圖:


1. 輸入框一行可輸入4位數字類型的驗證碼;
2. 4位數字之間有間隔(包括底線);
3. 輸入框不允許有光標;
4. 底線根據輸入位置顯示高亮(藍色);
6. 輸入完成,回調結果,輸入過程中,也進行回調;

分析

這種效果,很難直接在Edittext上處理:
-- 輸入框均分4等份,還要有間隔;
-- 更難處理的是Edittext輸入框禁止光標,那么,沒有光標,我們如何調起虛擬鍵盤輸入數據?
-- 等...

與其在一個控件上折騰,這么難受,不如自定義一個控件,實現(xiàn)這種效果。
自定義控件最簡單的方案:使用多個控件,組合出這種效果。

1、布局如何實現(xiàn)?

1.禁止光標,我們直接使用TextView就解決了,而非Edittext;
2.一行顯示4位數字,比較簡單,可以使用線性布局的權重,對TextView進行控制為4等分;
3.每個TextView下面跟著一個底線,將來我們就能對底線設置高亮顏色了;
這樣,基本的布局展示就可以了!??!

2、使用了TextView,那么我們如何接收用戶的輸入呢?
也很簡單,我們在4個TextView的上方平鋪一個EditText,設置透明,
當用戶點擊到該控件時,會自動調起軟鍵盤,接收輸入的文本。
EditText接收到用戶輸入的文本,如何顯示在TextView呢?

3、我們監(jiān)聽EditText文本輸入事件,最多僅接收4個輸入字符,
每接收到一個字符,我們就賦值給對應的TextView;
底線也隨要設置的文本切換顯示高亮;

4、如何刪除已輸入的數值?
我們監(jiān)聽EditText按鍵事件,攔截DEL鍵,從后向前挨著刪除字符即可;
底線也隨要刪除的文本切換顯示高亮;

5、是否需要自定義屬性
分析我們自己的項目,雖然是公用的控件,但是該控件比較簡單,沒有特別的要求,所以沒必要自定義屬性了!
如果大家有需要的,可根據需要自己定義;
如何定義屬性?請自行查找資料;

既然,問題都分析清楚了,那我們就開始快速實現(xiàn)吧

具體實現(xiàn)

布局文件 phone_code.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="wrap_content">
  <LinearLayout
    android:id="@+id/ll_code"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">
    <LinearLayout
      android:layout_width="0dp"
      android:layout_height="wrap_content"
      android:layout_weight="1"
      android:orientation="vertical"
      android:layout_marginRight="7dp">
      <TextView
        android:id="@+id/tv_code1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textColor="#2D2D2D"
        android:textSize="40sp"
        android:background="@null"
        android:gravity="center"/>
      <View
        android:id="@+id/v1"
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="#3F8EED" />
    </LinearLayout>

    <LinearLayout
      android:layout_width="0dp"
      android:layout_height="wrap_content"
      android:layout_weight="1"
      android:orientation="vertical"
      android:layout_marginRight="7dp"
      android:layout_marginLeft="7dp">
      <TextView
        android:id="@+id/tv_code2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textColor="#2D2D2D"
        android:textSize="40sp"
        android:background="@null"
        android:gravity="center"/>
      <View
        android:id="@+id/v2"
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="#999999" />
    </LinearLayout>
    <LinearLayout
      android:layout_width="0dp"
      android:layout_height="wrap_content"
      android:layout_weight="1"
      android:orientation="vertical"
      android:layout_marginRight="7dp"
      android:layout_marginLeft="7dp">
      <TextView
        android:id="@+id/tv_code3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textColor="#2D2D2D"
        android:textSize="40sp"
        android:background="@null"
        android:gravity="center"/>
      <View
        android:id="@+id/v3"
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="#999999" />
    </LinearLayout>
    <LinearLayout
      android:layout_width="0dp"
      android:layout_height="wrap_content"
      android:layout_weight="1"
      android:orientation="vertical"
      android:layout_marginLeft="7dp">
      <TextView
        android:id="@+id/tv_code4"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textColor="#2D2D2D"
        android:background="@null"
        android:textSize="40sp"
        android:gravity="center"/>
      <View
        android:id="@+id/v4"
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="#999999" />
    </LinearLayout>
  </LinearLayout>

  <EditText
    android:id="@+id/et_code"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignTop="@+id/ll_code"
    android:layout_alignBottom="@+id/ll_code"
    android:background="@android:color/transparent"
    android:textColor="@android:color/transparent"
    android:cursorVisible="false"
    android:inputType="number"/>
</RelativeLayout>

et_code 輸入框,設置了透明和無光標,僅接收數字;
tv_code1~4 為顯示數字的控件;
v1~4 為數字文本的底線,用于設置高亮;

自定義控件代碼 PhoneCode

package iwangzhe.customview2.phonecode;

import android.content.Context;
import android.graphics.Color;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.RelativeLayout;
import android.widget.TextView;

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

import iwangzhe.customview2.R;

/**
 * 類:PhoneCode
 * 作者: qxc
 * 日期:2018/3/14.
 */
public class PhoneCode extends RelativeLayout {
  private Context context;
  private TextView tv_code1;
  private TextView tv_code2;
  private TextView tv_code3;
  private TextView tv_code4;
  private View v1;
  private View v2;
  private View v3;
  private View v4;
  private EditText et_code;
  private List<String> codes = new ArrayList<>();
  private InputMethodManager imm;

  public PhoneCode(Context context) {
    super(context);
    this.context = context;
    loadView();
  }

  public PhoneCode(Context context, AttributeSet attrs) {
    super(context, attrs);
    this.context = context;
    loadView();
  }

  private void loadView(){
    imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
    View view = LayoutInflater.from(context).inflate(R.layout.phone_code, this);
    initView(view);
    initEvent();
  }

  private void initView(View view){
    tv_code1 = (TextView) view.findViewById(R.id.tv_code1);
    tv_code2 = (TextView) view.findViewById(R.id.tv_code2);
    tv_code3 = (TextView) view.findViewById(R.id.tv_code3);
    tv_code4 = (TextView) view.findViewById(R.id.tv_code4);
    et_code = (EditText) view.findViewById(R.id.et_code);
    v1 = view.findViewById(R.id.v1);
    v2 = view.findViewById(R.id.v2);
    v3 = view.findViewById(R.id.v3);
    v4 = view.findViewById(R.id.v4);
  }

  private void initEvent(){
    //驗證碼輸入
    et_code.addTextChangedListener(new TextWatcher() {
      @Override
      public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
      }
      @Override
      public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
      }
      @Override
      public void afterTextChanged(Editable editable) {
        if(editable != null && editable.length()>0) {
          et_code.setText("");
          if(codes.size() < 4){
            codes.add(editable.toString());
            showCode();
          }
        }
      }
    });
    // 監(jiān)聽驗證碼刪除按鍵
    et_code.setOnKeyListener(new View.OnKeyListener() {
      @Override
      public boolean onKey(View view, int keyCode, KeyEvent keyEvent) {
        if (keyCode == KeyEvent.KEYCODE_DEL && keyEvent.getAction() == KeyEvent.ACTION_DOWN && codes.size()>0) {
          codes.remove(codes.size()-1);
          showCode();
          return true;
        }
        return false;
      }
    });
  }

  /**
   * 顯示輸入的驗證碼
   */
  private void showCode(){
    String code1 = "";
    String code2 = "";
    String code3 = "";
    String code4 = "";
    if(codes.size()>=1){
      code1 = codes.get(0);
    }
    if(codes.size()>=2){
      code2 = codes.get(1);
    }
    if(codes.size()>=3){
      code3 = codes.get(2);
    }
    if(codes.size()>=4){
      code4 = codes.get(3);
    }
    tv_code1.setText(code1);
    tv_code2.setText(code2);
    tv_code3.setText(code3);
    tv_code4.setText(code4);    
    
    setColor();//設置高亮顏色
    callBack();//回調
  }

  /**
   * 設置高亮顏色
   */
  private void setColor(){
    int color_default = Color.parseColor("#999999");
    int color_focus = Color.parseColor("#3F8EED");
    v1.setBackgroundColor(color_default);
    v2.setBackgroundColor(color_default);
    v3.setBackgroundColor(color_default);
    v4.setBackgroundColor(color_default);
    if(codes.size()==0){
      v1.setBackgroundColor(color_focus);
    }
    if(codes.size()==1){
      v2.setBackgroundColor(color_focus);
    }
    if(codes.size()==2){
      v3.setBackgroundColor(color_focus);
    }
    if(codes.size()>=3){
      v4.setBackgroundColor(color_focus);
    }
  }

  /**
   * 回調
   */
  private void callBack(){
    if(onInputListener==null){
      return;
    }
    if(codes.size()==4){
      onInputListener.onSucess(getPhoneCode());
    }else{
      onInputListener.onInput();
    }
  }

  //定義回調
  public interface OnInputListener{
    void onSucess(String code);
    void onInput();
  }
  private OnInputListener onInputListener;
  public void setOnInputListener(OnInputListener onInputListener){
    this.onInputListener = onInputListener;
  }

  /**
   * 顯示鍵盤
   */
  public void showSoftInput(){
    //顯示軟鍵盤
    if(imm!=null && et_code!=null) {
      et_code.postDelayed(new Runnable() {
        @Override
        public void run() {
          imm.showSoftInput(et_code, 0);
        }
      },200);
    }
  }

  /**
   * 獲得手機號驗證碼
   * @return 驗證碼
   */
  public String getPhoneCode(){
    StringBuilder sb = new StringBuilder();
    for (String code : codes) {
      sb.append(code);
    }
    return sb.toString();
  }
}

codes 集合,用于存放用戶輸入的所有數字。使用該集合,可簡化輸入框、文本關聯(lián)邏輯和事件之間處理;
showSoftInput方法:顯示輸入鍵盤,可被外界調用;
getPhoneCode方法:獲得用戶輸入的驗證碼,可被外界調用;
OnInputListener接口:定義的數值輸入回調,用于告訴調用者是輸入中,還是輸入完成;

調用者 MainActivity

布局文件

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  android:id="@+id/activity_main"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  tools:context="iwangzhe.customview2.MainActivity">
  <iwangzhe.customview2.phonecode.PhoneCode
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/pc_1"
    android:layout_below="@+id/fpc_1"
    android:layout_marginTop="40dp"
    android:layout_marginLeft="20dp"
    android:layout_marginRight="20dp"/>
</RelativeLayout>

代碼

package iwangzhe.customview2;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import iwangzhe.customview2.phonecode.PhoneCode;
public class MainActivity extends AppCompatActivity {
  PhoneCode pc_1;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    pc_1 = (PhoneCode) findViewById(R.id.pc_1);
    //注冊事件回調(可寫,可不寫)
    pc_1.setOnInputListener(new PhoneCode.OnInputListener() {
      @Override
      public void onSucess(String code) {
        //TODO:
      }

      @Override
      public void onInput() {
        //TODO:
      }
    });
  }

  private void test(){
    //獲得驗證碼
    String phoneCode = pc_1.getPhoneCode();
  }
}

總結:

此控件實現(xiàn)起來,很簡單,代碼量也非常少。

本文章,主要是為了讓大家了解自定義控件的過程,如果想在自己的項目中使用,請根據需要自行調整優(yōu)化。

Demo下載地址:CustomView2_jb51.rar
(為了減小Demo大小,我刪除了build下的文件,大家獲取后rebuild一下代碼,就可以了)

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • Android性能優(yōu)化之圖片大小,尺寸壓縮綜合解決方案

    Android性能優(yōu)化之圖片大小,尺寸壓縮綜合解決方案

    隨著Android手機的越來越先進,給我們開發(fā)者而言傳遞的圖片也是越來越大,這個時候我們可以對一些沒有必要原圖展示的圖片進行壓縮,這篇文章主要給大家介紹了關于Android性能優(yōu)化之圖片大小,尺寸壓縮的綜合解決方案,需要的朋友可以參考下
    2022-04-04
  • Android 異步任務和消息機制面試題分析

    Android 異步任務和消息機制面試題分析

    這篇文章主要為大家介紹了Android 異步任務和消息機制面試題分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-07-07
  • android自定義倒計時控件示例

    android自定義倒計時控件示例

    這篇文章主要介紹了Android秒殺倒計時自定義TextView示例,大家參考使用吧
    2014-01-01
  • Android app應用多語言切換功能實現(xiàn)

    Android app應用多語言切換功能實現(xiàn)

    這篇文章主要為大家詳細介紹了Android app應用多語言切換功能實現(xiàn)代碼,感興趣的小伙伴們可以參考一下
    2016-08-08
  • Android后臺線程和UI線程通訊實例

    Android后臺線程和UI線程通訊實例

    這篇文章主要介紹了Android后臺線程和UI線程通訊實例,每一步的要點和步驟都有提及,并配有代碼例子,需要的朋友可以參考下
    2014-06-06
  • Android實現(xiàn)一個簡易的帶邊輸入框

    Android實現(xiàn)一個簡易的帶邊輸入框

    如今市面上APP的輸入框可以說是千奇百怪,不搞點花樣出來貌似代表格局沒打開,還在使用系統(tǒng)自帶的輸入框的兄弟可以停下腳步,哥帶你實現(xiàn)一個簡易的帶邊框輸入框,感興趣的同學可以自己動手試一下
    2023-08-08
  • Android中的Intent對象完全解析

    Android中的Intent對象完全解析

    這篇文章主要介紹了Android中的Intent對象,深入講解了intent對象傳遞消息的各種用法,需要的朋友可以參考下
    2016-04-04
  • Android中實現(xiàn)下載和解壓zip文件功能代碼分享

    Android中實現(xiàn)下載和解壓zip文件功能代碼分享

    這篇文章主要介紹了Android中實現(xiàn)下載和解壓zip文件功能代碼分享,本文直接給出了實現(xiàn)代碼,需要的朋友可以參考下
    2015-03-03
  • Android開發(fā)中的單例模式應用詳解

    Android開發(fā)中的單例模式應用詳解

    這篇文章主要介紹了Android開發(fā)中的單例模式應用,結合實例形式詳細分析了Android開發(fā)中常用單例模式的實現(xiàn)與使用方法,需要的朋友可以參考下
    2018-01-01
  • android 退出程序解決內存釋放的問題

    android 退出程序解決內存釋放的問題

    做Android項目的時候發(fā)現(xiàn)一個問題:當應用程序退出了,點擊"設置"查看應用程序,界面顯示著可以點擊"強制關閉 由于這個問題我發(fā)現(xiàn)了一個更加嚴重的問題,那就是,在我應用程序退出之后,系統(tǒng)并沒有釋放掉我應用程序所占內存
    2012-11-11

最新評論

望谟县| 石嘴山市| 启东市| 靖江市| 祁门县| 额尔古纳市| 武穴市| 成武县| 马关县| 崇阳县| 通海县| 安泽县| 宁乡县| 衡东县| 驻马店市| 彭水| 长宁区| 安新县| 秦皇岛市| 淳安县| 会东县| 大洼县| 营口市| 子长县| 闽清县| 瑞安市| 吉隆县| 南通市| 虎林市| 晴隆县| 雅江县| 安义县| 赞皇县| 抚顺县| 东阳市| 三亚市| 灵山县| 永州市| 海口市| 天全县| 海淀区|