Android Advent Calendar 2012 #androidadvent2012
12/20(裏) 担当の @katsummy です。表担当は@stachibanaさんとなります。
よろしくお願いします〜。
シニアの方にはこんなの自分で実装してるよ〜な内容になるかもです。
■ViewHolder
XMLでレイアウトを作成した後、ActivityまたはFragmentの中で扱う為に、inflateしてViewをfindViewByIdして、メンバー変数に格納しますよね?
結構面倒くさくないですか?
- レイアウトファイルからidを抜き出し
- メンバー変数にViewのクラスを記述して、mから始める名前で定義
- mXxxXxx = (View) findViewById(R.id.xxxx); を記述
EditText mFirstName;
mFirstName = (EditText) findViewById(R.id.first_name);
また、Activity/Fragmentにメンバー変数が多くなり見難くなると思います。
そこで、まずは、これらViewの項目の定義を外だしにしてしまいましょう。
1つのレイアウトに対してViewHolderクラスを作成します。
ViewHolderってのはListAdapterのテクニックでも使用しているあれです。
ViewHolderには、基本的にプロパティ値としてViewも持ちます。
使用前
public class EditActivity extends Activity implements OnClickListener {
public EditText mFirstName;
public EditText mLastName;
public TextView mLabelLastName;
public TextView mLabelFirstName;
public Spinner mSex;
public FrameLayout mFrameSex;
public TextView mLabelSex;
public TextView mLabelBirthday;
public DatePicker mBirthday;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mFirstName = findViewById(R.id.first_name);
mLastName = findViewById(R.id.last_name);
mLabelLastName = findViewById(R.id.label_last_name);
mLabelFirstName = findViewById(R.id.label_first_name);
mSex = findViewById(R.id.sex);
mFrameSex = findViewById(R.id.frame_sex);
mLabelSex = findViewById(R.id.label_sex);
mLabelBirthday = findViewById(R.id.label_birthday);
mBirthday = findViewById(R.id.birthday);
}
}
使用後
public class EditActivity extends Activity implements OnClickListener {
ViewHolder mViewHolder;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mViewHolder = new ViewHolder(getWindow().getDecorView());
}
}
public class ViewHolder {
public EditText mFirstName;
public EditText mLastName;
public TextView mLabelLastName;
public TextView mLabelFirstName;
public Spinner mSex;
public FrameLayout mFrameSex;
public TextView mLabelSex;
public TextView mLabelBirthday;
public DatePicker mBirthday;
public ViewHolder(View v) {
mFirstName = findViewById(v, R.id.first_name);
mLastName = findViewById(v, R.id.last_name);
mLabelLastName = findViewById(v, R.id.label_last_name);
mLabelFirstName = findViewById(v, R.id.label_first_name);
mSex = findViewById(v, R.id.sex);
mFrameSex = findViewById(v, R.id.frame_sex);
mLabelSex = findViewById(v, R.id.label_sex);
mLabelBirthday = findViewById(v, R.id.label_birthday);
mBirthday = findViewById(v, R.id.birthday);
}
@SuppressWarnings("unchecked")
private T findViewById(View v, int id) {
return (T) v.findViewById(id);
}
}
これで、Activity/Fragmentから大量のメンバー変数が消えて、コードを追いやすくなるのではないでしょうか?
でも、ViewHolderにいろいろ書くのは変ってないし、やっぱり面倒くさいよね?
なので、レイアウトからViewHolderを作成するスクリプトを作成しました。
なお、指定するレイアウトは予めフォーマーッター(Ctrl+Shift+F)でフォーマットしておく必要があります。要は、Viewタグの後にIDアトリビュートが定義されてる必要があります。
社員管理・顧客管理などの編集画面で、一度に多くの項目を入力を行わせるアプリを作成することもあります。
StrutsみたいなValidator欲しいなっと思ったので作ってみました。
granoeste/ValidatorForAndroid · GitHub
StrutsみたいなValidator欲しいなっと思ったので作ってみました。
apache commons validatorを参考にしています。
サンプル1 EditViewとValidatorの組み合わせ
サンプル1 EditViewとValidatorの組み合わせ
// Validators
Validators mValidators = new Validators();
EditText mTextPersonName;
EditText mTextPassword;
Button mButton;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextPersonName = (EditText) findViewById(R.id.textPersonName);
mTextPassword = (EditText) findViewById(R.id.textPassword);
mButton = findViewByIdAndCast(v, R.id.button);
// Define validators for views
mValidators.put(mTextPersonName, new Validator[] {
new RequiredValidator("Be sure to input. "),
new MaxLengthValidator(30, "Being allowed is to 30 characters. "),
});
mValidators.put(mTextPassword, new Validator[] {
new RequiredValidator("Be sure to input. "),
new RangeValidator(8, 16, "Being allowed is from 8 to 16 characters. "),
});
mButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// Execute Validators
mValidators.clearError();
if (mValidators.isValid()) {
Toast.makeText(getApplicationContext(), "It has some errors. ", Toast.LENGTH_SHORT).show();
}
}
});
}
// Validators
Validators mValidators = new Validators();
net.granoeste.validator.ValidatableEditText mTextPersonName;
net.granoeste.validator.ValidatableEditText mTextPassword;
Button mButton;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextPersonName = (net.granoeste.validator.ValidatableEditText) findViewById(R.id.textPersonName);
mTextPassword = (net.granoeste.validator.ValidatableEditText) findViewById(R.id.textPassword);
mButton = findViewByIdAndCast(v, R.id.button);
// add ValidatableEditText to Validators
mValidators.put(mTextPersonName);
mValidators.put(mTextEmailAddress);
mButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// Execute Validators
mValidators.clearError();
if (mValidators.isValid()) {
Toast.makeText(getApplicationContext(), "It has some errors. ", Toast.LENGTH_SHORT).show();
}
}
});
}
こんな感じで使用します。
詳しくは、GitHubに上げてるのでソース見てね。
解んなかったら聞いて下さい。
※バグがあったらIssue書いてくれても、ForkしてPull Requesteしてくれてもいいんだよ。
以上になります。
明日は、@out_of_kayaさん と @tarotaro4さん が担当されます。
でわでわ。
メリークリスマス&よいおとしを。
0 件のコメント:
コメントを投稿