このエントリーをはてなブックマークに追加

2010年4月19日月曜日

how to make kind of Twitter edit box

[In English]
Today, I'm going to make a component something like twitter edit box.
You know, edit box in http://twitter.com indicates the number of words that you can enter in real time.
EditText in Android SDK is not supported this function directory, so we need to implement similar function for ourselves.
We tend to think we can make it by applying a OnKeyListener to EditText.
But we can't in that way.

Basically OnKeyListener will inform you of hardware-keyboard events. But even in software-keyboard, OnKeyListener lets you know typical key events such as 'enter' or 'del'. But you cannot acquire whole events in software-keyborad.

In order to solve this problem, we create a new class extending EditText and then override onTextChanged method.
The method of 'onTextChanged' is called every time edit text is changed. Whichever software-keyboard or hardware-keyboard, you don't have to worry.

That way is very convenient solution this time. I wonder why onTextChanged method is provided as a listener. I think it's more useful for many occasions.

By the way, sample code is like this.


public class WordCountEditText extends EditText {

private TextView wordCountView;

private final static int MAX_LENGTH = 140;

public WordCountEditText(final Context context) {
super(context);
}

public WordCountEditText(final Context context, final AttributeSet attrs) {
super(context, attrs);
}

public WordCountEditText(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
}

@Override
protected void onTextChanged(final CharSequence text, final int start, final int before, final int after) {
if (wordCountView != null) {
final int textColor;
int leftLength = MAX_LENGTH - text.length();
if (leftLength < 0) {
textColor = Color.RED;
} else {
textColor = Color.GRAY;
}
wordCountView.setTextColor(textColor);
wordCountView.setText(String.valueOf(leftLength));
}
}

public void setWordCountView(final TextView wordCountView) {
this.wordCountView = wordCountView;
setText(getText());
}
}


And sample code in using class above.


WordCountEditText wordCountEditText = (WordCountEditText)findViewById(R.id.edit_text);
TextView wordCountView = (TextView)findViewById(R.id.word_count_view);
wordCountEditText.setWordCountView(wordCountView);






[In Japanese]
今日は、Twitter風のエディットテキストを作成する方法をご紹介します。
ご存知の通り、http://twitter.com で提供されているエディットボックスは、入力可能な残りの文字数がリアルタイムで表示されます。
残念ながら、Android SDKで提供されているEditTextには、この機能はありません。なので自分達で似たような機能を実装する必要があります。
Android SDKに慣れている人の中には、EditTextにOnKeyListenerを登録する事で実現できると考える人も多いと思います。しかしこのOnKeyListenerは、主にハードウェアキーボードのイベントを通知する為のものです。
ソフトウェアキーボードでも、「確定」キーや「DEL」キーのような代表的なキーのイベントはOnKeyListenerでイベントの検知が可能ですが、全てのイベントを検知する事はできません。

この問題を解決する為には、EditTextを継承した新しいクラスを作成し、onTextChangedメソッドをオーバーライドします。
onTextChangedメソッドは、EditTextの内容が書き換わる度に必ず呼び出されます。ハードウェアキーボードによる変更かソフトウェアキーボーかを気にする必要がありません。

今回の問題を解決するには正にうってつけの方法です。予断ですが、なぜonTextChangedメソッド相当のListenerが提供されていないのかが不思議です。Listenerが提供されていれば、新しいクラスを作成する必要もありませんし、色々な場面で便利だと思うのですが。

とりあえず、サンプルソースは以下のようになります。


public class WordCountEditText extends EditText {

private TextView wordCountView;

private final static int MAX_LENGTH = 140;

public WordCountEditText(final Context context) {
super(context);
}

public WordCountEditText(final Context context, final AttributeSet attrs) {
super(context, attrs);
}

public WordCountEditText(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
}

@Override
protected void onTextChanged(final CharSequence text, final int start, final int before, final int after) {
if (wordCountView != null) {
final int textColor;
int leftLength = MAX_LENGTH - text.length();
if (leftLength < 0) {
textColor = Color.RED;
} else {
textColor = Color.GRAY;
}
wordCountView.setTextColor(textColor);
wordCountView.setText(String.valueOf(leftLength));
}
}

public void setWordCountView(final TextView wordCountView) {
this.wordCountView = wordCountView;
setText(getText());
}
}


で、上記のクラスを使う側のコードが以下です。


WordCountEditText wordCountEditText = (WordCountEditText)findViewById(R.id.edit_text);
TextView wordCountView = (TextView)findViewById(R.id.word_count_view);
wordCountEditText.setWordCountView(wordCountView);

0 件のコメント:

コメントを投稿