スポンサーサイト

一定期間更新がないため広告を表示しています


  • 2010.11.01 Monday
  • -
  • -
  • -
  • -
  • by スポンサードリンク

Android ListView内のコントロールを取得する・・・

 こんなことで悩んでしまいました(汗:

ListView内のコントロールを以下のように定義して、



ListViewの外にあるボタンを押した際に、チェックされているものを全て削除する処理を書いていたのですが・・・

ハマりましたww

結局、以下のようにすれば、ListView内のチェックボックスの状態を取得できたのですが、もう少しいい方法はないのかな・・・

View btnDelete = findViewById(R.id.delete_button);
btnDelete.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// ListView内でチェックされている情報を削除する。
int size = listView.getChildCount();
for (int i = 0; i < size; i++) {
final View listDataView = listView.getChildAt(i);
CheckBox chkDel = (CheckBox) listDataView.findViewById(R.id.rest_del);
if (chkDel.isChecked()) {
System.out.println("選択された行番号=====" + i);
}
}
}
});




Android Market 〜出品〜

 デベロッパーならやっぱり公開でしょ!

ってことで、自分のアプリケーションをより多くの人に観てもらいたい人は、以下の手順でAndroid Marketに登録することで公開することができます。
(尚、登録手数料に$25ドルかかるみたいなので注意です)

  1. Android Marketへお邪魔します。
  2. 画面下部のhereを選択します。
    ※Googleのアカウントが必要となります。
  3. デベロッパー情報を入力します。
    ※電話番号が必要です。(日本は"81")
  4. 登録料$25.00の請求画面
    この際に、Google Checkoutが必要となります。
  5. 配布契約書に同意して手続き完了となります。

とりあえず、今回はここまでです。
次回は、アプリケーションのアップロードについて書きたいと思います。


Android 〜Adapter〜

 Adapter その名の通りですが、AndroidではデータとViewを関連付けるために利用するようです。

public class DailyListAdapter extends ArrayAdapter<DailyDomain> {
private LayoutInflater mInflater;
private TextView _dailyYmd;
private TextView _dailySb;
private TextView _dailyMoney;
private Button _detailButton;
private Button _editButton;

private Activity _parent;

public DailyListAdapter(Context context, List<DailyDomain> objects,
Activity parent) {
super(context, 0, objects);
mInflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this._parent = parent;
}

public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = mInflater.inflate(R.layout.dailylistview, null);
}
final DailyDomain item = this.getItem(position);
if (item != null) {
_dailyYmd = (TextView) convertView
.findViewById(R.id.daily_list_ymd);
_dailyYmd.setText(item.getDailyYmd());
_dailySb = (TextView) convertView.findViewById(R.id.daily_list_sb);
if (item.getDailySb().equals("0")) {
_dailySb.setText("支出");
} else if (item.getDailySb().equals("1")) {
_dailySb.setText("収入");
}
_dailyMoney = (TextView) convertView
.findViewById(R.id.daily_list_money);
_dailyMoney.setText("¥" + item.getDailyMoney());
_detailButton = (Button) convertView
.findViewById(R.id.daily_list_detail);
_detailButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// 詳細ダイアログ表示
Intent intent = new Intent(_parent, DailyDetail.class);

// メモ表示
intent.putExtra(KakeiboConst.DAILY_DETAIL_ACTIVITY_PARAM,
item.getDailyMemo());

// 詳細ダイアログを表示
_parent.startActivity(intent);

}
});

_editButton = (Button) convertView
.findViewById(R.id.daily_list_edit);
_editButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {

// 編集モードで日々入力Activityを表示
Intent intent = new Intent(_parent, DailyInput.class);

// rowidを設定(押されたボタンを判定する方法は?)
intent.putExtra(KakeiboConst.DAILY_INPUT_ACTIVITY_PARAM_1,
item.getRowid());

intent.putExtra(KakeiboConst.DAILY_INPUT_ACTIVITY_PARAM_2,
"1");

// 日々入力Activityを編集モードにて表示
_parent.startActivity(intent);

}
});
}
return convertView;
}

/**
* ListViewに表示するデータを取得する
* @return
*/
public static DailyListAdapter createListViewData(String ymd, Activity activity) {

DailyHelper helper = new DailyHelper(activity);
SQLiteDatabase db = helper.getWritableDatabase();

DailyDao dao = new DailyDao(db);

List<DailyDomain> dailyList = dao.findWhereDailyYMD(ymd);
DailyListAdapter adapter = new DailyListAdapter(activity, dailyList,
activity);

helper.close();

return adapter;
}
}

ちょっと、ソースが荒いですね。(すみません)

で、layoutです。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content" 
android:layout_height="fill_parent"
android:orientation="horizontal"
>
<ScrollView
android:layout_width="fill_parent" 
android:layout_height="fill_parent"
android:scrollbars="horizontal"
>
<LinearLayout
android:layout_width="wrap_content" 
android:layout_height="fill_parent"
android:orientation="horizontal"
>
<TextView android:layout_width="80dip"
android:layout_height="wrap_content"
android:id="@+id/daily_list_ymd">
></TextView>
<TextView android:layout_width="40dip"
android:layout_height="wrap_content"
android:id="@+id/daily_list_sb">
></TextView>
<TextView android:layout_width="120dip"
android:layout_height="wrap_content"
android:id="@+id/daily_list_money">
></TextView>
<Button android:layout_width="40dip"
android:layout_height="40dip"
android:id="@+id/daily_list_detail"
android:text="@string/daily_list_detail"
></Button>
<Button android:layout_width="40dip"
android:layout_height="40dip"
android:id="@+id/daily_list_edit"
android:text="@string/daily_list_edit"
></Button>
</LinearLayout>
</ScrollView>
</LinearLayout>

で、このAdapterをActivityで利用する場合は、以下のようにListActivityを継承させて、setListAdapterにAdapterクラスを渡してあげれば、簡単に表示することが可能になります。


public class DailyListActivity extends ListActivity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);
setContentView(R.layout.kakeibolist);

// インテントより検索条件取得
Bundle bundle = this.getIntent().getExtras();

this.setListAdapter(DailyListAdapter.createListViewData(bundle
.getString(KakeiboConst.DAILY_LIST_ACTIVITY_PARAM), this));

}
}


Android〜拡張ウィジット 

 Android 勉強進んでます。

お試しソフトということで、家計簿作りました。

日々入力するモードと、月々の収支を一覧で表示するだけのいたって簡単なアプリ。
最初の勉強としては、なかなかの出来でしたが、アーキテクチャをどう作ったらいいのか結構なやみました。

ボタン押下時のイベント系の処理ですが、
どこでも使いそうなものは、Listenerクラスを作成してそのクラス内で処理するようにしていたのですが、途中で悲しいかなデータのやりとりに苦戦しました。

成功したのは、拡張ウィジット。
とは言っても、あまり機能を持たせすぎると汎用性がなくなるので、
EditTextを継承して、数値入力用、日付入力用、文字列入力用のクラスを作成。

各クラスは、abstractで定義した親クラスを継承するようにして、
必要に応じて子クラスでプロパティを定義するようにしてました。

親クラスはこんな感じ・・・

public abstract class AbstractEditText extends EditText {
/**
* 入力チェック用メソッド.<p>
* @return TRUE:成功/FALSE:失敗
*/
protected abstract boolean validator();

/**
* コンストラクタ
* @param context
*/
public AbstractEditText(Context context) {
super(context);
}

/**
* コンストラクタ
* @param context
* @param attrs
*/
public AbstractEditText(Context context, AttributeSet attrs) {
super(context, attrs);
initView(context, attrs);
}

/**
* ビューの初期化処理
* @param context
* @param attrs
*/
private void initView(Context context, AttributeSet attrs) {
if (attrs != null) {
required = attrs.getAttributeBooleanValue(null, "required", false);
}
}

/**
* 必須チェック実施可否.
* <p>
*/
protected boolean required = false;

/**
* 必須チェック実施可否.
* <p>
* @return
*/
public boolean isRequired() {
return required;
}

/**
* 必須チェック実施可否の設定
* @param required
*            必須チェック実施可否
*/
public void setRequired(boolean required) {
this.required = required;
}
}

子クラスはこんな感じ・・・

public class CharacterEdit extends AbstractEditText {

/**
* コンストラクタ
* @param context
*/
public CharacterEdit(Context context) {
super(context);
}

/**
* コンストラクタ
* @param context
* @param attrs
*/
public CharacterEdit(Context context, AttributeSet attrs) {
super(context, attrs);
}

/**
* 入力チェック用メソッド.
* <p>
* @return TRUE:成功/FALSE:失敗
*/
@Override
public boolean validator() {
boolean result = true;

// 必須チェック
if (super.required) {
String target = super.getText().toString();
if (target == null || target.equals("")) {
this.setBackgroundColor(Color.RED);
result = false;
}
}
return result;
}

@Override
protected void onFocusChanged(boolean focused, int direction,
Rect previouslyFocusedRect) {
if ( this.validator() ) {
super.onFocusChanged(focused, direction, previouslyFocusedRect);
}
}
}

日付クラスはチェック処理がまだ甘いですが・・
タッチイベントで、DatePickerDialogを利用するようにしてみてます。

public class DateEdit extends AbstractEditText {

/**
 * コンストラクタ
 * 
 * @param context
 */
public DateEdit(Context context) {
super(context);
}

/**
 * コンストラクタ
 * 
 * @param context
 * @param attrs
 */
public DateEdit(Context context, AttributeSet attrs) {
super(context, attrs);
initView(context, attrs);
}

/**
 * ビューの初期化処理
 * 
 * @param context
 * @param attrs
 */
private void initView(Context context, AttributeSet attrs) {
if (attrs != null) {
addSlash = attrs.getAttributeBooleanValue(null, "addslash", false);
}
this.setInputType(InputType.TYPE_DATETIME_VARIATION_DATE);

datePickerDialog = new DatePickerDialog(context,
new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker view, int year,
int monthOfYear, int dayOfMonth) {
setText(year + "/" + monthOfYear + "/" + dayOfMonth);
}
}, Calendar.getInstance().get(Calendar.YEAR), Calendar
.getInstance().get(Calendar.MONTH) + 1, Calendar
.getInstance().get(Calendar.DAY_OF_MONTH));

}

private DatePickerDialog datePickerDialog = null;

@Override
public boolean onTouchEvent(MotionEvent event) {
if (datePickerDialog != null) {
datePickerDialog.show();
}
return super.onTouchEvent(event);
}

/**
 * 入力チェック用メソッド.
 * <p>
 * 
 * @return TRUE:成功/FALSE:失敗
 */
@Override
public boolean validator() {
boolean result = true;

// 必須チェック
if (super.required) {
String target = super.getText().toString();
if (target == null || target.equals("")) {
this.setBackgroundColor(Color.RED);
result = false;
}
}
// 日付妥当性チェックを実施
EditText ymdEdit = (EditText)findViewById(R.id.daily_ymd);
String ymd = ymdEdit.getText().toString();
if (!ymd.equals("")) {
String[] ymds = ymd.split("/");
if (ymds.length == 3) {
int month = Integer.parseInt(ymds[1]);
int day = Integer.parseInt(ymds[2]);
if (!(month <= 12 && month >= 1)) {
ymdEdit.setBackgroundColor(Color.RED);
result = false;
}
if (!(day <= 31 && day >= 1)) {
ymdEdit.setBackgroundColor(Color.RED);
result = false;
}
} else {
ymdEdit.setBackgroundColor(Color.RED);
result = false;
}
} else {
ymdEdit.setBackgroundColor(Color.RED);
result = false;
}
return result;
}

/**
 * テキストボックスに文字列(カンマ編集)を設定する
 * 
 * @param text
 */
public void setText(String date) {
if (date != null) {
if (this.addSlash) {
// カンマ編集
super.setText(DateEdit.getDate(date));
} else {
super.setText(date);
}
}
}

/**
 * 日付のフォーマットを返す。
 * 
 * Setting - Date & Time - Select date formatで設定された値を取得する
 * 
 * @param ctx
 *            the application context
 * 
 * @return
 */
public static final String getDate(String date) {

final String DEFAULT_DATE_FORMAT = "yyyy/MM/dd";

Date inputDate = new Date(date);

SimpleDateFormat formatter = new SimpleDateFormat(DEFAULT_DATE_FORMAT);

return formatter.format(inputDate);
}

/**
 * スラッシュ編集可否.
 * <p>
 */
private boolean addSlash = false;

public boolean isAddSlash() {
return addSlash;
}

public void setAddSlash(boolean addSlash) {
this.addSlash = addSlash;
}
}


参考になるのか?(笑)

Activityも親クラスを作成して、拡張ウィジットを取得できるようにラッパーメソッドを定義してみました。
public class AbstractActivity extends Activity {

/**
* TAG.<p>
*/
protected String _TAG = "AbstractActivity";

/**
* NumberEditクラスを取得する.<p>
* @param id リソースID
* @return NumberEditクラス
*/
protected NumberEdit getNumberEdit(int id) {
NumberEdit result = null;
try {
result = (NumberEdit) findViewById(id);
} catch (ClassCastException ex) {
Log.v(_TAG, ex.getMessage());
}
return result;
}
/**
* DateEditクラスを取得する.<p>
* @param id リソースID
* @return DateEditクラス
*/
protected DateEdit getDateEdit(int id) {
DateEdit result = null;
try {
result = (DateEdit) findViewById(id);
} catch (ClassCastException ex) {
Log.v(_TAG, ex.getMessage());
}
return result;
}
/**
* CharacterEditクラスを取得する.<p>
* @param id リソースID
* @return CharacterEditクラス
*/
protected CharacterEdit getCharacterEdit(int id) {
CharacterEdit result = null;
try {
result = (CharacterEdit) findViewById(id);
} catch (ClassCastException ex) {
Log.v(_TAG, ex.getMessage());
}
return result;
}
}

何よりも、Adapterクラス便利ですな(笑)



Android〜LinearLayout〜

 今日は、LinearLayoutについて・・・

とは言っても、そんなに記述することがないんだけど、

ちょっとわかりにくかったので、覚書です。


■LinearLayout
 android:orientation
   horizontal:水平報告(左から右)に配置
   vertical:垂直方向(上から下)に配置

 ⇒複数階層LinearLayoutを指定できることから、
  ある程度任意のレイアウトにてコントロールの配置が可能。

 ただし、android:layout_widthとandroid:layout_heightには、wrap_contentを
 指定したほうがよさそうだ。
 (horizontalを指定した場合に、最初に定義したコントロールしか表示されなかった・・・)

 wrap_contentを利用すれば、コードから任意の高さと幅を指定することが可能。
 これで、だいぶ自由にレイアウトを調整することができるようだ。

まだまだ、おくが深そう・・・


●追加メモ
 主要アクティビティクラス

  • Activity
  • ListActivity
  • ExpandableListActivity
  • MapActivity
  • LauncherActivity
  • PreferenceActivity
上記、アクティビティについては、段階的に調査してみようと思う。





暇つぶしAndroid〜リソースファイルの分割〜

 ってことで、Androidやってます。

Activityクラスを、いろいろなパッケージに作ってみて、マニフェストファイルから読み込んでみたり、イベントリスナーをファクトリー化してみたりして遊んでいます。

2Dの描画も挑戦しているんだけど、
最近の言語は便利ですね。VC++での実装方法に比べるとだいぶラクだなっと。

今、一つ悩んでいるのが
resourceフォルダで管理しているリソースの管理方法。

簡単なところから、string.xmlを分割するのは容易なんだけど、
valuesフォルダの下にさらにフォルダを作成して.xmlファイルを作成したときに
読み込みがうまくいかなく、Rクラスのメンバに登録されない・・・・

これって、できるのかな?
そろそろ、ネットを頼ったほうが良い気がしてきた・・・

【00:19ごろ】
いろいろと試してみましたが、ダメでした。
(できるのだろうか?)

valuesと同一階層にvalues-XXというフォルダを作成して、
その配下に保存したxmlファイルの定義は読み込んでくれました。

フォルダ分割での管理は、ひとまずこれでできそうですが・・・・・
(やりたかったことと違う・・・)

面白いのは、values-XXのXXの箇所を3文字以上にすると、怒られてしまいました。
また、values以外のフォルダに保存しても、これまたダメでした。

■ルール
valuesフォルダ/values-XXフォルダの配下に保存可能
△修里箸のファイル名は、任意の名称で保存することは可能


マーケティング

マーケティングをWikiで調べてみると、以下のような記述があります。

【マーケティング】
  • 企業や非営利組織が行うあらゆる活動のうち、「顧客が真に求める商品やサービスを作り、その情報を届け、顧客がその商品を効果的に得られるようにする活動」の全てを表す概念である。
要するに企業経営を行う上で、顧客の満足度が最大限に得られると思われる「モノまたはサービス」を提供するために行う全ての行動。

これは個人レベルでも同様なことが言えるので、
例えば、会社の上司なんかも顧客としてとらえることができます。
(当然、部下も顧客です)

上司=顧客という考え方は違和感を持つかたもいると思いますが、
捉え方によっては、上司=顧客も成り立つと思います。

上司の満足度を上げる!というのは、昔からある日本独特の媚をうるに近い印象をもたれる方もいると思いますが、そうではなく最終的に満足が得られればよいので、媚を売る必要はありません。

例えば、仕事を依頼されたときに、二つ返事をするのではなく、
自分なりの意見を言ってから、双方が納得した上で仕事を進めないと、
結果的に双方が後悔するケースが発生することもあると思います。

双方が納得した上で、かつ良い結果が出ることで双方が満足するわけです。
また、しっかりと話し合いを行っておくことで、悪い結果が出たとしても、二つ返事で作業を行う場合に比べて、結果的に得られる満足度は多少なりとも違うと思います。

こういった身近なマーケティングができる人が、最近減ってきているように思えます。特に私がいるIT業界では尚更です。

自分自信の意見を押し付けるだけではなく、
双方がしっかりと満足のいく結果を事前にマーケティングしておくことが、最終的に失敗しない秘訣の一つかと思います。






右手、左手、ネコの手

 だいぶ時間がたってしまいましたが、
先日まで一つのチームであるプロジェクトを完遂しました。

久しぶりに10数名体制での作業となったのですが、
やっぱりチームで作業を行うのは楽しい。

人それぞれが意見を持っていて、
人それぞれが様々なスキルを持っている。

どうしても、スキルに左右されてしまうこの業界ですが、
今回は特に品質を意識してみなで作業をしてもらいました。

今回、作業を実施した時のポイントを以下に4つほど

1点目
基本設計段階で、事前に不具合の発生しそうな箇所をリストアップ。
⇒リストアップした箇所については、詳細設計時にレビューを特に念入りに実施。
⇒また、ソースレビューも同様に念入りに実施。

なかなか、やらなければいけないと思いながら、
どうしても時間の都合で省いてしまう作業ですが、
残業してでも、今回は念入りに不具合発生予測箇所をリストアップしたことが、
のちのちの、みんなの力のいれようにも繋がったと思われます。

2点目
問題が発生した際には、どれだけ忙しい時間であろうと、
一旦、主要メンバーと話しを行い、問題発生箇所の解決を実施。
⇒一人で抱え込ませず、複数人で解決策を導いた。

開発期間が1ヶ月と短いこともあり、できるだけコミュニケーションを
頻繁にとり、問題が発生した際には話し合いをするようにしました。
(会議形式ではなく、自席で話しを行う形式)
また、質問事項等についても複数人に確認を行う形式をとり、
一人でも意見が違った場合は、再度仕様の再確認を行うような形で進めた。


3点目
レビューの徹底と、テストを繰り返し実施。
テスト工程の全工程にて複数回同じテストを行った。
レグレッションテストも随時実施。

⇒できるだけ手が早いメンバーに連続してテストを行ってもらった。
⇒繰り返し行うことで、テスト仕様書に記載されていないテストケースを網羅することができた。

4点目
開発を行う上でのスケジューリングは、皆で話しあい、
納得のいく形で工程を作成
⇒これは以前実施したことがあり、成功したことがあったので今回も採用。

プロジェクト毎にやり方は違うけれど、今回は主にこの4点が成功した要因でした。

当然、スキルがマッチした人と、スキルがマッチしない人とでの混成チームでしたが、
各々が自分達の得意分野を発揮することで、うまくバランスが取れていたと思います。

何より、メンバー全員を信頼することは忘れずに!!!ですけどね。


Android 開発環境を構築してみた。

 ってことで、最近?既に時代遅れ感がありますが、
GoogleのAndroidの書籍を3冊ほど購入。

まずは、開発環境の構築ということで、せかせかと以下の作業を実施。

Android SDKのインストール
 ダウンロードして解凍するだけ・・・・
 念のため、解凍されたディレクトリの、toolsにpathを設定

JDK 6.0 のインストール
 (既にインストール済みでした)

Eclipse 3.5 インストール
 (Eclipseがバージョンごとに増えてきたww)

ADT Plug-Inのインストール
[ヘルプ] - [新規ソフトウェアの更新]

 サイトの追加で、
  以下のURL
   
     https://dl-ssl.google.com/android/eclipse/

から全ての項目をインストール

・・・FATALエラーが発生したぞ・・・(汗)
インストールは完了しているみたいだけど・・・

いったん、Android SDKの更新が完了していなかったので、
AVD Managerから更新を実行。

さきほどのエラーは無視しつつ、そのままAVDの作成へ
AVD ManagerでVirtualDevicesの追加をし、開発の準備完了です。




性能を改善するということ

 どの業界でも、性能(何かを処理する速度)を改善することは
一筋縄ではいきません。

システム業界で製造しているシステムも、
もちろん上述した条件にあてはまるのですが、
昨年の12月から行ってきた今回のシステムの性能改善も、あと数日で終わります。

今までいろいろなことがあったけど、
結果的にお客様に満足がいくものを提供できたことが、
何よりの喜びであると実感しています。

また、今までいろいろなメンバーが
性能改善に携わっていただきました。


「本当にありがとうございます」

曖昧な指示もあったと思うけど、
皆さん我慢してお付き合いしてくれました。

どのような作業(仕事)にも無駄なものなんてありません。
一つ一つの積み重ねが、みなさんの今後の力になると私は信じています。

これから、どこか別の案件でお会いしたとときには、
是非、それまでに培った知識を存分に発揮できるような人として、
今以上に鍛錬を積み重ねて頂ければと思います。



関連会社
株式会社ツクル
誠意と創意で技術を社会に活かすIT企業
          
          
時計
calendar
     12
3456789
10111213141516
17181920212223
24252627282930
31      
<< December 2017 >>
Amazon
selected entries
categories
archives
recent comment
recommend
links
profile
search this site.
sponsored links
others
mobile
qrcode
powered
無料ブログ作成サービス JUGEM
2008JUGEMキャラコングランプリ
キャラクターデザイン:磯崎洋助/「おしゃれひつじ」