スポンサーサイト

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


  • 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フォルダの配下に保存可能
△修里箸のファイル名は、任意の名称で保存することは可能


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の追加をし、開発の準備完了です。




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