2012-10-29 243 views
9

我必須允許用戶在動態編輯文本中只輸入##:##格式的時間,有什麼方法可以實現嗎?我使用下面的代碼,但它不工作。如何在android中限制編輯文本的輸入時間

我能夠輸入超過24個數值,如45623:5689。

​​

即使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 : ""; 
     } 
    }; 

編輯問:main.xml中的文件代碼

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:gravity="center" 
    android:orientation="vertical" 
    android:padding="10dp" > 

    <LinearLayout 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:layout_marginTop="5dp" 
     android:gravity="center" 
     android:orientation="horizontal" > 

     <TextView 
      android:id="@+id/txtRecipientName" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:paddingRight="20dp" 
      android:text="@string/recipient_name" /> 

     <EditText 
      android:id="@+id/edTxtRecipient" 
      android:layout_width="fill_parent" 
      android:layout_height="wrap_content" 
      android:ems="10" 
      android:paddingLeft="20dp" > 

      <requestFocus /> 
     </EditText> 
    </LinearLayout> 

    <LinearLayout 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:layout_marginTop="5dp" 
     android:gravity="center" 
     android:orientation="horizontal" > 

     <TextView 
      android:id="@+id/txtParcelDeliverTime" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:paddingRight="20dp" 
      android:text="@string/delivered_time" /> 

     <EditText 
      android:id="@+id/edTxtParcelDeliverTime" 
      android:layout_width="fill_parent" 
      android:layout_height="wrap_content" 
      android:ems="10" 
      android:paddingLeft="20dp" > 
     </EditText> 
    </LinearLayout> 

    <LinearLayout 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:layout_marginTop="5dp" 
     android:gravity="center" 
     android:orientation="horizontal" > 

     <Button 
      android:id="@+id/btnRecipient_OK" 
      android:layout_width="100dp" 
      android:layout_height="wrap_content" 
      android:text="@android:string/ok" /> 
    </LinearLayout> 

</LinearLayout> 

此代碼工作,但如果我插入第一個字母和插入適當的值,那麼它不工作因爲source包含其先前的字符值。

+0

我剛纔試了你的代碼,我覺得在XML文件中的問題我昨天提到,從您的Activity的EditText的XML中刪除任何輸入類型驗證,然後它工作正常 –

+0

感謝您的幫助等待我會把我的XML文件代碼。沒有驗證或沒有輸入類型驗證。 –

+0

檢查我更新的問題 –

回答

1

嘗試鑄造字符到整型,然後測試它們是否大於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. 
} 

減號48因爲數字0是第48在ASCII表。 測試必須是ascii。

+0

我的自定義過濾器是工作,但它不工作,如果我輸入第一個字母,然後數字。 –

+0

當然,那麼長度如果排序呢? – Adude11

+0

我不能讓你 –

1

不是CHAR你爲什麼不使用字符串,因爲焦炭也可用於comparsion,因爲它可以返回你爲什麼不使用替代焦炭

或者你串號

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

    //OR 
int x = c; 

左右可以做的是,採取使用子字符串或類似的東西,並使用Integer的前兩個字符。解析()方法來解析它,如果它成功地解析那麼它還有一個有效的數字是不是這樣你就可以驗證它同樣地,對於接下來的兩個字符

編輯

如果你想做到這一點實現這樣的 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}); 
} 
} 

我剛把你的XML放在我的電源佈局 並且沒有更改XML 現在試試這個並告訴?

EDIT 2 現在在這裏,我已經使用doneOnce布爾值 增加了validtion的冷杉焦炭檢查這個工作現在,告訴我,如果你從這個代碼有其他任何問題,現在

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 }); 

} 
} 
+0

感謝您的回覆。當我在兩者之間輸入字母或' - '符號時,此代碼不起作用。如果我輸入其他符號,那麼它的工作正常。爲什麼在我的過濾器源代碼中包含以前的值而不是刪除無效的字符。 –

+0

在你的XML for EditText嘗試刪除android:inputType =「number」或類似的東西,然後重新驗證你的代碼,可能是它的過濾器由android系統本身,所以嘗試刪除任何這樣的項目,如果存在 –

+0

感謝您的答案。但是在你的工作應用程序中試試這個:首先輸入''q''然後輸入''t'',然後嘗試輸入'12',然後嘗試輸入任何字母。在這種情況下它不起作用。如果我輸入了第一個數字,那麼它的工作正常。 –

0

試試這個,我只是編輯你提供的代碼....

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 : ""; 
    } 
}; 

這對我來說絕對很好。僅接受格式hh:mm的時間(不接受其他字符)

0

我發現this library的時間爲EditText。該代碼易於使用。我想補充一些解釋從代碼店主:

自定義的EditText(實際上是從的TextView派生)輸入 時間24小時格式。 特點:
- 它總是顯示當前設置的時間,所以這是從來沒有空。

  • 虛擬鍵盤和物理鍵盤都可以使用。

  • 的當前數字被高亮顯示;

  • 當按下鍵盤上的數字,該數字將被替換。

  • 返回鍵向後移動光標。

  • 空格鍵移動光標 前進。

這裏是TimeEditText類:

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" /> 
相關問題