Java android中如何限制edittext的输入时间

Java android中如何限制edittext的输入时间,java,android,validation,android-edittext,Java,Android,Validation,Android Edittext,我必须允许用户以动态编辑文本的###:###格式只输入时间,有什么方法可以实现吗?我使用了下面的代码,但它不工作 我能够输入大于24的数值,如45623:5689 edit.setInputType(InputType.TYPE_DATETIME_VARIATION_TIME) 即使是android:text=“time”也不起作用 我怎样才能做到这一点。谁能建议我怎么做这件事 我想允许用户在前两个位置输入最多23个值,然后是compulasary:然后用户可以允许最多59个值 比如说 23:

我必须允许用户以动态编辑文本的###:###格式只输入时间,有什么方法可以实现吗?我使用了下面的代码,但它不工作

我能够输入大于24的数值,如45623:5689

edit.setInputType(InputType.TYPE_DATETIME_VARIATION_TIME)
即使是
android:text=“time”
也不起作用

我怎样才能做到这一点。谁能建议我怎么做这件事

我想允许用户在前两个位置输入最多23个值,然后是compulasary:然后用户可以允许最多59个值

比如说

23:59 correct
24:05 incorrect
02:56 correct
02:79 incorrect
我也使用了这个自定义过滤器,但它不起作用

我从其他地方得到了这个密码

代码:

    InputFilter timeFilter = new InputFilter() {
        public CharSequence filter(CharSequence source, int start, int end, Spanned dest,
                int dstart, int dend) {
            if (source.length() == 0) {
                return null;// deleting, keep original editing
            }
            String result = "";
            result += dest.toString().substring(0, dstart);
            result += source.toString().substring(start, end);
            result += dest.toString().substring(dend, dest.length());

            if (result.length() > 5) {
                return "";// do not allow this edit
            }
            boolean allowEdit = true;
            char c;
            if (result.length() > 0) {
                c = result.charAt(0);
                allowEdit &= (c >= '0' && c <= '2');
            }
            if (result.length() > 1) {
                c = result.charAt(1);
                allowEdit &= (c >= '0' && c <= '9');
            }
            if (result.length() > 2) {
                c = result.charAt(2);
                allowEdit &= (c == ':');
            }
            if (result.length() > 3) {
                c = result.charAt(3);
                allowEdit &= (c >= '0' && c <= '5');
            }
            if (result.length() > 4) {
                c = result.charAt(4);
                allowEdit &= (c >= '0' && c <= '9');
            }
            return allowEdit ? null : "";
        }
    };
InputFilter timeFilter=newinputfilter(){
公共CharSequence筛选器(CharSequence源、int开始、int结束、跨距目标、,
内部数据启动,内部数据存储){
if(source.length()==0){
返回null;//删除,保留原始编辑
}
字符串结果=”;
结果+=dest.toString()子字符串(0,dstart);
结果+=source.toString()子字符串(开始、结束);
结果+=dest.toString()子字符串(dend,dest.length());
如果(result.length()>5){
返回“”;//不允许进行此编辑
}
布尔allowEdit=true;
字符c;
if(result.length()>0){
c=结果字符(0);
允许它(&=(c>='0'和&c 1){
c=结果字符(1);
允许它(&=(c>='0'和&c 2){
c=结果字符(2);
允许它&=(c==':');
}
if(result.length()>3){
c=结果字符(3);
允许它(&=(c>='0'和&c 4){
c=结果字符(4);

allowEdit&=(c>='0'&&c尝试将字符强制转换为int,然后测试它们是否大于24和60

int a = ((int) result.charAt(0)) - 48;
int b = ((int) result.charAt(1)) - 48;
int c = ((int) result.charAt(3)) - 48;
if(a < 0 || b < 0 || c < 0) {
    Not right.
}

if((a > 2 || (a == 2 && b > 3)) || c > 59) {
    Neither is this.
}
inta=((int)result.charAt(0))-48;
intb=((int)result.charAt(1))-48;
int c=((int)result.charAt(3))-48;
if(a<0 | | b<0 | | c<0){
不对。
}
如果((a>2 | |(a==2&b>3))| | c>59){
这也不是。
}

减48,因为数字0在ascii表中是第48位。测试必须是ascii。

为什么不使用字符串,因为字符也可以用于比较,因为它可以返回数字

char c ='a';
    if(c>10)
    //do something

    //OR
int x = c;
那么为什么不使用字符串而不是字符呢

或者,您可以使用substring或类似的方法获取前两个字符,然后使用Integer.parse()方法对其进行解析,如果解析成功,那么它是一个有效数字,否则它不是,所以您可以验证它,并同样地对下两个字符进行解析

编辑

如果你想这样实现 23:59对 24:05不正确 02:56对 02:79不正确

这是我这边的代码

public class MainActivity extends Activity {
 InputFilter timeFilter;
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    timeFilter  = new InputFilter() {
        @Override
        public CharSequence filter(CharSequence source, int start, int end, Spanned dest,
                int dstart, int dend) {
            if (source.length() == 0) {
                return null;// deleting, keep original editing
            }
            String result = "";
            result += dest.toString().substring(0, dstart);
            result += source.toString().substring(start, end);
            result += dest.toString().substring(dend, dest.length());

            if (result.length() > 5) {
                return "";// do not allow this edit
            }
            boolean allowEdit = true;
            char c;
            if (result.length() > 0) {
                c = result.charAt(0);
                allowEdit &= (c >= '0' && c <= '2');
            }
            if (result.length() > 1) {
                c = result.charAt(1);
                if(result.charAt(0) == '0' || result.charAt(0) == '1')
                    allowEdit &= (c >= '0' && c <= '9');
                else
                    allowEdit &= (c >= '0' && c <= '3');
            }
            if (result.length() > 2) {
                c = result.charAt(2);
                allowEdit &= (c == ':');
            }
            if (result.length() > 3) {
                c = result.charAt(3);
                allowEdit &= (c >= '0' && c <= '5');
            }
            if (result.length() > 4) {
                c = result.charAt(4);
                allowEdit &= (c >= '0' && c <= '9');
            }
            return allowEdit ? null : "";
        }

    };

    EditText txt1 = (EditText) findViewById(R.id.edTxtParcelDeliverTime);
    txt1.setFilters(new InputFilter[]{timeFilter});
}
}
公共类MainActivity扩展活动{
输入滤波器时间滤波器;
@凌驾
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
timeFilter=新的InputFilter(){
@凌驾
公共CharSequence筛选器(CharSequence源、int开始、int结束、跨距目标、,
内部数据启动,内部数据存储){
if(source.length()==0){
返回null;//删除,保留原始编辑
}
字符串结果=”;
结果+=dest.toString()子字符串(0,dstart);
结果+=source.toString()子字符串(开始、结束);
结果+=dest.toString()子字符串(dend,dest.length());
如果(result.length()>5){
返回“”;//不允许进行此编辑
}
布尔allowEdit=true;
字符c;
if(result.length()>0){
c=结果字符(0);
允许它(&=(c>='0'和&c 1){
c=结果字符(1);
if(result.charAt(0)='0'| | result.charAt(0)='1')
允许它(&=(c>='0'和&c='0'和&c 2){
c=结果字符(2);
允许它&=(c==':');
}
if(result.length()>3){
c=结果字符(3);
允许它(&=(c>='0'和&c 4){
c=结果字符(4);
allowEdit&=(c>='0'&&c 1&&doneOnce==false){
source=source.subSequence(source.length()-1,source.length());
if(source.charAt(0)>=“0”和&source.charAt(0)5){
返回“”;//不允许进行此编辑
}
布尔allowEdit=true;
字符c;
if(result.length()>0){
c=结果字符(0);
允许它(&=(c>='0'和&c 1){
c=结果字符(1);
if(result.charAt(0)='0'| | result.charAt(0)='1')
允许它(&=(c>='0'和&c='0'和&c 2){
c=结果字符(2);
允许它&=(c==':');
}
if(result.length()>3){
c=结果字符(3);
允许它(&=(c>='0'和&c 4){
c=结果字符(4);

允许它&=(c>='0'&&c试试这个,我只是编辑了您提供的代码

InputFilter[] timeFilter = new InputFilter[1];

timeFilter[0] = new InputFilter() {
    public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {

        if (source.length() == 0) {
            return null;// deleting, keep original editing
        }

        String result = "";
        result += dest.toString().substring(0, dstart);
        result += source.toString().substring(start, end);
        result += dest.toString().substring(dend, dest.length());

        if (result.length() > 5) {
            return "";// do not allow this edit
        }

        boolean allowEdit = true;
        char c;
        if (result.length() > 0) {
            c = result.charAt(0);
            allowEdit &= (c >= '0' && c <= '2' && !(Character.isLetter(c)));
        }

        if (result.length() > 1) {
            c = result.charAt(1);
            allowEdit &= (c >= '0' && c <= '9' && !(Character.isLetter(c)));
        }

        if (result.length() > 2) {
            c = result.charAt(2);
            allowEdit &= (c == ':'&&!(Character.isLetter(c)));
        }

        if (result.length() > 3) {
            c = result.charAt(3);
            allowEdit &= (c >= '0' && c <= '5' && !(Character.isLetter(c)));
        }

        if (result.length() > 4) {
            c = result.charAt(4);
            allowEdit &= (c >= '0' && c <= '9'&& !(Character.isLetter(c)));
        }

        return allowEdit ? null : "";
    }
};
InputFilter[]时间过滤器=新的InputFilter[1];
timeFilter[0]=新的InputFilter(){
公共CharSequence筛选器(CharSequence源、int开始、int结束、跨区目标、int开始、int结束){
if(source.length()==0){
返回null;//删除,保留原始编辑
}
字符串结果=”;
结果+=dest.toString()子字符串(0,dstart);
结果+=source.toString()子字符串(开始、结束);
结果+=dest.toString()子字符串(dend,dest.length());
public class MainActivity extends Activity {
EditText edt1;
InputFilter timeFilter;
private String LOG_TAG = "MainActivity";
private boolean doneOnce = false;
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    timeFilter  = new InputFilter() {
        @Override
        public CharSequence filter(CharSequence source, int start, int end, Spanned dest,
                int dstart, int dend) {

            if(source.length() > 1 && doneOnce == false){
                source = source.subSequence(source.length()-1, source.length());
                if(source.charAt(0)  >= '0' && source.charAt(0) <= '2'){
                    doneOnce = true;
                    return source;
                }else{
                    return "";
                }
            }


            if (source.length() == 0) {
                return null;// deleting, keep original editing
            }
            String result = "";
            result += dest.toString().substring(0, dstart);
            result += source.toString().substring(start, end);
            result += dest.toString().substring(dend, dest.length());

            if (result.length() > 5) {
                return "";// do not allow this edit
            }
            boolean allowEdit = true;
            char c;
            if (result.length() > 0) {
                c = result.charAt(0);
                allowEdit &= (c >= '0' && c <= '2');
            }
            if (result.length() > 1) {
                c = result.charAt(1);
                if(result.charAt(0) == '0' || result.charAt(0) == '1')
                    allowEdit &= (c >= '0' && c <= '9');
                else
                    allowEdit &= (c >= '0' && c <= '3');
            }
            if (result.length() > 2) {
                c = result.charAt(2);
                allowEdit &= (c == ':');
            }
            if (result.length() > 3) {
                c = result.charAt(3);
                allowEdit &= (c >= '0' && c <= '5');
            }
            if (result.length() > 4) {
                c = result.charAt(4);
                allowEdit &= (c >= '0' && c <= '9');
            }
            return allowEdit ? null : "";
        }

    };


    edt1 = (EditText) findViewById(R.id.edTxtParcelDeliverTime);
    edt1.setFilters(new InputFilter[] { timeFilter });

}
}
InputFilter[] timeFilter = new InputFilter[1];

timeFilter[0] = new InputFilter() {
    public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {

        if (source.length() == 0) {
            return null;// deleting, keep original editing
        }

        String result = "";
        result += dest.toString().substring(0, dstart);
        result += source.toString().substring(start, end);
        result += dest.toString().substring(dend, dest.length());

        if (result.length() > 5) {
            return "";// do not allow this edit
        }

        boolean allowEdit = true;
        char c;
        if (result.length() > 0) {
            c = result.charAt(0);
            allowEdit &= (c >= '0' && c <= '2' && !(Character.isLetter(c)));
        }

        if (result.length() > 1) {
            c = result.charAt(1);
            allowEdit &= (c >= '0' && c <= '9' && !(Character.isLetter(c)));
        }

        if (result.length() > 2) {
            c = result.charAt(2);
            allowEdit &= (c == ':'&&!(Character.isLetter(c)));
        }

        if (result.length() > 3) {
            c = result.charAt(3);
            allowEdit &= (c >= '0' && c <= '5' && !(Character.isLetter(c)));
        }

        if (result.length() > 4) {
            c = result.charAt(4);
            allowEdit &= (c >= '0' && c <= '9'&& !(Character.isLetter(c)));
        }

        return allowEdit ? null : "";
    }
};
public class TimeEditText extends TextView {

private static final int POSITION_NONE = -1;

private int[] digits = new int[4];
private int currentPosition = POSITION_NONE;
private int mImeOptions;

public TimeEditText(Context context) {
    this(context, null, 0);
}

public TimeEditText(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
}

public TimeEditText(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    setFocusableInTouchMode(true);

    if (attrs != null && !isInEditMode()) {
        mImeOptions = attrs.getAttributeIntValue("http://schemas.android.com/apk/res/android", "imeOptions", 0);
    }

    updateText();       
}

/**
 * @return the current hour (from 0 to 23)
 */
public int getHour() {
    return digits[0]*10+digits[1];
}

/**
 * @return the current minute
 */
public int getMinutes() {
    return digits[2]*10+digits[3];
}

/**
 * Set the current hour
 * @param hour hour (from 0 to 23)
 */
public void setHour(int hour) {
    hour = hour % 24;
    digits[0] = hour/10;
    digits[1] = hour%10;
    updateText();
}

/**
 * Set the current minute
 * @param min minutes (from 0 to 59)
 */
public void setMinutes(int min) {
    min = min % 60;
    digits[2] = min/10;
    digits[3] = min%10;
    updateText();
}

@Override
protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
    // hide cursor if not focused
    currentPosition = focused ? 0 : POSITION_NONE;
    updateText();
    super.onFocusChanged(focused, direction, previouslyFocusedRect);
}   

private void updateText() {
    int bold = currentPosition > 1 ? currentPosition+1 : currentPosition;   
    int color = getTextColors().getDefaultColor();
    Spannable text = new SpannableString(String.format("%02d:%02d", getHour(), getMinutes()));
    if (bold >= 0) {
        text.setSpan(new ForegroundColorSpan(color & 0xFFFFFF | 0xA0000000), 0, 5, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        text.setSpan(new StyleSpan(Typeface.BOLD), bold, bold+1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        text.setSpan(new ForegroundColorSpan(Color.BLACK), bold, bold+1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        text.setSpan(new BackgroundColorSpan(0x40808080), bold, bold+1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    }
    setText(text);  
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    if (event.getAction() == MotionEvent.ACTION_UP) {
        requestFocusFromTouch();
        InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.showSoftInput(this,0);
        if (currentPosition == POSITION_NONE) {
            currentPosition = 0;
            updateText();
        }
    }
    return true;
}   

private boolean onKeyEvent(int keyCode, KeyEvent event) {
    if (event != null && event.getAction() != KeyEvent.ACTION_DOWN)
        return false;

    if (keyCode == KeyEvent.KEYCODE_DEL) {  
        // moves cursor backward
        currentPosition = currentPosition >= 0 ? (currentPosition+3)%4 : 3;
        updateText();
        return true;
    }

    if (keyCode == KeyEvent.KEYCODE_SPACE) {
        // moves cursor forward
        currentPosition = (currentPosition+1)%4;
        updateText();
        return true;
    }

    if (keyCode == KeyEvent.KEYCODE_ENTER) {
        View v = focusSearch(FOCUS_DOWN);
        boolean next = v!=null;
        if (next) {
            next = v.requestFocus(FOCUS_DOWN);
        }         
        if (!next) {
            hideKeyboard();
            currentPosition = POSITION_NONE;
            updateText();
        }
        return true;
    }       

    char c = (char) event.getUnicodeChar();  
    if (c >= '0' && c <= '9') {
        currentPosition = currentPosition == POSITION_NONE ? 0 : currentPosition;
        int n = c - '0';
        boolean valid = false;

        switch (currentPosition) {
            case 0: // first hour digit must be 0-2
                valid = n <= 2;
                break;
            case 1: // second hour digit must be 0-3 if first digit is 2
                valid = digits[0] < 2 || n <= 3;
                break;
            case 2: // first minute digit must be 0-6
                valid = n < 6;
                break;
            case 3: // second minuti digit always valid (0-9)
                valid = true;
                break;
        }

        if (valid) {
            if (currentPosition == 0 && n == 2 && digits[1] > 3) { // clip to 23 hours max
                digits[1] = 3;
            }

            digits[currentPosition] = n;
            currentPosition = currentPosition < 3 ? currentPosition+1 : POSITION_NONE;  // if it is the last digit, hide cursor
            updateText();
        }

        return true;
    }

    return false;
}

private void hideKeyboard() {
    InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(getWindowToken(), 0);        
}


@Override
public boolean onKeyDown(int keyCode, KeyEvent event) { 
    // events from physical keyboard
    return onKeyEvent(keyCode, event);
}

@Override
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
    // manage events from the virtual keyboard
    outAttrs.actionLabel = null;
    outAttrs.label = "time";
    outAttrs.inputType = InputType.TYPE_CLASS_NUMBER;
    outAttrs.imeOptions = mImeOptions | EditorInfo.IME_FLAG_NO_EXTRACT_UI;

    if ((outAttrs.imeOptions & EditorInfo.IME_MASK_ACTION) == EditorInfo.IME_ACTION_UNSPECIFIED) {
        if (focusSearch(FOCUS_DOWN) != null) {
            outAttrs.imeOptions |= EditorInfo.IME_ACTION_NEXT;
        } else {
            outAttrs.imeOptions |= EditorInfo.IME_ACTION_DONE;
        }
    }

    return new BaseInputConnection(this, false) {
        @Override
        public boolean performEditorAction(int actionCode) {
            if (actionCode == EditorInfo.IME_ACTION_DONE) {
                hideKeyboard();
                currentPosition = POSITION_NONE;
                updateText();
            } else if (actionCode == EditorInfo.IME_ACTION_NEXT){
                View v = focusSearch(FOCUS_DOWN);
                if (v!=null) {
                    v.requestFocus(FOCUS_DOWN);
                }
            }
            return true;
        }

        @Override
        public boolean deleteSurroundingText(int beforeLength, int afterLength) {
            onKeyEvent(KeyEvent.KEYCODE_DEL, null); 
            return true;
        }

        @Override
        public boolean sendKeyEvent(KeyEvent event) {
            onKeyEvent(event.getKeyCode(), event);
            return true;
        }           
     };
 }
}
<YourPackageName.TimeEditText
            android:id="@+id/satOpenEditText"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dp"
            android:layout_marginRight="10dp"
            android:layout_weight="1"
            android:ems="10"
            android:inputType="time"
            android:textSize="16sp" />
//using the input regulation for the time data
    timeField.addTextChangedListener(new TextWatcher() {
        String beforeTXT;
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                Log.i("before TEXT TEXXT", " this : "+s+" and "+start+" and "+count+"and "+after);
                beforeTXT= ""+s;
        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            int input ;

            //first determine whether user is at hrs side or min side
            if (s.toString().equals("")){
                return;
            }
            if(s.toString().length()>2 && start<=2){ //means the user is at hour side
                input = Integer.parseInt(s.toString().substring(0,1)) % 10;

            }
            else if(s.toString().length()>2 && start>=3) {//means that user is at min side
                input = Integer.parseInt("0"+s.toString().substring(3))%10;

            }
            else if(s.toString().indexOf(":")==1){ // if we have for eg 1: or 0: then we take first character for parsing
                input = Integer.parseInt(s.toString().charAt(0)+"");
            }
            else{ //else it is default where the user is at first position
                input = Integer.parseInt(s.toString()) % 10;
            }

            //Special case where 00: is autommatically converted to 12: in 12hr time format
            if(s.toString().contains("00:")){
                Log.i("INsisde )))","i am called ");
                timeField.setText("12:");
               return;
            }

            //Now we manipulate the input and its formattin and cursor movement
            if(input<=1 && start ==0){ //thiis is for first input value to check .... time shouldnt exceed 12 hr
                //do nothing
            }
            else if (input>1 && start==0){ //if at hour >1 is press then automaticc set the time as 02: or 05: etc
             timeField.setText("0"+s+":");
            }
            else if(input>2 && start==1 && !s.toString().startsWith("0")){ //whe dont have greater than 12 hrs so second postionn shouldn't exceed value 2
                timeField.setText(beforeTXT);
            }
            else if(start==1 && !beforeTXT.contains(":")){  //if valid input 10 or 11 or 12 is given then convert it to 10: 11: or 12:
                timeField.setText(s.toString()+":");

                if(s.toString().length()==1 && s.toString().startsWith("0")){
                timeField.setText("");
                }
                if(s.toString().startsWith("1")&& s.toString().length()==1){ //on back space convert 1: to 01:
                    timeField.setText("0"+timeField.getText().toString());
                }

           }
            else if(start == 3 && input >5 ){ //min fig shouldn't exceed 59 so ...if at first digit of min input >5 then do nothing or codpy the earlier text
                timeField.setText(beforeTXT);
            }
           else if (start>4 && s.toString().length()>5){ // the total string lenght shouldn't excced 5
                timeField.setText(beforeTXT);
            }
            else if(start<2 && beforeTXT.length()>2){
                timeField.setText(beforeTXT);

            }


        }

        @Override
        public void afterTextChanged(Editable s) {

            Log.i("after  TEXT TEXXT", " this : "+s);
            timeField.setSelection(timeField.getText().toString().length());

        }
    });