Skip to content

Instantly share code, notes, and snippets.

@gokhanbarisaker
Created September 20, 2012 07:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gokhanbarisaker/3754407 to your computer and use it in GitHub Desktop.
Save gokhanbarisaker/3754407 to your computer and use it in GitHub Desktop.
characters with navigation
public static String generateCharacterTagByIndex(int index)
{
return (Integer.toString(index + 14970));
}
class NavigatableEditText extends EditText
{
private WeakReference<View> navigationNext = null;
private WeakReference<View> navigationPrevious = null;
public NavigatableEditText(Context context)
{
super(context);
// TODO Auto-generated constructor stub
}
/**
* @return the navigationNext
*/
public View getNavigationNext()
{
return (navigationNext == null)?(null):(navigationNext.get());
}
/**
* @param navigationNext the navigationNext to set
*/
public void setNavigationNext(View navigationNext)
{
this.navigationNext = new WeakReference<View>(navigationNext);
}
/**
* @return the navigationPrevious
*/
public View getNavigationPrevious()
{
return (navigationPrevious == null)?(null):(navigationPrevious.get());
}
/**
* @param navigationPrevious the navigationPrevious to set
*/
public void setNavigationPrevious(View navigationPrevious)
{
this.navigationPrevious = new WeakReference<View>(navigationPrevious);
}
}
class CharacterBox extends NavigatableEditText
{
/*************************************************
* Log
*/
private static final String TAG = "Character Box";
private static final boolean LOG = true;
private CharacterState state;
public CharacterBox(Context context)
{
super(context);
setText("");
setState(CharacterState.STATE_INVISIBLE);
updateBackground(false);
super.setOnFocusChangeListener(new CharacterBoxOnFocusChangeListener());
super.setOnKeyListener(new CharacterBoxOnKeyListener());
super.addTextChangedListener(new CharacterBoxTextWatcher(this));
super.setFilters(new InputFilter[]{ new InputFilter.LengthFilter(99) });
}
public CharacterState getState() {
return state;
}
public void setState(CharacterState state) {
this.state = state;
}
// @Override
// public void setOnFocusChangeListener(OnFocusChangeListener l)
// {
// super.setOnFocusChangeListener(l);
//
// Exception deprecatedMethodException = new Exception("Attaching View.OnFocusChageListener() is deprecated.");
//
// throw deprecatedMethodException;
// }
public void moveToNextCharacter()
{
CharacterBox nextCharacterBox = (CharacterBox) getNavigationNext();
// If no view defined for next
if(nextCharacterBox == null)
{
if(LOG)
{
Log.d(TAG, "No navigationNext defined for CharacterBox with tag: " + getTag());
}
// Clear focus
clearFocus();
// Hide keyboard if shown
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(this.getWindowToken(), 0);
}
else
{
switch (getState())
{
case STATE_HINT:
{
if(LOG)
{
Log.d(TAG, "CharacterBox with tag: " + nextCharacterBox.getTag() + " (hint). Proceeding search...");
}
// Next character box not editable, keep searching...
nextCharacterBox.moveToNextCharacter();
break;
}
case STATE_INVISIBLE:
{
if(LOG)
{
Log.d(TAG, "Moving from CharacterBox with tag: " + getTag() + " to: " + nextCharacterBox.getTag() + " (invisible). Requesting focus...");
}
// Next character is ediatable, request focus for it.
nextCharacterBox.requestFocus();
break;
}
case STATE_USER_INPUT:
{
if(LOG)
{
Log.d(TAG, "Moving from CharacterBox with tag: " + getTag() + " to: " + nextCharacterBox.getTag() + " (user input). Requesting focus...");
}
// Next character is ediatable, request focus for it.
nextCharacterBox.requestFocus();
break;
}
default:
{
if(LOG)
{
Log.d(TAG, "Unable to perform moveToNextCharacter(). Undefined CharacterBox state: " + getState());
}
break;
}
}
}
}
public void moveToPreviousCharacter()
{
CharacterBox previousCharacterBox = (CharacterBox) getNavigationPrevious();
// If no view defined for next
if(previousCharacterBox == null)
{
if(LOG)
{
Log.d(TAG, "No navigationPrevious defined for CharacterBox with tag: " + getTag());
}
// // Hide keyboard if shown
// InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
// imm.hideSoftInputFromWindow(this.getWindowToken(), 0);
}
else
{
switch (getState())
{
case STATE_HINT:
{
if(LOG)
{
Log.d(TAG, "CharacterBox with tag: " + previousCharacterBox.getTag() + " defined as hint. Proceeding search...");
}
// previous character box not editable, keep searching...
previousCharacterBox.moveToPreviousCharacter();
break;
}
case STATE_INVISIBLE:
{
if(LOG)
{
Log.d(TAG, "CharacterBox with tag: " + previousCharacterBox.getTag() + " defined as invisible. Requesting focus...");
}
// Previous character is ediatable, request focus for it.
previousCharacterBox.requestFocus();
break;
}
case STATE_USER_INPUT:
{
if(LOG)
{
Log.d(TAG, "CharacterBox with tag: " + previousCharacterBox.getTag() + " defined as user input. Requesting focus...");
}
// Previous character is ediatable, request focus for it.
previousCharacterBox.requestFocus();
break;
}
default:
{
if(LOG)
{
Log.d(TAG, "Unable to perform moveToPreviousCharacter(). Undefined CharacterBox state: " + getState());
}
break;
}
}
}
}
public void updateBackground(boolean isCurrentlyEditing)
{
if(isCurrentlyEditing)
{
switch(getState())
{
case STATE_INVISIBLE:
case STATE_USER_INPUT:
{
setBackgroundResource(android.R.color.holo_blue_bright);
break;
}
case STATE_HINT:
default:
{
if(LOG)
{
Log.d(TAG, "Possible bug. Update background for state: " + getState() + " not defined for editing session.");
}
break;
}
}
}
else
{
switch(getState())
{
case STATE_INVISIBLE:
case STATE_USER_INPUT:
{
setBackgroundResource(android.R.color.holo_blue_dark);
break;
}
case STATE_HINT:
{
setBackgroundResource(android.R.color.holo_red_light);
break;
}
default:
{
if(LOG)
{
Log.d(TAG, "Possible bug. Update background for state: " + getState() + " not defined for non-editing session.");
}
break;
}
}
}
}
class CharacterBoxOnFocusChangeListener implements View.OnFocusChangeListener
{
@Override
public void onFocusChange(View v, boolean hasFocus)
{
Log.d(TAG, "Character (" + v.getTag() + ") has focus: " + hasFocus);
if(hasFocus)
{
CharacterBox.this.setSelection(CharacterBox.this.getText().length());
CharacterBox.this.updateBackground(true);
}
else
{
CharacterBox.this.updateBackground(false);
}
}
}
/**
*
* @author Mac
*
* Handles only KEYCODE_DEL
*
*/
class CharacterBoxOnKeyListener implements View.OnKeyListener
{
@Override
public boolean onKey(View v, int keyCode, KeyEvent event)
{
CharacterBox characterBox = (CharacterBox) v;
// If backspace pressed
if(keyCode == KeyEvent.KEYCODE_DEL)
{
// If character box empty
if(TextUtils.isEmpty(characterBox.getText()))
{
// Move to previous character box
characterBox.clearFocus();
characterBox.moveToPreviousCharacter();
}
else
{
characterBox.setText("");
characterBox.setState(CharacterState.STATE_INVISIBLE);
}
return true;
}
else
{
// Else condition handled at on text watcher.
}
return false;
}
}
/**
*
* @author Mac
*
* Controls user input except KEYCODE_DEL
*
*/
class CharacterBoxTextWatcher implements TextWatcher
{
private WeakReference<CharacterBox> characterBoxWeak = null;
private boolean validToUpdate = false;
public CharacterBoxTextWatcher(CharacterBox victimCharacterBox)
{
if(victimCharacterBox == null)
{
throw new NullPointerException("It is forbidden to use null reference for victimCharacterBox with CharacterBoxTextWatcher");
}
else
{
characterBoxWeak = new WeakReference<CharacterBox>(victimCharacterBox);
}
}
@Override
public void afterTextChanged(Editable s)
{
final CharacterBox characterBox = characterBoxWeak.get();
if(characterBox != null)
{
String successorString = formatEditable(s);
// If successor string not empty|null
if(!TextUtils.isEmpty(successorString))
{
Pattern matchPattern = Pattern.compile("[A-Z^ŞİÇÖÜĞ]");
Matcher matcher = matchPattern.matcher(successorString);
// If successor string matches given pattern
boolean isSuccessorStringValid = matcher.matches();
// If successor string not already exist
boolean isPatternFormerlyPrinted = successorString.equals(s.toString());;
if(!isPatternFormerlyPrinted)
{
if(isSuccessorStringValid)
{
characterBox.setText(successorString);
}
else
{
String ancestorString = s.toString().split(successorString)[0];
characterBox.setText(ancestorString);
}
}
else
{
characterBox.setState(CharacterState.STATE_USER_INPUT);
characterBox.clearFocus();
characterBox.moveToNextCharacter();
}
}
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {}
@Override
public void onTextChanged(final CharSequence s, int start, int before,
int count) {}
private String formatEditable(Editable e)
{
if(e != null)
{
if(!TextUtils.isEmpty(e))
{
String formattedEditableString = e.toString().trim();
int lastCharacterIndex = formattedEditableString.length() - 1;
String lastCharacter = formattedEditableString.substring(lastCharacterIndex);
return lastCharacter.toUpperCase();
}
}
return "";
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment