サンプルプログラム工場

AAKAKA Appで使われているプログラムのサンプルコードをそのまま公開!

サンプルプログラム工場 > android > AndroidのListViewにボタンをつけるサンプル@tryListView03
Google Play AAKAKAxSOFTへ

AndroidのListViewにボタンをつけるサンプル@tryListView03

実行ファイル(APK)やサンプル(zip)をダウンロードする
tryListView03の実行イメージtryListView03の実行イメージ

●やってること
ListViewの項目を拡張して作る
選択された項目だけ、ボタンを表示する
選択された項目をボタンから項目を消す
リストビューの項目ごとの削除ボタン
現在時刻のを取得する

●カスタムListViewの項目にボタンを追加
ボタンを追加
ボタンのプロパティのFocusableを「false」にする(これしないとListViewの項目が反応しなくなる)

●関連項目
LayoutInflater
Calendar
Context.LAYOUT_INFLATER_SERVICE
setSingleLine
setVisibility

同じようなLinearLayoutを表示/非表示したらレイアウトがうまく切り替わってるようにみえない?

package trial.sample.trylistview03;


import java.util.Calendar;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.net.Uri;
import android.opengl.Visibility;
import android.os.Bundle;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.Checkable;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;


public class TryListView03Activity extends Activity implements OnItemClickListener {
	
	private ListView mListView;	// リストビュー
	private CustomArrayAdapter mAdapter; // アダプタ
	
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // アダプタをリストビューにセットする
        //
        // アダプタを作る
        this.mAdapter = new CustomArrayAdapter(this, R.layout.item);
        // アダプタに項目を追加する
        for (int i = 0; i < 100; i++) {
	        this.mAdapter.add(new CustomArrayAdapterData("-------- " + i + " --------"));
	        this.mAdapter.add(new CustomArrayAdapterData("何か長い文章を考えなきゃいけないんだけど、そうそういい文章がうかぶわけないよねー。"));
	        this.mAdapter.add(new CustomArrayAdapterData("作家さんってすごいと思うんだ。"));
	        this.mAdapter.add(new CustomArrayAdapterData("今週は楽しみにしてた新しいやつの発売だ!"));
	        this.mAdapter.add(new CustomArrayAdapterData("android 4.0って使いやすいけど、開発はやっぱ2.2くらいのやつからやらないとだめなんだよね。"));
	        this.mAdapter.add(new CustomArrayAdapterData("いっそのこと2.3くらいまで上げてやってしまおうか?"));
        }
        // リストビューにアダプタを登録する
        //
        this.mListView = (ListView)this.findViewById(R.id.listView1);
        this.mListView.setAdapter(this.mAdapter);
        this.mListView.setOnItemClickListener(this);
    }
    
    
    /** リストビューが選択された */
	public void onItemClick(AdapterView<?> adapter, View view, int position, long id) {
		this.mAdapter.select(position);
	}
}

//////////////////////////////////////////////////////////////////
//ArrayAdapterの中で使うデータ
class CustomArrayAdapterData {
	String text; // テキスト
	String date;

	/** コンストラクタ */
	public CustomArrayAdapterData(String text) {
		this.text = text;
		
		//////////////////////////////////////////////////////////////////
		// 今の時刻を設定する
		Calendar calendar = Calendar.getInstance();
		this.date = calendar.get(Calendar.YEAR) + "/" +
			calendar.get(Calendar.MONDAY) + "/" +
			calendar.get(Calendar.DAY_OF_MONTH) + " " +
			calendar.get(Calendar.HOUR_OF_DAY) + ":" +
			calendar.get(Calendar.SECOND) + ":" +
			calendar.get(Calendar.MINUTE);
		//////////////////////////////////////////////////////////////////
	}
}

//////////////////////////////////////////////////////////////////
//リストビュー内の項目と関連付けるデータ
class ViewHolder {
	TextView text;
	TextView subText;
	Button button;
}

//////////////////////////////////////////////////////////////////
//ArrayAdapterの拡張
class CustomArrayAdapter extends ArrayAdapter<CustomArrayAdapterData> {

	private LayoutInflater mInflater; // レイアウトXMLファイルからビューを作ってくれるもの
	private int mLayoutId;	// このアダプタのレイアウトID
	private int mSelectedItem;	// 選択されているアイテム

	/** コンストラクタ */
	public CustomArrayAdapter(Context context, int layoutId) {
		super(context, layoutId);

		// ビューを作るためのサービスを取り出す
		this.mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		this.mLayoutId = layoutId;

		this.mSelectedItem = -1;
	}

	/** 選択されているものを設定する */
	public void select(int position) {
		// 新しく選択されたものをセットする
		this.mSelectedItem = position;

		// 変更を通知する
		this.notifyDataSetChanged();
	}

	/** ビューに変化があった時に呼ばれる */
	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		View view = convertView;
		ViewHolder vh = null;

		// 初期状態
		if (view == null) {
			// カスタムビューをリストビューに登録する
			view = this.mInflater.inflate(this.mLayoutId, parent, false);
			// ビューホルダーとしてビューにリストビューの項目を登録する
			vh = new ViewHolder();
			vh.text = (TextView)view.findViewById(R.id.item_text);
			vh.subText = (TextView)view.findViewById(R.id.item_sub_text);
			vh.button = (Button)view.findViewById(R.id.item_button1);
			
			//////////////////////////////////////////////////////////////////
			// 削除ボタンが押されたときに削除できるように
			vh.button.setTag(this.getItem(position));
			// 削除ボタンがクリックされたときの通知先を設定する
			vh.button.setOnClickListener(new OnClickListener() {
				
				// ボタンがクリックされました
				public void onClick(View v) {
					CustomArrayAdapterData data = (CustomArrayAdapterData)v.getTag();
					remove(data);
					showDlg("削除しました。", "object:" + data + " TEXT:" + data.text);
				}
			});
			//////////////////////////////////////////////////////////////////

			// ビューに登録する
			view.setTag(vh);
		} else {
			vh = (ViewHolder)view.getTag();
			//////////////////////////////////////////////////////////////////
			// 削除ボタンの削除用データの更新
			// ここで更新しない場合はだんだん削除位置がずれていく
			vh.button.setTag(this.getItem(position));
			//////////////////////////////////////////////////////////////////
		}

		// 今設定しないといけないアイテムを取り出す
		CustomArrayAdapterData data = (CustomArrayAdapterData)this.getItem(position);
		vh.text.setText(data.text);
		vh.subText.setText(data.date);

		// 選択されているものはすべての文章を表示
		if (this.mSelectedItem == position) {
			
			//////////////////////////////////////////////////////////////////
			// ボタンを表示する
			vh.button.setVisibility(View.VISIBLE);
			//////////////////////////////////////////////////////////////////

			// 文字列を全てを表示する
			vh.text.setSingleLine(false);

			// 未選択のもので長すぎるものは「...」を表示。
		} else {
			
			//////////////////////////////////////////////////////////////////
			// ボタンを非表示にする
			vh.button.setVisibility(View.INVISIBLE);
			//////////////////////////////////////////////////////////////////
			
			// 文字列が長すぎる場合は「...」を表示する
			vh.text.setSingleLine();
			
		}

		return view;
	}
	
	
	/** ダイアログを表示する */
	private void showDlg(String title, String text) {
		AlertDialog.Builder dlg = new AlertDialog.Builder(this.getContext());
		dlg.setTitle(title);
		dlg.setMessage(text);
		dlg.show();
	}
}

//////////////////////////////////////////////////////////////////
//選択したときに背景色を変えたままにするようなレイアウト
//Single Choiceするために必要なもの
class CheckableLinearLayout extends LinearLayout implements Checkable {

	private boolean mChecked;	// チェックされているかどうか
	private static final int[] CHECKED_STATE_SET = {
		android.R.attr.state_checked
	};

	/** コンストラクタ */
	public CheckableLinearLayout(Context context) {
		super(context);
		// TODO 自動生成されたコンストラクター・スタブ
	}

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

	/** 選択されているかどうかを返すもの */
	public boolean isChecked() {
		return this.mChecked;
	}

	/** 選択されたときに呼ばれるようなものかな? */
	public void setChecked(boolean checked) {
		if (this.mChecked != checked) {
			this.mChecked = checked;
			this.refreshDrawableState();
		}
	}
	
	/** 選択と選択解除の切り替えの時に呼ばれる感じ? */
	public void toggle() {
		this.mChecked = !this.mChecked;
		this.refreshDrawableState();
	}
	
	/** これなんだろね?やってることはステータスの変更だけど */
	@Override
	protected int[] onCreateDrawableState(int extraSpace) {
		// 新しいオプションを追加するためにextraSpaceより1つ多めの領域を作ってる?
		final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
		if (this.isChecked()) {
			// android.R.attr.state_checked機能を追加するようにする
			mergeDrawableStates(drawableState, CHECKED_STATE_SET);
		}
		return drawableState;
	}

}

APKファイルをダウンロード サンプルプロジェクトをダウンロード

, ,

GLES20の解説書 AndroidでSQLiteで書き込む、読み込むサンプル@DbProviderEx3

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です


*

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>