2012-10-29 11 views
9

Devo consentire all'utente di inserire solo il tempo in ##: ## nel testo di modifica al volo, esiste un modo per raggiungerlo? Ho usato sotto il codice ma non funziona.Come limitare il tempo di immissione per edittext in Android

Sono in grado di immettere il numero più di 24 valori come 45623: 5689.

edit.setInputType(InputType.TYPE_DATETIME_VARIATION_TIME) 

Anche android:text="time" non funziona.

come posso ottenere questa cosa. Qualcuno mi può suggerire come posso fare questa cosa.

Desidero consentire all'utente di inserire nei primi 2 posti fino a un valore 23 e quindi compositivo: e quindi l'utente può consentire fino a un valore di 59.

ad esempio

23:59 correct 
24:05 incorrect 
02:56 correct 
02:79 incorrect 

Ho usato questo filtro sarto anche, ma la sua non funziona

ho ottenuto questo codice da qualche altro posto in SO.

Codice:

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

A cura Domanda: main.xml codice del file

<?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> 

Questo codice funziona, ma se inserisco primo alfabeto e inserire il valore corretto allora la sua non funziona perché source contiene il suo precedente valore di carattere.

+0

ho provato il codice in questo momento, penso che il problema in file XML che avevo menzionato ieri, rimuovi qualsiasi convalida del tipo di input da XML di EditText della tua attività e poi funziona bene –

+0

Grazie per l'aiuto, attendo il mio codice di file XML. Non c'è convalida né convalida del tipo di input. –

+0

Controlla la mia domanda aggiornata –

risposta

1

Prova a trasmettere i caratteri da int, quindi verificare se sono maggiori di 24 e 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. 
} 

Minus 48 perché i numeri 0 è 48a nella tabella ASCII. Il test deve essere ascii.

+0

Il mio filtro personalizzato è funziona ma non funziona se inserisco il primo alfabeto e poi i numeri. –

+0

Sicuramente la lunghezza se lo ordina? – Adude11

+0

Non riesco a farti ottenere –

1

Invece di char Perché non si utilizza stringa, perché char può essere utilizzato anche per comparsion in quanto può restituire i numeri

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

    //OR 
int x = c; 

Allora perchè non si utilizza String invece di char

o quello che si può fare, prendere i primi due caratteri usando la sottostringa o qualcosa del genere e usare Integer.parse() per analizzarlo, se analizzato correttamente allora è un numero valido altrimenti non è così è possibile convalidare e allo stesso modo lo fa per i prossimi due caratteri

EDIT

Se si voleva per implementare come questo 23:59 corretta 24:05 errato 02:56 corretta 02:79 errato

Poi qui è il codice che ha lavorato dal mio lato

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

Ho appena preso il tuo XML e inserito come layout di rete E non ci sono modifiche in XML Ora prova questo e dire?

EDIT 2 Ora qui ho aggiunto un validtion per abeti controllo char utilizzando doneOnce valore booleano Questo funziona ora, ditemi se avete qualsiasi altro problema da questo codice ora

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

Grazie per la risposta. Il mio codice non funziona quando inserisco l'alfabeto o il simbolo '-' in mezzo. se ho inserito altri simboli, allora funziona bene. Perché nella mia origine del filtro contiene il valore precedente invece di eliminare quel carattere non valido. –

+0

In XML per EditText prova a rimuovere android: inputType = "number" o qualcosa di simile e quindi riconvalidare il tuo codice, potrebbe essere filtrato dal sistema Android stesso, quindi prova a rimuovere qualsiasi elemento se presente –

+0

Grazie per la risposta. ma nella tua applicazione di lavoro prova questo: prima inserisci il carattere ''q'' e poi il carattere' t '' e poi prova a inserire '12' e poi prova a inserire qualsiasi alfabeto. in questo caso non funziona. se ho inserito prima "cifre", allora funziona bene. –

0

Prova questo, ho semplicemente modificato il codice che hai fornito ....

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

Questo funziona perfettamente per me. Accetta il tempo nel formato hh:mm solo (nessun altro carattere accettato)

0

Ho trovato this library per il tempo EditText. Il codice è facile da usare. Aggiungo alcune spiegazioni da parte del proprietario Codice:

A EditText personalizzato (in realtà derivato da TextView) all'ingresso ora in formato 24 ore. Caratteristiche:
- Si mostra sempre il tempo attualmente impostato, quindi non è mai vuoto.

  • È possibile utilizzare sia tastiere virtuali che fisiche.

  • La cifra corrente è evidenziata;

  • quando viene premuto un numero sulla tastiera, la cifra viene sostituita.

  • Tasto Indietro sposta il cursore indietro.

  • Tasto di spostamento sposta il cursore in avanti.

Qui è la classe 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; 
     }   
    }; 
} 
} 

è necessario aggiungere queste righe alla vista:

<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" /> 
Problemi correlati